static void ParseObject(const char* pszId, json_object* poObj, OGRGeoJSONLayer* poLayer, json_object* poArcsDB, ScalingParams* psParams) { json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type"); if( poType == NULL || json_object_get_type(poType) != json_type_string ) return; const char* pszType = json_object_get_string(poType); json_object* poArcsObj = OGRGeoJSONFindMemberByName(poObj, "arcs"); json_object* poCoordinatesObj = OGRGeoJSONFindMemberByName(poObj, "coordinates"); if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 ) { if( poCoordinatesObj == NULL || json_type_array != json_object_get_type(poCoordinatesObj) ) return; } else { if( poArcsObj == NULL || json_type_array != json_object_get_type(poArcsObj) ) return; } if( pszId == NULL ) { json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id"); if( poId != NULL && (json_type_string == json_object_get_type(poId) || json_type_int == json_object_get_type(poId)) ) { pszId = json_object_get_string(poId); } } OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn()); if( pszId != NULL ) poFeature->SetField("id", pszId); json_object* poProperties = OGRGeoJSONFindMemberByName(poObj, "properties"); if( poProperties != NULL && json_type_object == json_object_get_type(poProperties) ) { json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poProperties, it ) { const int nField = poFeature->GetFieldIndex(it.key); OGRGeoJSONReaderSetField(poLayer, poFeature, nField, it.key, it.val, false, 0); } }
bool OGRESRIJSONReader::GenerateLayerDefn() { CPLAssert( nullptr != poGJObject_ ); CPLAssert( nullptr != poLayer_->GetLayerDefn() ); CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() ); bool bSuccess = true; /* -------------------------------------------------------------------- */ /* Scan all features and generate layer definition. */ /* -------------------------------------------------------------------- */ json_object* poFields = OGRGeoJSONFindMemberByName( poGJObject_, "fields" ); if( nullptr != poFields && json_type_array == json_object_get_type( poFields ) ) { const int nFeatures = json_object_array_length( poFields ); for( int i = 0; i < nFeatures; ++i ) { json_object* poField = json_object_array_get_idx( poFields, i ); if( !ParseField( poField ) ) { CPLDebug( "GeoJSON", "Create feature schema failure." ); bSuccess = false; } } } else { poFields = OGRGeoJSONFindMemberByName( poGJObject_, "fieldAliases" ); if( nullptr != poFields && json_object_get_type(poFields) == json_type_object ) { OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn(); json_object_iter it; it.key = nullptr; it.val = nullptr; it.entry = nullptr; json_object_object_foreachC( poFields, it ) { OGRFieldDefn fldDefn( it.key, OFTString ); poDefn->AddFieldDefn( &fldDefn ); } }
bool OGRGeoJSONReader::GenerateFeatureDefn( json_object* poObj ) { OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn(); CPLAssert( NULL != poDefn ); bool bSuccess = false; /* -------------------------------------------------------------------- */ /* Read collection of properties. */ /* -------------------------------------------------------------------- */ json_object* poObjProps = NULL; poObjProps = OGRGeoJSONFindMemberByName( poObj, "properties" ); if( NULL != poObjProps && json_object_get_type(poObjProps) == json_type_object ) { if (bIsGeocouchSpatiallistFormat) { poObjProps = json_object_object_get(poObjProps, "properties"); if( NULL == poObjProps || json_object_get_type(poObjProps) != json_type_object ) { return true; } } json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poObjProps, it ) { int nFldIndex = poDefn->GetFieldIndex( it.key ); if( -1 == nFldIndex ) { /* Detect the special kind of GeoJSON output by a spatiallist of GeoCouch */ /* such as http://gd.iriscouch.com/cphosm/_design/geo/_rewrite/data?bbox=12.53%2C55.73%2C12.54%2C55.73 */ if (strcmp(it.key, "_id") == 0) bFoundId = true; else if (bFoundId && strcmp(it.key, "_rev") == 0) bFoundRev = true; else if (bFoundRev && strcmp(it.key, "type") == 0 && it.val != NULL && json_object_get_type(it.val) == json_type_string && strcmp(json_object_get_string(it.val), "Feature") == 0) bFoundTypeFeature = true; else if (bFoundTypeFeature && strcmp(it.key, "properties") == 0 && it.val != NULL && json_object_get_type(it.val) == json_type_object) { if (bFlattenGeocouchSpatiallistFormat < 0) bFlattenGeocouchSpatiallistFormat = CSLTestBoolean( CPLGetConfigOption("GEOJSON_FLATTEN_GEOCOUCH", "TRUE")); if (bFlattenGeocouchSpatiallistFormat) { poDefn->DeleteFieldDefn(poDefn->GetFieldIndex("type")); bIsGeocouchSpatiallistFormat = true; return GenerateFeatureDefn(poObj); } } OGRFieldDefn fldDefn( it.key, GeoJSONPropertyToFieldType( it.val ) ); poDefn->AddFieldDefn( &fldDefn ); } else { OGRFieldDefn* poFDefn = poDefn->GetFieldDefn(nFldIndex); OGRFieldType eType = poFDefn->GetType(); if( eType == OFTInteger ) { OGRFieldType eNewType = GeoJSONPropertyToFieldType( it.val ); if( eNewType == OFTReal ) poFDefn->SetType(eNewType); } } } bSuccess = true; // SUCCESS }
bool OGRGeoJSONReader::GenerateLayerDefn() { CPLAssert( NULL != poGJObject_ ); CPLAssert( NULL != poLayer_->GetLayerDefn() ); CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() ); bool bSuccess = true; if( bAttributesSkip_ ) return true; /* -------------------------------------------------------------------- */ /* Scan all features and generate layer definition. */ /* -------------------------------------------------------------------- */ GeoJSONObject::Type objType = OGRGeoJSONGetType( poGJObject_ ); if( GeoJSONObject::eFeature == objType ) { bSuccess = GenerateFeatureDefn( poGJObject_ ); } else if( GeoJSONObject::eFeatureCollection == objType ) { json_object* poObjFeatures = NULL; poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "features" ); if( NULL != poObjFeatures && json_type_array == json_object_get_type( poObjFeatures ) ) { json_object* poObjFeature = NULL; const int nFeatures = json_object_array_length( poObjFeatures ); for( int i = 0; i < nFeatures; ++i ) { poObjFeature = json_object_array_get_idx( poObjFeatures, i ); if( !GenerateFeatureDefn( poObjFeature ) ) { CPLDebug( "GeoJSON", "Create feature schema failure." ); bSuccess = false; } } } else { CPLError( CE_Failure, CPLE_AppDefined, "Invalid FeatureCollection object. " "Missing \'features\' member." ); bSuccess = false; } } /* -------------------------------------------------------------------- */ /* Validate and add FID column if necessary. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn* poLayerDefn = poLayer_->GetLayerDefn(); CPLAssert( NULL != poLayerDefn ); bool bHasFID = false; for( int i = 0; i < poLayerDefn->GetFieldCount(); ++i ) { OGRFieldDefn* poDefn = poLayerDefn->GetFieldDefn(i); if( EQUAL( poDefn->GetNameRef(), OGRGeoJSONLayer::DefaultFIDColumn ) && OFTInteger == poDefn->GetType() ) { poLayer_->SetFIDColumn( poDefn->GetNameRef() ); bHasFID = true; break; } } // TODO - mloskot: This is wrong! We want to add only FID field if // found in source layer (by default name or by FID_PROPERTY= specifier, // the latter has to be implemented). /* if( !bHasFID ) { OGRFieldDefn fldDefn( OGRGeoJSONLayer::DefaultFIDColumn, OFTInteger ); poLayerDefn->AddFieldDefn( &fldDefn ); poLayer_->SetFIDColumn( fldDefn.GetNameRef() ); } */ return bSuccess; }
OGRSpatialReference* OGRGeoJSONReadSpatialReference( json_object* poObj) { /* -------------------------------------------------------------------- */ /* Read spatial reference definition. */ /* -------------------------------------------------------------------- */ OGRSpatialReference* poSRS = NULL; json_object* poObjSrs = OGRGeoJSONFindMemberByName( poObj, "crs" ); if( NULL != poObjSrs ) { json_object* poObjSrsType = OGRGeoJSONFindMemberByName( poObjSrs, "type" ); if (poObjSrsType == NULL) return NULL; const char* pszSrsType = json_object_get_string( poObjSrsType ); // TODO: Add URL and URN types support if( EQUALN( pszSrsType, "NAME", 4 ) ) { json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" ); if (poObjSrsProps == NULL) return NULL; json_object* poNameURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "name" ); if (poNameURL == NULL) return NULL; const char* pszName = json_object_get_string( poNameURL ); poSRS = new OGRSpatialReference(); if( OGRERR_NONE != poSRS->SetFromUserInput( pszName ) ) { delete poSRS; poSRS = NULL; } } if( EQUALN( pszSrsType, "EPSG", 4 ) ) { json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" ); if (poObjSrsProps == NULL) return NULL; json_object* poObjCode = OGRGeoJSONFindMemberByName( poObjSrsProps, "code" ); if (poObjCode == NULL) return NULL; int nEPSG = json_object_get_int( poObjCode ); poSRS = new OGRSpatialReference(); if( OGRERR_NONE != poSRS->importFromEPSG( nEPSG ) ) { delete poSRS; poSRS = NULL; } } if( EQUALN( pszSrsType, "URL", 3 ) || EQUALN( pszSrsType, "LINK", 4 ) ) { json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" ); if (poObjSrsProps == NULL) return NULL; json_object* poObjURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "url" ); if (NULL == poObjURL) { poObjURL = OGRGeoJSONFindMemberByName( poObjSrsProps, "href" ); } if (poObjURL == NULL) return NULL; const char* pszURL = json_object_get_string( poObjURL ); poSRS = new OGRSpatialReference(); if( OGRERR_NONE != poSRS->importFromUrl( pszURL ) ) { delete poSRS; poSRS = NULL; } } if( EQUAL( pszSrsType, "OGC" ) ) { json_object* poObjSrsProps = OGRGeoJSONFindMemberByName( poObjSrs, "properties" ); if (poObjSrsProps == NULL) return NULL; json_object* poObjURN = OGRGeoJSONFindMemberByName( poObjSrsProps, "urn" ); if (poObjURN == NULL) return NULL; poSRS = new OGRSpatialReference(); if( OGRERR_NONE != poSRS->importFromURN( json_object_get_string(poObjURN) ) ) { delete poSRS; poSRS = NULL; } } } return poSRS; }
void OGRTopoJSONReader::ReadLayers( OGRGeoJSONDataSource* poDS ) { if( NULL == poGJObject_ ) { CPLDebug( "TopoJSON", "Missing parset TopoJSON data. Forgot to call Parse()?" ); return; } ScalingParams sParams; sParams.dfScale0 = 1.0; sParams.dfScale1 = 1.0; sParams.dfTranslate0 = 0.0; sParams.dfTranslate1 = 0.0; json_object* poObjTransform = OGRGeoJSONFindMemberByName( poGJObject_, "transform" ); if( NULL != poObjTransform && json_type_object == json_object_get_type( poObjTransform ) ) { json_object* poObjScale = OGRGeoJSONFindMemberByName( poObjTransform, "scale" ); if( NULL != poObjScale && json_type_array == json_object_get_type( poObjScale ) && json_object_array_length( poObjScale ) == 2 ) { json_object* poScale0 = json_object_array_get_idx(poObjScale, 0); json_object* poScale1 = json_object_array_get_idx(poObjScale, 1); if( poScale0 != NULL && (json_object_get_type(poScale0) == json_type_double || json_object_get_type(poScale0) == json_type_int) && poScale1 != NULL && (json_object_get_type(poScale1) == json_type_double || json_object_get_type(poScale1) == json_type_int) ) { sParams.dfScale0 = json_object_get_double(poScale0); sParams.dfScale1 = json_object_get_double(poScale1); } } json_object* poObjTranslate = OGRGeoJSONFindMemberByName( poObjTransform, "translate" ); if( NULL != poObjTranslate && json_type_array == json_object_get_type( poObjTranslate ) && json_object_array_length( poObjTranslate ) == 2 ) { json_object* poTranslate0 = json_object_array_get_idx(poObjTranslate, 0); json_object* poTranslate1 = json_object_array_get_idx(poObjTranslate, 1); if( poTranslate0 != NULL && (json_object_get_type(poTranslate0) == json_type_double || json_object_get_type(poTranslate0) == json_type_int) && poTranslate1 != NULL && (json_object_get_type(poTranslate1) == json_type_double || json_object_get_type(poTranslate1) == json_type_int) ) { sParams.dfTranslate0 = json_object_get_double(poTranslate0); sParams.dfTranslate1 = json_object_get_double(poTranslate1); } } } json_object* poArcs = OGRGeoJSONFindMemberByName( poGJObject_, "arcs" ); if( poArcs == NULL || json_type_array != json_object_get_type( poArcs ) ) return; OGRGeoJSONLayer* poMainLayer = NULL; json_object* poObjects = OGRGeoJSONFindMemberByName( poGJObject_, "objects" ); if( poObjects == NULL ) return; if( json_type_object == json_object_get_type( poObjects ) ) { json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poObjects, it ) { json_object* poObj = it.val; ParseObjectMain(it.key, poObj, poDS, &poMainLayer, poArcs, &sParams); }
static void ParseObjectMain(const char* pszId, json_object* poObj, OGRGeoJSONDataSource* poDS, OGRGeoJSONLayer **ppoMainLayer, json_object* poArcs, ScalingParams* psParams) { if( poObj != NULL && json_type_object == json_object_get_type( poObj ) ) { json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type"); if( poType != NULL && json_type_string == json_object_get_type( poType ) ) { const char* pszType = json_object_get_string(poType); if( strcmp(pszType, "GeometryCollection") == 0 ) { json_object* poGeometries = OGRGeoJSONFindMemberByName(poObj, "geometries"); if( poGeometries != NULL && json_type_array == json_object_get_type( poGeometries ) ) { if( pszId == NULL ) { json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id"); if( poId != NULL && (json_type_string == json_object_get_type(poId) || json_type_int == json_object_get_type(poId)) ) { pszId = json_object_get_string(poId); } } OGRGeoJSONLayer* poLayer = new OGRGeoJSONLayer( pszId ? pszId : "TopoJSON", NULL, wkbUnknown, poDS ); { OGRFieldDefn fldDefn( "id", OFTString ); poLayer->GetLayerDefn()->AddFieldDefn( &fldDefn ); } { OGRFieldDefn fldDefn( "name", OFTString ); poLayer->GetLayerDefn()->AddFieldDefn( &fldDefn ); } int nGeometries = json_object_array_length(poGeometries); for(int i=0; i<nGeometries; i++) { json_object* poGeom = json_object_array_get_idx(poGeometries, i); if( poGeom != NULL && json_type_object == json_object_get_type( poGeom ) ) { ParseObject(NULL, poGeom, poLayer, poArcs, psParams); } } poDS->AddLayer(poLayer); } } else if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 || strcmp(pszType, "LineString") == 0 || strcmp(pszType, "MultiLineString") == 0 || strcmp(pszType, "Polygon") == 0 || strcmp(pszType, "MultiPolygon") == 0 ) { if( *ppoMainLayer == NULL ) { *ppoMainLayer = new OGRGeoJSONLayer( "TopoJSON", NULL, wkbUnknown, poDS ); { OGRFieldDefn fldDefn( "id", OFTString ); (*ppoMainLayer)->GetLayerDefn()->AddFieldDefn( &fldDefn ); } { OGRFieldDefn fldDefn( "name", OFTString ); (*ppoMainLayer)->GetLayerDefn()->AddFieldDefn( &fldDefn ); } } ParseObject(pszId, poObj, *ppoMainLayer, poArcs, psParams); } } } }
static void ParseObject(const char* pszId, json_object* poObj, OGRGeoJSONLayer* poLayer, json_object* poArcsDB, ScalingParams* psParams) { json_object* poType = OGRGeoJSONFindMemberByName(poObj, "type"); if( poType == NULL || json_object_get_type(poType) != json_type_string ) return; const char* pszType = json_object_get_string(poType); json_object* poArcsObj = OGRGeoJSONFindMemberByName(poObj, "arcs"); json_object* poCoordinatesObj = OGRGeoJSONFindMemberByName(poObj, "coordinates"); if( strcmp(pszType, "Point") == 0 || strcmp(pszType, "MultiPoint") == 0 ) { if( poCoordinatesObj == NULL || json_type_array != json_object_get_type(poCoordinatesObj) ) return; } else { if( poArcsObj == NULL || json_type_array != json_object_get_type(poArcsObj) ) return; } if( pszId == NULL ) { json_object* poId = OGRGeoJSONFindMemberByName(poObj, "id"); if( poId != NULL && (json_type_string == json_object_get_type(poId) || json_type_int == json_object_get_type(poId)) ) { pszId = json_object_get_string(poId); } } OGRFeature* poFeature = new OGRFeature(poLayer->GetLayerDefn()); if( pszId != NULL ) poFeature->SetField("id", pszId); json_object* poProperties = OGRGeoJSONFindMemberByName(poObj, "properties"); if( poProperties != NULL && json_type_object == json_object_get_type(poProperties) ) { json_object* poName = OGRGeoJSONFindMemberByName(poProperties, "name"); if( poName != NULL && json_type_string == json_object_get_type(poName) ) { const char* pszName = json_object_get_string(poName); poFeature->SetField("name", pszName); } } OGRGeometry* poGeom = NULL; if( strcmp(pszType, "Point") == 0 ) { double dfX = 0.0, dfY = 0.0; if( ParsePoint( poCoordinatesObj, &dfX, &dfY ) ) { dfX = dfX * psParams->dfScale0 + psParams->dfTranslate0; dfY = dfY * psParams->dfScale1 + psParams->dfTranslate1; poGeom = new OGRPoint(dfX, dfY); } else poGeom = new OGRPoint(); } else if( strcmp(pszType, "MultiPoint") == 0 ) { OGRMultiPoint* poMP = new OGRMultiPoint(); poGeom = poMP; int nTuples = json_object_array_length(poCoordinatesObj); for(int i=0; i<nTuples; i++) { json_object* poPair = json_object_array_get_idx(poCoordinatesObj, i); double dfX = 0.0, dfY = 0.0; if( ParsePoint( poPair, &dfX, &dfY ) ) { dfX = dfX * psParams->dfScale0 + psParams->dfTranslate0; dfY = dfY * psParams->dfScale1 + psParams->dfTranslate1; poMP->addGeometryDirectly(new OGRPoint(dfX, dfY)); } } } else if( strcmp(pszType, "LineString") == 0 ) { OGRLineString* poLS = new OGRLineString(); poGeom = poLS; ParseLineString(poLS, poArcsObj, poArcsDB, psParams); } else if( strcmp(pszType, "MultiLineString") == 0 ) { OGRMultiLineString* poMLS = new OGRMultiLineString(); poGeom = poMLS; ParseMultiLineString(poMLS, poArcsObj, poArcsDB, psParams); } else if( strcmp(pszType, "Polygon") == 0 ) { OGRPolygon* poPoly = new OGRPolygon(); poGeom = poPoly; ParsePolygon(poPoly, poArcsObj, poArcsDB, psParams); } else if( strcmp(pszType, "MultiPolygon") == 0 ) { OGRMultiPolygon* poMultiPoly = new OGRMultiPolygon(); poGeom = poMultiPoly; ParseMultiPolygon(poMultiPoly, poArcsObj, poArcsDB, psParams); } if( poGeom != NULL ) poFeature->SetGeometryDirectly(poGeom); poLayer->AddFeature(poFeature); delete poFeature; }