void OGRGeoJSONSeqLayer::Init() { if( STARTS_WITH(m_poDS->GetDescription(), "/vsimem/") || !STARTS_WITH(m_poDS->GetDescription(), "/vsi") ) { VSIFSeekL(m_fp, 0, SEEK_END); m_nFileSize = VSIFTellL(m_fp); } ResetReading(); while( true ) { auto poObject = GetNextObject(); if( !poObject ) break; if( OGRGeoJSONGetType(poObject) == GeoJSONObject::eFeature ) { m_oReader.GenerateFeatureDefn(this, poObject); } json_object_put(poObject); m_nTotalFeatures ++; } ResetReading(); m_nFileSize = 0; m_nIter = 0; m_oReader.FinalizeLayerDefn( this, m_osFIDColumn ); }
OGRFeature* OGRGeoJSONSeqLayer::GetNextFeature() { while( true ) { auto poObject = GetNextObject(); if( !poObject ) return nullptr; OGRFeature* poFeature; auto type = OGRGeoJSONGetType(poObject); if( type == GeoJSONObject::eFeature ) { poFeature = m_oReader.ReadFeature( this, poObject, m_osFeatureBuffer.c_str() ); json_object_put(poObject); } else if( type == GeoJSONObject::eFeatureCollection || type == GeoJSONObject::eUnknown ) { json_object_put(poObject); continue; } else { OGRGeometry* poGeom = m_oReader.ReadGeometry(poObject, GetSpatialRef()); json_object_put(poObject); if( !poGeom ) { continue; } poFeature = new OGRFeature(m_poFeatureDefn); poFeature->SetGeometryDirectly(poGeom); } if( poFeature->GetFID() == OGRNullFID ) { poFeature->SetFID(m_nNextFID); m_nNextFID ++; } if( (m_poFilterGeom == nullptr || FilterGeometry(poFeature->GetGeomFieldRef(m_iGeomFieldFilter)) ) && (m_poAttrQuery == nullptr || m_poAttrQuery->Evaluate(poFeature)) ) { return poFeature; } delete poFeature; } }
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; }
OGRGeoJSONLayer* OGRGeoJSONReader::ReadLayer( const char* pszName, OGRGeoJSONDataSource* poDS ) { CPLAssert( NULL == poLayer_ ); if( NULL == poGJObject_ ) { CPLDebug( "GeoJSON", "Missing parset GeoJSON data. Forgot to call Parse()?" ); return NULL; } poLayer_ = new OGRGeoJSONLayer( pszName, NULL, OGRGeoJSONLayer::DefaultGeometryType, NULL, poDS ); if( !GenerateLayerDefn() ) { CPLError( CE_Failure, CPLE_AppDefined, "Layer schema generation failed." ); delete poLayer_; return NULL; } /* -------------------------------------------------------------------- */ /* Translate single geometry-only Feature object. */ /* -------------------------------------------------------------------- */ GeoJSONObject::Type objType = OGRGeoJSONGetType( poGJObject_ ); if( GeoJSONObject::ePoint == objType || GeoJSONObject::eMultiPoint == objType || GeoJSONObject::eLineString == objType || GeoJSONObject::eMultiLineString == objType || GeoJSONObject::ePolygon == objType || GeoJSONObject::eMultiPolygon == objType || GeoJSONObject::eGeometryCollection == objType ) { OGRGeometry* poGeometry = NULL; poGeometry = ReadGeometry( poGJObject_ ); if( !AddFeature( poGeometry ) ) { CPLDebug( "GeoJSON", "Translation of single geometry failed." ); delete poLayer_; return NULL; } } /* -------------------------------------------------------------------- */ /* Translate single but complete Feature object. */ /* -------------------------------------------------------------------- */ else if( GeoJSONObject::eFeature == objType ) { OGRFeature* poFeature = NULL; poFeature = ReadFeature( poGJObject_ ); if( !AddFeature( poFeature ) ) { CPLDebug( "GeoJSON", "Translation of single feature failed." ); delete poLayer_; return NULL; } } /* -------------------------------------------------------------------- */ /* Translate multi-feature FeatureCollection object. */ /* -------------------------------------------------------------------- */ else if( GeoJSONObject::eFeatureCollection == objType ) { OGRGeoJSONLayer* poThisLayer = NULL; poThisLayer = ReadFeatureCollection( poGJObject_ ); CPLAssert( poLayer_ == poThisLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognized GeoJSON structure." ); delete poLayer_; return NULL; } OGRSpatialReference* poSRS = NULL; poSRS = OGRGeoJSONReadSpatialReference( poGJObject_ ); if (poSRS == NULL ) { // If there is none defined, we use 4326 poSRS = new OGRSpatialReference(); if( OGRERR_NONE != poSRS->importFromEPSG( 4326 ) ) { delete poSRS; poSRS = NULL; } poLayer_->SetSpatialRef( poSRS ); delete poSRS; } else { poLayer_->SetSpatialRef( poSRS ); delete poSRS; } // TODO: FeatureCollection return poLayer_; }