OGRErr OGRLayer::GetExtent(OGREnvelope *psExtent, int bForce ) { OGRFeature *poFeature; OGREnvelope oEnv; GBool bExtentSet = FALSE; /* -------------------------------------------------------------------- */ /* If this layer has a none geometry type, then we can */ /* reasonably assume there are not extents available. */ /* -------------------------------------------------------------------- */ if( GetLayerDefn()->GetGeomType() == wkbNone ) { psExtent->MinX = 0.0; psExtent->MaxX = 0.0; psExtent->MinY = 0.0; psExtent->MaxY = 0.0; return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* If not forced, we should avoid having to scan all the */ /* features and just return a failure. */ /* -------------------------------------------------------------------- */ if( !bForce ) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* OK, we hate to do this, but go ahead and read through all */ /* the features to collect geometries and build extents. */ /* -------------------------------------------------------------------- */ ResetReading(); while( (poFeature = GetNextFeature()) != NULL ) { OGRGeometry *poGeom = poFeature->GetGeometryRef(); if (poGeom && !bExtentSet) { poGeom->getEnvelope(psExtent); bExtentSet = TRUE; } else if (poGeom) { poGeom->getEnvelope(&oEnv); if (oEnv.MinX < psExtent->MinX) psExtent->MinX = oEnv.MinX; if (oEnv.MinY < psExtent->MinY) psExtent->MinY = oEnv.MinY; if (oEnv.MaxX > psExtent->MaxX) psExtent->MaxX = oEnv.MaxX; if (oEnv.MaxY > psExtent->MaxY) psExtent->MaxY = oEnv.MaxY; } delete poFeature; } ResetReading(); return (bExtentSet ? OGRERR_NONE : OGRERR_FAILURE); }
OGRErr OGRGeoJSONSeqWriteLayer::ICreateFeature( OGRFeature* poFeature ) { VSILFILE* fp = m_poDS->GetOutputFile(); std::unique_ptr<OGRFeature> poFeatureToWrite; if( m_poCT != nullptr ) { poFeatureToWrite.reset(new OGRFeature(m_poFeatureDefn)); poFeatureToWrite->SetFrom( poFeature ); poFeatureToWrite->SetFID( poFeature->GetFID() ); OGRGeometry* poGeometry = poFeatureToWrite->GetGeometryRef(); if( poGeometry ) { const char* const apszOptions[] = { "WRAPDATELINE=YES", nullptr }; OGRGeometry* poNewGeom = OGRGeometryFactory::transformWithOptions( poGeometry, m_poCT, const_cast<char**>(apszOptions)); if( poNewGeom == nullptr ) { return OGRERR_FAILURE; } OGREnvelope sEnvelope; poNewGeom->getEnvelope(&sEnvelope); if( sEnvelope.MinX < -180.0 || sEnvelope.MaxX > 180.0 || sEnvelope.MinY < -90.0 || sEnvelope.MaxY > 90.0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Geometry extent outside of [-180.0,180.0]x[-90.0,90.0] bounds"); return OGRERR_FAILURE; } poFeatureToWrite->SetGeometryDirectly( poNewGeom ); } } json_object* poObj = OGRGeoJSONWriteFeature( poFeatureToWrite.get() ? poFeatureToWrite.get() : poFeature, m_oWriteOptions ); CPLAssert( nullptr != poObj ); if( m_bRS ) { VSIFPrintfL( fp, "%c", RS); } VSIFPrintfL( fp, "%s\n", json_object_to_json_string( poObj ) ); json_object_put( poObj ); return OGRERR_NONE; }
OGRErr OGRLayer::GetExtent(OGREnvelope *psExtent, int bForce ) { OGRFeature *poFeature; OGREnvelope oEnv; GBool bExtentSet = FALSE; if( !bForce ) return OGRERR_FAILURE; ResetReading(); while( (poFeature = GetNextFeature()) != NULL ) { OGRGeometry *poGeom = poFeature->GetGeometryRef(); if (poGeom && !bExtentSet) { poGeom->getEnvelope(psExtent); bExtentSet = TRUE; } else if (poGeom) { poGeom->getEnvelope(&oEnv); if (oEnv.MinX < psExtent->MinX) psExtent->MinX = oEnv.MinX; if (oEnv.MinY < psExtent->MinY) psExtent->MinY = oEnv.MinY; if (oEnv.MaxX > psExtent->MaxX) psExtent->MaxX = oEnv.MaxX; if (oEnv.MaxY > psExtent->MaxY) psExtent->MaxY = oEnv.MaxY; } delete poFeature; } ResetReading(); return (bExtentSet ? OGRERR_NONE : OGRERR_FAILURE); }
void GetFeatureBoundsFunc(const void* hFeature, CPLRectObj* pBounds) { OGRFeature* pFeature = (OGRFeature*)hFeature; if(!pFeature) return; OGRGeometry* pGeom = pFeature->GetGeometryRef(); if(!pGeom) return; OGREnvelope Env; pGeom->getEnvelope(&Env); pBounds->minx = Env.MinX; pBounds->maxx = Env.MaxX; pBounds->miny = Env.MinY; pBounds->maxy = Env.MaxY; }
OGRErr OGRGeoJSONWriteLayer::ICreateFeature( OGRFeature* poFeature ) { VSILFILE* fp = poDS_->GetOutputFile(); if( NULL == poFeature ) { CPLDebug( "GeoJSON", "Feature is null" ); return OGRERR_INVALID_HANDLE; } json_object* poObj = OGRGeoJSONWriteFeature( poFeature, bWriteBBOX, nCoordPrecision ); CPLAssert( NULL != poObj ); if( nOutCounter_ > 0 ) { /* Separate "Feature" entries in "FeatureCollection" object. */ VSIFPrintfL( fp, ",\n" ); } VSIFPrintfL( fp, "%s", json_object_to_json_string( poObj ) ); json_object_put( poObj ); ++nOutCounter_; OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if ( bWriteBBOX && !poGeometry->IsEmpty() ) { OGREnvelope3D sEnvelope; poGeometry->getEnvelope(&sEnvelope); if( poGeometry->getCoordinateDimension() == 3 ) bBBOX3D = TRUE; sEnvelopeLayer.Merge(sEnvelope); } return OGRERR_NONE; }
OGRErr OGRGeoJSONWriteLayer::ICreateFeature( OGRFeature* poFeature ) { VSILFILE* fp = poDS_->GetOutputFile(); OGRFeature* poFeatureToWrite; if( poCT_ != nullptr || bRFC7946_ ) { poFeatureToWrite = new OGRFeature(poFeatureDefn_); poFeatureToWrite->SetFrom( poFeature ); poFeatureToWrite->SetFID( poFeature->GetFID() ); OGRGeometry* poGeometry = poFeatureToWrite->GetGeometryRef(); if( poGeometry ) { const char* const apszOptions[] = { "WRAPDATELINE=YES", nullptr }; OGRGeometry* poNewGeom = OGRGeometryFactory::transformWithOptions( poGeometry, poCT_, const_cast<char**>(apszOptions), oTransformCache_); if( poNewGeom == nullptr ) { delete poFeatureToWrite; return OGRERR_FAILURE; } OGREnvelope sEnvelope; poNewGeom->getEnvelope(&sEnvelope); if( sEnvelope.MinX < -180.0 || sEnvelope.MaxX > 180.0 || sEnvelope.MinY < -90.0 || sEnvelope.MaxY > 90.0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Geometry extent outside of [-180.0,180.0]x[-90.0,90.0] bounds"); delete poFeatureToWrite; return OGRERR_FAILURE; } poFeatureToWrite->SetGeometryDirectly( poNewGeom ); } } else { poFeatureToWrite = poFeature; } json_object* poObj = OGRGeoJSONWriteFeature( poFeatureToWrite, oWriteOptions_ ); CPLAssert( nullptr != poObj ); if( nOutCounter_ > 0 ) { /* Separate "Feature" entries in "FeatureCollection" object. */ VSIFPrintfL( fp, ",\n" ); } VSIFPrintfL( fp, "%s", json_object_to_json_string( poObj ) ); json_object_put( poObj ); ++nOutCounter_; OGRGeometry* poGeometry = poFeatureToWrite->GetGeometryRef(); if( bWriteFC_BBOX && poGeometry != nullptr && !poGeometry->IsEmpty() ) { OGREnvelope3D sEnvelope = OGRGeoJSONGetBBox( poGeometry, oWriteOptions_ ); if( poGeometry->getCoordinateDimension() == 3 ) bBBOX3D = true; if( !sEnvelopeLayer.IsInit() ) { sEnvelopeLayer = sEnvelope; } else if( oWriteOptions_.bBBOXRFC7946 ) { const bool bEnvelopeCrossAM = ( sEnvelope.MinX > sEnvelope.MaxX ); const bool bEnvelopeLayerCrossAM = ( sEnvelopeLayer.MinX > sEnvelopeLayer.MaxX ); if( bEnvelopeCrossAM ) { if( bEnvelopeLayerCrossAM ) { sEnvelopeLayer.MinX = std::min(sEnvelopeLayer.MinX, sEnvelope.MinX); sEnvelopeLayer.MaxX = std::max(sEnvelopeLayer.MaxX, sEnvelope.MaxX); } else { if( sEnvelopeLayer.MinX > 0 ) { sEnvelopeLayer.MinX = std::min(sEnvelopeLayer.MinX, sEnvelope.MinX); sEnvelopeLayer.MaxX = sEnvelope.MaxX; } else if( sEnvelopeLayer.MaxX < 0 ) { sEnvelopeLayer.MaxX = std::max(sEnvelopeLayer.MaxX, sEnvelope.MaxX); sEnvelopeLayer.MinX = sEnvelope.MinX; } else { sEnvelopeLayer.MinX = -180.0; sEnvelopeLayer.MaxX = 180.0; } } } else if( bEnvelopeLayerCrossAM ) { if( sEnvelope.MinX > 0 ) { sEnvelopeLayer.MinX = std::min(sEnvelopeLayer.MinX, sEnvelope.MinX); } else if( sEnvelope.MaxX < 0 ) { sEnvelopeLayer.MaxX = std::max(sEnvelopeLayer.MaxX, sEnvelope.MaxX); } else { sEnvelopeLayer.MinX = -180.0; sEnvelopeLayer.MaxX = 180.0; } } else { sEnvelopeLayer.MinX = std::min(sEnvelopeLayer.MinX, sEnvelope.MinX); sEnvelopeLayer.MaxX = std::max(sEnvelopeLayer.MaxX, sEnvelope.MaxX); } sEnvelopeLayer.MinY = std::min(sEnvelopeLayer.MinY, sEnvelope.MinY); sEnvelopeLayer.MaxY = std::max(sEnvelopeLayer.MaxY, sEnvelope.MaxY); } else { sEnvelopeLayer.Merge(sEnvelope); } } if( poFeatureToWrite != poFeature ) delete poFeatureToWrite; return OGRERR_NONE; }
static int OGR2SQLITEDealWithSpatialColumn(OGRLayer* poLayer, int iGeomCol, const LayerDesc& oLayerDesc, const CPLString& osTableName, OGRSQLiteDataSource* poSQLiteDS, sqlite3* hDB, int bSpatialiteDB, const std::set<LayerDesc>& WHEN_SPATIALITE(oSetLayers), const std::set<CPLString>& WHEN_SPATIALITE(oSetSpatialIndex) ) { OGRGeomFieldDefn* poGeomField = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomCol); CPLString osGeomColRaw; if( iGeomCol == 0 ) osGeomColRaw = OGR2SQLITE_GetNameForGeometryColumn(poLayer); else osGeomColRaw = poGeomField->GetNameRef(); const char* pszGeomColRaw = osGeomColRaw.c_str(); CPLString osGeomColEscaped(OGRSQLiteEscape(pszGeomColRaw)); const char* pszGeomColEscaped = osGeomColEscaped.c_str(); CPLString osLayerNameEscaped(OGRSQLiteEscape(osTableName)); const char* pszLayerNameEscaped = osLayerNameEscaped.c_str(); CPLString osIdxNameRaw(CPLSPrintf("idx_%s_%s", oLayerDesc.osLayerName.c_str(), pszGeomColRaw)); CPLString osIdxNameEscaped(OGRSQLiteEscapeName(osIdxNameRaw)); /* Make sure that the SRS is injected in spatial_ref_sys */ OGRSpatialReference* poSRS = poGeomField->GetSpatialRef(); if( iGeomCol == 0 && poSRS == NULL ) poSRS = poLayer->GetSpatialRef(); int nSRSId = poSQLiteDS->GetUndefinedSRID(); if( poSRS != NULL ) nSRSId = poSQLiteDS->FetchSRSId(poSRS); CPLString osSQL; #ifdef HAVE_SPATIALITE bool bCreateSpatialIndex = false; #endif if( !bSpatialiteDB ) { osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_format, geometry_type, " "coord_dimension, srid) " "VALUES ('%s','%s','SpatiaLite',%d,%d,%d)", pszLayerNameEscaped, pszGeomColEscaped, (int) wkbFlatten(poLayer->GetGeomType()), wkbHasZ( poLayer->GetGeomType() ) ? 3 : 2, nSRSId); } #ifdef HAVE_SPATIALITE else { /* We detect the need for creating a spatial index by 2 means : */ /* 1) if there's an explicit reference to a 'idx_layername_geometrycolumn' */ /* table in the SQL --> old/traditional way of requesting spatial indices */ /* with spatialite. */ std::set<LayerDesc>::const_iterator oIter2 = oSetLayers.begin(); for(; oIter2 != oSetLayers.end(); ++oIter2) { const LayerDesc& oLayerDescIter = *oIter2; if( EQUAL(oLayerDescIter.osLayerName, osIdxNameRaw) ) { bCreateSpatialIndex = true; break; } } /* 2) or if there's a SELECT FROM SpatialIndex WHERE f_table_name = 'layername' */ if( !bCreateSpatialIndex ) { std::set<CPLString>::const_iterator oIter3 = oSetSpatialIndex.begin(); for(; oIter3 != oSetSpatialIndex.end(); ++oIter3) { const CPLString& osNameIter = *oIter3; if( EQUAL(osNameIter, oLayerDesc.osLayerName) ) { bCreateSpatialIndex = true; break; } } } if( poSQLiteDS->HasSpatialite4Layout() ) { int nGeomType = poLayer->GetGeomType(); int nCoordDimension = 2; if( wkbHasZ((OGRwkbGeometryType)nGeomType) ) { nGeomType += 1000; nCoordDimension = 3; } osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES (Lower('%s'),Lower('%s'),%d ,%d ,%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, nGeomType, nCoordDimension, nSRSId, static_cast<int>(bCreateSpatialIndex) ); } else { const char *pszGeometryType = OGRToOGCGeomType(poLayer->GetGeomType()); if (pszGeometryType[0] == '\0') pszGeometryType = "GEOMETRY"; osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES ('%s','%s','%s','%s',%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, pszGeometryType, wkbHasZ( poLayer->GetGeomType() ) ? "XYZ" : "XY", nSRSId, static_cast<int>(bCreateSpatialIndex) ); } } #endif // HAVE_SPATIALITE char* pszErrMsg = NULL; int rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, &pszErrMsg ); if( pszErrMsg != NULL ) { CPLDebug("SQLITE", "%s -> %s", osSQL.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); } #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Should we create a spatial index ?. */ /* -------------------------------------------------------------------- */ if( !bSpatialiteDB || !bCreateSpatialIndex ) return rc == SQLITE_OK; CPLDebug("SQLITE", "Create spatial index %s", osIdxNameRaw.c_str()); /* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */ #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING " "VirtualOGRSpatialIndex(%d, '%s', pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str()); rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); if( rc != SQLITE_OK ) { CPLDebug( "SQLITE", "Error occurred during spatial index creation : %s", sqlite3_errmsg(hDB)); } #else // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, NULL ); osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" " "USING rtree(pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str()); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); sqlite3_stmt *hStmt = NULL; if( rc == SQLITE_OK ) { const char* pszInsertInto = CPLSPrintf( "INSERT INTO \"%s\" (pkid, xmin, xmax, ymin, ymax) " "VALUES (?,?,?,?,?)", osIdxNameEscaped.c_str()); rc = sqlite3_prepare(hDB, pszInsertInto, -1, &hStmt, NULL); } OGRFeature* poFeature; OGREnvelope sEnvelope; OGR2SQLITE_IgnoreAllFieldsExceptGeometry(poLayer); poLayer->ResetReading(); while( rc == SQLITE_OK && (poFeature = poLayer->GetNextFeature()) != NULL ) { OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && !poGeom->IsEmpty() ) { poGeom->getEnvelope(&sEnvelope); sqlite3_bind_int64(hStmt, 1, (sqlite3_int64) poFeature->GetFID() ); sqlite3_bind_double(hStmt, 2, sEnvelope.MinX); sqlite3_bind_double(hStmt, 3, sEnvelope.MaxX); sqlite3_bind_double(hStmt, 4, sEnvelope.MinY); sqlite3_bind_double(hStmt, 5, sEnvelope.MaxY); rc = sqlite3_step(hStmt); if( rc == SQLITE_OK || rc == SQLITE_DONE ) rc = sqlite3_reset(hStmt); } delete poFeature; } poLayer->SetIgnoredFields(NULL); sqlite3_finalize(hStmt); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, NULL ); else { CPLDebug( "SQLITE", "Error occurred during spatial index creation : %s", sqlite3_errmsg(hDB)); rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, NULL ); } #endif // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX #endif // HAVE_SPATIALITE return rc == SQLITE_OK; }
OGRErr OGRDXFWriterLayer::ICreateFeature( OGRFeature *poFeature ) { OGRGeometry *poGeom = poFeature->GetGeometryRef(); OGRwkbGeometryType eGType = wkbNone; if( poGeom != nullptr ) { if( !poGeom->IsEmpty() ) { OGREnvelope sEnvelope; poGeom->getEnvelope(&sEnvelope); poDS->UpdateExtent(&sEnvelope); } eGType = wkbFlatten(poGeom->getGeometryType()); } if( eGType == wkbPoint ) { const char *pszBlockName = poFeature->GetFieldAsString("BlockName"); // We don't want to treat as a blocks ref if the block is not defined if( pszBlockName && poDS->oHeaderDS.LookupBlock(pszBlockName) == nullptr ) { if( poDS->poBlocksLayer == nullptr || poDS->poBlocksLayer->FindBlock(pszBlockName) == nullptr ) pszBlockName = nullptr; } if( pszBlockName != nullptr ) return WriteINSERT( poFeature ); else if( poFeature->GetStyleString() != nullptr && STARTS_WITH_CI(poFeature->GetStyleString(), "LABEL") ) return WriteTEXT( poFeature ); else return WritePOINT( poFeature ); } else if( eGType == wkbLineString || eGType == wkbMultiLineString ) return WritePOLYLINE( poFeature ); else if( eGType == wkbPolygon || eGType == wkbTriangle || eGType == wkbMultiPolygon) { if( bWriteHatch ) return WriteHATCH( poFeature ); else return WritePOLYLINE( poFeature ); } // Explode geometry collections into multiple entities. else if( eGType == wkbGeometryCollection ) { OGRGeometryCollection *poGC = poFeature->StealGeometry()->toGeometryCollection(); for( auto&& poMember: poGC ) { poFeature->SetGeometry( poMember ); OGRErr eErr = CreateFeature( poFeature ); if( eErr != OGRERR_NONE ) { delete poGC; return eErr; } } poFeature->SetGeometryDirectly( poGC ); return OGRERR_NONE; } else { CPLError( CE_Failure, CPLE_AppDefined, "No known way to write feature with geometry '%s'.", OGRGeometryTypeToName(eGType) ); return OGRERR_FAILURE; } }
OGRErr OGRIngresTableLayer::GetExtent(OGREnvelope *psExtent, int bForce ) { if( GetLayerDefn()->GetGeomType() == wkbNone ) { psExtent->MinX = 0.0; psExtent->MaxX = 0.0; psExtent->MinY = 0.0; psExtent->MaxY = 0.0; return OGRERR_FAILURE; } OGREnvelope oEnv; CPLString osCommand; GBool bExtentSet = FALSE; osCommand.Printf( "SELECT Envelope(%s) FROM %s;", pszGeomColumn, pszGeomColumnTable); if (ingres_query(poDS->GetConn(), osCommand) == 0) { INGRES_RES* result = ingres_use_result(poDS->GetConn()); if ( result == NULL ) { poDS->ReportError( "ingres_use_result() failed on extents query." ); return OGRERR_FAILURE; } INGRES_ROW row; unsigned long *panLengths = NULL; while ((row = ingres_fetch_row(result))) { if (panLengths == NULL) { panLengths = ingres_fetch_lengths( result ); if ( panLengths == NULL ) { poDS->ReportError( "ingres_fetch_lengths() failed on extents query." ); return OGRERR_FAILURE; } } OGRGeometry *poGeometry = NULL; // Geometry columns will have the first 4 bytes contain the SRID. OGRGeometryFactory::createFromWkb(((GByte *)row[0]) + 4, NULL, &poGeometry, panLengths[0] - 4 ); if ( poGeometry != NULL ) { if (poGeometry && !bExtentSet) { poGeometry->getEnvelope(psExtent); bExtentSet = TRUE; } else if (poGeometry) { poGeometry->getEnvelope(&oEnv); if (oEnv.MinX < psExtent->MinX) psExtent->MinX = oEnv.MinX; if (oEnv.MinY < psExtent->MinY) psExtent->MinY = oEnv.MinY; if (oEnv.MaxX > psExtent->MaxX) psExtent->MaxX = oEnv.MaxX; if (oEnv.MaxY > psExtent->MaxY) psExtent->MaxY = oEnv.MaxY; } delete poGeometry; } } ingres_free_result(result); } return (bExtentSet ? OGRERR_NONE : OGRERR_FAILURE); }
int NASReader::PrescanForSchema( int bGetExtents ) { GMLFeature *poFeature; if( m_pszFilename == NULL ) return FALSE; SetClassListLocked( FALSE ); ClearClasses(); if( !SetupParser() ) return FALSE; std::string osWork; while( (poFeature = NextFeature()) != NULL ) { GMLFeatureClass *poClass = poFeature->GetClass(); if( poClass->GetFeatureCount() == -1 ) poClass->SetFeatureCount( 1 ); else poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 ); #ifdef SUPPORT_GEOMETRY if( bGetExtents ) { OGRGeometry *poGeometry = NULL; const CPLXMLNode* const * papsGeometry = poFeature->GetGeometryList(); if( papsGeometry[0] != NULL ) { poGeometry = (OGRGeometry*) OGR_G_CreateFromGMLTree(papsGeometry[0]); } if( poGeometry != NULL ) { double dfXMin, dfXMax, dfYMin, dfYMax; OGREnvelope sEnvelope; OGRwkbGeometryType eGType = (OGRwkbGeometryType) poClass->GetGeometryType(); // Merge SRSName into layer. const char* pszSRSName = GML_ExtractSrsNameFromGeometry(papsGeometry, osWork, FALSE); // if (pszSRSName != NULL) // m_bCanUseGlobalSRSName = FALSE; poClass->MergeSRSName(pszSRSName); // Merge geometry type into layer. if( poClass->GetFeatureCount() == 1 && eGType == wkbUnknown ) eGType = wkbNone; poClass->SetGeometryType( (int) OGRMergeGeometryTypes( eGType, poGeometry->getGeometryType() ) ); // merge extents. poGeometry->getEnvelope( &sEnvelope ); delete poGeometry; if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) ) { dfXMin = MIN(dfXMin,sEnvelope.MinX); dfXMax = MAX(dfXMax,sEnvelope.MaxX); dfYMin = MIN(dfYMin,sEnvelope.MinY); dfYMax = MAX(dfYMax,sEnvelope.MaxY); } else { dfXMin = sEnvelope.MinX; dfXMax = sEnvelope.MaxX; dfYMin = sEnvelope.MinY; dfYMax = sEnvelope.MaxY; } poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax ); } else { if( poClass->GetGeometryType() == (int) wkbUnknown && poClass->GetFeatureCount() == 1 ) poClass->SetGeometryType( wkbNone ); } #endif /* def SUPPORT_GEOMETRY */ } delete poFeature; } CleanupParser(); return GetClassCount() > 0; }
OGRErr OGRGMLLayer::ICreateFeature( OGRFeature *poFeature ) { int bIsGML3Output = poDS->IsGML3Output(); VSILFILE *fp = poDS->GetOutputFP(); int bWriteSpaceIndentation = poDS->WriteSpaceIndentation(); const char* pszPrefix = poDS->GetAppPrefix(); int bRemoveAppPrefix = poDS->RemoveAppPrefix(); if( !bWriter ) return OGRERR_FAILURE; poFeature->FillUnsetWithDefault(TRUE, NULL); if( !poFeature->Validate( OGR_F_VAL_ALL & ~OGR_F_VAL_GEOM_TYPE & ~OGR_F_VAL_ALLOW_NULL_WHEN_DEFAULT, TRUE ) ) return OGRERR_FAILURE; if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if (bIsGML3Output) { if( bRemoveAppPrefix ) poDS->PrintLine( fp, "<featureMember>" ); else poDS->PrintLine( fp, "<%s:featureMember>", pszPrefix ); } else poDS->PrintLine( fp, "<gml:featureMember>" ); if( iNextGMLId == 0 ) { bSameSRS = true; for( int iGeomField = 1; iGeomField < poFeatureDefn->GetGeomFieldCount(); iGeomField++ ) { OGRGeomFieldDefn *poFieldDefn0 = poFeatureDefn->GetGeomFieldDefn(0); OGRGeomFieldDefn *poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iGeomField); OGRSpatialReference* poSRS0 = poFieldDefn0->GetSpatialRef(); OGRSpatialReference* poSRS = poFieldDefn->GetSpatialRef(); if( poSRS0 != NULL && poSRS == NULL ) bSameSRS = false; else if( poSRS0 == NULL && poSRS != NULL ) bSameSRS = false; else if( poSRS0 != NULL && poSRS != NULL && poSRS0 != poSRS && !poSRS0->IsSame(poSRS) ) { bSameSRS = false; } } } if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( iNextGMLId++ ); int nGMLIdIndex = -1; if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); VSIFPrintfL(fp, "<"); if( !bRemoveAppPrefix ) VSIFPrintfL(fp, "%s:", pszPrefix); if (bIsGML3Output) { nGMLIdIndex = poFeatureDefn->GetFieldIndex("gml_id"); if (nGMLIdIndex >= 0 && poFeature->IsFieldSet( nGMLIdIndex ) ) poDS->PrintLine( fp, "%s gml:id=\"%s\">", poFeatureDefn->GetName(), poFeature->GetFieldAsString(nGMLIdIndex) ); else poDS->PrintLine( fp, "%s gml:id=\"%s." CPL_FRMT_GIB "\">", poFeatureDefn->GetName(), poFeatureDefn->GetName(), poFeature->GetFID() ); } else { nGMLIdIndex = poFeatureDefn->GetFieldIndex("fid"); if (bUseOldFIDFormat) { poDS->PrintLine( fp, "%s fid=\"F" CPL_FRMT_GIB "\">", poFeatureDefn->GetName(), poFeature->GetFID() ); } else if (nGMLIdIndex >= 0 && poFeature->IsFieldSet( nGMLIdIndex ) ) { poDS->PrintLine( fp, "%s fid=\"%s\">", poFeatureDefn->GetName(), poFeature->GetFieldAsString(nGMLIdIndex) ); } else { poDS->PrintLine( fp, "%s fid=\"%s." CPL_FRMT_GIB "\">", poFeatureDefn->GetName(), poFeatureDefn->GetName(), poFeature->GetFID() ); } } for( int iGeomField = 0; iGeomField < poFeatureDefn->GetGeomFieldCount(); iGeomField++ ) { OGRGeomFieldDefn *poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iGeomField); // Write out Geometry - for now it isn't indented properly. /* GML geometries don't like very much the concept of empty geometry */ OGRGeometry* poGeom = poFeature->GetGeomFieldRef(iGeomField); if( poGeom != NULL && !poGeom->IsEmpty()) { char *pszGeometry; OGREnvelope3D sGeomBounds; int nCoordDimension = poGeom->getCoordinateDimension(); poGeom->getEnvelope( &sGeomBounds ); if( bSameSRS ) poDS->GrowExtents( &sGeomBounds, nCoordDimension ); if (poGeom->getSpatialReference() == NULL && poFieldDefn->GetSpatialRef() != NULL) poGeom->assignSpatialReference(poFieldDefn->GetSpatialRef()); if (bIsGML3Output && poDS->WriteFeatureBoundedBy()) { bool bCoordSwap; char* pszSRSName = GML_GetSRSName(poGeom->getSpatialReference(), poDS->IsLongSRSRequired(), &bCoordSwap); char szLowerCorner[75], szUpperCorner[75]; if (bCoordSwap) { OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinY, sGeomBounds.MinX, sGeomBounds.MinZ, nCoordDimension); OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxY, sGeomBounds.MaxX, sGeomBounds.MaxZ, nCoordDimension); } else { OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinX, sGeomBounds.MinY, sGeomBounds.MinZ, nCoordDimension); OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxX, sGeomBounds.MaxY, sGeomBounds.MaxZ, nCoordDimension); } if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); poDS->PrintLine( fp, "<gml:boundedBy><gml:Envelope%s%s><gml:lowerCorner>%s</gml:lowerCorner><gml:upperCorner>%s</gml:upperCorner></gml:Envelope></gml:boundedBy>", (nCoordDimension == 3) ? " srsDimension=\"3\"" : "",pszSRSName, szLowerCorner, szUpperCorner); CPLFree(pszSRSName); } char** papszOptions = (bIsGML3Output) ? CSLAddString(NULL, "FORMAT=GML3") : NULL; if (bIsGML3Output && !poDS->IsLongSRSRequired()) papszOptions = CSLAddString(papszOptions, "GML3_LONGSRS=NO"); const char* pszSRSDimensionLoc = poDS->GetSRSDimensionLoc(); if( pszSRSDimensionLoc != NULL ) papszOptions = CSLSetNameValue(papszOptions, "SRSDIMENSION_LOC", pszSRSDimensionLoc); if (poDS->IsGML32Output()) { if( poFeatureDefn->GetGeomFieldCount() > 1 ) papszOptions = CSLAddString(papszOptions, CPLSPrintf("GMLID=%s.%s." CPL_FRMT_GIB, poFeatureDefn->GetName(), poFieldDefn->GetNameRef(), poFeature->GetFID())); else papszOptions = CSLAddString(papszOptions, CPLSPrintf("GMLID=%s.geom." CPL_FRMT_GIB, poFeatureDefn->GetName(), poFeature->GetFID())); } if( !bIsGML3Output && OGR_GT_IsNonLinear(poGeom->getGeometryType()) ) { OGRGeometry* poGeomTmp = OGRGeometryFactory::forceTo( poGeom->clone(),OGR_GT_GetLinear(poGeom->getGeometryType())); pszGeometry = poGeomTmp->exportToGML(papszOptions); delete poGeomTmp; } else pszGeometry = poGeom->exportToGML(papszOptions); CSLDestroy(papszOptions); if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if( bRemoveAppPrefix ) poDS->PrintLine( fp, "<%s>%s</%s>", poFieldDefn->GetNameRef(), pszGeometry, poFieldDefn->GetNameRef() ); else poDS->PrintLine( fp, "<%s:%s>%s</%s:%s>", pszPrefix, poFieldDefn->GetNameRef(), pszGeometry, pszPrefix, poFieldDefn->GetNameRef() ); CPLFree( pszGeometry ); } } // Write all "set" fields. for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && iField != nGMLIdIndex ) { OGRFieldType eType = poFieldDefn->GetType(); if (eType == OFTStringList ) { char ** papszIter = poFeature->GetFieldAsStringList( iField ); while( papszIter != NULL && *papszIter != NULL ) { char *pszEscaped = OGRGetXML_UTF8_EscapedString( *papszIter ); GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, pszEscaped); CPLFree( pszEscaped ); papszIter ++; } } else if (eType == OFTIntegerList ) { int nCount = 0; const int* panVals = poFeature->GetFieldAsIntegerList( iField, &nCount ); if( poFieldDefn->GetSubType() == OFSTBoolean ) { for(int i = 0; i < nCount; i++) { /* 0 and 1 are OK, but the canonical representation is false and true */ GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, panVals[i] ? "true" : "false"); } } else { for(int i = 0; i < nCount; i++) { GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, CPLSPrintf("%d", panVals[i])); } } } else if (eType == OFTInteger64List ) { int nCount = 0; const GIntBig* panVals = poFeature->GetFieldAsInteger64List( iField, &nCount ); if( poFieldDefn->GetSubType() == OFSTBoolean ) { for(int i = 0; i < nCount; i++) { /* 0 and 1 are OK, but the canonical representation is false and true */ GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, panVals[i] ? "true" : "false"); } } else { for(int i = 0; i < nCount; i++) { GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, CPLSPrintf(CPL_FRMT_GIB, panVals[i])); } } } else if (eType == OFTRealList ) { int nCount = 0; const double* padfVals = poFeature->GetFieldAsDoubleList( iField, &nCount ); for(int i = 0; i < nCount; i++) { char szBuffer[80]; CPLsnprintf( szBuffer, sizeof(szBuffer), "%.15g", padfVals[i]); GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, szBuffer); } } else if ((eType == OFTInteger || eType == OFTInteger64) && poFieldDefn->GetSubType() == OFSTBoolean ) { /* 0 and 1 are OK, but the canonical representation is false and true */ GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, (poFeature->GetFieldAsInteger(iField)) ? "true" : "false"); } else { const char *pszRaw = poFeature->GetFieldAsString( iField ); char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); GMLWriteField(poDS, fp, bWriteSpaceIndentation, pszPrefix, bRemoveAppPrefix, poFieldDefn, pszEscaped); CPLFree( pszEscaped ); } } } if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if( bRemoveAppPrefix ) poDS->PrintLine( fp, "</%s>", poFeatureDefn->GetName() ); else poDS->PrintLine( fp, "</%s:%s>", pszPrefix, poFeatureDefn->GetName() ); if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if (bIsGML3Output) { if( bRemoveAppPrefix ) poDS->PrintLine( fp, "</featureMember>" ); else poDS->PrintLine( fp, "</%s:featureMember>", pszPrefix ); } else poDS->PrintLine( fp, "</gml:featureMember>" ); return OGRERR_NONE; }
OGRErr OGRDXFWriterLayer::ICreateFeature( OGRFeature *poFeature ) { OGRGeometry *poGeom = poFeature->GetGeometryRef(); OGRwkbGeometryType eGType = wkbNone; if( poGeom != NULL ) { if( !poGeom->IsEmpty() ) { OGREnvelope sEnvelope; poGeom->getEnvelope(&sEnvelope); poDS->UpdateExtent(&sEnvelope); } eGType = wkbFlatten(poGeom->getGeometryType()); } if( eGType == wkbPoint ) { const char *pszBlockName = poFeature->GetFieldAsString("BlockName"); // we don't want to treat as a block ref if we are writing blocks layer if( pszBlockName != NULL && poDS->poBlocksLayer != NULL && poFeature->GetDefnRef() == poDS->poBlocksLayer->GetLayerDefn()) pszBlockName = NULL; // We don't want to treat as a blocks ref if the block is not defined if( pszBlockName && poDS->oHeaderDS.LookupBlock(pszBlockName) == NULL ) { if( poDS->poBlocksLayer == NULL || poDS->poBlocksLayer->FindBlock(pszBlockName) == NULL ) pszBlockName = NULL; } if( pszBlockName != NULL ) return WriteINSERT( poFeature ); else if( poFeature->GetStyleString() != NULL && EQUALN(poFeature->GetStyleString(),"LABEL",5) ) return WriteTEXT( poFeature ); else return WritePOINT( poFeature ); } else if( eGType == wkbLineString || eGType == wkbMultiLineString ) return WritePOLYLINE( poFeature ); else if( eGType == wkbPolygon || eGType == wkbMultiPolygon ) { if( bWriteHatch ) return WriteHATCH( poFeature ); else return WritePOLYLINE( poFeature ); } // Explode geometry collections into multiple entities. else if( eGType == wkbGeometryCollection ) { OGRGeometryCollection *poGC = (OGRGeometryCollection *) poFeature->StealGeometry(); int iGeom; for( iGeom = 0; iGeom < poGC->getNumGeometries(); iGeom++ ) { poFeature->SetGeometry( poGC->getGeometryRef(iGeom) ); OGRErr eErr = CreateFeature( poFeature ); if( eErr != OGRERR_NONE ) return eErr; } poFeature->SetGeometryDirectly( poGC ); return OGRERR_NONE; } else { CPLError( CE_Failure, CPLE_AppDefined, "No known way to write feature with geometry '%s'.", OGRGeometryTypeToName(eGType) ); return OGRERR_FAILURE; } }
OGRLayer * OGRSQLiteExecuteSQL( OGRDataSource* poDS, const char *pszStatement, OGRGeometry *poSpatialFilter, const char *pszDialect ) { char* pszTmpDBName = (char*) CPLMalloc(256); sprintf(pszTmpDBName, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName); OGRSQLiteDataSource* poSQLiteDS = NULL; int nRet; int bSpatialiteDB = FALSE; CPLString osOldVal; const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL); if( pszOldVal != NULL ) { osOldVal = pszOldVal; pszOldVal = osOldVal.c_str(); } /* -------------------------------------------------------------------- */ /* Create in-memory sqlite/spatialite DB */ /* -------------------------------------------------------------------- */ #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Creating an empty spatialite DB (with spatial_ref_sys populated */ /* has a non-neglectable cost. So at the first attempt, let's make */ /* one and cache it for later use. */ /* -------------------------------------------------------------------- */ #if 1 static vsi_l_offset nEmptyDBSize = 0; static GByte* pabyEmptyDB = NULL; { static void* hMutex = NULL; CPLMutexHolder oMutexHolder(&hMutex); static int bTried = FALSE; if( !bTried && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { bTried = TRUE; char* pszCachedFilename = (char*) CPLMalloc(256); sprintf(pszCachedFilename, "/vsimem/ogr2sqlite/reference_%p.db",pszCachedFilename); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource(); nRet = poCachedDS->Create( pszCachedFilename, papszOptions ); CSLDestroy(papszOptions); papszOptions = NULL; delete poCachedDS; if( nRet ) /* Note: the reference file keeps the ownership of the data, so that */ /* it gets released with VSICleanupFileManager() */ pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSize, FALSE ); CPLFree( pszCachedFilename ); } } /* The following configuration option is usefull mostly for debugging/testing */ if( pabyEmptyDB != NULL && CSLTestBoolean(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { GByte* pabyEmptyDBClone = (GByte*)VSIMalloc(nEmptyDBSize); if( pabyEmptyDBClone == NULL ) { CPLFree(pszTmpDBName); return NULL; } memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize); VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE )); poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Open( pszTmpDBName, TRUE ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { /* should not happen really ! */ delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bSpatialiteDB = TRUE; } #else /* No caching version */ poSQLiteDS = new OGRSQLiteDataSource(); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); CSLDestroy(papszOptions); papszOptions = NULL; if( nRet ) { bSpatialiteDB = TRUE; } #endif else { delete poSQLiteDS; poSQLiteDS = NULL; #else // HAVE_SPATIALITE if( TRUE ) { #endif // HAVE_SPATIALITE poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } } /* -------------------------------------------------------------------- */ /* Attach the Virtual Table OGR2SQLITE module to it. */ /* -------------------------------------------------------------------- */ OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS); sqlite3* hDB = poSQLiteDS->GetDB(); /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); std::set<LayerDesc>::iterator oIter = oSetLayers.begin(); if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 ) CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str()); pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */ int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos ); /* -------------------------------------------------------------------- */ /* For each of those tables, create a Virtual Table. */ /* -------------------------------------------------------------------- */ for(; oIter != oSetLayers.end(); ++oIter) { const LayerDesc& oLayerDesc = *oIter; /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s", oLayerDesc.osOriginalStr.c_str(), oLayerDesc.osSubstitutedName.c_str(), oLayerDesc.osDSName.c_str(), oLayerDesc.osLayerName.c_str());*/ CPLString osSQL; OGRLayer* poLayer = NULL; CPLString osTableName; int nExtraDS; if( oLayerDesc.osDSName.size() == 0 ) { poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName); /* Might be a false positive (unlikely) */ if( poLayer == NULL ) continue; osTableName = oLayerDesc.osLayerName; nExtraDS = -1; osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(osTableName).c_str(), bFoundOGRStyle); } else { OGRDataSource* poOtherDS = (OGRDataSource* ) OGROpen(oLayerDesc.osDSName, FALSE, NULL); if( poOtherDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open datasource '%s'", oLayerDesc.osDSName.c_str() ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName); if( poLayer == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find layer '%s' in '%s'", oLayerDesc.osLayerName.c_str(), oLayerDesc.osDSName.c_str() ); delete poOtherDS; delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } osTableName = oLayerDesc.osSubstitutedName; nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS); osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(), bFoundOGRStyle); } char* pszErrMsg = NULL; int rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create virtual table for layer '%s' : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); continue; } if( poLayer->GetGeomType() == wkbNone ) continue; CPLString osGeomColRaw(OGR2SQLITE_GetNameForGeometryColumn(poLayer)); const char* pszGeomColRaw = osGeomColRaw.c_str(); CPLString osGeomColEscaped(OGRSQLiteEscape(pszGeomColRaw)); const char* pszGeomColEscaped = osGeomColEscaped.c_str(); CPLString osLayerNameEscaped(OGRSQLiteEscape(osTableName)); const char* pszLayerNameEscaped = osLayerNameEscaped.c_str(); CPLString osIdxNameRaw(CPLSPrintf("idx_%s_%s", oLayerDesc.osLayerName.c_str(), pszGeomColRaw)); CPLString osIdxNameEscaped(OGRSQLiteEscapeName(osIdxNameRaw)); /* Make sure that the SRS is injected in spatial_ref_sys */ OGRSpatialReference* poSRS = poLayer->GetSpatialRef(); int nSRSId = poSQLiteDS->GetUndefinedSRID(); if( poSRS != NULL ) nSRSId = poSQLiteDS->FetchSRSId(poSRS); int bCreateSpatialIndex = FALSE; if( !bSpatialiteDB ) { osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_format, geometry_type, " "coord_dimension, srid) " "VALUES ('%s','%s','SpatiaLite',%d,%d,%d)", pszLayerNameEscaped, pszGeomColEscaped, (int) wkbFlatten(poLayer->GetGeomType()), ( poLayer->GetGeomType() & wkb25DBit ) ? 3 : 2, nSRSId); } #ifdef HAVE_SPATIALITE else { /* We detect the need for creating a spatial index by 2 means : */ /* 1) if there's an explicit reference to a 'idx_layername_geometrycolumn' */ /* table in the SQL --> old/traditionnal way of requesting spatial indices */ /* with spatialite. */ std::set<LayerDesc>::iterator oIter2 = oSetLayers.begin(); for(; oIter2 != oSetLayers.end(); ++oIter2) { const LayerDesc& oLayerDescIter = *oIter2; if( EQUAL(oLayerDescIter.osLayerName, osIdxNameRaw) ) { bCreateSpatialIndex = TRUE; break; } } /* 2) or if there's a SELECT FROM SpatialIndex WHERE f_table_name = 'layername' */ if( !bCreateSpatialIndex ) { std::set<CPLString>::iterator oIter3 = oSetSpatialIndex.begin(); for(; oIter3 != oSetSpatialIndex.end(); ++oIter3) { const CPLString& osNameIter = *oIter3; if( EQUAL(osNameIter, oLayerDesc.osLayerName) ) { bCreateSpatialIndex = TRUE; break; } } } if( poSQLiteDS->HasSpatialite4Layout() ) { int nGeomType = poLayer->GetGeomType(); int nCoordDimension = 2; if( nGeomType & wkb25DBit ) { nGeomType += 1000; nCoordDimension = 3; } osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, geometry_type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES ('%s',Lower('%s'),%d ,%d ,%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, nGeomType, nCoordDimension, nSRSId, bCreateSpatialIndex ); } else { const char *pszGeometryType = OGRToOGCGeomType(poLayer->GetGeomType()); if (pszGeometryType[0] == '\0') pszGeometryType = "GEOMETRY"; osSQL.Printf("INSERT INTO geometry_columns (f_table_name, " "f_geometry_column, type, coord_dimension, " "srid, spatial_index_enabled) " "VALUES ('%s','%s','%s','%s',%d, %d)", pszLayerNameEscaped, pszGeomColEscaped, pszGeometryType, ( poLayer->GetGeomType() & wkb25DBit ) ? "XYZ" : "XY", nSRSId, bCreateSpatialIndex ); } } #endif // HAVE_SPATIALITE sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Should we create a spatial index ?. */ /* -------------------------------------------------------------------- */ if( !bSpatialiteDB || !bCreateSpatialIndex ) continue; CPLDebug("SQLITE", "Create spatial index %s", osIdxNameRaw.c_str()); /* ENABLE_VIRTUAL_OGR_SPATIAL_INDEX is not defined */ #ifdef ENABLE_VIRTUAL_OGR_SPATIAL_INDEX osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING " "VirtualOGRSpatialIndex(%d, '%s', pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str()); rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); if( rc != SQLITE_OK ) { CPLDebug("SQLITE", "Error occured during spatial index creation : %s", sqlite3_errmsg(hDB)); } #else // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX rc = sqlite3_exec( hDB, "BEGIN", NULL, NULL, NULL ); osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" " "USING rtree(pkid, xmin, xmax, ymin, ymax)", osIdxNameEscaped.c_str()); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, NULL ); sqlite3_stmt *hStmt = NULL; if( rc == SQLITE_OK ) { const char* pszInsertInto = CPLSPrintf( "INSERT INTO \"%s\" (pkid, xmin, xmax, ymin, ymax) " "VALUES (?,?,?,?,?)", osIdxNameEscaped.c_str()); rc = sqlite3_prepare(hDB, pszInsertInto, -1, &hStmt, NULL); } OGRFeature* poFeature; OGREnvelope sEnvelope; OGR2SQLITE_IgnoreAllFieldsExceptGeometry(poLayer); poLayer->ResetReading(); while( rc == SQLITE_OK && (poFeature = poLayer->GetNextFeature()) != NULL ) { OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && !poGeom->IsEmpty() ) { poGeom->getEnvelope(&sEnvelope); sqlite3_bind_int64(hStmt, 1, (sqlite3_int64) poFeature->GetFID() ); sqlite3_bind_double(hStmt, 2, sEnvelope.MinX); sqlite3_bind_double(hStmt, 3, sEnvelope.MaxX); sqlite3_bind_double(hStmt, 4, sEnvelope.MinY); sqlite3_bind_double(hStmt, 5, sEnvelope.MaxY); rc = sqlite3_step(hStmt); if( rc == SQLITE_OK || rc == SQLITE_DONE ) rc = sqlite3_reset(hStmt); } delete poFeature; } poLayer->SetIgnoredFields(NULL); sqlite3_finalize(hStmt); if( rc == SQLITE_OK ) rc = sqlite3_exec( hDB, "COMMIT", NULL, NULL, NULL ); else { CPLDebug("SQLITE", "Error occured during spatial index creation : %s", sqlite3_errmsg(hDB)); rc = sqlite3_exec( hDB, "ROLLBACK", NULL, NULL, NULL ); } #endif // ENABLE_VIRTUAL_OGR_SPATIAL_INDEX #endif // HAVE_SPATIALITE } /* -------------------------------------------------------------------- */ /* Reload, so that virtual tables are recognized */ /* -------------------------------------------------------------------- */ poSQLiteDS->ReloadLayers(); /* -------------------------------------------------------------------- */ /* Prepare the statement. */ /* -------------------------------------------------------------------- */ /* This will speed-up layer creation */ /* ORDER BY are costly to evaluate and are not necessary to establish */ /* the layer definition. */ int bUseStatementForGetNextFeature = TRUE; int bEmptyLayer = FALSE; sqlite3_stmt *hSQLStmt = NULL; int rc = sqlite3_prepare( hDB, pszStatement, strlen(pszStatement), &hSQLStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_prepare(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); if( hSQLStmt != NULL ) { sqlite3_finalize( hSQLStmt ); } delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } /* -------------------------------------------------------------------- */ /* Do we get a resultset? */ /* -------------------------------------------------------------------- */ rc = sqlite3_step( hSQLStmt ); if( rc != SQLITE_ROW ) { if ( rc != SQLITE_DONE ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_step(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } if( !EQUALN(pszStatement, "SELECT ", 7) ) { sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bUseStatementForGetNextFeature = FALSE; bEmptyLayer = TRUE; } /* -------------------------------------------------------------------- */ /* Create layer. */ /* -------------------------------------------------------------------- */ OGRSQLiteSelectLayer *poLayer = NULL; poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName, poSQLiteDS, pszStatement, hSQLStmt, bUseStatementForGetNextFeature, bEmptyLayer ); if( poSpatialFilter != NULL ) poLayer->SetSpatialFilter( poSpatialFilter ); return poLayer; } /************************************************************************/ /* OGRSQLiteGetReferencedLayers() */ /************************************************************************/ std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement) { /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); return oSetLayers; }
CPLString OGRPLScenesLayer::BuildURL(int nFeatures) { CPLString osURL = osBaseURL + CPLSPrintf("?count=%d", nFeatures); if( bAcquiredAscending == 1 ) osURL += "&order_by=acquired%20asc"; else if( bAcquiredAscending == 0 ) osURL += "&order_by=acquired%20desc"; if( m_poFilterGeom != NULL || poMainFilter != NULL ) { OGRGeometry* poIntersection = NULL; OGRGeometry* poFilterGeom = m_poFilterGeom; if( poFilterGeom ) { OGREnvelope sEnvelope; poFilterGeom->getEnvelope(&sEnvelope); if( sEnvelope.MinX <= -180 && sEnvelope.MinY <= -90 && sEnvelope.MaxX >= 180 && sEnvelope.MaxY >= 90 ) poFilterGeom = NULL; } if( poFilterGeom && poMainFilter ) poIntersection = poFilterGeom->Intersection(poMainFilter); else if( poFilterGeom ) poIntersection = poFilterGeom; else if( poMainFilter ) poIntersection = poMainFilter; if( poIntersection ) { char* pszWKT = NULL; OGREnvelope sEnvelope; poIntersection->getEnvelope(&sEnvelope); if( sEnvelope.MinX == sEnvelope.MaxX && sEnvelope.MinY == sEnvelope.MaxY ) { pszWKT = CPLStrdup(CPLSPrintf("POINT(%.18g %.18g)", sEnvelope.MinX, sEnvelope.MinY)); } else poIntersection->exportToWkt(&pszWKT); osURL += "&intersects="; char* pszWKTEscaped = CPLEscapeString(pszWKT, -1, CPLES_URL); osURL += pszWKTEscaped; CPLFree(pszWKTEscaped); CPLFree(pszWKT); } if( poIntersection != m_poFilterGeom && poIntersection != poMainFilter ) delete poIntersection; } if( osFilterURLPart.size() ) { if( osFilterURLPart[0] == '&' ) osURL += osFilterURLPart; else osURL = osBaseURL + osFilterURLPart; } return osURL; }
int NASReader::PrescanForSchema( int bGetExtents ) { GMLFeature *poFeature; if( m_pszFilename == NULL ) return FALSE; SetClassListLocked( FALSE ); ClearClasses(); if( !SetupParser() ) return FALSE; while( (poFeature = NextFeature()) != NULL ) { GMLFeatureClass *poClass = poFeature->GetClass(); if( poClass->GetFeatureCount() == -1 ) poClass->SetFeatureCount( 1 ); else poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 ); #ifdef SUPPORT_GEOMETRY if( bGetExtents ) { OGRGeometry *poGeometry = NULL; if( poFeature->GetGeometry() != NULL && strlen(poFeature->GetGeometry()) != 0 ) { poGeometry = (OGRGeometry *) OGR_G_CreateFromGML( poFeature->GetGeometry() ); } if( poGeometry != NULL ) { double dfXMin, dfXMax, dfYMin, dfYMax; OGREnvelope sEnvelope; OGRwkbGeometryType eGType = (OGRwkbGeometryType) poClass->GetGeometryType(); // Merge geometry type into layer. if( poClass->GetFeatureCount() == 1 && eGType == wkbUnknown ) eGType = wkbNone; poClass->SetGeometryType( (int) OGRMergeGeometryTypes( eGType, poGeometry->getGeometryType() ) ); // merge extents. poGeometry->getEnvelope( &sEnvelope ); delete poGeometry; if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) ) { dfXMin = MIN(dfXMin,sEnvelope.MinX); dfXMax = MAX(dfXMax,sEnvelope.MaxX); dfYMin = MIN(dfYMin,sEnvelope.MinY); dfYMax = MAX(dfYMax,sEnvelope.MaxY); } else { dfXMin = sEnvelope.MinX; dfXMax = sEnvelope.MaxX; dfYMin = sEnvelope.MinY; dfYMax = sEnvelope.MaxY; } poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax ); } else { if( poClass->GetGeometryType() == (int) wkbUnknown && poClass->GetFeatureCount() == 1 ) poClass->SetGeometryType( wkbNone ); } #endif /* def SUPPORT_GEOMETRY */ } delete poFeature; } CleanupParser(); return GetClassCount() > 0; }
json_object* OGRGeoJSONWriteFeature( OGRFeature* poFeature, int bWriteBBOX, int nCoordPrecision ) { CPLAssert( NULL != poFeature ); json_object* poObj = json_object_new_object(); CPLAssert( NULL != poObj ); json_object_object_add( poObj, "type", json_object_new_string("Feature") ); /* -------------------------------------------------------------------- */ /* Write FID if available */ /* -------------------------------------------------------------------- */ if ( poFeature->GetFID() != OGRNullFID ) { json_object_object_add( poObj, "id", json_object_new_int64(poFeature->GetFID()) ); } /* -------------------------------------------------------------------- */ /* Write feature attributes to GeoJSON "properties" object. */ /* -------------------------------------------------------------------- */ json_object* poObjProps = NULL; poObjProps = OGRGeoJSONWriteAttributes( poFeature ); json_object_object_add( poObj, "properties", poObjProps ); /* -------------------------------------------------------------------- */ /* Write feature geometry to GeoJSON "geometry" object. */ /* Null geometries are allowed, according to the GeoJSON Spec. */ /* -------------------------------------------------------------------- */ json_object* poObjGeom = NULL; OGRGeometry* poGeometry = poFeature->GetGeometryRef(); if ( NULL != poGeometry ) { poObjGeom = OGRGeoJSONWriteGeometry( poGeometry, nCoordPrecision ); if ( bWriteBBOX && !poGeometry->IsEmpty() ) { OGREnvelope3D sEnvelope; poGeometry->getEnvelope(&sEnvelope); json_object* poObjBBOX = json_object_new_array(); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MinX, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MinY, nCoordPrecision)); if (poGeometry->getCoordinateDimension() == 3) json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MinZ, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MaxX, nCoordPrecision)); json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MaxY, nCoordPrecision)); if (poGeometry->getCoordinateDimension() == 3) json_object_array_add(poObjBBOX, json_object_new_double_with_precision(sEnvelope.MaxZ, nCoordPrecision)); json_object_object_add( poObj, "bbox", poObjBBOX ); } } json_object_object_add( poObj, "geometry", poObjGeom ); return poObj; }
OGRErr OGRGMLLayer::CreateFeature( OGRFeature *poFeature ) { int bIsGML3Output = poDS->IsGML3Output(); VSILFILE *fp = poDS->GetOutputFP(); int bWriteSpaceIndentation = poDS->WriteSpaceIndentation(); if( !bWriter ) return OGRERR_FAILURE; if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if (bIsGML3Output) poDS->PrintLine( fp, "<ogr:featureMember>" ); else poDS->PrintLine( fp, "<gml:featureMember>" ); if( poFeature->GetFID() == OGRNullFID ) poFeature->SetFID( iNextGMLId++ ); int nGMLIdIndex = -1; if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if (bIsGML3Output) { nGMLIdIndex = poFeatureDefn->GetFieldIndex("gml_id"); if (nGMLIdIndex >= 0 && poFeature->IsFieldSet( nGMLIdIndex ) ) poDS->PrintLine( fp, "<ogr:%s gml:id=\"%s\">", poFeatureDefn->GetName(), poFeature->GetFieldAsString(nGMLIdIndex) ); else poDS->PrintLine( fp, "<ogr:%s gml:id=\"%s.%ld\">", poFeatureDefn->GetName(), poFeatureDefn->GetName(), poFeature->GetFID() ); } else poDS->PrintLine( fp, "<ogr:%s fid=\"F%ld\">", poFeatureDefn->GetName(), poFeature->GetFID() ); // Write out Geometry - for now it isn't indented properly. /* GML geometries don't like very much the concept of empty geometry */ OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && !poGeom->IsEmpty()) { char *pszGeometry; OGREnvelope sGeomBounds; poGeom->getEnvelope( &sGeomBounds ); poDS->GrowExtents( &sGeomBounds ); if (bIsGML3Output) { int bCoordSwap; if (poGeom->getSpatialReference() == NULL && poSRS != NULL) poGeom->assignSpatialReference(poSRS); char* pszSRSName = GML_GetSRSName(poGeom->getSpatialReference(), poDS->IsLongSRSRequired(), &bCoordSwap); char szLowerCorner[75], szUpperCorner[75]; if (bCoordSwap) { OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinY, sGeomBounds.MinX, 0, 2); OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxY, sGeomBounds.MaxX, 0, 2); } else { OGRMakeWktCoordinate(szLowerCorner, sGeomBounds.MinX, sGeomBounds.MinY, 0, 2); OGRMakeWktCoordinate(szUpperCorner, sGeomBounds.MaxX, sGeomBounds.MaxY, 0, 2); } if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); poDS->PrintLine( fp, "<gml:boundedBy><gml:Envelope%s><gml:lowerCorner>%s</gml:lowerCorner><gml:upperCorner>%s</gml:upperCorner></gml:Envelope></gml:boundedBy>", pszSRSName, szLowerCorner, szUpperCorner); CPLFree(pszSRSName); } char** papszOptions = (bIsGML3Output) ? CSLAddString(NULL, "FORMAT=GML3") : NULL; if (bIsGML3Output && !poDS->IsLongSRSRequired()) papszOptions = CSLAddString(papszOptions, "GML3_LONGSRS=NO"); pszGeometry = poGeom->exportToGML(papszOptions); CSLDestroy(papszOptions); if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); poDS->PrintLine( fp, "<ogr:geometryProperty>%s</ogr:geometryProperty>", pszGeometry ); CPLFree( pszGeometry ); } // Write all "set" fields. for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( iField ); if( poFeature->IsFieldSet( iField ) && iField != nGMLIdIndex ) { const char *pszRaw = poFeature->GetFieldAsString( iField ); while( *pszRaw == ' ' ) pszRaw++; char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw ); if (poFieldDefn->GetType() == OFTReal) { /* Use point as decimal separator */ char* pszComma = strchr(pszEscaped, ','); if (pszComma) *pszComma = '.'; } if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); poDS->PrintLine( fp, "<ogr:%s>%s</ogr:%s>", poFieldDefn->GetNameRef(), pszEscaped, poFieldDefn->GetNameRef() ); CPLFree( pszEscaped ); } } if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); poDS->PrintLine( fp, "</ogr:%s>", poFeatureDefn->GetName() ); if (bWriteSpaceIndentation) VSIFPrintfL(fp, " "); if (bIsGML3Output) poDS->PrintLine( fp, "</ogr:featureMember>" ); else poDS->PrintLine( fp, "</gml:featureMember>" ); return OGRERR_NONE; }
int GMLReader::PrescanForSchema( int bGetExtents ) { GMLFeature *poFeature; if( m_pszFilename == NULL ) return FALSE; SetClassListLocked( FALSE ); ClearClasses(); if( !SetupParser() ) return FALSE; while( (poFeature = NextFeature()) != NULL ) { GMLFeatureClass *poClass = poFeature->GetClass(); if( poClass->GetFeatureCount() == -1 ) poClass->SetFeatureCount( 1 ); else poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 ); #ifdef SUPPORT_GEOMETRY if( bGetExtents ) { OGRGeometry *poGeometry = NULL; if( poFeature->GetGeometry() != NULL && strlen(poFeature->GetGeometry()) != 0 ) { poGeometry = OGRGeometryFactory::createFromGML( poFeature->GetGeometry() ); } if( poGeometry != NULL ) { double dfXMin, dfXMax, dfYMin, dfYMax; OGREnvelope sEnvelope; poGeometry->getEnvelope( &sEnvelope ); delete poGeometry; if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) ) { dfXMin = MIN(dfXMin,sEnvelope.MinX); dfXMax = MAX(dfXMax,sEnvelope.MaxX); dfYMin = MIN(dfYMin,sEnvelope.MinY); dfYMax = MAX(dfYMax,sEnvelope.MaxY); } else { dfXMin = sEnvelope.MinX; dfXMax = sEnvelope.MaxX; dfYMin = sEnvelope.MinY; dfYMax = sEnvelope.MaxY; } poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax ); } #endif /* def SUPPORT_GEOMETRY */ } delete poFeature; } CleanupParser(); return GetClassCount() > 0; }
OGRErr OGRMySQLTableLayer::GetExtent(OGREnvelope *psExtent, CPL_UNUSED int bForce ) { if( GetLayerDefn()->GetGeomType() == wkbNone ) { psExtent->MinX = 0.0; psExtent->MaxX = 0.0; psExtent->MinY = 0.0; psExtent->MaxY = 0.0; return OGRERR_FAILURE; } ResetReading(); OGREnvelope oEnv; CPLString osCommand; GBool bExtentSet = FALSE; if( poDS->GetMajorVersion() >= 8 && !poDS->IsMariaDB() ) { // ST_Envelope() does not work on geographic SRS, so force to 0 osCommand.Printf( "SELECT ST_Envelope(ST_SRID(`%s`,0)) FROM `%s`;", pszGeomColumn, pszGeomColumnTable); } else { osCommand.Printf( "SELECT Envelope(`%s`) FROM `%s`;", pszGeomColumn, pszGeomColumnTable); } if (mysql_query(poDS->GetConn(), osCommand) == 0) { MYSQL_RES* result = mysql_use_result(poDS->GetConn()); if ( result == nullptr ) { poDS->ReportError( "mysql_use_result() failed on extents query." ); return OGRERR_FAILURE; } MYSQL_ROW row; unsigned long *panLengths = nullptr; while ((row = mysql_fetch_row(result)) != nullptr) { if (panLengths == nullptr) { panLengths = mysql_fetch_lengths( result ); if ( panLengths == nullptr ) { poDS->ReportError( "mysql_fetch_lengths() failed on extents query." ); return OGRERR_FAILURE; } } OGRGeometry *poGeometry = nullptr; // Geometry columns will have the first 4 bytes contain the SRID. OGRGeometryFactory::createFromWkb(row[0] + 4, nullptr, &poGeometry, static_cast<int>(panLengths[0] - 4) ); if ( poGeometry != nullptr ) { if (poGeometry && !bExtentSet) { poGeometry->getEnvelope(psExtent); bExtentSet = TRUE; } else if (poGeometry) { poGeometry->getEnvelope(&oEnv); if (oEnv.MinX < psExtent->MinX) psExtent->MinX = oEnv.MinX; if (oEnv.MinY < psExtent->MinY) psExtent->MinY = oEnv.MinY; if (oEnv.MaxX > psExtent->MaxX) psExtent->MaxX = oEnv.MaxX; if (oEnv.MaxY > psExtent->MaxY) psExtent->MaxY = oEnv.MaxY; } delete poGeometry; } } mysql_free_result(result); } else { poDS->ReportError( osCommand.c_str() ); } return bExtentSet ? OGRERR_NONE : OGRERR_FAILURE; }