bool OGRCouchDBDataSource::IsError(json_object* poAnswerObj, const char* pszErrorMsg) { if ( poAnswerObj == NULL || !json_object_is_type(poAnswerObj, json_type_object) ) { return false; } json_object* poError = CPL_json_object_object_get(poAnswerObj, "error"); json_object* poReason = CPL_json_object_object_get(poAnswerObj, "reason"); const char* pszError = json_object_get_string(poError); const char* pszReason = json_object_get_string(poReason); if (pszError != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "%s : %s, %s", pszErrorMsg, pszError, pszReason ? pszReason : ""); return true; } return false; }
bool OGRPLScenesDataV1Dataset::ParseItemTypes(json_object* poObj, CPLString& osNext) { json_object* poItemTypes = CPL_json_object_object_get(poObj, "item_types"); if( poItemTypes == nullptr || json_object_get_type(poItemTypes) != json_type_array ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing item_types object, or not of type array"); return false; } const auto nCatalogsLength = json_object_array_length(poItemTypes); for( auto i=decltype(nCatalogsLength){0}; i<nCatalogsLength; i++ ) { json_object* poItemType = json_object_array_get_idx(poItemTypes, i); ParseItemType(poItemType); } // Is there a next page ? osNext = ""; json_object* poLinks = CPL_json_object_object_get(poObj, "_links"); if( poLinks && json_object_get_type(poLinks) == json_type_object ) { json_object* poNext = CPL_json_object_object_get(poLinks, "_next"); if( poNext && json_object_get_type(poNext) == json_type_string ) { osNext = json_object_get_string(poNext); } } return true; }
void OGRElasticDataSource::FetchMapping(const char* pszIndexName) { if( m_oSetLayers.find(pszIndexName) != m_oSetLayers.end() ) return; CPLString osURL(m_osURL + CPLString("/") + pszIndexName + CPLString("/_mapping?pretty")); json_object* poRes = RunRequest(osURL, nullptr, std::vector<int>({403})); if( poRes ) { json_object* poLayerObj = CPL_json_object_object_get(poRes, pszIndexName); json_object* poMappings = nullptr; if( poLayerObj && json_object_get_type(poLayerObj) == json_type_object ) poMappings = CPL_json_object_object_get(poLayerObj, "mappings"); if( poMappings && json_object_get_type(poMappings) == json_type_object ) { json_object_iter it; it.key = nullptr; it.val = nullptr; it.entry = nullptr; std::vector<CPLString> aosMappings; json_object_object_foreachC( poMappings, it ) { aosMappings.push_back(it.key); } if( aosMappings.size() == 1 && (aosMappings[0] == "FeatureCollection" || aosMappings[0] == "default") ) { m_oSetLayers.insert(pszIndexName); OGRElasticLayer* poLayer = new OGRElasticLayer( pszIndexName, pszIndexName, aosMappings[0], this, papszOpenOptions); poLayer->InitFeatureDefnFromMapping( CPL_json_object_object_get(poMappings, aosMappings[0]), "", std::vector<CPLString>()); m_apoLayers.push_back(std::unique_ptr<OGRElasticLayer>(poLayer)); } else { for(size_t i=0; i<aosMappings.size();i++) { CPLString osLayerName(pszIndexName + CPLString("_") + aosMappings[i]); if( m_oSetLayers.find(osLayerName) == m_oSetLayers.end() ) { m_oSetLayers.insert(osLayerName); OGRElasticLayer* poLayer = new OGRElasticLayer( osLayerName, pszIndexName, aosMappings[i], this, papszOpenOptions); poLayer->InitFeatureDefnFromMapping( CPL_json_object_object_get(poMappings, aosMappings[i]), "", std::vector<CPLString>()); m_apoLayers.push_back(std::unique_ptr<OGRElasticLayer>(poLayer)); } } } }
bool OGRAmigoCloudDataSource::ListDatasets() { std::stringstream url; url << std::string(GetAPIURL()) << "/users/0/projects/" << std::string(GetProjectId()) << "/datasets/?summary"; json_object* result = RunGET(url.str().c_str()); if( result == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "AmigoCloud:get failed."); return false; } if( result != nullptr ) { auto type = json_object_get_type(result); if(type == json_type_object) { json_object *poResults = CPL_json_object_object_get(result, "results"); if(poResults != nullptr && json_object_get_type(poResults) == json_type_array) { CPLprintf("List of available datasets for project id: %s\n", GetProjectId()); CPLprintf("| id \t | name\n"); CPLprintf("|--------|-------------------\n"); const auto nSize = json_object_array_length(poResults); for(auto i = decltype(nSize){0}; i < nSize; ++i) { json_object *ds = json_object_array_get_idx(poResults, i); if(ds!=nullptr) { const char *name = nullptr; int64_t dataset_id = 0; json_object *poName = CPL_json_object_object_get(ds, "name"); if (poName != nullptr) { name = json_object_get_string(poName); } json_object *poId = CPL_json_object_object_get(ds, "id"); if (poId != nullptr) { dataset_id = json_object_get_int64(poId); } if (name != nullptr) { std::stringstream str; str << "| " << dataset_id << "\t | " << name; CPLprintf("%s\n", str.str().c_str()); } } } } } json_object_put(result); } return true; }
bool OGRAmigoCloudDataSource::waitForJobToFinish(const char* jobId) { std::stringstream url; url << std::string(GetAPIURL()) << "/me/jobs/" << std::string(jobId); int count = 0; while (count<5) { count++; json_object *result = RunGET(url.str().c_str()); if (result == nullptr) { CPLError(CE_Failure, CPLE_AppDefined, "waitForJobToFinish failed."); return false; } if (result != nullptr) { int type = json_object_get_type(result); if (type == json_type_object) { json_object *poStatus = CPL_json_object_object_get(result, "status"); const char *status = json_object_get_string(poStatus); if (status != nullptr) { if (std::string(status) == "SUCCESS") { return true; } else if (std::string(status) == "FAILURE") { CPLError(CE_Failure, CPLE_AppDefined, "Job failed : %s", json_object_get_string(result)); return false; } } } } CPLSleep(1.0); // Sleep 1 sec. } return false; }
bool OGRCouchDBDataSource::IsOK(json_object* poAnswerObj, const char* pszErrorMsg) { if ( poAnswerObj == NULL || !json_object_is_type(poAnswerObj, json_type_object) ) { CPLError(CE_Failure, CPLE_AppDefined, "%s", pszErrorMsg); return false; } json_object* poOK = CPL_json_object_object_get(poAnswerObj, "ok"); if ( !poOK ) { IsError(poAnswerObj, pszErrorMsg); return false; } const char* pszOK = json_object_get_string(poOK); if ( !pszOK || !CPLTestBool(pszOK) ) { CPLError(CE_Failure, CPLE_AppDefined, "%s", pszErrorMsg); return false; } return true; }
OGRLayer* OGRPLScenesDataV1Dataset::ParseItemType(json_object* poItemType) { if( poItemType == nullptr || json_object_get_type(poItemType) != json_type_object ) return nullptr; json_object* poId = CPL_json_object_object_get(poItemType, "id"); if( poId == nullptr || json_object_get_type(poId) != json_type_string ) return nullptr; CPLString osDisplayDescription; json_object* poDisplayDescription = CPL_json_object_object_get(poItemType, "display_description"); if( poDisplayDescription != nullptr && json_object_get_type(poDisplayDescription) == json_type_string ) osDisplayDescription = json_object_get_string(poDisplayDescription); CPLString osDisplayName; json_object* poDisplayName = CPL_json_object_object_get(poItemType, "display_name"); if( poDisplayName != nullptr && json_object_get_type(poDisplayName) == json_type_string ) osDisplayName = json_object_get_string(poDisplayName); const char* pszId = json_object_get_string(poId); // The layer might already exist if GetLayerByName() is called before // GetLayer()/GetLayerCount() is // Prevent GetLayerCount() from calling EstablishLayerList() bool bLayerListInitializedBackup = m_bLayerListInitialized; m_bLayerListInitialized = true; OGRLayer* poExistingLayer = GDALDataset::GetLayerByName(pszId); m_bLayerListInitialized = bLayerListInitializedBackup; if( poExistingLayer != nullptr ) return poExistingLayer; OGRPLScenesDataV1Layer* poPLLayer = new OGRPLScenesDataV1Layer( this, pszId); if( !osDisplayName.empty() ) poPLLayer->SetMetadataItem("SHORT_DESCRIPTION", osDisplayName.c_str()); if( !osDisplayDescription.empty() ) poPLLayer->SetMetadataItem("DESCRIPTION", osDisplayDescription.c_str()); m_papoLayers = (OGRPLScenesDataV1Layer**) CPLRealloc(m_papoLayers, sizeof(OGRPLScenesDataV1Layer*) * (m_nLayers + 1)); m_papoLayers[m_nLayers ++] = poPLLayer; return poPLLayer; }
static const char *GetJsonValueStr( json_object * pJSONObject, CPLString pszKey ) { json_object *pJSONItem = CPL_json_object_object_get(pJSONObject, pszKey.c_str()); if( pJSONItem == nullptr ) { CPLDebug("ARGDataset", "GetJsonValueStr(): " "Could not find '%s' in JSON.", pszKey.c_str()); return nullptr; } return json_object_get_string(pJSONItem); }
void OGRCloudantTableLayer::GetSpatialView() { if (pszSpatialView == nullptr) { if (bHasStandardSpatial < 0 || bHasStandardSpatial == FALSE) { pszSpatialView = CPLGetConfigOption("CLOUDANT_SPATIAL_FILTER" , nullptr); if (pszSpatialView) bHasStandardSpatial = FALSE; } if (bHasStandardSpatial < 0) { // get standard cloudant geo spatial view CPLString osURI("/"); osURI += osEscapedName; osURI += "/_design/SpatialView"; json_object* poAnswerObj = poDS->GET(osURI); bHasStandardSpatial = (poAnswerObj != nullptr && json_object_is_type(poAnswerObj, json_type_object) && CPL_json_object_object_get(poAnswerObj, "st_indexes") != nullptr); json_object_put(poAnswerObj); } if (bHasStandardSpatial) pszSpatialView = "_design/SpatialView/_geo/spatial"; char **papszTokens = CSLTokenizeString2( pszSpatialView, "/", 0); if ((papszTokens[0] == nullptr) || (papszTokens[1] == nullptr)) { CPLError(CE_Failure, CPLE_AppDefined, "GetSpatialView() failed, invalid spatial design doc."); CSLDestroy(papszTokens); return; } const size_t nLen = strlen(papszTokens[0]) + strlen(papszTokens[1]) + 2; pszSpatialDDoc = static_cast<char *>(CPLCalloc(nLen, 1)); snprintf(pszSpatialDDoc, nLen, "%s/%s", papszTokens[0], papszTokens[1]); CSLDestroy(papszTokens); } }
GIntBig OGRPLScenesLayer::GetFeatureCount(int bForce) { if( nFeatureCount < 0 ) { CPLString osURL(BuildURL(1)); if( bFilterMustBeClientSideEvaluated ) { nFeatureCount = OGRLayer::GetFeatureCount(bForce); } else if( osURL.find('?') == std::string::npos ) { /* Case of a "id = XXXXX" filter: we get directly a Feature, */ /* not a FeatureCollection */ GetNextPage(); } else { nFeatureCount = 0; json_object* poObj = poDS->RunRequest(osURL); if( poObj != NULL ) { json_object* poCount = CPL_json_object_object_get(poObj, "count"); if( poCount != NULL ) nFeatureCount = MAX(0, json_object_get_int64(poCount)); // Small optimization, if the feature count is actually 1 // then we can fetch it as the full layer if( nFeatureCount == 1 ) { delete poGeoJSONDS; // Parse the Feature/FeatureCollection with the GeoJSON reader poGeoJSONDS = new OGRGeoJSONDataSource(); OGRGeoJSONReader oReader; oReader.SetFlattenNestedAttributes(true, '.'); oReader.ReadLayer( poGeoJSONDS, "layer", poObj); poGeoJSONLayer = poGeoJSONDS->GetLayer(0); osNextURL = ""; } json_object_put(poObj); } } } return nFeatureCount; }
json_object* OGRAMIGOCLOUDGetSingleRow(json_object* poObj) { if( poObj == NULL ) { return NULL; } json_object* poRows = CPL_json_object_object_get(poObj, "data"); if( poRows == NULL || json_object_get_type(poRows) != json_type_array || json_object_array_length(poRows) != 1 ) { return NULL; } json_object* poRowObj = json_object_array_get_idx(poRows, 0); if( poRowObj == NULL || json_object_get_type(poRowObj) != json_type_object ) { return NULL; } return poRowObj; }
OGRPLScenesLayer::OGRPLScenesLayer( OGRPLScenesDataset* poDSIn, const char* pszName, const char* pszBaseURL, json_object* poObjCount10 ) : poDS(poDSIn), osBaseURL(pszBaseURL), poFeatureDefn(new OGRFeatureDefn(pszName)), poSRS(new OGRSpatialReference(SRS_WKT_WGS84)), bEOF(false), nNextFID(1), nFeatureCount(-1), poGeoJSONDS(NULL), poGeoJSONLayer(NULL), poMainFilter(NULL), nPageSize(atoi(CPLGetConfigOption("PLSCENES_PAGE_SIZE", "1000"))), bStillInFirstPage(false), bAcquiredAscending(-1), bFilterMustBeClientSideEvaluated(false) { SetDescription(pszName); poFeatureDefn->SetGeomType(wkbMultiPolygon); for( int i = 0; i < static_cast<int>(sizeof(apsAttrs)) / static_cast<int>(sizeof(apsAttrs[0])); i++ ) { OGRFieldDefn oField(apsAttrs[i].pszName, apsAttrs[i].eType); poFeatureDefn->AddFieldDefn(&oField); } poFeatureDefn->Reference(); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); ResetReading(); if( poObjCount10 != NULL ) { json_object* poCount = CPL_json_object_object_get(poObjCount10, "count"); if( poCount != NULL ) nFeatureCount = MAX(0, json_object_get_int64(poCount)); OGRGeoJSONDataSource* poTmpDS = new OGRGeoJSONDataSource(); OGRGeoJSONReader oReader; oReader.SetFlattenNestedAttributes(true, '.'); oReader.ReadLayer( poTmpDS, "layer", poObjCount10 ); OGRLayer* poTmpLayer = poTmpDS->GetLayer(0); if( poTmpLayer ) { OGRFeatureDefn* poTmpFDefn = poTmpLayer->GetLayerDefn(); std::vector<CPLString> aosNewFields; for(int i=0;i<poTmpFDefn->GetFieldCount();i++) { if( poFeatureDefn->GetFieldIndex(poTmpFDefn->GetFieldDefn(i)->GetNameRef()) < 0 ) aosNewFields.push_back(poTmpFDefn->GetFieldDefn(i)->GetNameRef()); } std::sort(aosNewFields.begin(), aosNewFields.end(), OGRPLScenesLayerFieldNameComparator); for(int i=0;i<(int)aosNewFields.size();i++) { OGRFieldDefn oField(poTmpFDefn->GetFieldDefn(poTmpFDefn->GetFieldIndex(aosNewFields[i]))); poFeatureDefn->AddFieldDefn(&oField); } } delete poTmpDS; } }
GDALDataset* OGRPLScenesDataV1Dataset::OpenRasterScene(GDALOpenInfo* poOpenInfo, CPLString osScene, char** papszOptions) { if( !(poOpenInfo->nOpenFlags & GDAL_OF_RASTER) ) { CPLError(CE_Failure, CPLE_AppDefined, "The scene option must only be used with vector access"); return nullptr; } int nActivationTimeout = atoi(CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "ACTIVATION_TIMEOUT", "3600")); for( char** papszIter = papszOptions; papszIter && *papszIter; papszIter ++ ) { char* pszKey = nullptr; const char* pszValue = CPLParseNameValue(*papszIter, &pszKey); if( pszValue != nullptr ) { if( !EQUAL(pszKey, "api_key") && !EQUAL(pszKey, "scene") && !EQUAL(pszKey, "product_type") && !EQUAL(pszKey, "asset") && !EQUAL(pszKey, "catalog") && !EQUAL(pszKey, "itemtypes") && !EQUAL(pszKey, "version") && !EQUAL(pszKey, "follow_links") && !EQUAL(pszKey, "metadata")) { CPLError(CE_Failure, CPLE_NotSupported, "Unsupported option %s", pszKey); CPLFree(pszKey); return nullptr; } CPLFree(pszKey); } } const char* pszCatalog = CSLFetchNameValueDef(papszOptions, "itemtypes", CSLFetchNameValueDef(papszOptions, "catalog", CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "ITEMTYPES", CSLFetchNameValue(poOpenInfo->papszOpenOptions, "CATALOG")))); if( pszCatalog == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing catalog"); return nullptr; } const char* pszProductType = CSLFetchNameValueDef(papszOptions, "asset", CSLFetchNameValueDef(papszOptions, "product_type", CSLFetchNameValueDef(poOpenInfo->papszOpenOptions, "ASSET", CSLFetchNameValue(poOpenInfo->papszOpenOptions, "PRODUCT_TYPE")))); CPLString osRasterURL; osRasterURL = m_osBaseURL; osRasterURL += "item-types/"; osRasterURL += pszCatalog; osRasterURL += "/items/"; osRasterURL += osScene; osRasterURL += "/assets/"; time_t nStartTime = time(nullptr); retry: time_t nCurrentTime = time(nullptr); if( nCurrentTime - nStartTime > nActivationTimeout ) { CPLError(CE_Failure, CPLE_AppDefined, "Activation timeout reached"); return nullptr; } json_object* poObj = RunRequest( osRasterURL ); if( poObj == nullptr ) return nullptr; json_object* poSubObj = nullptr; if( pszProductType != nullptr && (poSubObj = CPL_json_object_object_get(poObj, pszProductType)) != nullptr ) { /* do nothing */ } else if( pszProductType != nullptr && !EQUAL(pszProductType, "LIST") && (poSubObj = CPL_json_object_object_get(poObj, pszProductType)) == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find asset %s", pszProductType); json_object_put(poObj); return nullptr; } else if( pszProductType == nullptr && (poSubObj = CPL_json_object_object_get(poObj, "visual")) != nullptr ) { /* do nothing */ } else { json_object_iter it; it.key = nullptr; it.val = nullptr; it.entry = nullptr; char** papszSubdatasets = nullptr; int nSubDataset = 0; json_object_object_foreachC( poObj, it ) { ++nSubDataset; papszSubdatasets = CSLSetNameValue(papszSubdatasets, CPLSPrintf("SUBDATASET_%d_NAME", nSubDataset), CPLSPrintf("Scene=%s of item types %s, asset %s", osScene.c_str(), pszCatalog, it.key)); papszSubdatasets = CSLSetNameValue(papszSubdatasets, CPLSPrintf("SUBDATASET_%d_DESC", nSubDataset), CPLSPrintf("PLScenes:version=Data_V1,itemtypes=%s,scene=%s,asset=%s", pszCatalog, osScene.c_str(), it.key)); } json_object_put(poObj); if( nSubDataset != 0 ) { GDALDataset* poDS = new OGRPLScenesDataV1Dataset(); poDS->SetMetadata(papszSubdatasets, "SUBDATASETS"); CSLDestroy(papszSubdatasets); return poDS; } return nullptr; }
OGRLayer* OGRCouchDBDataSource::OpenDatabase(const char* pszLayerName) { CPLString osTableName; CPLString osEscapedName; if (pszLayerName) { osTableName = pszLayerName; char* pszEscapedName = CPLEscapeString(pszLayerName, -1, CPLES_URL); osEscapedName = pszEscapedName; CPLFree(pszEscapedName); } else { char* pszURL = CPLStrdup(osURL); char* pszLastSlash = strrchr(pszURL, '/'); if (pszLastSlash) { osEscapedName = pszLastSlash + 1; char* l_pszName = CPLUnescapeString(osEscapedName, NULL, CPLES_URL); osTableName = l_pszName; CPLFree(l_pszName); *pszLastSlash = 0; } osURL = pszURL; CPLFree(pszURL); pszURL = NULL; if (pszLastSlash == NULL) return NULL; } CPLString osURI("/"); osURI += osEscapedName; json_object* poAnswerObj = GET(osURI); if (poAnswerObj == NULL) return NULL; if ( !json_object_is_type(poAnswerObj, json_type_object) || CPL_json_object_object_get(poAnswerObj, "db_name") == NULL ) { IsError(poAnswerObj, "Database opening failed"); json_object_put(poAnswerObj); return NULL; } OGRCouchDBTableLayer* poLayer = new OGRCouchDBTableLayer(this, osTableName); if ( CPL_json_object_object_get(poAnswerObj, "update_seq") != NULL ) { int nUpdateSeq = json_object_get_int(CPL_json_object_object_get(poAnswerObj, "update_seq")); poLayer->SetUpdateSeq(nUpdateSeq); } json_object_put(poAnswerObj); papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*)); papoLayers[nLayers ++] = poLayer; return poLayer; }
json_object* OGRAmigoCloudDataSource::RunGET(const char*pszURL) { CPLString osURL(pszURL); /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( osAPIKey.size() > 0 ) { osURL += "?token="; osURL += osAPIKey; } CPLHTTPResult * psResult = CPLHTTPFetch( osURL.c_str(), NULL); if( psResult == NULL ) return NULL; if (psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "AMIGOCLOUD", "RunGET HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server:%s", psResult->pabyData); CPLHTTPDestroyResult(psResult); return NULL; } if ( psResult->pszErrBuf != NULL) { CPLDebug( "AMIGOCLOUD", "RunGET Error Message:%s", psResult->pszErrBuf ); } else if (psResult->nStatus != 0) { CPLDebug( "AMIGOCLOUD", "RunGET Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == NULL ) { CPLHTTPDestroyResult(psResult); return NULL; } CPLDebug( "AMIGOCLOUD", "RunGET Response:%s", psResult->pabyData ); json_tokener* jstok = NULL; json_object* poObj = NULL; jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1); if( jstok->err != json_tokener_success) { CPLError( CE_Failure, CPLE_AppDefined, "JSON parsing error: %s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); return NULL; } json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); if( poObj != NULL ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = CPL_json_object_object_get(poObj, "error"); if( poError != NULL && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != NULL && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return NULL; } } } else { json_object_put(poObj); return NULL; } } return poObj; }
json_object* OGRAmigoCloudDataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL; osSQL = "/users/0/projects/" + CPLString(pszProjetctId) + "/sql"; /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( osAPIKey.size() > 0 ) { osSQL += "?token="; osSQL += osAPIKey; } osSQL += "&query="; char * pszEscaped = CPLEscapeString( pszUnescapedSQL, -1, CPLES_URL ); std::string escaped = pszEscaped; CPLFree( pszEscaped ); osSQL += escaped; /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ std::string pszAPIURL = GetAPIURL(); char** papszOptions = NULL; pszAPIURL += osSQL; CPLHTTPResult * psResult = CPLHTTPFetch( pszAPIURL.c_str(), papszOptions); CSLDestroy(papszOptions); if( psResult == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "AMIGOCLOUD", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); return NULL; } if (psResult->pszErrBuf != NULL) { CPLDebug( "AMIGOCLOUD", "RunSQL Error Message:%s", psResult->pszErrBuf ); } else if (psResult->nStatus != 0) { CPLDebug( "AMIGOCLOUD", "RunSQL Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == NULL ) { CPLHTTPDestroyResult(psResult); return NULL; } CPLDebug( "AMIGOCLOUD", "RunSQL Response:%s", psResult->pabyData ); json_tokener* jstok = NULL; json_object* poObj = NULL; jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1); if( jstok->err != json_tokener_success) { CPLError( CE_Failure, CPLE_AppDefined, "JSON parsing error: %s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); return NULL; } json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); if( poObj != NULL ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = CPL_json_object_object_get(poObj, "error"); if( poError != NULL && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != NULL && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return NULL; } } } else { json_object_put(poObj); return NULL; } } return poObj; }
json_object* OGRAmigoCloudDataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL; osSQL = "/users/0/projects/" + CPLString(pszProjectId) + "/sql"; /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( !osAPIKey.empty() ) { osSQL += "?token=" + osAPIKey; } osSQL += "&query="; char * pszEscaped = CPLEscapeString( pszUnescapedSQL, -1, CPLES_URL ); std::string escaped = pszEscaped; CPLFree( pszEscaped ); osSQL += escaped; /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ std::string pszAPIURL = GetAPIURL(); char** papszOptions = nullptr; papszOptions = CSLAddString(papszOptions, GetUserAgentOption().c_str()); pszAPIURL += osSQL; CPLHTTPResult * psResult = CPLHTTPFetch( pszAPIURL.c_str(), papszOptions); CSLDestroy(papszOptions); if( psResult == nullptr ) return nullptr; /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLDebug( "AMIGOCLOUD", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); return nullptr; } if (psResult->pszErrBuf != nullptr && psResult->pabyData != nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "GET Response: %s", psResult->pabyData ); } else if (psResult->nStatus != 0) { CPLDebug( "AMIGOCLOUD", "RunGET Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == nullptr ) { CPLHTTPDestroyResult(psResult); return nullptr; } CPLDebug( "AMIGOCLOUD", "RunSQL Response:%s", psResult->pabyData ); json_object* poObj = nullptr; const char* pszText = reinterpret_cast<const char*>(psResult->pabyData); if( !OGRJSonParse(pszText, &poObj, true) ) { CPLHTTPDestroyResult(psResult); return nullptr; } CPLHTTPDestroyResult(psResult); if( poObj != nullptr ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = CPL_json_object_object_get(poObj, "error"); if( poError != nullptr && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != nullptr && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return nullptr; } } } else { json_object_put(poObj); return nullptr; } } return poObj; }
void OGRCloudantTableLayer::WriteMetadata() { if (pszSpatialDDoc == nullptr) OGRCloudantTableLayer::GetSpatialView(); if( pszSpatialDDoc == nullptr ) return; CPLString osURI; osURI = "/"; osURI += osEscapedName; osURI += "/"; osURI += pszSpatialDDoc; json_object* poDDocObj = poDS->GET(osURI); if (poDDocObj == nullptr) return; if ( !json_object_is_type(poDDocObj, json_type_object) ) { CPLError(CE_Failure, CPLE_AppDefined, "WriteMetadata() failed"); json_object_put(poDDocObj); return; } json_object* poError = CPL_json_object_object_get(poDDocObj, "error"); const char* pszError = json_object_get_string(poError); if (pszError && strcmp(pszError, "not_found") == 0) { json_object_put(poDDocObj); return; } if (poDS->IsError(poDDocObj, "WriteMetadata() failed")) { json_object_put(poDDocObj); return; } if (poSRS) { // epsg codes are supported in Cloudant const char * pszEpsg = nullptr; const char * pszAuthName = nullptr; char szSrid[100]; if (poSRS->IsProjected()) { pszAuthName = poSRS->GetAuthorityName("PROJCS"); if ((pszAuthName != nullptr) && (STARTS_WITH(pszAuthName, "EPSG"))) pszEpsg = poSRS->GetAuthorityCode("PROJCS"); } else { pszAuthName = poSRS->GetAuthorityName("GEOGCS"); if ((pszAuthName != nullptr) && (STARTS_WITH(pszAuthName, "EPSG"))) pszEpsg = poSRS->GetAuthorityCode("GEOGCS"); } if (pszEpsg != nullptr) { const char * pszUrn = "urn:ogc:def:crs:epsg::"; CPLStrlcpy(szSrid, pszUrn, sizeof(szSrid)); if (CPLStrlcpy(szSrid + sizeof(pszUrn), pszEpsg, sizeof(szSrid)) <= sizeof(szSrid)) { json_object_object_add(poDDocObj, "srsid", json_object_new_string(pszUrn)); } } } if (eGeomType != wkbNone) { json_object_object_add(poDDocObj, "geomtype", json_object_new_string(OGRToOGCGeomType(eGeomType))); if (wkbHasZ(poFeatureDefn->GetGeomType())) { json_object_object_add(poDDocObj, "is_25D", json_object_new_boolean(TRUE)); } } else { json_object_object_add(poDDocObj, "geomtype", json_object_new_string("NONE")); } json_object_object_add(poDDocObj, "geojson_documents", json_object_new_boolean(bGeoJSONDocument)); json_object* poFields = json_object_new_array(); json_object_object_add(poDDocObj, "fields", poFields); for(int i=COUCHDB_FIRST_FIELD;i<poFeatureDefn->GetFieldCount();i++) { json_object* poField = json_object_new_object(); json_object_array_add(poFields, poField); json_object_object_add(poField, "name", json_object_new_string(poFeatureDefn->GetFieldDefn(i)->GetNameRef())); const char* pszType = nullptr; switch (poFeatureDefn->GetFieldDefn(i)->GetType()) { case OFTInteger: pszType = "integer"; break; case OFTReal: pszType = "real"; break; case OFTString: pszType = "string"; break; case OFTIntegerList: pszType = "integerlist"; break; case OFTRealList: pszType = "reallist"; break; case OFTStringList: pszType = "stringlist"; break; default: pszType = "string"; break; } json_object_object_add(poField, "type", json_object_new_string(pszType)); } json_object* poAnswerObj = poDS->PUT(osURI, json_object_to_json_string(poDDocObj)); json_object_put(poDDocObj); json_object_put(poAnswerObj); }
json_object* OGRAmigoCloudDataSource::RunGET(const char*pszURL) { CPLString osURL(pszURL); /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( !osAPIKey.empty() ) { if(osURL.find("?") == std::string::npos) osURL += "?token="; else osURL += "&token="; osURL += osAPIKey; } char** papszOptions=nullptr; papszOptions = CSLAddString(papszOptions, GetUserAgentOption().c_str()); CPLHTTPResult * psResult = CPLHTTPFetch( osURL.c_str(), papszOptions); CSLDestroy( papszOptions ); if( psResult == nullptr ) { return nullptr; } if (psResult->pszContentType && strncmp(psResult->pszContentType, "text/html", 9) == 0) { CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server:%s", psResult->pabyData); CPLHTTPDestroyResult(psResult); return nullptr; } if (psResult->pszErrBuf != nullptr && psResult->pabyData != nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "GET Response: %s", psResult->pabyData ); } else if (psResult->nStatus != 0) { CPLDebug( "AMIGOCLOUD", "RunGET Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == nullptr ) { CPLHTTPDestroyResult(psResult); return nullptr; } CPLDebug( "AMIGOCLOUD", "RunGET Response:%s", psResult->pabyData ); json_object* poObj = nullptr; const char* pszText = reinterpret_cast<const char*>(psResult->pabyData); if( !OGRJSonParse(pszText, &poObj, true) ) { CPLHTTPDestroyResult(psResult); return nullptr; } CPLHTTPDestroyResult(psResult); if( poObj != nullptr ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = CPL_json_object_object_get(poObj, "error"); if( poError != nullptr && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != nullptr && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return nullptr; } } } else { json_object_put(poObj); return nullptr; } } return poObj; }
void OGRCloudantTableLayer::LoadMetadata() { if( bHasLoadedMetadata ) return; bHasLoadedMetadata = true; if (pszSpatialDDoc == nullptr) GetSpatialView(); if( pszSpatialDDoc == nullptr ) return; CPLString osURI("/"); osURI += osEscapedName; osURI += "/"; osURI += pszSpatialDDoc; json_object* poAnswerObj = poDS->GET(osURI); if (poAnswerObj == nullptr) return; if ( !json_object_is_type(poAnswerObj, json_type_object) ) { CPLError(CE_Failure, CPLE_AppDefined, "LoadMetadata() failed"); json_object_put(poAnswerObj); return; } json_object* poRev = CPL_json_object_object_get(poAnswerObj, "_rev"); const char* pszRev = json_object_get_string(poRev); if (pszRev) osMetadataRev = pszRev; json_object* poError = CPL_json_object_object_get(poAnswerObj, "error"); const char* pszError = json_object_get_string(poError); if (pszError && strcmp(pszError, "not_found") == 0) { json_object_put(poAnswerObj); return; } if (poDS->IsError(poAnswerObj, "LoadMetadata() failed")) { json_object_put(poAnswerObj); return; } json_object* poJsonSRS = CPL_json_object_object_get(poAnswerObj, "srsid"); const char* pszSRS = json_object_get_string(poJsonSRS); if (pszSRS != nullptr) { poSRS = new OGRSpatialReference(); if (poSRS->importFromURN(pszSRS) != OGRERR_NONE) { delete poSRS; poSRS = nullptr; } } json_object* poGeomType = CPL_json_object_object_get(poAnswerObj, "geomtype"); const char* pszGeomType = json_object_get_string(poGeomType); if (pszGeomType) { if (EQUAL(pszGeomType, "NONE")) { eGeomType = wkbNone; bExtentValid = true; } else { eGeomType = OGRFromOGCGeomType(pszGeomType); json_object* poIs25D = CPL_json_object_object_get(poAnswerObj, "is_25D"); if (poIs25D && json_object_get_boolean(poIs25D)) eGeomType = wkbSetZ(eGeomType); json_object* poExtent = CPL_json_object_object_get(poAnswerObj, "extent"); if (poExtent && json_object_get_type(poExtent) == json_type_object) { json_object* poBbox = CPL_json_object_object_get(poExtent, "bbox"); if (poBbox && json_object_get_type(poBbox) == json_type_array && json_object_array_length(poBbox) == 4 && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 0)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 1)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 2)) && OGRCloudantIsNumericObject(json_object_array_get_idx(poBbox, 3))) { dfMinX = json_object_get_double(json_object_array_get_idx(poBbox, 0)); dfMinY = json_object_get_double(json_object_array_get_idx(poBbox, 1)); dfMaxX = json_object_get_double(json_object_array_get_idx(poBbox, 2)); dfMaxY = json_object_get_double(json_object_array_get_idx(poBbox, 3)); bExtentValid = true; bExtentSet = true; } } } } json_object* poGeoJSON = CPL_json_object_object_get(poAnswerObj, "geojson_documents"); if (poGeoJSON && json_object_is_type(poGeoJSON, json_type_boolean)) bGeoJSONDocument = CPL_TO_BOOL(json_object_get_boolean(poGeoJSON)); json_object* poFields = CPL_json_object_object_get(poAnswerObj, "fields"); if (poFields && json_object_is_type(poFields, json_type_array)) { poFeatureDefn = new OGRFeatureDefn( osName ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType(eGeomType); if( poFeatureDefn->GetGeomFieldCount() != 0 ) poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); OGRFieldDefn oFieldId("_id", OFTString); poFeatureDefn->AddFieldDefn(&oFieldId); OGRFieldDefn oFieldRev("_rev", OFTString); poFeatureDefn->AddFieldDefn(&oFieldRev); int nFields = json_object_array_length(poFields); for(int i=0;i<nFields;i++) { json_object* poField = json_object_array_get_idx(poFields, i); if (poField && json_object_is_type(poField, json_type_object)) { json_object* poName = CPL_json_object_object_get(poField, "name"); const char* pszName = json_object_get_string(poName); if (pszName) { json_object* poType = CPL_json_object_object_get(poField, "type"); const char* pszType = json_object_get_string(poType); OGRFieldType eType = OFTString; if (pszType) { if (strcmp(pszType, "integer") == 0) eType = OFTInteger; else if (strcmp(pszType, "integerlist") == 0) eType = OFTIntegerList; else if (strcmp(pszType, "real") == 0) eType = OFTReal; else if (strcmp(pszType, "reallist") == 0) eType = OFTRealList; else if (strcmp(pszType, "string") == 0) eType = OFTString; else if (strcmp(pszType, "stringlist") == 0) eType = OFTStringList; } OGRFieldDefn oField(pszName, eType); poFeatureDefn->AddFieldDefn(&oField); } } } } std::sort(aosIdsToFetch.begin(), aosIdsToFetch.end()); json_object_put(poAnswerObj); return; }
bool OGRCloudantTableLayer::RunSpatialFilterQueryIfNecessary() { if( !bMustRunSpatialFilter ) return true; bMustRunSpatialFilter = false; CPLAssert(nOffset == 0); aosIdsToFetch.resize(0); if (pszSpatialView == nullptr) GetSpatialView(); OGREnvelope sEnvelope; m_poFilterGeom->getEnvelope( &sEnvelope ); CPLString osURI("/"); osURI += osEscapedName; osURI += "/"; osURI += pszSpatialView; osURI += "?bbox="; osURI += CPLSPrintf("%.9f,%.9f,%.9f,%.9f", sEnvelope.MinX, sEnvelope.MinY, sEnvelope.MaxX, sEnvelope.MaxY); json_object* poAnswerObj = poDS->GET(osURI); if (poAnswerObj == nullptr) { CPLDebug("Cloudant", "Cloudant geo not working --> client-side spatial filtering"); bServerSideSpatialFilteringWorks = false; return false; } if ( !json_object_is_type(poAnswerObj, json_type_object) ) { CPLDebug("Cloudant", "Cloudant geo not working --> client-side spatial filtering"); bServerSideSpatialFilteringWorks = false; CPLError(CE_Failure, CPLE_AppDefined, "FetchNextRowsSpatialFilter() failed"); json_object_put(poAnswerObj); return false; } /* Catch error for a non cloudant geo database */ json_object* poError = CPL_json_object_object_get(poAnswerObj, "error"); json_object* poReason = CPL_json_object_object_get(poAnswerObj, "reason"); const char* pszError = json_object_get_string(poError); const char* pszReason = json_object_get_string(poReason); if (pszError && pszReason && strcmp(pszError, "not_found") == 0 && strcmp(pszReason, "Document is missing attachment") == 0) { CPLDebug("Cloudant", "Cloudant geo not working --> client-side spatial filtering"); bServerSideSpatialFilteringWorks = false; json_object_put(poAnswerObj); return false; } if (poDS->IsError(poAnswerObj, "FetchNextRowsSpatialFilter() failed")) { CPLDebug("Cloudant", "Cloudant geo not working --> client-side spatial filtering"); bServerSideSpatialFilteringWorks = false; json_object_put(poAnswerObj); return false; } json_object* poRows = CPL_json_object_object_get(poAnswerObj, "rows"); if (poRows == nullptr || !json_object_is_type(poRows, json_type_array)) { CPLDebug("Cloudant", "Cloudant geo not working --> client-side spatial filtering"); bServerSideSpatialFilteringWorks = false; CPLError(CE_Failure, CPLE_AppDefined, "FetchNextRowsSpatialFilter() failed"); json_object_put(poAnswerObj); return false; } int nRows = json_object_array_length(poRows); for(int i=0;i<nRows;i++) { json_object* poRow = json_object_array_get_idx(poRows, i); if ( poRow == nullptr || !json_object_is_type(poRow, json_type_object) ) { CPLError(CE_Failure, CPLE_AppDefined, "FetchNextRowsSpatialFilter() failed"); json_object_put(poAnswerObj); return false; } json_object* poId = CPL_json_object_object_get(poRow, "id"); const char* pszId = json_object_get_string(poId); if (pszId != nullptr) { aosIdsToFetch.push_back(pszId); } } std::sort(aosIdsToFetch.begin(), aosIdsToFetch.end()); json_object_put(poAnswerObj); return true; }
int OGRCouchDBDataSource::Open( const char * pszFilename, int bUpdateIn) { bool bHTTP = STARTS_WITH(pszFilename, "http://") || STARTS_WITH(pszFilename, "https://"); if( !bHTTP && !STARTS_WITH_CI(pszFilename, "CouchDB:")) return FALSE; bReadWrite = CPL_TO_BOOL(bUpdateIn); pszName = CPLStrdup( pszFilename ); if( bHTTP ) osURL = pszFilename; else osURL = pszFilename + 8; if (!osURL.empty() && osURL.back() == '/') osURL.resize(osURL.size() - 1); const char* pszUserPwd = CPLGetConfigOption("COUCHDB_USERPWD", NULL); if (pszUserPwd) osUserPwd = pszUserPwd; if ((strstr(osURL, "/_design/") && strstr(osURL, "/_view/")) || strstr(osURL, "/_all_docs")) { return OpenView() != NULL; } /* If passed with http://useraccount.knownprovider.com/database, do not */ /* try to issue /all_dbs, but directly open the database */ const char* pszKnowProvider = strstr(osURL, ".iriscouch.com/"); if (pszKnowProvider != NULL && strchr(pszKnowProvider + strlen(".iriscouch.com/"), '/' ) == NULL) { return OpenDatabase() != NULL; } pszKnowProvider = strstr(osURL, ".cloudant.com/"); if (pszKnowProvider != NULL && strchr(pszKnowProvider + strlen(".cloudant.com/"), '/' ) == NULL) { return OpenDatabase() != NULL; } /* Get list of tables */ json_object* poAnswerObj = GET("/_all_dbs"); if (poAnswerObj == NULL) { if (!STARTS_WITH_CI(pszFilename, "CouchDB:")) CPLErrorReset(); return FALSE; } if ( !json_object_is_type(poAnswerObj, json_type_array) ) { if ( json_object_is_type(poAnswerObj, json_type_object) ) { json_object* poError = CPL_json_object_object_get(poAnswerObj, "error"); json_object* poReason = CPL_json_object_object_get(poAnswerObj, "reason"); const char* pszError = json_object_get_string(poError); const char* pszReason = json_object_get_string(poReason); if (pszError && pszReason && strcmp(pszError, "not_found") == 0 && strcmp(pszReason, "missing") == 0) { json_object_put(poAnswerObj); poAnswerObj = NULL; CPLErrorReset(); return OpenDatabase() != NULL; } } if (poAnswerObj) { IsError(poAnswerObj, "Database listing failed"); json_object_put(poAnswerObj); return FALSE; } } int nTables = json_object_array_length(poAnswerObj); for(int i=0;i<nTables;i++) { json_object* poAnswerObjDBName = json_object_array_get_idx(poAnswerObj, i); if ( json_object_is_type(poAnswerObjDBName, json_type_string) ) { const char* pszDBName = json_object_get_string(poAnswerObjDBName); if ( strcmp(pszDBName, "_users") != 0 && strcmp(pszDBName, "_replicator") != 0 ) { papoLayers = (OGRLayer**) CPLRealloc(papoLayers, (nLayers + 1) * sizeof(OGRLayer*)); papoLayers[nLayers ++] = new OGRCouchDBTableLayer(this, pszDBName); } } } json_object_put(poAnswerObj); return TRUE; }
int OGRPLScenesLayer::GetNextPage() { delete poGeoJSONDS; poGeoJSONLayer = NULL; poGeoJSONDS = NULL; if( osRequestURL.size() == 0 ) { bEOF = true; if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 ) nFeatureCount = 0; return FALSE; } // In the case of a "id = 'foo'" filter, a non existing resource // will cause a 404 error, which we want to be silent int bQuiet404Error = ( osRequestURL.find('?') == std::string::npos ); json_object* poObj = poDS->RunRequest(osRequestURL, bQuiet404Error); if( poObj == NULL ) { bEOF = true; if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 ) nFeatureCount = 0; return FALSE; } if( !bFilterMustBeClientSideEvaluated && nFeatureCount < 0 ) { json_object* poType = CPL_json_object_object_get(poObj, "type"); if( poType && json_object_get_type(poType) == json_type_string && strcmp(json_object_get_string(poType), "Feature") == 0 ) { nFeatureCount = 1; } else { json_object* poCount = CPL_json_object_object_get(poObj, "count"); if( poCount == NULL ) { json_object_put(poObj); bEOF = true; nFeatureCount = 0; return FALSE; } nFeatureCount = MAX(0, json_object_get_int64(poCount)); } } // Parse the Feature/FeatureCollection with the GeoJSON reader poGeoJSONDS = new OGRGeoJSONDataSource(); OGRGeoJSONReader oReader; oReader.SetFlattenNestedAttributes(true, '.'); oReader.ReadLayer( poGeoJSONDS, "layer", poObj); poGeoJSONLayer = poGeoJSONDS->GetLayer(0); // Get URL of next page osNextURL = ""; if( poGeoJSONLayer ) { json_object* poLinks = CPL_json_object_object_get(poObj, "links"); if( poLinks && json_object_get_type(poLinks) == json_type_object ) { json_object* poNext = CPL_json_object_object_get(poLinks, "next"); if( poNext && json_object_get_type(poNext) == json_type_string ) { osNextURL = json_object_get_string(poNext); } } } json_object_put(poObj); return poGeoJSONLayer != NULL; }
OGRLayer * OGRCouchDBDataSource::ExecuteSQLStats( const char *pszSQLCommand ) { swq_select sSelectInfo; if( sSelectInfo.preparse( pszSQLCommand ) != CE_None ) { return NULL; } if (sSelectInfo.table_count != 1) { return NULL; } swq_table_def *psTableDef = &sSelectInfo.table_defs[0]; if( psTableDef->data_source != NULL ) { return NULL; } OGRCouchDBLayer* _poSrcLayer = (OGRCouchDBLayer* )GetLayerByName( psTableDef->table_name ); if (_poSrcLayer == NULL) { return NULL; } if (_poSrcLayer->GetLayerType() != COUCHDB_TABLE_LAYER) return NULL; OGRCouchDBTableLayer* poSrcLayer = (OGRCouchDBTableLayer* ) _poSrcLayer; int nFieldCount = poSrcLayer->GetLayerDefn()->GetFieldCount(); swq_field_list sFieldList; memset( &sFieldList, 0, sizeof(sFieldList) ); sFieldList.table_count = sSelectInfo.table_count; sFieldList.table_defs = sSelectInfo.table_defs; sFieldList.count = 0; sFieldList.names = static_cast<char **>( CPLMalloc( sizeof(char *) * nFieldCount )); sFieldList.types = static_cast<swq_field_type *>( CPLMalloc( sizeof(swq_field_type) * nFieldCount )); sFieldList.table_ids = static_cast<int *>( CPLMalloc( sizeof(int) * nFieldCount )); sFieldList.ids = static_cast<int *>( CPLMalloc( sizeof(int) * nFieldCount )); PointerAutoFree oHolderNames(sFieldList.names); PointerAutoFree oHolderTypes(sFieldList.types); PointerAutoFree oHolderTableIds(sFieldList.table_ids); PointerAutoFree oHolderIds(sFieldList.ids); for( int iField = 0; iField < poSrcLayer->GetLayerDefn()->GetFieldCount(); iField++ ) { OGRFieldDefn *poFDefn=poSrcLayer->GetLayerDefn()->GetFieldDefn(iField); int iOutField = sFieldList.count++; sFieldList.names[iOutField] = (char *) poFDefn->GetNameRef(); if( poFDefn->GetType() == OFTInteger ) sFieldList.types[iOutField] = SWQ_INTEGER; else if( poFDefn->GetType() == OFTReal ) sFieldList.types[iOutField] = SWQ_FLOAT; else if( poFDefn->GetType() == OFTString ) sFieldList.types[iOutField] = SWQ_STRING; else sFieldList.types[iOutField] = SWQ_OTHER; sFieldList.table_ids[iOutField] = 0; sFieldList.ids[iOutField] = iField; } CPLString osLastFieldName; for( int iField = 0; iField < sSelectInfo.result_columns; iField++ ) { swq_col_def *psColDef = sSelectInfo.column_defs + iField; if (psColDef->field_name == NULL) return NULL; if (strcmp(psColDef->field_name, "*") != 0) { if (osLastFieldName.empty()) osLastFieldName = psColDef->field_name; else if (strcmp(osLastFieldName, psColDef->field_name) != 0) return NULL; if (poSrcLayer->GetLayerDefn()->GetFieldIndex(psColDef->field_name) == -1) return NULL; } if (!(psColDef->col_func == SWQCF_AVG || psColDef->col_func == SWQCF_MIN || psColDef->col_func == SWQCF_MAX || psColDef->col_func == SWQCF_COUNT || psColDef->col_func == SWQCF_SUM)) return NULL; if (psColDef->distinct_flag) /* TODO: could perhaps be relaxed */ return NULL; } if (osLastFieldName.empty()) return NULL; /* Normalize field name */ int nIndex = poSrcLayer->GetLayerDefn()->GetFieldIndex(osLastFieldName); osLastFieldName = poSrcLayer->GetLayerDefn()->GetFieldDefn(nIndex)->GetNameRef(); /* -------------------------------------------------------------------- */ /* Finish the parse operation. */ /* -------------------------------------------------------------------- */ if( sSelectInfo.parse( &sFieldList, NULL ) != CE_None ) { return NULL; } if (sSelectInfo.join_defs != NULL || sSelectInfo.where_expr != NULL || sSelectInfo.order_defs != NULL || sSelectInfo.query_mode != SWQM_SUMMARY_RECORD) { return NULL; } for( int iField = 0; iField < sSelectInfo.result_columns; iField++ ) { swq_col_def *psColDef = sSelectInfo.column_defs + iField; if (psColDef->field_index == -1) { if (psColDef->col_func == SWQCF_COUNT) continue; return NULL; } if (psColDef->field_type != SWQ_INTEGER && psColDef->field_type != SWQ_FLOAT) { return NULL; } } const bool bFoundFilter = CPL_TO_BOOL( poSrcLayer->HasFilterOnFieldOrCreateIfNecessary(osLastFieldName)); if( !bFoundFilter ) return NULL; CPLString osURI = "/"; osURI += poSrcLayer->GetName(); osURI += "/_design/ogr_filter_"; osURI += osLastFieldName; osURI += "/_view/filter?reduce=true"; json_object* poAnswerObj = GET(osURI); json_object* poRows = NULL; if (!(poAnswerObj != NULL && json_object_is_type(poAnswerObj, json_type_object) && (poRows = CPL_json_object_object_get(poAnswerObj, "rows")) != NULL && json_object_is_type(poRows, json_type_array))) { json_object_put(poAnswerObj); return NULL; } int nLength = json_object_array_length(poRows); if (nLength != 1) { json_object_put(poAnswerObj); return NULL; } json_object* poRow = json_object_array_get_idx(poRows, 0); if (!(poRow && json_object_is_type(poRow, json_type_object))) { json_object_put(poAnswerObj); return NULL; } json_object* poValue = CPL_json_object_object_get(poRow, "value"); if (!(poValue != NULL && json_object_is_type(poValue, json_type_object))) { json_object_put(poAnswerObj); return NULL; } json_object* poSum = CPL_json_object_object_get(poValue, "sum"); json_object* poCount = CPL_json_object_object_get(poValue, "count"); json_object* poMin = CPL_json_object_object_get(poValue, "min"); json_object* poMax = CPL_json_object_object_get(poValue, "max"); if (poSum != NULL && (json_object_is_type(poSum, json_type_int) || json_object_is_type(poSum, json_type_double)) && poCount != NULL && (json_object_is_type(poCount, json_type_int) || json_object_is_type(poCount, json_type_double)) && poMin != NULL && (json_object_is_type(poMin, json_type_int) || json_object_is_type(poMin, json_type_double)) && poMax != NULL && (json_object_is_type(poMax, json_type_int) || json_object_is_type(poMax, json_type_double)) ) { double dfSum = json_object_get_double(poSum); int nCount = json_object_get_int(poCount); double dfMin = json_object_get_double(poMin); double dfMax = json_object_get_double(poMax); json_object_put(poAnswerObj); //CPLDebug("CouchDB", "sum=%f, count=%d, min=%f, max=%f", // dfSum, nCount, dfMin, dfMax); OGRFeatureDefn* poFeatureDefn = new OGRFeatureDefn(poSrcLayer->GetName()); poFeatureDefn->Reference(); for( int iField = 0; iField < sSelectInfo.result_columns; iField++ ) { swq_col_def *psColDef = sSelectInfo.column_defs + iField; OGRFieldDefn oFDefn( "", OFTInteger ); if( psColDef->field_alias != NULL ) { oFDefn.SetName(psColDef->field_alias); } else { const swq_operation *op = swq_op_registrar::GetOperator( (swq_op) psColDef->col_func ); oFDefn.SetName( CPLSPrintf( "%s_%s", op->pszName, psColDef->field_name ) ); } if( psColDef->col_func == SWQCF_COUNT ) oFDefn.SetType( OFTInteger ); else if (psColDef->field_type == SWQ_INTEGER) oFDefn.SetType( OFTInteger ); else if (psColDef->field_type == SWQ_FLOAT) oFDefn.SetType( OFTReal ); poFeatureDefn->AddFieldDefn(&oFDefn); } OGRFeature* poFeature = new OGRFeature(poFeatureDefn); for( int iField = 0; iField < sSelectInfo.result_columns; iField++ ) { swq_col_def *psColDef = sSelectInfo.column_defs + iField; switch(psColDef->col_func) { case SWQCF_AVG: if (nCount) poFeature->SetField(iField, dfSum / nCount); break; case SWQCF_MIN: poFeature->SetField(iField, dfMin); break; case SWQCF_MAX: poFeature->SetField(iField, dfMax); break; case SWQCF_COUNT: poFeature->SetField(iField, nCount); break; case SWQCF_SUM: poFeature->SetField(iField, dfSum); break; default: break; } } poFeature->SetFID(0); OGRCouchDBOneLineLayer* poAnswerLayer = new OGRCouchDBOneLineLayer(); poAnswerLayer->poFeatureDefn = poFeatureDefn; poAnswerLayer->poFeature = poFeature; return poAnswerLayer; } json_object_put(poAnswerObj); return NULL; }
json_object* OGRCARTODataSource::RunSQL(const char* pszUnescapedSQL) { CPLString osSQL("POSTFIELDS=q="); /* Do post escaping */ for(int i=0;pszUnescapedSQL[i] != 0;i++) { const int ch = ((unsigned char*)pszUnescapedSQL)[i]; if (ch != '&' && ch >= 32 && ch < 128) osSQL += (char)ch; else osSQL += CPLSPrintf("%%%02X", ch); } /* -------------------------------------------------------------------- */ /* Provide the API Key */ /* -------------------------------------------------------------------- */ if( osAPIKey.size() ) { osSQL += "&api_key="; osSQL += osAPIKey; } /* -------------------------------------------------------------------- */ /* Collection the header options and execute request. */ /* -------------------------------------------------------------------- */ const char* pszAPIURL = GetAPIURL(); char** papszOptions = CSLAddString( !STARTS_WITH(pszAPIURL, "/vsimem/") ? AddHTTPOptions(): NULL, osSQL); CPLHTTPResult * psResult = CPLHTTPFetch( GetAPIURL(), papszOptions); CSLDestroy(papszOptions); if( psResult == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Check for some error conditions and report. HTML Messages */ /* are transformed info failure. */ /* -------------------------------------------------------------------- */ if (psResult->pszContentType && STARTS_WITH(psResult->pszContentType, "text/html")) { CPLDebug( "CARTO", "RunSQL HTML Response:%s", psResult->pabyData ); CPLError(CE_Failure, CPLE_AppDefined, "HTML error page returned by server"); CPLHTTPDestroyResult(psResult); return NULL; } if (psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL Error Message:%s", psResult->pszErrBuf ); } else if (psResult->nStatus != 0) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL Error Status:%d", psResult->nStatus ); } if( psResult->pabyData == NULL ) { CPLHTTPDestroyResult(psResult); return NULL; } if( strlen((const char*)psResult->pabyData) < 1000 ) CPLDebug( "CARTO", "RunSQL Response:%s", psResult->pabyData ); json_tokener* jstok = NULL; json_object* poObj = NULL; jstok = json_tokener_new(); poObj = json_tokener_parse_ex(jstok, (const char*) psResult->pabyData, -1); if( jstok->err != json_tokener_success) { CPLError( CE_Failure, CPLE_AppDefined, "JSON parsing error: %s (at offset %d)", json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); return NULL; } json_tokener_free(jstok); CPLHTTPDestroyResult(psResult); if( poObj != NULL ) { if( json_object_get_type(poObj) == json_type_object ) { json_object* poError = CPL_json_object_object_get(poObj, "error"); if( poError != NULL && json_object_get_type(poError) == json_type_array && json_object_array_length(poError) > 0 ) { poError = json_object_array_get_idx(poError, 0); if( poError != NULL && json_object_get_type(poError) == json_type_string ) { CPLError(CE_Failure, CPLE_AppDefined, "Error returned by server : %s", json_object_get_string(poError)); json_object_put(poObj); return NULL; } } } else { json_object_put(poObj); return NULL; } } return poObj; }