bool OGRESRIJSONReader::GenerateLayerDefn() { CPLAssert( NULL != poGJObject_ ); CPLAssert( NULL != poLayer_->GetLayerDefn() ); CPLAssert( 0 == poLayer_->GetLayerDefn()->GetFieldCount() ); bool bSuccess = true; /* -------------------------------------------------------------------- */ /* Scan all features and generate layer definition. */ /* -------------------------------------------------------------------- */ json_object* poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "fields" ); if( NULL != poObjFeatures && json_type_array == json_object_get_type( poObjFeatures ) ) { const int nFeatures = json_object_array_length( poObjFeatures ); for( int i = 0; i < nFeatures; ++i ) { json_object* poObjFeature = json_object_array_get_idx( poObjFeatures, i ); if( !GenerateFeatureDefn( poObjFeature ) ) { CPLDebug( "GeoJSON", "Create feature schema failure." ); bSuccess = false; } } } else { poObjFeatures = OGRGeoJSONFindMemberByName( poGJObject_, "fieldAliases" ); if( NULL != poObjFeatures && json_object_get_type(poObjFeatures) == json_type_object ) { OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn(); json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poObjFeatures, 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; }