Skip to content

Instantly share code, notes, and snippets.

@koloritcm
Created April 30, 2016 20:39
Show Gist options
  • Save koloritcm/76364b6bc8c0ff48dcf9fb81a5fdc060 to your computer and use it in GitHub Desktop.
Save koloritcm/76364b6bc8c0ff48dcf9fb81a5fdc060 to your computer and use it in GitHub Desktop.
- (WarpResultC*)warpImageWithGeoTransformMBTiles:(NSArray<NSNumber*>*)geoTransformArray sourceFile:(NSString*)inFilepath destinationFile:(NSString*)outFilepath
{
char *argv[] = { strdup("gdal_translate"),
strdup("-of"), strdup("MBTILES"),
strdup(inFilepath.UTF8String), strdup(outFilepath.UTF8String),
NULL };
int argc = sizeof(argv) / sizeof(char*) - 1;
GDALDatasetH hDataset, hOutDS;
int bUsageError;
EarlySetConfigOptions(argc, argv);
/* ------------------------------------------- */
/* Register standard GDAL drivers. */
/* ------------------------------------------- */
GDALAllRegister();
/* -------------------------------------------------------------------- */
/* Set optimal setting for best performance with huge input VRT. */
/* The rationale for 450 is that typical Linux process allow */
/* only 1024 file descriptors per process and we need to keep some */
/* spare for shared libraries, etc. so let's go down to 900. */
/* And some datasets may need 2 file descriptors, so divide by 2 */
/* for security. */
/* -------------------------------------------------------------------- */
if( CPLGetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", NULL) == NULL )
{
CPLSetConfigOption("GDAL_MAX_DATASET_POOL_SIZE", "450");
}
GDALTranslateOptionsForBinary* psOptionsForBinary = GDALTranslateOptionsForBinaryNew();
GDALTranslateOptions *psOptions = GDALTranslateOptionsNew(argv + 1, psOptionsForBinary);
GDALTranslateOptionsSetProgress(psOptions, GDALTermProgress, NULL);
/* -------------------------------------------------------------------- */
/* Attempt to open source file. */
/* -------------------------------------------------------------------- */
hDataset = GDALOpenEx( psOptionsForBinary->pszSource, GDAL_OF_RASTER | GDAL_OF_VERBOSE_ERROR, NULL,
(const char* const* )psOptionsForBinary->papszOpenOptions, NULL );
if( hDataset == NULL )
{
GDALDestroyDriverManager();
exit( 1 );
}
char *pszSRS_WKT = NULL;
OGRSpatialReference oSRS;
oSRS.SetWellKnownGeogCS("WGS84");
oSRS.exportToWkt( &pszSRS_WKT );
GDALSetProjection(hDataset, pszSRS_WKT);
CPLFree( pszSRS_WKT );
// Set the GeoTransform on the source image
double geoTransform[] = { geoTransformArray[0].doubleValue, geoTransformArray[1].doubleValue, geoTransformArray[2].doubleValue, geoTransformArray[3].doubleValue, geoTransformArray[4].doubleValue, geoTransformArray[5].doubleValue };
GDALSetGeoTransform(hDataset, geoTransform);
/* -------------------------------------------------------------------- */
/* Handle subdatasets. */
/* -------------------------------------------------------------------- */
if( !psOptionsForBinary->bCopySubDatasets
&& CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0
&& GDALGetRasterCount(hDataset) == 0 )
{
fprintf( stderr, "Input file contains subdatasets. Please, select one of them for reading.\n" );
GDALClose( hDataset );
GDALDestroyDriverManager();
exit( 1 );
}
if( CSLCount(GDALGetMetadata( hDataset, "SUBDATASETS" )) > 0
&& psOptionsForBinary->bCopySubDatasets )
{
char **papszSubdatasets = GDALGetMetadata(hDataset,"SUBDATASETS");
char *pszSubDest = (char *) CPLMalloc(strlen(psOptionsForBinary->pszDest)+32);
int i;
CPLString osPath = CPLGetPath(psOptionsForBinary->pszDest);
CPLString osBasename = CPLGetBasename(psOptionsForBinary->pszDest);
CPLString osExtension = CPLGetExtension(psOptionsForBinary->pszDest);
CPLString osTemp;
const char* pszFormat = NULL;
if ( CSLCount(papszSubdatasets)/2 < 10 )
{
pszFormat = "%s_%d";
}
else if ( CSLCount(papszSubdatasets)/2 < 100 )
{
pszFormat = "%s_%002d";
}
else
{
pszFormat = "%s_%003d";
}
const char* pszDest = pszSubDest;
for( i = 0; papszSubdatasets[i] != NULL; i += 2 )
{
char* pszSource = CPLStrdup(strstr(papszSubdatasets[i],"=")+1);
osTemp = CPLSPrintf( pszFormat, osBasename.c_str(), i/2 + 1 );
osTemp = CPLFormFilename( osPath, osTemp, osExtension );
strcpy( pszSubDest, osTemp.c_str() );
hDataset = GDALOpenEx( pszSource, GDAL_OF_RASTER, NULL,
(const char* const* )psOptionsForBinary->papszOpenOptions, NULL );
CPLFree(pszSource);
if( !psOptionsForBinary->bQuiet )
printf("Input file size is %d, %d\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset));
hOutDS = GDALTranslate(pszDest, hDataset, psOptions, &bUsageError);
if(bUsageError == TRUE)
printf("Usage error");
if (hOutDS == NULL)
break;
GDALClose(hOutDS);
}
GDALClose(hDataset);
GDALTranslateOptionsFree(psOptions);
GDALTranslateOptionsForBinaryFree(psOptionsForBinary);
CPLFree(pszSubDest);
GDALDestroyDriverManager();
return 0;
}
printf("Input file size is %d, %d\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset));
hOutDS = GDALTranslate(psOptionsForBinary->pszDest, hDataset, psOptions, &bUsageError);
if(bUsageError == TRUE)
printf("Usage error");
int overviewList[3] = { 2, 4, 8 };
// WARNING: This doesn't create overviews and store it in MBTiles, it stores in a separate file
CPLErr eErr = GDALBuildOverviews(hDataset, "NEAREST", 3, overviewList, 0, NULL, GDALDummyProgress, NULL);
CPLAssert( eErr == CE_None );
/* Close hOutDS before hDataset for the -f VRT case */
GDALClose(hOutDS);
GDALClose(hDataset);
GDALTranslateOptionsFree(psOptions);
GDALTranslateOptionsForBinaryFree(psOptionsForBinary);
GDALDestroyDriverManager();
WarpResultC* warpResultC = [WarpResultC new];
warpResultC.success = (hOutDS) ? false : true;
return warpResultC;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment