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 }
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); } } } }