CPLXMLNode *GDALSerializeRPCTransformer( void *pTransformArg ) { VALIDATE_POINTER1( pTransformArg, "GDALSerializeRPCTransformer", NULL ); CPLXMLNode *psTree; GDALRPCTransformInfo *psInfo = (GDALRPCTransformInfo *)(pTransformArg); psTree = CPLCreateXMLNode( NULL, CXT_Element, "RPCTransformer" ); /* -------------------------------------------------------------------- */ /* Serialize bReversed. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "Reversed", CPLString().Printf( "%d", psInfo->bReversed ) ); /* -------------------------------------------------------------------- */ /* Serialize Height Offset. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "HeightOffset", CPLString().Printf( "%.15g", psInfo->dfHeightOffset ) ); /* -------------------------------------------------------------------- */ /* Serialize Height Scale. */ /* -------------------------------------------------------------------- */ if (psInfo->dfHeightScale != 1.0) CPLCreateXMLElementAndValue( psTree, "HeightScale", CPLString().Printf( "%.15g", psInfo->dfHeightScale ) ); /* -------------------------------------------------------------------- */ /* Serialize DEM path. */ /* -------------------------------------------------------------------- */ if (psInfo->pszDEMPath != NULL) { CPLCreateXMLElementAndValue( psTree, "DEMPath", CPLString().Printf( "%s", psInfo->pszDEMPath ) ); /* -------------------------------------------------------------------- */ /* Serialize DEM interpolation */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "DEMInterpolation", GDALSerializeRPCDEMResample(psInfo->eResampleAlg) ); if( psInfo->bHasDEMMissingValue ) { CPLCreateXMLElementAndValue( psTree, "DEMMissingValue", CPLSPrintf("%.18g", psInfo->dfDEMMissingValue) ); } } /* -------------------------------------------------------------------- */ /* Serialize pixel error threshold. */ /* -------------------------------------------------------------------- */ CPLCreateXMLElementAndValue( psTree, "PixErrThreshold", CPLString().Printf( "%.15g", psInfo->dfPixErrThreshold ) ); /* -------------------------------------------------------------------- */ /* RPC metadata. */ /* -------------------------------------------------------------------- */ char **papszMD = RPCInfoToMD( &(psInfo->sRPC) ); CPLXMLNode *psMD= CPLCreateXMLNode( psTree, CXT_Element, "Metadata" ); for( int i = 0; papszMD != NULL && papszMD[i] != NULL; i++ ) { const char *pszRawValue; char *pszKey; CPLXMLNode *psMDI; pszRawValue = CPLParseNameValue( papszMD[i], &pszKey ); psMDI = CPLCreateXMLNode( psMD, CXT_Element, "MDI" ); CPLSetXMLValue( psMDI, "#key", pszKey ); CPLCreateXMLNode( psMDI, CXT_Text, pszRawValue ); CPLFree( pszKey ); } CSLDestroy( papszMD ); return psTree; }
GDALDataset* OGRPLScenesDataset::OpenRasterScene(GDALOpenInfo* poOpenInfo, CPLString osScene, char** papszOptions) { if( !(poOpenInfo->nOpenFlags & GDAL_OF_RASTER) ) { return NULL; } for( char** papszIter = papszOptions; papszIter && *papszIter; papszIter ++ ) { char* pszKey; const char* pszValue = CPLParseNameValue(*papszIter, &pszKey); if( pszValue != NULL ) { if( !EQUAL(pszKey, "api_key") && !EQUAL(pszKey, "scene") && !EQUAL(pszKey, "product_type") ) { CPLError(CE_Failure, CPLE_NotSupported, "Unsupported option %s", pszKey); CPLFree(pszKey); return NULL; } CPLFree(pszKey); } } const char* pszProductType = CSLFetchNameValueDef(papszOptions, "product_type", CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "PRODUCT_TYPE", "visual")); CPLString osRasterURL; osRasterURL = osBaseURL; osRasterURL += "ortho/"; osRasterURL += osScene; json_object* poObj = RunRequest( osRasterURL ); if( poObj == NULL ) return NULL; json_object* poProperties = json_object_object_get(poObj, "properties"); if( poProperties == NULL || json_object_get_type(poProperties) != json_type_object ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find properties object"); json_object_put(poObj); return NULL; } const char* pszLink = NULL; if( EQUAL(pszProductType, "thumb") ) { json_object* poLinks = json_object_object_get(poProperties, "links"); if( poLinks != NULL && json_object_get_type(poLinks) == json_type_object ) { json_object* poThumbnail = json_object_object_get(poLinks, "thumbnail"); if( poThumbnail && json_object_get_type(poThumbnail) == json_type_string ) pszLink = json_object_get_string(poThumbnail); } } else { json_object* poData = json_object_object_get(poProperties, "data"); if( poData != NULL && json_object_get_type(poData) == json_type_object ) { json_object* poProducts = json_object_object_get(poData, "products"); if( poProducts != NULL && json_object_get_type(poProducts) == json_type_object ) { json_object* poProduct = json_object_object_get(poProducts, pszProductType); if( poProduct != NULL && json_object_get_type(poProduct) == json_type_object ) { json_object* poFull = json_object_object_get(poProduct, "full"); if( poFull && json_object_get_type(poFull) == json_type_string ) pszLink = json_object_get_string(poFull); } } } } osRasterURL = pszLink ? pszLink : ""; json_object_put(poObj); if( osRasterURL.size() == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find link to scene %s", osScene.c_str()); return NULL; } if( strncmp(osRasterURL, "http://", strlen("http://")) == 0 ) { osRasterURL = "http://" + osAPIKey + ":@" + osRasterURL.substr(strlen("http://")); } else if( strncmp(osRasterURL, "https://", strlen("https://")) == 0 ) { osRasterURL = "https://" + osAPIKey + ":@" + osRasterURL.substr(strlen("https://")); } CPLString osOldHead(CPLGetConfigOption("CPL_VSIL_CURL_USE_HEAD", "")); CPLString osOldExt(CPLGetConfigOption("CPL_VSIL_CURL_ALLOWED_EXTENSIONS", "")); int bUseVSICURL = CSLFetchBoolean(poOpenInfo->papszOpenOptions, "RANDOM_ACCESS", TRUE); if( bUseVSICURL && !(strncmp(osBaseURL, "/vsimem/", strlen("/vsimem/")) == 0) ) { CPLSetThreadLocalConfigOption("CPL_VSIL_CURL_USE_HEAD", "NO"); CPLSetThreadLocalConfigOption("CPL_VSIL_CURL_ALLOWED_EXTENSIONS", "{noext}"); VSIStatBufL sStat; if( VSIStatL(("/vsicurl/" + osRasterURL).c_str(), &sStat) == 0 && sStat.st_size > 0 ) { osRasterURL = "/vsicurl/" + osRasterURL; } else { CPLDebug("PLSCENES", "Cannot use random access for that file"); } } GDALDataset* poOutDS = (GDALDataset*) GDALOpen(osRasterURL, GA_ReadOnly); if( poOutDS ) { poOutDS->SetDescription(poOpenInfo->pszFilename); poOutDS->GetFileList(); /* so as to probe all auxiliary files before reseting the allowed extensions */ if( !EQUAL(pszProductType, "thumb") ) { OGRPLScenesLayer* poLayer = new OGRPLScenesLayer(this, "ortho", (osBaseURL + "ortho/").c_str()); papoLayers = (OGRPLScenesLayer**) CPLRealloc(papoLayers, sizeof(OGRPLScenesLayer*) * (nLayers + 1)); papoLayers[nLayers ++] = poLayer; /* Attach scene matadata */ poLayer->SetAttributeFilter(CPLSPrintf("id = '%s'", osScene.c_str())); OGRFeature* poFeat = poLayer->GetNextFeature(); if( poFeat ) { for(int i=0;i<poFeat->GetFieldCount();i++) { if( poFeat->IsFieldSet(i) ) { const char* pszKey = poFeat->GetFieldDefnRef(i)->GetNameRef(); const char* pszVal = poFeat->GetFieldAsString(i); if( strstr(pszKey, "file_size") == NULL && strstr(pszVal, "https://") == NULL ) { poOutDS->SetMetadataItem(pszKey, pszVal); } } } } delete poFeat; } } if( bUseVSICURL ) { CPLSetThreadLocalConfigOption("CPL_VSIL_CURL_USE_HEAD", osOldHead.size() ? osOldHead.c_str(): NULL); CPLSetThreadLocalConfigOption("CPL_VSIL_CURL_ALLOWED_EXTENSIONS", osOldExt.size() ? osOldExt.c_str(): NULL); } return poOutDS; }
GDALDataset* OGRPLScenesDataset::Open(GDALOpenInfo* poOpenInfo) { if( !Identify(poOpenInfo) || poOpenInfo->eAccess == GA_Update ) return NULL; OGRPLScenesDataset* poDS = new OGRPLScenesDataset(); poDS->osBaseURL = CPLGetConfigOption("PL_URL", "https://api.planet.com/v0/scenes/"); char** papszOptions = CSLTokenizeStringComplex( poOpenInfo->pszFilename+strlen("PLScenes:"), ",", TRUE, FALSE ); poDS->osAPIKey = CSLFetchNameValueDef(papszOptions, "api_key", CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "API_KEY", CPLGetConfigOption("PL_API_KEY","")) ); if( poDS->osAPIKey.size() == 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing PL_API_KEY configuration option or API_KEY open option"); delete poDS; CSLDestroy(papszOptions); return NULL; } const char* pszScene = CSLFetchNameValueDef(papszOptions, "scene", CSLFetchNameValue(poOpenInfo->papszOpenOptions, "SCENE")); if( pszScene ) { GDALDataset* poRasterDS = poDS->OpenRasterScene(poOpenInfo, pszScene, papszOptions); delete poDS; CSLDestroy(papszOptions); return poRasterDS; } for( char** papszIter = papszOptions; papszIter && *papszIter; papszIter ++ ) { char* pszKey; const char* pszValue = CPLParseNameValue(*papszIter, &pszKey); if( pszValue != NULL ) { if( !EQUAL(pszKey, "api_key") && !EQUAL(pszKey, "spat") ) { CPLError(CE_Failure, CPLE_NotSupported, "Unsupported option %s", pszKey); CPLFree(pszKey); delete poDS; CSLDestroy(papszOptions); return NULL; } CPLFree(pszKey); } } json_object* poObj = poDS->RunRequest(poDS->osBaseURL); if( poObj == NULL ) { delete poDS; CSLDestroy(papszOptions); return NULL; } json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poObj, it ) { if( it.val != NULL && json_object_get_type(it.val) == json_type_string ) { const char* pszSceneType = it.key; const char* pszSceneTypeURL = json_object_get_string(it.val); json_object* poObj = NULL; if( !EQUAL(pszSceneType, "ortho") ) poObj = poDS->RunRequest( (CPLString(pszSceneTypeURL) + CPLString("?count=10")).c_str() ); OGRPLScenesLayer* poLayer = new OGRPLScenesLayer(poDS, pszSceneType, pszSceneTypeURL, poObj); if( poObj ) json_object_put(poObj); poDS->papoLayers = (OGRPLScenesLayer**) CPLRealloc(poDS->papoLayers, sizeof(OGRPLScenesLayer*) * (poDS->nLayers + 1)); poDS->papoLayers[poDS->nLayers ++] = poLayer; const char* pszSpat = CSLFetchNameValue(papszOptions, "spat"); if( pszSpat ) { char** papszTokens = CSLTokenizeString2(pszSpat, " ", 0); if( CSLCount(papszTokens) >= 4 ) { poLayer->SetMainFilterRect(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]), CPLAtof(papszTokens[2]), CPLAtof(papszTokens[3])); } CSLDestroy(papszTokens); } } } json_object_put(poObj); CSLDestroy(papszOptions); if( !(poOpenInfo->nOpenFlags & GDAL_OF_VECTOR) ) { delete poDS; return NULL; } return poDS; }
CPLErr GDALWriteIMDFile( const char *pszFilename, char **papszMD ) { CPLString osRPBFilename = CPLResetExtension( pszFilename, "IMD" ); /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osRPBFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create %s for writing.\n%s", osRPBFilename.c_str(), CPLGetLastErrorMsg() ); return CE_Failure; } /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Loop through all values writing. */ /* -------------------------------------------------------------------- */ /* ==================================================================== */ int iKey; CPLString osCurSection; for( iKey = 0; papszMD[iKey] != NULL; iKey++ ) { char *pszRawKey = NULL; const char *pszValue = CPLParseNameValue( papszMD[iKey], &pszRawKey ); CPLString osKeySection, osKeyItem; char *pszDot = strchr(pszRawKey,'.'); /* -------------------------------------------------------------------- */ /* Split stuff like BAND_P.ULLon into section and item. */ /* -------------------------------------------------------------------- */ if( pszDot == NULL ) { osKeyItem = pszRawKey; } else { osKeyItem = pszDot+1; *pszDot = '\0'; osKeySection = pszRawKey; } CPLFree( pszRawKey ); /* -------------------------------------------------------------------- */ /* Close and/or start sections as needed. */ /* -------------------------------------------------------------------- */ if( osCurSection.size() && !EQUAL(osCurSection,osKeySection) ) VSIFPrintfL( fp, "END_GROUP = %s\n", osCurSection.c_str() ); if( osKeySection.size() && !EQUAL(osCurSection,osKeySection) ) VSIFPrintfL( fp, "BEGIN_GROUP = %s\n", osKeySection.c_str() ); osCurSection = osKeySection; /* -------------------------------------------------------------------- */ /* Print out simple item. */ /* -------------------------------------------------------------------- */ if( osCurSection.size() ) VSIFPrintfL( fp, "\t%s = ", osKeyItem.c_str() ); else VSIFPrintfL( fp, "%s = ", osKeyItem.c_str() ); if( pszValue[0] != '(' ) VSIFPrintfL( fp, "%s;\n", pszValue ); else GDALWriteIMDMultiLine( fp, pszValue ); } /* -------------------------------------------------------------------- */ /* Close off. */ /* -------------------------------------------------------------------- */ if( osCurSection.size() ) VSIFPrintfL( fp, "END_GROUP = %s\n", osCurSection.c_str() ); VSIFPrintfL( fp, "END;\n" ); VSIFCloseL( fp ); return CE_None; }