/** Load proj.4 geoidgrids as GDAL dataset * * @param pszProj4Geoidgrids Value of proj.4 geoidgrids parameter. * @param pbError If not NULL, the pointed value will be set to TRUE if an * error occurred. * * @return a dataset. If not NULL, it must be closed with GDALClose(). * * @since GDAL 2.2 */ GDALDatasetH GDALOpenVerticalShiftGrid( const char* pszProj4Geoidgrids, int* pbError ) { char** papszGrids = CSLTokenizeString2( pszProj4Geoidgrids, ",", 0); const int nGridCount = CSLCount(papszGrids); if( nGridCount == 1 ) { CSLDestroy(papszGrids); bool bMissingOk = false; if( *pszProj4Geoidgrids == '@' ) { pszProj4Geoidgrids ++; bMissingOk = true; } const CPLString osFilename(GetProj4Filename(pszProj4Geoidgrids)); const char* const papszOpenOptions[] = { "@SHIFT_ORIGIN_IN_MINUS_180_PLUS_180=YES", nullptr }; GDALDatasetH hDS = GDALOpenEx(osFilename, 0, nullptr, papszOpenOptions, nullptr); if( hDS == nullptr ) { CPLDebug("GDAL", "Cannot find file corresponding to %s", pszProj4Geoidgrids); } if( pbError ) *pbError = (!bMissingOk && hDS == nullptr); return hDS; } CPLStringList aosFilenames; for( int i = nGridCount - 1; i >= 0; i-- ) { const char* pszName = papszGrids[i]; bool bMissingOk = false; if( *pszName == '@' ) { pszName ++; bMissingOk = true; } const CPLString osFilename(GetProj4Filename(pszName)); VSIStatBufL sStat; if( osFilename.empty() || VSIStatL(osFilename, &sStat) != 0 ) { CPLDebug("GDAL", "Cannot find file corresponding to %s", pszName); if( !bMissingOk ) { if( pbError ) *pbError = true; CSLDestroy(papszGrids); return nullptr; } } else { aosFilenames.AddString(osFilename); } } CSLDestroy(papszGrids); if( aosFilenames.empty() ) { if( pbError ) *pbError = false; return nullptr; } char** papszArgv = nullptr; papszArgv = CSLAddString(papszArgv, "-resolution"); papszArgv = CSLAddString(papszArgv, "highest"); papszArgv = CSLAddString(papszArgv, "-vrtnodata"); papszArgv = CSLAddString(papszArgv, "-inf"); papszArgv = CSLAddString(papszArgv, "-oo"); papszArgv = CSLAddString(papszArgv, "@SHIFT_ORIGIN_IN_MINUS_180_PLUS_180=YES"); GDALBuildVRTOptions* psOptions = GDALBuildVRTOptionsNew(papszArgv, nullptr); CSLDestroy(papszArgv); GDALDatasetH hDS = GDALBuildVRT( "", aosFilenames.size(), nullptr, aosFilenames.List(), psOptions, nullptr ); GDALBuildVRTOptionsFree( psOptions ); if( pbError ) *pbError = hDS != nullptr; return hDS; }