OGRPLScenesLayer::OGRPLScenesLayer(OGRPLScenesDataset* poDS, const char* pszName, const char* pszBaseURL, json_object* poObjCount10) { this->poDS = poDS; osBaseURL = pszBaseURL; SetDescription(pszName); poFeatureDefn = new OGRFeatureDefn(pszName); poFeatureDefn->SetGeomType(wkbMultiPolygon); for(int i = 0; i < (int)sizeof(apsAttrs) / (int)sizeof(apsAttrs[0]); i++) { OGRFieldDefn oField(apsAttrs[i].pszName, apsAttrs[i].eType); poFeatureDefn->AddFieldDefn(&oField); } poFeatureDefn->Reference(); poSRS = new OGRSpatialReference(SRS_WKT_WGS84); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); bEOF = FALSE; nFeatureCount = -1; nNextFID = 1; poGeoJSONDS = NULL; poGeoJSONLayer = NULL; poMainFilter = NULL; nPageSize = atoi(CPLGetConfigOption("PLSCENES_PAGE_SIZE", "1000")); bStillInFirstPage = FALSE; bAcquiredAscending = -1; bFilterMustBeClientSideEvaluated = FALSE; ResetReading(); if( poObjCount10 != NULL ) { json_object* poCount = 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; } }
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 = 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; }
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 = 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 = 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 = json_object_object_get(poObj, "links"); if( poLinks && json_object_get_type(poLinks) == json_type_object ) { json_object* poNext = 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; }
OGRGeoJSONLayer* OGRGeoJSONDataSource::LoadLayer() { if( NULL == pszGeoData_ ) { CPLError( CE_Failure, CPLE_ObjectNull, "GeoJSON data buffer empty" ); return NULL; } if ( !GeoJSONIsObject( pszGeoData_) ) { CPLDebug( "GeoJSON", "No valid GeoJSON data found in source '%s'", pszName_ ); return NULL; } OGRErr err = OGRERR_NONE; OGRGeoJSONLayer* poLayer = NULL; /* -------------------------------------------------------------------- */ /* Is it ESRI Feature Service data ? */ /* -------------------------------------------------------------------- */ if ( strstr(pszGeoData_, "esriGeometry") || strstr(pszGeoData_, "esriFieldTypeOID") ) { OGRESRIJSONReader reader; err = reader.Parse( pszGeoData_ ); if( OGRERR_NONE == err ) { // TODO: Think about better name selection poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName, this ); } return poLayer; } /* -------------------------------------------------------------------- */ /* Configure GeoJSON format translator. */ /* -------------------------------------------------------------------- */ OGRGeoJSONReader reader; if( eGeometryAsCollection == flTransGeom_ ) { reader.SetPreserveGeometryType( false ); CPLDebug( "GeoJSON", "Geometry as OGRGeometryCollection type." ); } if( eAtributesSkip == flTransAttrs_ ) { reader.SetSkipAttributes( true ); CPLDebug( "GeoJSON", "Skip all attributes." ); } /* -------------------------------------------------------------------- */ /* Parse GeoJSON and build valid OGRLayer instance. */ /* -------------------------------------------------------------------- */ err = reader.Parse( pszGeoData_ ); if( OGRERR_NONE == err ) { // TODO: Think about better name selection poLayer = reader.ReadLayer( OGRGeoJSONLayer::DefaultName, this ); } return poLayer; }