1 #include <gdal_priv.h>
2 #include <gdal_alg.h>
3 #include <gdal_rat.h>
4 #include <cpl_string.h>
5 #include <cpl_csv.h>
6 #include <ogr_spatialref.h>
7 #include <ogrsf_frmts.h>
8 #include <cpl_error.h>
9 
10 #include <gdal_version.h>
11 
12 // R headers moved outside extern "C" 070808 RSB re. note from BDR
13 // #ifdef __cplusplus
14 // extern "C" {
15 // #endif
16 
17 /*#include <R.h>
18 #include <Rdefines.h>
19 #include <Rinternals.h>*/
20 #include "rgdal.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #if R_XDR_INTEGER_SIZE == 1
27 #define GDAL_INTEGER_TYPE GDT_Byte
28 #elif R_XDR_INTEGER_SIZE == 2
29 #define GDAL_INTEGER_TYPE GDT_Int16
30 #elif R_XDR_INTEGER_SIZE == 4
31 #define GDAL_INTEGER_TYPE GDT_Int32
32 #endif
33 
34 #if R_XDR_DOUBLE_SIZE == 4
35 #define GDAL_FLOAT_TYPE GDT_Float32
36 #define GDAL_COMPLEX_TYPE GDT_CFloat32
37 #elif R_XDR_DOUBLE_SIZE == 8
38 #define GDAL_FLOAT_TYPE GDT_Float64
39 #define GDAL_COMPLEX_TYPE GDT_CFloat64
40 #endif
41 
42 static CPLErr saved_eErrClass = CE_None;
43 static int saved_err_no = 0;
44 static char saved_error_msg[2048];
45 
46 static SEXP
mkString_safe(const char * string)47 mkString_safe(const char *string) {
48 
49   if (string == NULL) return(R_NilValue);
50 
51   return(mkString(string));
52 
53 }
54 
55 //static char* RSB 070604
56 static const char*
asString(SEXP sxpString,const int i=0)57 asString(SEXP sxpString, const int i = 0) {
58 
59   if (isNull(sxpString)) return NULL;
60 
61   return(CHAR(STRING_ELT(sxpString, i)));
62 
63 }
64 
65 static SEXP
getObjHandle(SEXP sxpObj)66 getObjHandle(SEXP sxpObj) {
67 
68   SEXP sxpHandle;
69   PROTECT(sxpHandle = getAttrib(sxpObj, install("handle")));
70 
71   if (isNull(sxpHandle)) error("Null object handle\n");
72   UNPROTECT(1);
73   return(sxpHandle);
74 
75 }
76 
77 static void*
getGDALObjPtr(SEXP sxpObj)78 getGDALObjPtr(SEXP sxpObj) {
79 
80   SEXP sxpHandle;
81   PROTECT(sxpHandle = getObjHandle(sxpObj));
82 
83   void *extPtr = R_ExternalPtrAddr(sxpHandle);
84 
85   if (extPtr == NULL) error("Null external pointer\n");
86   UNPROTECT(1);
87   return(extPtr);
88 
89 }
90 
isGDALObjPtrNULL(SEXP sxpObj)91 SEXP isGDALObjPtrNULL(SEXP sxpObj) {
92 
93   SEXP sxpHandle, res;
94   PROTECT(sxpHandle = getObjHandle(sxpObj));
95   PROTECT(res = NEW_LOGICAL(1));
96   LOGICAL_POINTER(res)[0] = FALSE;
97 
98   void *extPtr = R_ExternalPtrAddr(sxpHandle);
99 
100   if (extPtr == NULL) LOGICAL_POINTER(res)[0] = TRUE;
101 
102   UNPROTECT(2);
103 
104   return(res);
105 
106 }
107 
108 static GDALDriver*
getGDALDriverPtr(SEXP sxpDriver)109 getGDALDriverPtr(SEXP sxpDriver) {
110 
111   GDALDriver *pDriver = (GDALDriver *) getGDALObjPtr(sxpDriver);
112 
113   if (pDriver == NULL) error("Invalid GDAL driver\n");
114 
115   return (pDriver);
116 
117 }
118 
119 static GDALDataset*
getGDALDatasetPtr(SEXP sxpDataset)120 getGDALDatasetPtr(SEXP sxpDataset) {
121 
122   GDALDataset *pDataset = (GDALDataset *) getGDALObjPtr(sxpDataset);
123 
124   if (pDataset == NULL) error("Invalid GDAL dataset handle\n");
125 
126   return(pDataset);
127 
128 }
129 
130 static GDALRasterBand*
getGDALRasterPtr(SEXP sxpRasterBand)131 getGDALRasterPtr(SEXP sxpRasterBand) {
132 
133   GDALRasterBand *pRasterBand =
134     (GDALRasterBand *) getGDALObjPtr(sxpRasterBand);
135 
136   if (pRasterBand == NULL) error("Invalid raster band\n");
137 
138   return(pRasterBand);
139 
140 }
141 
142 /*static void
143 __errorHandler(CPLErr eErrClass, int err_no, const char *msg) {
144 
145   if (eErrClass == CE_Warning) {
146 
147     warning("\n\tNon-fatal GDAL Error %d: %s\n", err_no, msg);
148 
149   } else {
150 
151     error("\n\tGDAL Error %d: %s\n", err_no, msg);
152 
153   }
154 
155   return;
156 
157 }*/
158 
159 /************************************************************************/
160 /*                       CPLDefaultErrorHandler()                       */
161 /* quoted from GDAL, pointed at REprintf()                              */
162 /************************************************************************/
163 
164 /*void CPL_STDCALL R_CPLDefaultErrorHandler( CPLErr eErrClass, int nError,
165                              const char * pszErrorMsg )
166 
167 {
168     static int       nCount = 0;
169     static int       nMaxErrors = -1;
170 
171     if (eErrClass != CE_Debug)
172     {
173         if( nMaxErrors == -1 )
174         {
175             nMaxErrors =
176                 atoi(CPLGetConfigOption( "CPL_MAX_ERROR_REPORTS", "1000" ));
177         }
178 
179         nCount++;
180         if (nCount > nMaxErrors && nMaxErrors > 0 )
181             return;
182     }
183 
184 
185     if( eErrClass == CE_Debug )
186         REprintf("%s\n", pszErrorMsg );
187     else if( eErrClass == CE_Warning )
188         REprintf("CPL Warning %d: %s\n", nError, pszErrorMsg );
189     else
190         REprintf("CPL ERROR %d: %s\n", nError, pszErrorMsg );
191 
192     if (eErrClass != CE_Debug
193         && nMaxErrors > 0
194         && nCount == nMaxErrors )
195     {
196         REprintf( "More than %d errors or warnings have been reported. "
197                  "No more will be reported from now.\n",
198                  nMaxErrors );
199     }
200 
201 }*/
202 
203 static void
__errorHandler(CPLErr eErrClass,int err_no,const char * msg)204 __errorHandler(CPLErr eErrClass, int err_no, const char *msg) {
205         saved_eErrClass = eErrClass;
206         saved_err_no = err_no;
207 /* a mutex could be usefull here to avoid a race condition if 2 threads
208 trigger the error handler at the same time */
209         strncpy(saved_error_msg, msg, sizeof(saved_error_msg));
210         saved_error_msg[sizeof(saved_error_msg)-1] = 0;
211 }
212 
installErrorHandler()213 void installErrorHandler()
214 {
215    CPLPushErrorHandler(__errorHandler);
216    saved_err_no = 0;
217 }
218 
uninstallErrorHandlerAndTriggerError()219 void uninstallErrorHandlerAndTriggerError()
220 {
221     CPLPopErrorHandler();
222     if (saved_err_no == CE_Warning) {
223 
224     warning("\n\tNon-fatal GDAL Error %d: %s\n", saved_err_no,
225 saved_error_msg);
226 
227   } else if (saved_err_no == CE_Failure) {
228 
229     error("\n\tGDAL Error %d: %s\n", saved_err_no, saved_error_msg);
230 
231   }
232 }
233 
234 
235 
236 SEXP
RGDAL_Init(void)237 RGDAL_Init(void) {
238 
239 //  CPLSetErrorHandler((CPLErrorHandler)__errorHandler);
240 //  CPLPushErrorHandler((CPLErrorHandler)__errorHandler);
241 #ifdef GDALV2
242 
243     installErrorHandler();
244   GDALAllRegister();
245     uninstallErrorHandlerAndTriggerError();
246 
247 #else
248 
249     installErrorHandler();
250   GDALAllRegister();
251     uninstallErrorHandlerAndTriggerError();
252 
253     installErrorHandler();
254   OGRRegisterAll();
255     uninstallErrorHandlerAndTriggerError();
256 
257 #endif
258 
259   return(R_NilValue);
260 
261 }
262 
263 SEXP
RGDAL_Exit(void)264 RGDAL_Exit(void) {
265 
266 //  CPLPopErrorHandler();
267 // from sf CPL_gdal_cleanup_all()
268   OGRCleanupAll();
269   OSRCleanup();
270   GDALDestroyDriverManager();
271 
272   return(R_NilValue);
273 
274 }
275 
276 SEXP
RGDAL_GDALVersionInfo(SEXP str)277 RGDAL_GDALVersionInfo(SEXP str) {
278     SEXP ans;
279 
280     PROTECT(ans=NEW_CHARACTER(1));
281 
282     installErrorHandler();
283     SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(GDALVersionInfo(asString(str))));
284     uninstallErrorHandlerAndTriggerError();
285 
286     UNPROTECT(1);
287 
288     return(ans);
289 }
290 
291 SEXP
RGDAL_GDALCheckVersion(void)292 RGDAL_GDALCheckVersion(void) {
293     SEXP ans;
294 
295     PROTECT(ans=NEW_LOGICAL(1));
296 
297     installErrorHandler();
298     LOGICAL_POINTER(ans)[0] = GDALCheckVersion(GDAL_VERSION_MAJOR,
299         GDAL_VERSION_MINOR, NULL);
300     uninstallErrorHandlerAndTriggerError();
301 
302     UNPROTECT(1);
303 
304     return(ans);
305 }
306 
307 
308 SEXP
RGDAL_GDAL_DATA_Info(void)309 RGDAL_GDAL_DATA_Info(void) {
310     SEXP ans;
311 
312     PROTECT(ans=NEW_CHARACTER(1));
313     installErrorHandler();
314     SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(CSVFilename( "stateplane.csv" )));
315     uninstallErrorHandlerAndTriggerError();
316 
317     UNPROTECT(1);
318 
319     return(ans);
320 }
321 
322 SEXP
RGDAL_GDALwithGEOS(void)323 RGDAL_GDALwithGEOS(void) {
324     SEXP ans;
325 
326 //    int withGEOS;
327 
328 #if GDAL_VERSION_MAJOR >= 3 // New GDAL
329 
330     PROTECT(ans=NEW_CHARACTER(1));
331     SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(GDALVersionInfo("BUILD_INFO")));
332 
333 #else // Old GDAL
334 
335     PROTECT(ans=NEW_LOGICAL(1));
336 
337     CPLPushErrorHandler(CPLQuietErrorHandler);
338     saved_err_no = 0;
339 
340     OGRGeometry *poGeometry1, *poGeometry2;
341     char* pszWKT;
342     pszWKT = (char*) "POINT (10 20)";
343 #if GDAL_VERSION_MAJOR == 1 || ( GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR <= 2 ) // thanks to Even Roualt https://github.com/OSGeo/gdal/issues/681
344 //#if GDAL_VERSION_MAJOR <= 2 && GDAL_VERSION_MINOR <= 2
345     OGRGeometryFactory::createFromWkt( &pszWKT, NULL, &poGeometry1 );
346 #else // l 339
347     OGRGeometryFactory::createFromWkt( (const char*) pszWKT, NULL, &poGeometry1 );
348 #endif // l 339
349     pszWKT = (char*) "POINT (30 20)";
350 #if GDAL_VERSION_MAJOR == 1 || ( GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR <= 2 ) // thanks to Even Roualt https://github.com/OSGeo/gdal/issues/681
351 //#if GDAL_VERSION_MAJOR <= 2 && GDAL_VERSION_MINOR <= 2
352     OGRGeometryFactory::createFromWkt( &pszWKT, NULL, &poGeometry2 );
353 #else // l 346
354     OGRGeometryFactory::createFromWkt( (const char*) pszWKT, NULL, &poGeometry2 );
355 #endif // l 346
356     int withGEOS = 1;
357     if (poGeometry1->Union(poGeometry2) == NULL) withGEOS = 0;//FIXME VG
358     OGRGeometryFactory::destroyGeometry(poGeometry1);
359     OGRGeometryFactory::destroyGeometry(poGeometry2);
360 
361     CPLPopErrorHandler();
362     saved_err_no = 0;
363     LOGICAL_POINTER(ans)[0] = withGEOS;
364 
365 #endif // New GDAL
366 
367     UNPROTECT(1);
368 
369     return(ans);
370 }
371 
372 SEXP
RGDAL_NullHandle(void)373 RGDAL_NullHandle(void) {
374 
375   return(R_MakeExternalPtr(NULL,
376 			   install("Null handle"),
377 			   R_NilValue));
378 
379 }
380 
381 SEXP
RGDAL_GetDescription(SEXP sxpObj)382 RGDAL_GetDescription(SEXP sxpObj) {
383 
384   void *pGDALObj = getGDALObjPtr(sxpObj);
385 
386   installErrorHandler();
387   const char *desc = ((GDALMajorObject *)pGDALObj)->GetDescription();
388   uninstallErrorHandlerAndTriggerError();
389 
390   return(mkString_safe(desc));
391 
392 }
393 
394 
395 SEXP
RGDAL_GetDriverNames(void)396 RGDAL_GetDriverNames(void) {
397 
398 #ifdef GDALV2
399   SEXP ans, ansnames, vattr, rattr;
400 #else
401   SEXP ans, ansnames;
402 #endif
403   int pc=0;
404   installErrorHandler();
405   int nDr=GDALGetDriverCount();
406   uninstallErrorHandlerAndTriggerError();
407 
408   PROTECT(ans = NEW_LIST(4)); pc++;
409   PROTECT(ansnames = NEW_CHARACTER(4)); pc++;
410   SET_STRING_ELT(ansnames, 0, COPY_TO_USER_STRING("name"));
411   SET_STRING_ELT(ansnames, 1, COPY_TO_USER_STRING("long_name"));
412   SET_STRING_ELT(ansnames, 2, COPY_TO_USER_STRING("create"));
413   SET_STRING_ELT(ansnames, 3, COPY_TO_USER_STRING("copy"));
414   setAttrib(ans, R_NamesSymbol, ansnames);
415 //  PROTECT(sxpDriverList = allocVector(STRSXP, GDALGetDriverCount()));
416   SET_VECTOR_ELT(ans, 0, NEW_CHARACTER(nDr));
417   SET_VECTOR_ELT(ans, 1, NEW_CHARACTER(nDr));
418   SET_VECTOR_ELT(ans, 2, NEW_LOGICAL(nDr));
419   SET_VECTOR_ELT(ans, 3, NEW_LOGICAL(nDr));
420 #ifdef GDALV2
421   PROTECT(vattr = NEW_LOGICAL(nDr)); pc++;
422   PROTECT(rattr = NEW_LOGICAL(nDr)); pc++;
423 #endif
424 
425 
426   int i, flag;
427   installErrorHandler();
428   for (i = 0; i < nDr; ++i) {
429 #ifdef GDALV2
430     LOGICAL_POINTER(vattr)[i] = FALSE;
431     LOGICAL_POINTER(rattr)[i] = FALSE;
432 #endif
433 
434     GDALDriver *pDriver = GetGDALDriverManager()->GetDriver(i);
435 #ifdef GDALV2
436     if(pDriver->GetMetadataItem(GDAL_DCAP_VECTOR) != NULL)
437       LOGICAL_POINTER(vattr)[i] = TRUE;
438     if(pDriver->GetMetadataItem(GDAL_DCAP_RASTER) != NULL)
439       LOGICAL_POINTER(rattr)[i] = TRUE;
440 #endif
441 
442     SET_STRING_ELT(VECTOR_ELT(ans, 0), i,
443       mkChar(GDALGetDriverShortName( pDriver )));
444     SET_STRING_ELT(VECTOR_ELT(ans, 1), i,
445       mkChar(GDALGetDriverLongName( pDriver )));
446     flag=0;
447     if (GDALGetMetadataItem( pDriver, GDAL_DCAP_CREATE, NULL )) flag=1;
448     LOGICAL_POINTER(VECTOR_ELT(ans, 2))[i] = flag;
449     flag=0;
450     if (GDALGetMetadataItem( pDriver, GDAL_DCAP_CREATECOPY, NULL )) flag=1;
451     LOGICAL_POINTER(VECTOR_ELT(ans, 3))[i] = flag;
452   }
453   uninstallErrorHandlerAndTriggerError();
454 #ifdef GDALV2
455   setAttrib(ans, install("isVector"), vattr);
456   setAttrib(ans, install("isRaster"), rattr);
457 #endif
458 
459   UNPROTECT(pc);
460 
461   return(ans);
462 
463 }
464 
465 SEXP
RGDAL_GetDriver(SEXP sxpDriverName)466 RGDAL_GetDriver(SEXP sxpDriverName) {
467 
468   const char *pDriverName = asString(sxpDriverName);
469 
470   installErrorHandler();
471   GDALDriver *pDriver = (GDALDriver *) GDALGetDriverByName(pDriverName);
472   uninstallErrorHandlerAndTriggerError();
473 
474   if (pDriver == NULL)
475     error("No driver registered with name: %s\n", pDriverName);
476 
477   SEXP sxpHandle = R_MakeExternalPtr((void *) pDriver,
478 				     install("GDAL Driver"),
479 				     R_NilValue);
480 
481   return(sxpHandle);
482 
483 }
484 
485 static void
deleteFile(GDALDriver * pDriver,const char * filename)486 deleteFile(GDALDriver *pDriver, const char *filename) {
487 
488 
489 #ifdef RGDALDEBUG
490   Rprintf("Deleting temp file: %s... ", filename);
491 //  fflush(stderr);
492 #endif
493 
494   installErrorHandler();
495   if (strcmp(GDALGetDriverLongName( pDriver ), "In Memory Raster") != 0) {
496 //      CPLErr eErr = pDriver->Delete(filename);
497     GDALDeleteDataset((GDALDriverH) pDriver, filename);
498 /*    if (eErr == CE_Failure)
499       warning("Failed to delete dataset: %s\n", filename);*/
500   }
501   uninstallErrorHandlerAndTriggerError();
502 
503 #ifdef RGDALDEBUG
504   Rprintf("done.\n", filename);
505 //  fflush(stderr);
506 #endif
507 
508   return;
509 
510 }
511 
512 SEXP
RGDAL_DeleteFile(SEXP sxpDriver,SEXP sxpFileName)513 RGDAL_DeleteFile(SEXP sxpDriver, SEXP sxpFileName) {
514 
515   GDALDriver *pDriver = getGDALDriverPtr(sxpDriver);
516 
517   const char *filename = asString(sxpFileName);
518 
519 //  GDALDeleteDataset((GDALDriverH) pDriver, filename);
520 
521   deleteFile(pDriver, filename);
522 
523   return(R_NilValue);
524 
525 }
526 
527 SEXP
RGDAL_CloseHandle(SEXP sxpHandle)528 RGDAL_CloseHandle(SEXP sxpHandle) {
529 
530   GDALDataset *pDataset =
531     (GDALDataset *) R_ExternalPtrAddr(sxpHandle);
532 
533 #ifdef RGDALDEBUG
534   Rprintf("Closing GDAL dataset handle %p... ", (void *) pDataset);
535 #endif
536 
537   installErrorHandler();
538   if (pDataset != NULL) {
539 
540 // Even Roualt 120816
541       GDALClose((GDALDatasetH)pDataset);
542 //    pDataset->~GDALDataset();
543 
544     R_ClearExternalPtr(sxpHandle);
545 
546 #ifdef RGDALDEBUG
547     Rprintf(" destroyed ... ");
548 #endif
549 
550   }
551   uninstallErrorHandlerAndTriggerError();
552 
553 #ifdef RGDALDEBUG
554   Rprintf("done.\n");
555 #endif
556 
557   return(R_NilValue);
558 
559 }
560 
561 SEXP
RGDAL_DeleteHandle(SEXP sxpHandle)562 RGDAL_DeleteHandle(SEXP sxpHandle) {
563 
564   GDALDataset *pDataset =
565     (GDALDataset *) R_ExternalPtrAddr(sxpHandle);
566 
567   if (pDataset == NULL) return(R_NilValue);
568 
569   installErrorHandler();
570 
571   GDALDriver *pDriver = pDataset->GetDriver();
572 // 131202 ASAN fix
573   const char *desc = GDALGetDriverShortName( pDriver );
574 //Rprintf("Driver short name %s\n", desc);
575   GDALDriver *pDriver1 = (GDALDriver *) GDALGetDriverByName(desc);
576 
577   char *filename = strdup(pDataset->GetDescription());
578 //Rprintf("file: %s\n", filename);
579 
580 // 131105 Even Roualt idea
581   GDALClose((GDALDatasetH) pDataset);
582 //Rprintf("after GDALClose\n");
583   GDALDeleteDataset((GDALDriverH) pDriver1, filename);
584 //Rprintf("after GDALDeleteDataset\n");
585   free(filename);
586 
587 /* #ifndef OSGEO4W
588   deleteFile(pDriver, filename);
589 #endif */
590 
591   R_ClearExternalPtr(sxpHandle);
592 //  RGDAL_CloseHandle(sxpHandle);
593 
594   uninstallErrorHandlerAndTriggerError();
595   return(R_NilValue);
596 
597 }
598 
599 SEXP
RGDAL_CloseDataset(SEXP sxpDataset)600 RGDAL_CloseDataset(SEXP sxpDataset) {
601 
602 
603   SEXP sxpHandle;
604   PROTECT(sxpHandle = getObjHandle(sxpDataset));
605 
606   if (sxpHandle == NULL) {
607     UNPROTECT(1);
608     return(R_NilValue);
609   }
610 
611   const char *classname = asString(getAttrib(sxpDataset, R_ClassSymbol));
612 
613   if (strcmp(classname, "GDALTransientDataset") == 0) {
614 
615     RGDAL_DeleteHandle(sxpHandle);
616 
617   } else {
618 
619     RGDAL_CloseHandle(sxpHandle);
620   }
621   UNPROTECT(1);
622 
623   return(R_NilValue);
624 
625 }
626 
627 // FIXME rchk Function RGDAL_CloseDataset
628 //  [PB] has possible protection stack imbalance rgdal/src/gdal-bindings.cpp:608
629 SEXP
RGDAL_CreateDataset(SEXP sxpDriver,SEXP sDim,SEXP sType,SEXP sOpts,SEXP sFile)630 RGDAL_CreateDataset(SEXP sxpDriver, SEXP sDim, SEXP sType,
631 		    SEXP sOpts, SEXP sFile) {
632 
633   GDALDriver *pDriver = getGDALDriverPtr(sxpDriver);
634   GDALDataset *pDataset;
635   const char *filename = asString(sFile);
636   int i/*, n*/;
637   char **papszCreateOptions = NULL;
638 
639 #ifdef RGDALDEBUG
640   Rprintf("Opening dataset: %s\n", filename);
641 //  fflush(stderr);
642 #endif
643 
644   if (filename == NULL) error("Invalid file name\n");
645 
646   GDALDataType eGDALType = (GDALDataType) asInteger(sType);
647 
648   installErrorHandler();
649   for (i=0; i < length(sOpts); i++) papszCreateOptions = CSLAddString(
650     papszCreateOptions, CHAR(STRING_ELT(sOpts, i)) );
651 #ifdef RGDALDEBUG
652   for (i=0; i < CSLCount(papszCreateOptions); i++)
653     Rprintf("option %d: %s\n", i, CSLGetField(papszCreateOptions, i));
654 #endif
655   uninstallErrorHandlerAndTriggerError();
656   installErrorHandler();
657   pDataset = pDriver->Create(filename,
658 			  INTEGER(sDim)[0],
659 			  INTEGER(sDim)[1],
660 			  INTEGER(sDim)[2],
661 			  eGDALType, papszCreateOptions);
662   uninstallErrorHandlerAndTriggerError();
663   installErrorHandler();
664   CSLDestroy(papszCreateOptions);
665   uninstallErrorHandlerAndTriggerError();
666 
667   if (pDataset == NULL) error("Unable to create dataset\n");
668 
669   installErrorHandler();
670   pDataset->SetDescription(filename);
671   uninstallErrorHandlerAndTriggerError();
672 
673   SEXP sxpHandle = R_MakeExternalPtr((void *) pDataset,
674 				     install("GDAL Dataset"),
675 				     R_NilValue);
676 
677   return(sxpHandle);
678 
679 }
680 
681 SEXP
RGDAL_OpenDataset(SEXP filename,SEXP read_only,SEXP silent,SEXP allowedDr,SEXP sOpts)682 RGDAL_OpenDataset(SEXP filename, SEXP read_only, SEXP silent, SEXP allowedDr, SEXP sOpts) {
683 
684   const char *fn = asString(filename);
685 
686 #ifdef GDALV2
687   int i;
688   char **papszOpenOptions = NULL;
689   char **papszAllowedDrivers = NULL;
690   installErrorHandler();
691   for (i=0; i < length(sOpts); i++) papszOpenOptions = CSLAddString(
692     papszOpenOptions, CHAR(STRING_ELT(sOpts, i)) );
693   for (i=0; i < CSLCount(papszOpenOptions); i++)
694     Rprintf("option %d: %s\n", i, CSLGetField(papszOpenOptions, i));
695   uninstallErrorHandlerAndTriggerError();
696   installErrorHandler();
697   for (i=0; i < length(allowedDr); i++) papszAllowedDrivers = CSLAddString(
698     papszAllowedDrivers, CHAR(STRING_ELT(allowedDr, i)) );
699   for (i=0; i < CSLCount(papszAllowedDrivers); i++)
700     Rprintf("driver %d: %s\n", i, CSLGetField(papszAllowedDrivers, i));
701   uninstallErrorHandlerAndTriggerError();
702 #endif
703 
704 #ifdef GDALV2
705   unsigned int RWFlag;
706   if (asLogical(read_only))
707     RWFlag = GDAL_OF_RASTER | GDAL_OF_READONLY;
708   else
709     RWFlag = GDAL_OF_RASTER | GDAL_OF_UPDATE;
710 #else
711   GDALAccess RWFlag;
712   if (asLogical(read_only))
713     RWFlag = GA_ReadOnly;
714   else
715     RWFlag = GA_Update;
716 #endif
717 
718 /* Modification suggested by Even Rouault, 2009-08-08: */
719 
720   CPLErrorReset();
721   if (asLogical(silent))
722     CPLPushErrorHandler(CPLQuietErrorHandler);
723   else
724      installErrorHandler();
725 
726 #ifdef GDALV2
727   GDALDataset *pDataset = (GDALDataset *) GDALOpenEx(fn, RWFlag,
728     papszAllowedDrivers, papszOpenOptions, NULL);
729 #else
730   GDALDataset *pDataset = (GDALDataset *) GDALOpen(fn, RWFlag);
731 #endif
732 
733 
734   if (pDataset == NULL)
735     error("%s\n", CPLGetLastErrorMsg());
736 
737   if (asLogical(silent))
738     CPLPopErrorHandler();
739   else
740     uninstallErrorHandlerAndTriggerError();
741 
742 #ifdef GDALV2
743   installErrorHandler();
744   CSLDestroy(papszOpenOptions);
745   CSLDestroy(papszAllowedDrivers);
746   uninstallErrorHandlerAndTriggerError();
747 #endif
748 
749 /* Similarly to SWIG bindings, the following lines will cause
750 RGDAL_OpenDataset() to fail on - uncleared - errors even if pDataset is not
751 NULL. They could also be just removed. While pDataset != NULL, there's some
752 hope ;-) */
753 
754 /*  CPLErr eclass = CPLGetLastErrorType();
755 
756   if (pDataset != NULL && eclass == CE_Failure) {
757     GDALClose(pDataset);
758     pDataset = NULL;
759     __errorHandler(eclass, CPLGetLastErrorNo(), CPLGetLastErrorMsg());
760   }*/
761 
762 
763   SEXP sxpHandle = R_MakeExternalPtr((void *) pDataset,
764 				     install("GDAL Dataset"),
765 				     R_NilValue);
766 
767   return(sxpHandle);
768 
769 }
770 
771 SEXP
RGDAL_CopyDataset(SEXP sxpDataset,SEXP sxpDriver,SEXP sxpStrict,SEXP sxpOpts,SEXP sxpFile)772 RGDAL_CopyDataset(SEXP sxpDataset, SEXP sxpDriver,
773 		  SEXP sxpStrict,  SEXP sxpOpts,
774 		  SEXP sxpFile) {
775 
776   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
777   char **papszCreateOptions = NULL;
778   int i;
779 
780   const char *filename = asString(sxpFile);
781 
782   if (filename == NULL) error("Invalid filename\n");
783 
784   GDALDriver *pDriver = getGDALDriverPtr(sxpDriver);
785 
786   installErrorHandler();
787   for (i=0; i < length(sxpOpts); i++) papszCreateOptions = CSLAddString(
788     papszCreateOptions, CHAR(STRING_ELT(sxpOpts, i)) );
789   uninstallErrorHandlerAndTriggerError();
790 #ifdef RGDALDEBUG
791   installErrorHandler();
792   for (i=0; i < CSLCount(papszCreateOptions); i++)
793     Rprintf("option %d: %s\n", i, CSLGetField(papszCreateOptions, i));
794   uninstallErrorHandlerAndTriggerError();
795 #endif
796   installErrorHandler();
797   GDALDataset *pDatasetCopy = pDriver->CreateCopy(filename,
798 		pDataset, asInteger(sxpStrict),
799 		papszCreateOptions, NULL, NULL);
800   uninstallErrorHandlerAndTriggerError();
801 
802   if (pDatasetCopy == NULL) error("Dataset copy failed\n");
803 
804   installErrorHandler();
805   CSLDestroy(papszCreateOptions);
806   uninstallErrorHandlerAndTriggerError();
807 
808   SEXP sxpHandle = R_MakeExternalPtr((void *) pDatasetCopy,
809 				     install("GDAL Dataset"),
810 				     R_NilValue);
811 
812 
813   return(sxpHandle);
814 
815 }
816 
817 SEXP
RGDAL_GetRasterXSize(SEXP sDataset)818 RGDAL_GetRasterXSize(SEXP sDataset) {
819 
820   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
821 
822   int res;
823 
824   installErrorHandler();
825   res = pDataset->GetRasterXSize();
826   uninstallErrorHandlerAndTriggerError();
827   return(ScalarInteger(res));
828 
829 }
830 
831 SEXP
RGDAL_GetRasterYSize(SEXP sDataset)832 RGDAL_GetRasterYSize(SEXP sDataset) {
833 
834   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
835 
836   int res;
837 
838   installErrorHandler();
839   res = pDataset->GetRasterYSize();
840   uninstallErrorHandlerAndTriggerError();
841   return(ScalarInteger(res));
842 
843 }
844 
845 SEXP
RGDAL_GetRasterCount(SEXP sDataset)846 RGDAL_GetRasterCount(SEXP sDataset) {
847 
848   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
849 
850   int res;
851 
852   installErrorHandler();
853   res = pDataset->GetRasterCount();
854   uninstallErrorHandlerAndTriggerError();
855   return(ScalarInteger(res));
856 
857 }
858 
859 SEXP
860 RGDAL_GetProjectionRef3(SEXP sDataset, SEXP enforce_xy);
861 
862 SEXP
RGDAL_GetProjectionRef3(SEXP sDataset,SEXP enforce_xy)863 RGDAL_GetProjectionRef3(SEXP sDataset, SEXP enforce_xy) {
864 
865 #if GDAL_VERSION_MAJOR > 2
866 
867   SEXP ans, Datum, ToWGS84, Ellps;
868   int i, pc=0;
869   const char *datum, *towgs84, *ellps;
870   OGRSpatialReference *oSRS;
871   int vis_order;
872 
873   if (enforce_xy == R_NilValue) vis_order = 0;
874   else if (LOGICAL_POINTER(enforce_xy)[0] == 1) vis_order = 1;
875   else if (LOGICAL_POINTER(enforce_xy)[0] == 0) vis_order = 0;
876   else vis_order = 0;
877 
878   installErrorHandler();
879   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
880   oSRS = (OGRSpatialReference*) pDataset->GetSpatialRef();
881   uninstallErrorHandlerAndTriggerError();
882 
883   if (oSRS != NULL) {
884     installErrorHandler();
885     if (vis_order == 1)
886     oSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
887     uninstallErrorHandlerAndTriggerError();
888   }
889 
890   PROTECT(ans = NEW_CHARACTER(1)); pc++;
891 
892   if (oSRS != NULL) {
893 
894     installErrorHandler();
895     datum = oSRS->GetAttrValue("DATUM");
896     uninstallErrorHandlerAndTriggerError();
897     PROTECT(Datum = NEW_CHARACTER(1)); pc++;
898     if (datum != NULL) {
899       SET_STRING_ELT(Datum, 0, COPY_TO_USER_STRING(datum));
900       setAttrib(ans, install("datum"), Datum);
901     }
902 
903     installErrorHandler();
904     ellps = oSRS->GetAttrValue("DATUM|SPHEROID");
905     uninstallErrorHandlerAndTriggerError();
906     PROTECT(Ellps = NEW_CHARACTER(1)); pc++;
907     if (ellps != NULL) {
908       SET_STRING_ELT(Ellps, 0, COPY_TO_USER_STRING(ellps));
909       setAttrib(ans, install("ellps"), Ellps);
910     }
911 
912     PROTECT(ToWGS84 = NEW_CHARACTER(7)); pc++;
913     installErrorHandler();
914     for (i=0; i<7; i++) {
915       towgs84 = oSRS->GetAttrValue("TOWGS84", i);
916       if (towgs84 != NULL) SET_STRING_ELT(ToWGS84, i,
917         COPY_TO_USER_STRING(towgs84));
918     }
919     setAttrib(ans, install("towgs84"), ToWGS84);
920     uninstallErrorHandlerAndTriggerError();
921 
922     SEXP WKT2_2018;
923     char *wkt2=NULL;
924     PROTECT(WKT2_2018 = NEW_CHARACTER(1)); pc++;
925     const char* papszOptions[] = { "FORMAT=WKT2_2018", "MULTILINE=YES", nullptr };
926     installErrorHandler();
927     if (oSRS->exportToWkt(&wkt2, papszOptions) != OGRERR_NONE) {
928       SET_STRING_ELT(WKT2_2018, 0, NA_STRING);
929     } else {
930       SET_STRING_ELT(WKT2_2018, 0, COPY_TO_USER_STRING(wkt2));
931       CPLFree( wkt2 );
932     }
933     uninstallErrorHandlerAndTriggerError();
934     setAttrib(ans, install("WKT2_2018"), WKT2_2018);
935 
936     installErrorHandler();
937     char *pszSRS_P4 = NULL;
938     if (oSRS->exportToProj4( &pszSRS_P4 ) != OGRERR_NONE) {
939       SET_STRING_ELT(ans, 0, NA_STRING);
940     } else {
941       SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(pszSRS_P4));
942       CPLFree( pszSRS_P4 );
943     }
944     uninstallErrorHandlerAndTriggerError();
945   } else SET_STRING_ELT(ans, 0, NA_STRING);
946 
947 
948   UNPROTECT(pc);
949   return(ans);
950 
951 #else
952 
953   return(R_NilValue);
954 
955 #endif
956 
957 }
958 
959 /* changed to return proj4 string 20060212 RSB */
960 SEXP
RGDAL_GetProjectionRef(SEXP sDataset,SEXP enforce_xy)961 RGDAL_GetProjectionRef(SEXP sDataset, SEXP enforce_xy) {
962 
963   if (GDAL_VERSION_MAJOR >= 3) {
964     return(RGDAL_GetProjectionRef3(sDataset, enforce_xy));
965   }
966 
967   OGRSpatialReference *oSRS = new OGRSpatialReference;
968   char *pszSRS_WKT = NULL;
969   SEXP ans;
970   int pc=0;
971 
972   installErrorHandler();
973 
974   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
975 
976   pszSRS_WKT = (char*) pDataset->GetProjectionRef();
977   uninstallErrorHandlerAndTriggerError();
978 
979   PROTECT(ans = NEW_CHARACTER(1)); pc++;
980 
981   if (strlen(pszSRS_WKT) == 0) {
982     SET_STRING_ELT(ans, 0, NA_STRING);
983     UNPROTECT(pc);
984     return(ans);
985   }
986 
987   installErrorHandler();
988 #if GDAL_VERSION_MAJOR == 1 || ( GDAL_VERSION_MAJOR == 2 && GDAL_VERSION_MINOR <= 2 ) // https://github.com/OSGeo/gdal/issues/681
989 //#if GDAL_VERSION_MAJOR <= 2 && GDAL_VERSION_MINOR <= 2
990   oSRS->importFromWkt( &pszSRS_WKT );
991 #else
992   oSRS->importFromWkt( (const char*) pszSRS_WKT );
993 #endif
994   uninstallErrorHandlerAndTriggerError();
995 
996   if (oSRS != NULL) {
997     installErrorHandler();
998     if (oSRS->exportToProj4( &pszSRS_WKT ) != OGRERR_NONE) {
999       SET_STRING_ELT(ans, 0, NA_STRING);
1000     } else {
1001       SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(pszSRS_WKT));
1002       CPLFree( pszSRS_WKT );
1003     }
1004     uninstallErrorHandlerAndTriggerError();
1005   } else SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(""));
1006 
1007 
1008 //  delete oSRS;
1009 
1010   UNPROTECT(pc);
1011   return(ans);
1012 
1013 }
1014 
1015 SEXP
RGDAL_GetMetadata(SEXP sDataset,SEXP tag)1016 RGDAL_GetMetadata(SEXP sDataset, SEXP tag) {
1017 
1018     char **papszMetadata;
1019     SEXP ans;
1020     int i, n, pc=0;
1021 
1022     GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
1023 
1024   installErrorHandler();
1025     if (tag == R_NilValue) {
1026         papszMetadata = pDataset->GetMetadata( NULL );
1027     } else {
1028         papszMetadata = pDataset->GetMetadata(CHAR(STRING_ELT(tag, 0)));
1029     }
1030   uninstallErrorHandlerAndTriggerError();
1031 
1032     if (CSLCount(papszMetadata) == 0) return(R_NilValue);
1033 
1034     for (n=0; papszMetadata[n] != NULL; n++);
1035     PROTECT(ans = NEW_CHARACTER(n)); pc++;
1036     for (i=0; i<n; i++)
1037         SET_STRING_ELT(ans, i, COPY_TO_USER_STRING(papszMetadata[i]));
1038 
1039     UNPROTECT(pc);
1040     return(ans);
1041 }
1042 
1043 
1044 
1045 
1046 
1047 SEXP
RGDAL_GetDatasetDriver(SEXP sDataset)1048 RGDAL_GetDatasetDriver(SEXP sDataset) {
1049 
1050   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
1051 
1052   installErrorHandler();
1053   GDALDriver *pDriver = pDataset->GetDriver();
1054   uninstallErrorHandlerAndTriggerError();
1055 
1056   SEXP sxpDriver = R_MakeExternalPtr((void *) pDriver,
1057 				     install("GDAL Dataset"),
1058 				     R_NilValue);
1059 
1060   return(sxpDriver);
1061 
1062 }
1063 
1064 SEXP
RGDAL_GetDriverShortName(SEXP sxpDriver)1065 RGDAL_GetDriverShortName(SEXP sxpDriver) {
1066 
1067   GDALDriver *pDriver = getGDALDriverPtr(sxpDriver);
1068 
1069   installErrorHandler();
1070   const char *desc = GDALGetDriverShortName( pDriver );
1071   uninstallErrorHandlerAndTriggerError();
1072   return(mkString_safe(desc));
1073 
1074 }
1075 
1076 SEXP
RGDAL_GetDriverLongName(SEXP sxpDriver)1077 RGDAL_GetDriverLongName(SEXP sxpDriver) {
1078 
1079   GDALDriver *pDriver = getGDALDriverPtr(sxpDriver);
1080   installErrorHandler();
1081   const char *desc = GDALGetDriverLongName( pDriver );
1082   uninstallErrorHandlerAndTriggerError();
1083   return(mkString_safe(desc));
1084 }
1085 
1086 SEXP
RGDAL_GetRasterBand(SEXP sDataset,SEXP sBand)1087 RGDAL_GetRasterBand(SEXP sDataset, SEXP sBand) {
1088 
1089   GDALDataset *pDataset = getGDALDatasetPtr(sDataset);
1090 
1091   int band = asInteger(sBand);
1092 
1093   installErrorHandler();
1094   GDALRasterBand *pRasterBand = pDataset->GetRasterBand(band);
1095   uninstallErrorHandlerAndTriggerError();
1096 
1097   SEXP rpRasterBand = R_MakeExternalPtr((void *) pRasterBand,
1098 					install("GDAL Raster Band"),
1099 					R_NilValue);
1100   return(rpRasterBand);
1101 
1102 }
1103 
1104 SEXP
RGDAL_GetXSize(SEXP sRasterBand)1105 RGDAL_GetXSize(SEXP sRasterBand) {
1106 
1107   GDALRasterBand *pRasterBand = getGDALRasterPtr(sRasterBand);
1108 
1109   int res;
1110 
1111   installErrorHandler();
1112   res = pRasterBand->GetXSize();
1113   uninstallErrorHandlerAndTriggerError();
1114   return(ScalarInteger(res));
1115 
1116 }
1117 
1118 SEXP
RGDAL_GetYSize(SEXP sRasterBand)1119 RGDAL_GetYSize(SEXP sRasterBand) {
1120 
1121   GDALRasterBand *pRasterBand = getGDALRasterPtr(sRasterBand);
1122 
1123   int res;
1124 
1125   installErrorHandler();
1126   res = pRasterBand->GetYSize();
1127   uninstallErrorHandlerAndTriggerError();
1128   return(ScalarInteger(res));
1129 
1130 }
1131 
1132 SEXP
RGDAL_GetRasterBlockSize(SEXP rasterObj)1133 RGDAL_GetRasterBlockSize(SEXP rasterObj) {
1134 
1135 	 GDALRasterBand *raster = getGDALRasterPtr(rasterObj);
1136 
1137 	 SEXP blockSize;
1138          PROTECT(blockSize = allocVector(INTSXP, 2));
1139 
1140   installErrorHandler();
1141 	 raster->GetBlockSize(INTEGER(blockSize) + 1, INTEGER(blockSize));
1142   uninstallErrorHandlerAndTriggerError();
1143 	 UNPROTECT(1);
1144 	 return(blockSize);
1145 
1146 }
1147 
1148 SEXP
RGDAL_GetAccess(SEXP sxpDataset)1149 RGDAL_GetAccess(SEXP sxpDataset) {
1150 
1151   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
1152   int res;
1153 
1154   installErrorHandler();
1155   res = pDataset->GetAccess() == GA_ReadOnly;
1156   uninstallErrorHandlerAndTriggerError();
1157   return(ScalarLogical(res));
1158 
1159 }
1160 
1161 SEXP
RGDAL_GetRasterAccess(SEXP sxpRasterBand)1162 RGDAL_GetRasterAccess(SEXP sxpRasterBand) {
1163 
1164   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1165 
1166   int res;
1167 
1168   installErrorHandler();
1169   res = pRasterBand->GetAccess() == GA_ReadOnly;
1170   uninstallErrorHandlerAndTriggerError();
1171   return(ScalarLogical(res));
1172 
1173 }
1174 
1175 SEXP
RGDAL_GetNoDataValue(SEXP sxpRasterBand)1176 RGDAL_GetNoDataValue(SEXP sxpRasterBand) {
1177 
1178   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1179 
1180   int hasNoDataValue;
1181 
1182   installErrorHandler();
1183   double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue);
1184   uninstallErrorHandlerAndTriggerError();
1185 
1186   return(hasNoDataValue ? ScalarReal(noDataValue) : R_NilValue);
1187 
1188 }
1189 
1190 SEXP
RGDAL_GetOffset(SEXP sxpRasterBand)1191 RGDAL_GetOffset(SEXP sxpRasterBand) {
1192 
1193   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1194   double res;
1195 
1196   installErrorHandler();
1197   res = pRasterBand->GetOffset();
1198   uninstallErrorHandlerAndTriggerError();
1199   return(ScalarReal(res));
1200 
1201 }
1202 
1203 SEXP
RGDAL_GetScale(SEXP sxpRasterBand)1204 RGDAL_GetScale(SEXP sxpRasterBand) {
1205 
1206   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1207   double res;
1208 
1209   installErrorHandler();
1210   res = pRasterBand->GetScale();
1211   uninstallErrorHandlerAndTriggerError();
1212   return(ScalarReal(res));
1213 
1214 }
1215 
1216 /* SEXP
1217 RGDAL_GetBandMetadataItem(SEXP sxpRasterBand, SEXP sxpItem, SEXP sxpDomain) {
1218  item: PIXELTYPE, domain: IMAGE_STRUCTURE
1219  http://trac.osgeo.org/gdal/wiki/rfc14_imagestructure
1220 
1221   SEXP ans;
1222 
1223   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1224   PROTECT(ans = NEW_CHARACTER(1));
1225 
1226   SET_STRING_ELT(ans, 0, COPY_TO_USER_STRING(pRasterBand->GetMetadataItem(
1227     CHAR(STRING_ELT(sxpItem, 0)), CHAR(STRING_ELT(sxpDomain, 0)))));
1228 
1229   UNPROTECT(1);
1230   return(ans);
1231 } */
1232 
1233 
1234 SEXP
RGDAL_GetRAT(SEXP sxpRasterBand)1235 RGDAL_GetRAT(SEXP sxpRasterBand) {
1236 
1237   SEXP ans, GFT_type, GFT_usage, nc_names;
1238 
1239   int nc, nr, i, j, ival, np=0;
1240   double val;
1241   GDALRATFieldType *nc_types;
1242   GDALRATFieldUsage *nc_usages;
1243   const char *GFU_type_string[] = {"GFT_Integer",
1244                                    "GFT_Real",
1245                                    "GFT_String"};
1246   const char *GFU_usage_string[] = {"GFU_Generic",
1247                                     "GFU_PixelCount",
1248                                     "GFU_Name",
1249                                     "GFU_Min",
1250                                     "GFU_Max",
1251                                     "GFU_MinMax",
1252                                     "GFU_Red",
1253                                     "GFU_Green",
1254                                     "GFU_Blue",
1255                                     "GFU_Alpha",
1256                                     "GFU_RedMin",
1257                                     "GFU_GreenMin",
1258                                     "GFU_BlueMin",
1259                                     "GFU_AlphaMin",
1260                                     "GFU_RedMax",
1261                                     "GFU_GreenMax",
1262                                     "GFU_BlueMax",
1263                                     "GFU_AlphaMax",
1264                                     "GFU_MaxCount"};
1265 
1266   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1267 
1268   installErrorHandler();
1269   const GDALRasterAttributeTable *pRAT = pRasterBand->GetDefaultRAT();
1270   uninstallErrorHandlerAndTriggerError();
1271 
1272   if (pRAT == NULL) return(R_NilValue);
1273 
1274   installErrorHandler();
1275   nc = (int) pRAT->GetColumnCount();
1276   uninstallErrorHandlerAndTriggerError();
1277   PROTECT(ans = NEW_LIST(nc));np++;
1278   PROTECT(nc_names = NEW_CHARACTER(nc));np++;
1279   nc_types = (GDALRATFieldType *) R_alloc((size_t) nc,
1280     sizeof(GDALRATFieldType));
1281   nc_usages = (GDALRATFieldUsage *) R_alloc((size_t) nc,
1282     sizeof(GDALRATFieldUsage));
1283   installErrorHandler();
1284   nr = (int) pRAT->GetRowCount();
1285   uninstallErrorHandlerAndTriggerError();
1286 
1287   installErrorHandler();
1288   for (i=0; i<nc; i++) {
1289     nc_types[i] = pRAT->GetTypeOfCol(i);
1290     nc_usages[i] = pRAT->GetUsageOfCol(i);
1291     SET_STRING_ELT(nc_names, i, COPY_TO_USER_STRING(pRAT->GetNameOfCol(i)));
1292     if (nc_types[i] == GFT_Integer) {
1293       SET_VECTOR_ELT(ans, i, NEW_INTEGER(nr));
1294     } else if (nc_types[i] == GFT_Real) {
1295       SET_VECTOR_ELT(ans, i, NEW_NUMERIC(nr));
1296     } else if (nc_types[i] == GFT_String) {
1297       SET_VECTOR_ELT(ans, i, NEW_CHARACTER(nr));
1298     } else {
1299       error("unknown column type");
1300     }
1301   }
1302   uninstallErrorHandlerAndTriggerError();
1303   installErrorHandler();
1304   for (i=0; i<nc; i++) {
1305 
1306     if (nc_types[i] == GFT_Integer) {
1307 
1308       for (j=0; j<nr; j++) {
1309         ival = (int) pRAT->GetValueAsInt(j, i);
1310         INTEGER_POINTER(VECTOR_ELT(ans, i))[j] = ival;
1311       }
1312 
1313     } else if (nc_types[i] == GFT_Real) {
1314 
1315       for (j=0; j<nr; j++) {
1316         val = (double) pRAT->GetValueAsDouble(j, i);
1317         NUMERIC_POINTER(VECTOR_ELT(ans, i))[j] = val;
1318       }
1319 
1320     } else if (nc_types[i] == GFT_String) {
1321 
1322       for (j=0; j<nr; j++) {
1323         SET_STRING_ELT(VECTOR_ELT(ans, i), j,
1324           COPY_TO_USER_STRING(pRAT->GetValueAsString(j, i)));
1325       }
1326 
1327     }
1328 
1329   }
1330   uninstallErrorHandlerAndTriggerError();
1331   PROTECT(GFT_type = NEW_CHARACTER(nc));np++;
1332   PROTECT(GFT_usage = NEW_CHARACTER(nc));np++;
1333 
1334   for (i=0; i<nc; i++) {
1335     SET_STRING_ELT(GFT_type, i,
1336       COPY_TO_USER_STRING(GFU_type_string[nc_types[i]]));
1337     SET_STRING_ELT(GFT_usage, i,
1338       COPY_TO_USER_STRING(GFU_usage_string[nc_usages[i]]));
1339   }
1340 
1341   setAttrib(ans, install("GFT_type"), GFT_type);
1342   setAttrib(ans, install("GFT_usage"), GFT_usage);
1343   setAttrib(ans, R_NamesSymbol, nc_names);
1344 
1345   UNPROTECT(np);
1346   return(ans);
1347 }
1348 
1349 SEXP
RGDAL_GetBandMinimum(SEXP sxpRasterBand)1350 RGDAL_GetBandMinimum(SEXP sxpRasterBand) {
1351 
1352   SEXP ans;
1353 
1354   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1355   PROTECT(ans = NEW_NUMERIC(1));
1356 
1357   installErrorHandler();
1358   NUMERIC_POINTER(ans)[0] = (double) pRasterBand->GetMinimum();
1359   uninstallErrorHandlerAndTriggerError();
1360 
1361   UNPROTECT(1);
1362   return(ans);
1363 }
1364 
1365 SEXP
RGDAL_GetBandMaximum(SEXP sxpRasterBand)1366 RGDAL_GetBandMaximum(SEXP sxpRasterBand) {
1367 
1368   SEXP ans;
1369 
1370   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1371   PROTECT(ans = NEW_NUMERIC(1));
1372 
1373   installErrorHandler();
1374   NUMERIC_POINTER(ans)[0] = (double) pRasterBand->GetMaximum();
1375   uninstallErrorHandlerAndTriggerError();
1376 
1377   UNPROTECT(1);
1378   return(ans);
1379 }
1380 
1381 SEXP
RGDAL_GetBandStatistics(SEXP sxpRasterBand,SEXP silent)1382 RGDAL_GetBandStatistics(SEXP sxpRasterBand, SEXP silent) {
1383 
1384   CPLErr err;
1385 
1386   SEXP ans;
1387 
1388   double min, max, mean, sd;
1389 
1390   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1391 
1392   installErrorHandler();
1393   err = pRasterBand->GetStatistics(FALSE, FALSE, &min, &max, &mean, &sd);
1394 
1395   if (err == CE_Failure) {
1396 	if (!LOGICAL_POINTER(silent)[0])
1397             warning("statistics not supported by this driver");
1398   uninstallErrorHandlerAndTriggerError();
1399         return(R_NilValue);
1400   }
1401 
1402   if (err == CE_Warning) {
1403 	if (!LOGICAL_POINTER(silent)[0])
1404     	    warning("statistics not supported by this driver");
1405   uninstallErrorHandlerAndTriggerError();
1406         return(R_NilValue);
1407   }
1408   uninstallErrorHandlerAndTriggerError();
1409 
1410   PROTECT(ans = NEW_NUMERIC(4));
1411   NUMERIC_POINTER(ans)[0] = min;
1412   NUMERIC_POINTER(ans)[1] = max;
1413   NUMERIC_POINTER(ans)[2] = mean;
1414   NUMERIC_POINTER(ans)[3] = sd;
1415 
1416   UNPROTECT(1);
1417   return(ans);
1418 }
1419 
1420 
1421 
1422 SEXP
RGDAL_GetBandType(SEXP sxpRasterBand)1423 RGDAL_GetBandType(SEXP sxpRasterBand) {
1424 
1425   SEXP ans;
1426 
1427   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1428   PROTECT(ans = NEW_INTEGER(1));
1429 
1430   installErrorHandler();
1431   INTEGER_POINTER(ans)[0] = (int) pRasterBand->GetRasterDataType();
1432   uninstallErrorHandlerAndTriggerError();
1433 
1434   UNPROTECT(1);
1435   return(ans);
1436 }
1437 
1438 
1439 SEXP
RGDAL_PutRasterData(SEXP sxpRasterBand,SEXP sxpData,SEXP sxpOffset)1440 RGDAL_PutRasterData(SEXP sxpRasterBand, SEXP sxpData, SEXP sxpOffset) {
1441 
1442   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1443 
1444   int rowsIn = nrows(sxpData);
1445   int colsIn = ncols(sxpData);
1446 
1447   GDALDataType eGDALType = GDT_Int32;
1448 
1449   switch(pRasterBand->GetRasterDataType()) {
1450 
1451   case GDT_Byte:
1452   case GDT_UInt16:
1453   case GDT_Int16:
1454   case GDT_UInt32:
1455   case GDT_Int32:
1456 
1457     eGDALType = GDAL_INTEGER_TYPE;
1458     PROTECT(sxpData = coerceVector(sxpData, INTSXP));
1459   // Transpose data
1460 // replication for 2.4.0 RSB 20060726
1461     installErrorHandler();
1462     if(pRasterBand->RasterIO(GF_Write,
1463 			   INTEGER(sxpOffset)[1],
1464 			   INTEGER(sxpOffset)[0],
1465 			   rowsIn, colsIn,
1466 			   (void *)INTEGER(sxpData),
1467 			   rowsIn, colsIn,
1468 			   eGDALType,
1469 			   0, 0)
1470        == CE_Failure) {
1471       uninstallErrorHandlerAndTriggerError();
1472       error("Failure during raster IO\n");
1473     }
1474     uninstallErrorHandlerAndTriggerError();
1475 
1476     break;
1477 
1478   case GDT_Float32:
1479   case GDT_Float64:
1480 
1481     eGDALType = GDAL_FLOAT_TYPE;
1482     PROTECT(sxpData = coerceVector(sxpData, REALSXP));
1483   // Transpose data
1484     installErrorHandler();
1485     if(pRasterBand->RasterIO(GF_Write,
1486 			   INTEGER(sxpOffset)[1],
1487 			   INTEGER(sxpOffset)[0],
1488 			   rowsIn, colsIn,
1489 			   (void *)REAL(sxpData),
1490 			   rowsIn, colsIn,
1491 			   eGDALType,
1492 			   0, 0)
1493        == CE_Failure) {
1494       uninstallErrorHandlerAndTriggerError();
1495       error("Failure during raster IO\n");
1496     }
1497     uninstallErrorHandlerAndTriggerError();
1498 
1499     break;
1500 
1501   case GDT_CInt16:
1502   case GDT_CInt32:
1503   case GDT_CFloat32:
1504   case GDT_CFloat64:
1505 
1506     eGDALType = GDAL_COMPLEX_TYPE;
1507     PROTECT(sxpData = coerceVector(sxpData, CPLXSXP));
1508   // Transpose data
1509     installErrorHandler();
1510     if(pRasterBand->RasterIO(GF_Write,
1511 			   INTEGER(sxpOffset)[1],
1512 			   INTEGER(sxpOffset)[0],
1513 			   rowsIn, colsIn,
1514 			   (void *)COMPLEX(sxpData),
1515 			   rowsIn, colsIn,
1516 			   eGDALType,
1517 			   0, 0)
1518        == CE_Failure) {
1519       uninstallErrorHandlerAndTriggerError();
1520       error("Failure during raster IO\n");
1521     }
1522     uninstallErrorHandlerAndTriggerError();
1523 
1524     break;
1525 
1526   default:
1527 
1528     error("Raster data type unknown\n");
1529 
1530     break;
1531 
1532   }
1533 
1534   UNPROTECT(1);
1535 
1536   return(sxpRasterBand);
1537 
1538 }
1539 
1540 SEXP
RGDAL_GetBandNoDataValue(SEXP sxpRasterBand)1541 RGDAL_GetBandNoDataValue(SEXP sxpRasterBand) {
1542 
1543   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1544   SEXP res;
1545   int hasNoDataValue;
1546   installErrorHandler();
1547   double noDataValue = pRasterBand->GetNoDataValue(&hasNoDataValue);
1548   uninstallErrorHandlerAndTriggerError();
1549 
1550   if (hasNoDataValue) {
1551     PROTECT(res = NEW_NUMERIC(1));
1552     NUMERIC_POINTER(res)[0] = noDataValue;
1553   } else {
1554     return(R_NilValue);
1555   }
1556 
1557   UNPROTECT(1);
1558   return(res);
1559 
1560 }
1561 
1562 SEXP
RGDAL_GetRasterData(SEXP sxpRasterBand,SEXP sxpRegion,SEXP sxpDimOut,SEXP sxpInterleave)1563 RGDAL_GetRasterData(SEXP sxpRasterBand,
1564 		    SEXP sxpRegion,
1565 		    SEXP sxpDimOut,
1566 		    SEXP sxpInterleave) {
1567 
1568   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1569 
1570   GDALDataType eGDALType = GDT_Int32;
1571   SEXPTYPE uRType = INTSXP;
1572 
1573   installErrorHandler();
1574   int RDT = pRasterBand->GetRasterDataType();
1575   uninstallErrorHandlerAndTriggerError();
1576 
1577   switch(RDT) {
1578 
1579   case GDT_Byte:
1580   case GDT_UInt16:
1581   case GDT_Int16:
1582   case GDT_UInt32:
1583   case GDT_Int32:
1584 
1585     uRType = INTSXP;
1586     eGDALType = GDAL_INTEGER_TYPE;
1587 
1588     break;
1589 
1590   case GDT_Float32:
1591   case GDT_Float64:
1592 
1593     uRType = REALSXP;
1594     eGDALType = GDAL_FLOAT_TYPE;
1595 
1596     break;
1597 
1598   case GDT_CInt16:
1599   case GDT_CInt32:
1600   case GDT_CFloat32:
1601   case GDT_CFloat64:
1602 
1603     uRType = CPLXSXP;
1604     eGDALType = GDAL_COMPLEX_TYPE;
1605 
1606     break;
1607 
1608   default:
1609 
1610     error("Raster data type unknown\n");
1611 
1612     break;
1613 
1614   }
1615 
1616   // Create matrix transposed
1617   int pc=0;
1618   SEXP sRStorage;
1619 // Mathias Moser https://stat.ethz.ch/pipermail/r-sig-geo/2020-April/028072.html
1620   PROTECT(sRStorage = allocVector(uRType,
1621 			       ((R_xlen_t) INTEGER(sxpDimOut)[1]) *
1622 			       INTEGER(sxpDimOut)[0])); pc++;
1623 
1624 // replication for 2.4.0 RSB 20060726
1625   switch(uRType) {
1626 
1627     case INTSXP:
1628       installErrorHandler();
1629       if(pRasterBand->RasterIO(GF_Read,
1630 			   INTEGER(sxpRegion)[1],
1631 			   INTEGER(sxpRegion)[0],
1632 			   INTEGER(sxpRegion)[3],
1633 			   INTEGER(sxpRegion)[2],
1634 			   (void *)INTEGER(sRStorage),
1635 			   INTEGER(sxpDimOut)[1],
1636 			   INTEGER(sxpDimOut)[0],
1637 			   eGDALType,
1638 			   INTEGER(sxpInterleave)[0],
1639 			   INTEGER(sxpInterleave)[1])
1640          == CE_Failure) {
1641            uninstallErrorHandlerAndTriggerError();
1642            error("Failure during raster IO\n");
1643       }
1644       uninstallErrorHandlerAndTriggerError();
1645       break;
1646 
1647     case REALSXP:
1648 
1649       installErrorHandler();
1650       if(pRasterBand->RasterIO(GF_Read,
1651 			   INTEGER(sxpRegion)[1],
1652 			   INTEGER(sxpRegion)[0],
1653 			   INTEGER(sxpRegion)[3],
1654 			   INTEGER(sxpRegion)[2],
1655 			   (void *)REAL(sRStorage),
1656 			   INTEGER(sxpDimOut)[1],
1657 			   INTEGER(sxpDimOut)[0],
1658 			   eGDALType,
1659 			   INTEGER(sxpInterleave)[0],
1660 			   INTEGER(sxpInterleave)[1])
1661          == CE_Failure) {
1662            uninstallErrorHandlerAndTriggerError();
1663            error("Failure during raster IO\n");
1664       }
1665       uninstallErrorHandlerAndTriggerError();
1666       break;
1667 
1668     case CPLXSXP:
1669 
1670       installErrorHandler();
1671       if(pRasterBand->RasterIO(GF_Read,
1672 			   INTEGER(sxpRegion)[1],
1673 			   INTEGER(sxpRegion)[0],
1674 			   INTEGER(sxpRegion)[3],
1675 			   INTEGER(sxpRegion)[2],
1676 			   (void *)COMPLEX(sRStorage),
1677 			   INTEGER(sxpDimOut)[1],
1678 			   INTEGER(sxpDimOut)[0],
1679 			   eGDALType,
1680 			   INTEGER(sxpInterleave)[0],
1681 			   INTEGER(sxpInterleave)[1])
1682          == CE_Failure) {
1683            uninstallErrorHandlerAndTriggerError();
1684            error("Failure during raster IO\n");
1685       }
1686       uninstallErrorHandlerAndTriggerError();
1687       break;
1688 
1689     default:
1690 
1691           error("Raster data type unknown\n");
1692 
1693       break;
1694 
1695   }
1696 
1697   int hasNoDataValue;
1698 
1699   double noDataValue;
1700 
1701   SEXP NDV = RGDAL_GetBandNoDataValue(sxpRasterBand);
1702 
1703   if (NDV == R_NilValue) {
1704     hasNoDataValue = FALSE;
1705   } else {
1706     hasNoDataValue = TRUE;
1707     noDataValue = NUMERIC_POINTER(NDV)[0];
1708   }
1709 
1710   /*int*/ R_xlen_t i;
1711         R_xlen_t sz = XLENGTH(sRStorage);
1712 
1713   if (hasNoDataValue) {
1714 
1715     switch(uRType) {
1716 
1717     case INTSXP:
1718     {
1719       int* pVals = INTEGER(sRStorage);
1720         for (i = 0; i < sz; ++i)
1721 	if (pVals[i] == (int) noDataValue) {
1722 	  pVals[i] = NA_INTEGER;
1723 	}
1724     }
1725 
1726       break;
1727 
1728     case REALSXP:
1729 
1730       switch(pRasterBand->GetRasterDataType()) {
1731 
1732         case GDT_Float32:
1733         {
1734           double* pVals = REAL(sRStorage);
1735 
1736         for (i = 0; i < sz; ++i)
1737 	  if (pVals[i] == (double) ((float) noDataValue)) {
1738 	    pVals[i] = NA_REAL;
1739 	  }
1740         }
1741 	break;
1742 
1743         case GDT_Float64:
1744         {
1745           double* pVals = REAL(sRStorage);
1746 
1747         for (i = 0; i < sz; ++i)
1748 	  if (pVals[i] == (double) (noDataValue)) {
1749 	    pVals[i] = NA_REAL;
1750 	  }
1751         }
1752 	break;
1753 
1754         default:
1755 
1756           error("Raster data type unknown\n");
1757 
1758         break;
1759 
1760       }
1761 
1762       break;
1763 
1764     default:
1765 
1766       warning("Output data values = %f are invalid\n", noDataValue);
1767 
1768       break;
1769 
1770     }
1771 
1772   } else {
1773     installErrorHandler();
1774     if (uRType == REALSXP && pRasterBand->GetRasterDataType() == GDT_Float32) {
1775       double* pVals = REAL(sRStorage);
1776         for (i = 0; i < sz; ++i)
1777 	  if (ISNAN(pVals[i])) {
1778 	    pVals[i] = NA_REAL;
1779 	  }
1780 
1781     }
1782     uninstallErrorHandlerAndTriggerError();
1783   }
1784 
1785   UNPROTECT(pc);
1786   return(sRStorage);
1787 
1788 }
1789 
1790 SEXP
RGDAL_GetPaletteInterp(SEXP sxpRasterBand)1791 RGDAL_GetPaletteInterp(SEXP sxpRasterBand) {
1792 
1793   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1794 
1795   installErrorHandler();
1796   GDALPaletteInterp ePI =
1797     pRasterBand->GetColorTable()->GetPaletteInterpretation();
1798   uninstallErrorHandlerAndTriggerError();
1799 
1800   installErrorHandler();
1801   const char *desc = GDALGetPaletteInterpretationName(ePI);
1802   uninstallErrorHandlerAndTriggerError();
1803   return(mkString_safe(desc));
1804 
1805 }
1806 
1807 SEXP
RGDAL_GetColorInterp(SEXP sxpRasterBand)1808 RGDAL_GetColorInterp(SEXP sxpRasterBand) {
1809 
1810   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1811 
1812   installErrorHandler();
1813   GDALColorInterp eCI = pRasterBand->GetColorInterpretation();
1814   uninstallErrorHandlerAndTriggerError();
1815 
1816   installErrorHandler();
1817   const char *desc = GDALGetColorInterpretationName(eCI);
1818   uninstallErrorHandlerAndTriggerError();
1819   return(mkString_safe(desc));
1820 
1821 }
1822 
1823 static SEXP
GDALColorTable2Matrix(GDALColorTableH ctab)1824 GDALColorTable2Matrix(GDALColorTableH ctab) {
1825 
1826         installErrorHandler();
1827 	int ncol = GDALGetColorEntryCount(ctab);
1828         uninstallErrorHandlerAndTriggerError();
1829 
1830 	SEXP cmat;
1831         PROTECT(cmat = allocMatrix(INTSXP, ncol, 4));
1832 
1833         installErrorHandler();
1834 	for (int i = 0; i < ncol; ++i) {
1835 
1836     	const GDALColorEntry* ce = GDALGetColorEntry(ctab, i);
1837 
1838     	INTEGER(cmat)[i] = static_cast<int>(ce->c1);
1839     	INTEGER(cmat)[i + ncol] = static_cast<int>(ce->c2);
1840     	INTEGER(cmat)[i + 2 * ncol] = static_cast<int>(ce->c3);
1841     	INTEGER(cmat)[i + 3 * ncol] = static_cast<int>(ce->c4);
1842 
1843   	}
1844         uninstallErrorHandlerAndTriggerError();
1845         UNPROTECT(1);
1846 
1847   	return(cmat);
1848 
1849 }
1850 
1851 SEXP
RGDAL_GetColorTable(SEXP rasterObj)1852 RGDAL_GetColorTable(SEXP rasterObj) {
1853 
1854 	GDALRasterBandH rasterBand = getGDALRasterPtr(rasterObj);
1855 
1856         installErrorHandler();
1857 	GDALColorTableH ctab = GDALGetRasterColorTable(rasterBand);
1858         uninstallErrorHandlerAndTriggerError();
1859 
1860 	if (ctab == NULL) return(R_NilValue);
1861 
1862 	return(GDALColorTable2Matrix(ctab));
1863 
1864 }
1865 
1866 
1867 SEXP
RGDAL_SetCategoryNames(SEXP sxpRasterBand,SEXP sxpNames)1868 RGDAL_SetCategoryNames(SEXP sxpRasterBand, SEXP sxpNames) {
1869 
1870   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1871 
1872   char **nameList = NULL;
1873 
1874   int i;
1875   installErrorHandler();
1876   for (i = 0; i < length(sxpNames); ++i)
1877     nameList = CSLAddString(nameList, asString(sxpNames, i));
1878   uninstallErrorHandlerAndTriggerError();
1879 
1880   installErrorHandler();
1881   CPLErr err = pRasterBand->SetCategoryNames(nameList);
1882 
1883   if (err == CE_Failure) warning("Failed to set category names");
1884   CSLDestroy(nameList);
1885   uninstallErrorHandlerAndTriggerError();
1886 
1887   return(sxpRasterBand);
1888 
1889 }
1890 
1891 SEXP
RGDAL_GetCategoryNames(SEXP sxpRasterBand)1892 RGDAL_GetCategoryNames(SEXP sxpRasterBand) {
1893 
1894   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1895 
1896   installErrorHandler();
1897   char **pcCNames = pRasterBand->GetCategoryNames();
1898   uninstallErrorHandlerAndTriggerError();
1899 
1900   if (pcCNames == NULL) return(R_NilValue);
1901 
1902   installErrorHandler();
1903   pcCNames = CSLDuplicate(pcCNames);
1904   uninstallErrorHandlerAndTriggerError();
1905 
1906   SEXP sxpCNames;
1907 
1908   installErrorHandler();
1909   int ii = CSLCount(pcCNames);
1910   uninstallErrorHandlerAndTriggerError();
1911   PROTECT(sxpCNames = allocVector(STRSXP, ii));
1912 
1913   int i;
1914   installErrorHandler();
1915   for (i = 0; i < ii; ++i) {
1916 
1917     const char *field = CSLGetField(pcCNames, i);
1918 
1919     SET_STRING_ELT(sxpCNames, i, mkChar(field));
1920 
1921   }
1922   CSLDestroy(pcCNames);
1923   uninstallErrorHandlerAndTriggerError();
1924 
1925   UNPROTECT(1);
1926 
1927   return(sxpCNames);
1928 
1929 }
1930 
1931 SEXP
RGDAL_GetGeoTransform(SEXP sxpDataset)1932 RGDAL_GetGeoTransform(SEXP sxpDataset) {
1933 
1934   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
1935 
1936   SEXP sxpGeoTrans, ceFail;
1937   PROTECT(sxpGeoTrans = allocVector(REALSXP, 6));
1938   PROTECT(ceFail = NEW_LOGICAL(1));
1939   LOGICAL_POINTER(ceFail)[0] = FALSE;
1940 
1941   installErrorHandler();
1942   CPLErr err = pDataset->GetGeoTransform(REAL(sxpGeoTrans));
1943 
1944   if (err == CE_Failure) {
1945 
1946     REAL(sxpGeoTrans)[0] = 0; // x-origin ul
1947     REAL(sxpGeoTrans)[1] = 1; // x-resolution (pixel width)
1948     REAL(sxpGeoTrans)[2] = 0; // x-oblique
1949     REAL(sxpGeoTrans)[3] = (double) pDataset->GetRasterYSize();
1950  // y-origin ul; 091028
1951     REAL(sxpGeoTrans)[4] = 0; // y-oblique
1952     REAL(sxpGeoTrans)[5] = -1; // y-resolution (pixel height); 091028 added sign
1953     LOGICAL_POINTER(ceFail)[0] = TRUE;
1954 
1955   }
1956   setAttrib(sxpGeoTrans, install("CE_Failure"), ceFail);
1957   uninstallErrorHandlerAndTriggerError();
1958   UNPROTECT(2);
1959 
1960   return(sxpGeoTrans);
1961 
1962 }
1963 
1964 SEXP
RGDAL_SetNoDataValue(SEXP sxpRasterBand,SEXP NoDataValue)1965 RGDAL_SetNoDataValue(SEXP sxpRasterBand, SEXP NoDataValue) {
1966   CPLErr err;
1967 
1968   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1969 
1970   installErrorHandler();
1971   err = pRasterBand->SetNoDataValue(NUMERIC_POINTER(NoDataValue)[0]);
1972 
1973   if (err == CE_Failure)
1974 	warning("setting of missing value not supported by this driver");
1975   uninstallErrorHandlerAndTriggerError();
1976 
1977   return(sxpRasterBand);
1978 
1979 }
1980 
RGDAL_SetStatistics(SEXP sxpRasterBand,SEXP statistics)1981 SEXP RGDAL_SetStatistics(SEXP sxpRasterBand, SEXP statistics) {
1982 
1983   CPLErr err;
1984 
1985   GDALRasterBand *pRasterBand = getGDALRasterPtr(sxpRasterBand);
1986 
1987   installErrorHandler();
1988   err = pRasterBand->SetStatistics(NUMERIC_POINTER(statistics)[0],
1989     NUMERIC_POINTER(statistics)[1], NUMERIC_POINTER(statistics)[2],
1990     NUMERIC_POINTER(statistics)[3]);
1991 
1992   if (err == CE_Failure)
1993 	warning("setting of statistics not supported by this driver");
1994   uninstallErrorHandlerAndTriggerError();
1995 
1996   return(sxpRasterBand);
1997 
1998 }
1999 
2000 SEXP
RGDAL_SetGeoTransform(SEXP sxpDataset,SEXP GeoTransform)2001 RGDAL_SetGeoTransform(SEXP sxpDataset, SEXP GeoTransform) {
2002 
2003   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
2004 
2005   if (LENGTH(GeoTransform) != 6)
2006 	error("GeoTransform argument should have length 6");
2007 
2008   installErrorHandler();
2009   CPLErr err = pDataset->SetGeoTransform(NUMERIC_POINTER(GeoTransform));
2010 
2011   if (err == CE_Failure)
2012 	warning("Failed to set GeoTransform\n");
2013   uninstallErrorHandlerAndTriggerError();
2014 
2015   return(sxpDataset);
2016 }
2017 /* added RSB 20060212 */
2018 SEXP
RGDAL_SetProject(SEXP sxpDataset,SEXP proj4string)2019 RGDAL_SetProject(SEXP sxpDataset, SEXP proj4string) {
2020 
2021   OGRSpatialReference *oSRS = new OGRSpatialReference;
2022   char *pszSRS_WKT = NULL;
2023 
2024   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
2025 
2026   installErrorHandler();
2027   oSRS->importFromProj4(CHAR(STRING_ELT(proj4string, 0)));
2028   uninstallErrorHandlerAndTriggerError();
2029 
2030 #if GDAL_VERSION_MAJOR >= 3
2031   installErrorHandler();
2032     oSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
2033   uninstallErrorHandlerAndTriggerError();
2034 #endif
2035 
2036   installErrorHandler();
2037   oSRS->exportToWkt( &pszSRS_WKT );
2038   uninstallErrorHandlerAndTriggerError();
2039 
2040   installErrorHandler();
2041   OGRErr err = pDataset->SetProjection(pszSRS_WKT);
2042   CPLFree( pszSRS_WKT );
2043 
2044   if (err == CE_Failure)
2045 	warning("Failed to set projection\n");
2046   delete oSRS;
2047   uninstallErrorHandlerAndTriggerError();
2048 
2049   return(sxpDataset);
2050 }
2051 /* added RSB 20191103 */
2052 SEXP
RGDAL_SetProject_WKT2(SEXP sxpDataset,SEXP WKT2string,SEXP enforce_xy)2053 RGDAL_SetProject_WKT2(SEXP sxpDataset, SEXP WKT2string, SEXP enforce_xy) {
2054 
2055 #if GDAL_VERSION_MAJOR >= 3
2056 
2057   OGRSpatialReference *oSRS = new OGRSpatialReference;
2058   int vis_order;
2059 
2060   if (enforce_xy == R_NilValue) vis_order = 0;
2061   else if (LOGICAL_POINTER(enforce_xy)[0] == 1) vis_order = 1;
2062   else if (LOGICAL_POINTER(enforce_xy)[0] == 0) vis_order = 0;
2063   else vis_order = 0;
2064 
2065   GDALDataset *pDataset = getGDALDatasetPtr(sxpDataset);
2066 
2067 //Rprintf("%s\n", CHAR(STRING_ELT(WKT2string, 0)));
2068 
2069   installErrorHandler();
2070   oSRS->importFromWkt(CHAR(STRING_ELT(WKT2string, 0)));
2071   uninstallErrorHandlerAndTriggerError();
2072 
2073   installErrorHandler();
2074   if (vis_order == 1)
2075     oSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
2076   uninstallErrorHandlerAndTriggerError();
2077 
2078   installErrorHandler();
2079   OGRErr err = pDataset->SetSpatialRef(oSRS);
2080 
2081   if (err == CE_Failure) {
2082 	warning("Failed to set projection\n");
2083         delete oSRS;
2084   }
2085   delete oSRS;
2086   uninstallErrorHandlerAndTriggerError();
2087 
2088   return(sxpDataset);
2089 #else
2090   return(R_NilValue);
2091 #endif
2092 }
2093 
2094 
RGDAL_SetRasterColorTable(SEXP raster,SEXP icT,SEXP ricT,SEXP cicT)2095 SEXP RGDAL_SetRasterColorTable(SEXP raster, SEXP icT, SEXP ricT, SEXP cicT) {
2096 
2097     int i, nr=INTEGER_POINTER(ricT)[0], nc=INTEGER_POINTER(cicT)[0];
2098     GDALRasterBand* target = getGDALRasterPtr(raster);
2099 
2100     installErrorHandler();
2101     GDALColorTableH ctab = GDALCreateColorTable(GPI_RGB);//FIXME VG
2102     uninstallErrorHandlerAndTriggerError();
2103 
2104     for (i=0; i<nr; i++) {
2105 
2106         GDALColorEntry ce;
2107 
2108         ce.c1 = (GByte) INTEGER_POINTER(icT)[i];
2109         ce.c2 = (GByte) INTEGER_POINTER(icT)[i+nr];
2110         ce.c3 = (GByte) INTEGER_POINTER(icT)[i+(nr*2)];
2111         if (nc == 3) ce.c4 = 255;
2112         else ce.c4 = (GByte) INTEGER_POINTER(icT)[i+(nr*3)];
2113 
2114         installErrorHandler();
2115         GDALSetColorEntry (ctab, i, &ce);
2116         uninstallErrorHandlerAndTriggerError();
2117     }
2118 
2119     installErrorHandler();
2120     int err = GDALSetRasterColorTable(target, ctab);
2121 
2122     if (err == CE_Failure) {
2123         uninstallErrorHandlerAndTriggerError();
2124         warning("Unable to set color table");
2125     }
2126     GDALDestroyColorTable(ctab);
2127     uninstallErrorHandlerAndTriggerError();
2128 
2129     return(raster);
2130 
2131 }
2132 
2133 SEXP
RGDAL_GenCMap(SEXP input1,SEXP input2,SEXP input3,SEXP output,SEXP nColors,SEXP setCMap)2134 RGDAL_GenCMap(SEXP input1, SEXP input2, SEXP input3, SEXP output, SEXP nColors, SEXP setCMap) {
2135 
2136 	GDALRasterBand* band1 = getGDALRasterPtr(input1);
2137 	GDALRasterBand* band2 = getGDALRasterPtr(input2);
2138 	GDALRasterBand* band3 = getGDALRasterPtr(input3);
2139 
2140 	GDALColorTable ctab;
2141 
2142 	int ncol = asInteger(nColors);
2143 
2144 	if (ncol < 2 || ncol > 256)
2145 		error("Number of colors should range from 2 to 256");
2146 
2147         installErrorHandler();
2148 	int err = GDALComputeMedianCutPCT(band1, band2, band3, NULL,
2149 	                                  ncol, &ctab, NULL, NULL);
2150 
2151 	if (err == CE_Failure) {
2152           uninstallErrorHandlerAndTriggerError();
2153           error("Error generating color table");
2154 	}
2155         uninstallErrorHandlerAndTriggerError();
2156 	if (output != R_NilValue) {
2157 
2158 		GDALRasterBand* target = getGDALRasterPtr(output);
2159 
2160                 installErrorHandler();
2161 		err = GDALDitherRGB2PCT(band1, band2, band3, target, &ctab, NULL, NULL);
2162 
2163 		if (err == CE_Failure) {
2164                   uninstallErrorHandlerAndTriggerError();
2165                   error("Image dithering failed");
2166                 }
2167                 uninstallErrorHandlerAndTriggerError();
2168 
2169 		if (asLogical(setCMap)) {
2170 
2171                         installErrorHandler();
2172 			err = GDALSetRasterColorTable(target, &ctab);
2173 
2174 			if (err == CE_Failure) {
2175                           uninstallErrorHandlerAndTriggerError();
2176                           warning("Unable to set color table");
2177                         }
2178                         uninstallErrorHandlerAndTriggerError();
2179 
2180 		}
2181 
2182 	}
2183 
2184 	return(GDALColorTable2Matrix(&ctab));
2185 
2186 }
2187 
2188 // CPLGetConfigOption( const char *pszKey, const char *pszDefault )
2189 
RGDAL_CPLGetConfigOption(SEXP inOption)2190 SEXP RGDAL_CPLGetConfigOption(SEXP inOption) {
2191     installErrorHandler();
2192     if (CPLGetConfigOption(asString(inOption), NULL) == NULL) {
2193         uninstallErrorHandlerAndTriggerError();
2194         return(R_NilValue);
2195     }
2196     SEXP res;
2197     PROTECT(res=NEW_CHARACTER(1));
2198     installErrorHandler();
2199     SET_STRING_ELT(res, 0,
2200         COPY_TO_USER_STRING(CPLGetConfigOption(asString(inOption), NULL)));
2201     uninstallErrorHandlerAndTriggerError();
2202     UNPROTECT(1);
2203     return(res);
2204 }
2205 
2206 // CPLSetConfigOption( const char *pszKey, const char *pszValue )
2207 
RGDAL_CPLSetConfigOption(SEXP inOption,SEXP value)2208 SEXP RGDAL_CPLSetConfigOption(SEXP inOption, SEXP value) {
2209     installErrorHandler();
2210     if (value == R_NilValue)
2211         CPLSetConfigOption(asString(inOption), NULL);
2212     else
2213         CPLSetConfigOption(asString(inOption), asString(value));
2214     uninstallErrorHandlerAndTriggerError();
2215     return(R_NilValue);
2216 }
2217 
RGDAL_CPL_RECODE_ICONV(void)2218 SEXP RGDAL_CPL_RECODE_ICONV(void) {
2219     SEXP ans;
2220     PROTECT(ans=NEW_LOGICAL(1));
2221 #ifdef CPL_RECODE_ICONV
2222     LOGICAL_POINTER(ans)[0] = TRUE;
2223 #else /* CPL_RECODE_ICONV */
2224     LOGICAL_POINTER(ans)[0] = FALSE;
2225 #endif /* CPL_RECODE_ICONV */
2226     UNPROTECT(1);
2227     return(ans);
2228 }
2229 
2230 
2231 #ifdef __cplusplus
2232 }
2233 #endif
2234 
2235