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; }
void OGRCloudantTableLayer::WriteMetadata() { GetLayerDefn(); if (pszSpatialDDoc == NULL) GetSpatialView(); if( pszSpatialDDoc == NULL ) return; CPLString osURI; osURI = "/"; osURI += osEscapedName; osURI += "/"; osURI += pszSpatialDDoc; json_object* poDDocObj = poDS->GET(osURI); if (poDDocObj == NULL) 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 = 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 = NULL; const char * pszAuthName = NULL; char szSrid[100]; if (poSRS->IsProjected()) { pszAuthName = poSRS->GetAuthorityName("PROJCS"); if ((pszAuthName != NULL) && (strncmp(pszAuthName, "EPSG", 4) == 0)) pszEpsg = poSRS->GetAuthorityCode("PROJCS"); } else { pszAuthName = poSRS->GetAuthorityName("GEOGCS"); if ((pszAuthName != NULL) && (strncmp(pszAuthName, "EPSG", 4) == 0)) pszEpsg = poSRS->GetAuthorityCode("GEOGCS"); } if (pszEpsg != NULL) { 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=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 = NULL; 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); }