static void ReportOnLayer( OGRLayer * poLayer, int bVerbose ) { OGRFeatureDefn *poDefn = poLayer->GetLayerDefn(); /* -------------------------------------------------------------------- */ /* Report various overall information. */ /* -------------------------------------------------------------------- */ printf( "\n" ); printf( "Layer name: %s\n", poLayer->GetName() ); if( bVerbose ) { int nGeomFieldCount = poLayer->GetLayerDefn()->GetGeomFieldCount(); if( nGeomFieldCount > 1 ) { for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); printf( "Geometry (%s): %s\n", poGFldDefn->GetNameRef(), OGRGeometryTypeToName( poGFldDefn->GetType() ) ); } } else { printf( "Geometry: %s\n", OGRGeometryTypeToName( poLayer->GetGeomType() ) ); } printf( "Feature Count: " CPL_FRMT_GIB "\n", poLayer->GetFeatureCount() ); OGREnvelope oExt; if( nGeomFieldCount > 1 ) { for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { if (poLayer->GetExtent(iGeom, &oExt, TRUE) == OGRERR_NONE) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); CPLprintf("Extent (%s): (%f, %f) - (%f, %f)\n", poGFldDefn->GetNameRef(), oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY); } } } else if ( poLayer->GetExtent(&oExt, TRUE) == OGRERR_NONE) { CPLprintf("Extent: (%f, %f) - (%f, %f)\n", oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY); } char *pszWKT; if( nGeomFieldCount > 1 ) { for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); OGRSpatialReference* poSRS = poGFldDefn->GetSpatialRef(); if( poSRS == NULL ) pszWKT = CPLStrdup( "(unknown)" ); else { poSRS->exportToPrettyWkt( &pszWKT ); } printf( "SRS WKT (%s):\n%s\n", poGFldDefn->GetNameRef(), pszWKT ); CPLFree( pszWKT ); } } else { if( poLayer->GetSpatialRef() == NULL ) pszWKT = CPLStrdup( "(unknown)" ); else { poLayer->GetSpatialRef()->exportToPrettyWkt( &pszWKT ); } printf( "Layer SRS WKT:\n%s\n", pszWKT ); CPLFree( pszWKT ); } if( strlen(poLayer->GetFIDColumn()) > 0 ) printf( "FID Column = %s\n", poLayer->GetFIDColumn() ); for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); if( nGeomFieldCount == 1 && EQUAL(poGFldDefn->GetNameRef(), "") && poGFldDefn->IsNullable() ) break; printf( "Geometry Column "); if( nGeomFieldCount > 1 ) printf("%d ", iGeom + 1); if( !poGFldDefn->IsNullable() ) printf("NOT NULL "); printf("= %s\n", poGFldDefn->GetNameRef() ); } for( int iAttr = 0; iAttr < poDefn->GetFieldCount(); iAttr++ ) { OGRFieldDefn *poField = poDefn->GetFieldDefn( iAttr ); const char* pszType = (poField->GetSubType() != OFSTNone) ? CPLSPrintf("%s(%s)", poField->GetFieldTypeName( poField->GetType() ), poField->GetFieldSubTypeName(poField->GetSubType())) : poField->GetFieldTypeName( poField->GetType() ); printf( "%s: %s (%d.%d)", poField->GetNameRef(), pszType, poField->GetWidth(), poField->GetPrecision() ); if( !poField->IsNullable() ) printf(" NOT NULL"); if( poField->GetDefault() != NULL ) printf(" DEFAULT %s", poField->GetDefault() ); printf( "\n" ); } } /* -------------------------------------------------------------------- */ /* Read, and dump features. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature = NULL; while( (poFeature = poLayer->GetNextFeature()) != NULL ) { poFeature->DumpReadable( NULL ); OGRFeature::DestroyFeature( poFeature ); } }
OGRFeatureDefn *OGRUnionLayer::GetLayerDefn() { if( poFeatureDefn != NULL ) return poFeatureDefn; poFeatureDefn = new OGRFeatureDefn( osName ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType(wkbNone); int iCompareFirstIndex = 0; if( osSourceLayerFieldName.size() ) { OGRFieldDefn oField(osSourceLayerFieldName, OFTString); poFeatureDefn->AddFieldDefn(&oField); iCompareFirstIndex = 1; } if( eFieldStrategy == FIELD_SPECIFIED ) { int i; for(i = 0; i < nFields; i++) poFeatureDefn->AddFieldDefn(papoFields[i]); for(i = 0; i < nGeomFields; i++) { poFeatureDefn->AddGeomFieldDefn(new OGRUnionLayerGeomFieldDefn(papoGeomFields[i]), FALSE); OGRUnionLayerGeomFieldDefn* poGeomFieldDefn = (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(i); if( poGeomFieldDefn->bGeomTypeSet == FALSE || poGeomFieldDefn->bSRSSet == FALSE ) { for(int iLayer = 0; iLayer < nSrcLayers; iLayer++) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); int nIndex = poSrcFeatureDefn->GetGeomFieldIndex(poGeomFieldDefn->GetNameRef()); if( nIndex >= 0 ) { OGRGeomFieldDefn* poSrcGeomFieldDefn = poSrcFeatureDefn->GetGeomFieldDefn(nIndex); if( poGeomFieldDefn->bGeomTypeSet == FALSE ) { poGeomFieldDefn->bGeomTypeSet = TRUE; poGeomFieldDefn->SetType(poSrcGeomFieldDefn->GetType()); } if( poGeomFieldDefn->bSRSSet == FALSE ) { poGeomFieldDefn->bSRSSet = TRUE; poGeomFieldDefn->SetSpatialRef(poSrcGeomFieldDefn->GetSpatialRef()); if( i == 0 && poGlobalSRS == NULL ) { poGlobalSRS = poSrcGeomFieldDefn->GetSpatialRef(); if( poGlobalSRS != NULL ) poGlobalSRS->Reference(); } } break; } } } } } else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER ) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn(); int i; for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++) poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i)); for(i = 0; nGeomFields != - 1 && i < poSrcFeatureDefn->GetGeomFieldCount(); i++) { OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i); poFeatureDefn->AddGeomFieldDefn( new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE); } } else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS ) { if( nGeomFields == 1 ) { poFeatureDefn->AddGeomFieldDefn( new OGRUnionLayerGeomFieldDefn(papoGeomFields[0]), FALSE); } for(int iLayer = 0; iLayer < nSrcLayers; iLayer++) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); /* Add any field that is found in the source layers */ int i; for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++) { OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i); int nIndex = poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef()); if( nIndex < 0 ) poFeatureDefn->AddFieldDefn(poSrcFieldDefn); else { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(nIndex); MergeFieldDefn(poFieldDefn, poSrcFieldDefn); } } for(i = 0; nGeomFields != - 1 && i < poSrcFeatureDefn->GetGeomFieldCount(); i++) { OGRGeomFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i); int nIndex = poFeatureDefn->GetGeomFieldIndex(poSrcFieldDefn->GetNameRef()); if( nIndex < 0 ) { poFeatureDefn->AddGeomFieldDefn( new OGRUnionLayerGeomFieldDefn(poSrcFieldDefn), FALSE); if( poFeatureDefn->GetGeomFieldCount() == 1 && nGeomFields == 0 && GetSpatialRef() != NULL ) { OGRUnionLayerGeomFieldDefn* poGeomFieldDefn = (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(0); poGeomFieldDefn->bSRSSet = TRUE; poGeomFieldDefn->SetSpatialRef(GetSpatialRef()); } } else { if( nIndex == 0 && nGeomFields == 1 ) { OGRUnionLayerGeomFieldDefn* poGeomFieldDefn = (OGRUnionLayerGeomFieldDefn* ) poFeatureDefn->GetGeomFieldDefn(0); if( poGeomFieldDefn->bGeomTypeSet == FALSE ) { poGeomFieldDefn->bGeomTypeSet = TRUE; poGeomFieldDefn->SetType(poSrcFieldDefn->GetType()); } if( poGeomFieldDefn->bSRSSet == FALSE ) { poGeomFieldDefn->bSRSSet = TRUE; poGeomFieldDefn->SetSpatialRef(poSrcFieldDefn->GetSpatialRef()); } } /* TODO: merge type, SRS, extent ? */ } } } } else if (eFieldStrategy == FIELD_INTERSECTION_ALL_LAYERS ) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn(); int i; for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++) poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i)); for(i = 0; i < poSrcFeatureDefn->GetGeomFieldCount(); i++) { OGRGeomFieldDefn* poFldDefn = poSrcFeatureDefn->GetGeomFieldDefn(i); poFeatureDefn->AddGeomFieldDefn( new OGRUnionLayerGeomFieldDefn(poFldDefn), FALSE); } /* Remove any field that is not found in the source layers */ for(int iLayer = 1; iLayer < nSrcLayers; iLayer++) { OGRFeatureDefn* l_poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); for(i = iCompareFirstIndex; i < poFeatureDefn->GetFieldCount();) { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i); int nSrcIndex = l_poSrcFeatureDefn->GetFieldIndex( poFieldDefn->GetNameRef()); if( nSrcIndex < 0 ) { poFeatureDefn->DeleteFieldDefn(i); } else { OGRFieldDefn* poSrcFieldDefn = l_poSrcFeatureDefn->GetFieldDefn(nSrcIndex); MergeFieldDefn(poFieldDefn, poSrcFieldDefn); i ++; } } for(i = 0; i < poFeatureDefn->GetGeomFieldCount();) { OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(i); int nSrcIndex = l_poSrcFeatureDefn->GetGeomFieldIndex( poFieldDefn->GetNameRef()); if( nSrcIndex < 0 ) { poFeatureDefn->DeleteGeomFieldDefn(i); } else { /* TODO: merge type, SRS, extent ? */ i ++; } } } } return poFeatureDefn; }
OGRFeature *OGRGeoPackageLayer::TranslateFeature( sqlite3_stmt* hStmt ) { /* -------------------------------------------------------------------- */ /* Create a feature from the current result. */ /* -------------------------------------------------------------------- */ int iField; OGRFeature *poFeature = new OGRFeature( m_poFeatureDefn ); /* -------------------------------------------------------------------- */ /* Set FID if we have a column to set it from. */ /* -------------------------------------------------------------------- */ if( iFIDCol >= 0 ) poFeature->SetFID( sqlite3_column_int64( hStmt, iFIDCol ) ); else poFeature->SetFID( iNextShapeId ); iNextShapeId++; m_nFeaturesRead++; /* -------------------------------------------------------------------- */ /* Process Geometry if we have a column. */ /* -------------------------------------------------------------------- */ if( iGeomCol >= 0 ) { OGRGeomFieldDefn* poGeomFieldDefn = m_poFeatureDefn->GetGeomFieldDefn(0); if ( sqlite3_column_type(hStmt, iGeomCol) != SQLITE_NULL && !poGeomFieldDefn->IsIgnored() ) { OGRSpatialReference* poSrs = poGeomFieldDefn->GetSpatialRef(); int iGpkgSize = sqlite3_column_bytes(hStmt, iGeomCol); GByte *pabyGpkg = (GByte *)sqlite3_column_blob(hStmt, iGeomCol); OGRGeometry *poGeom = GPkgGeometryToOGR(pabyGpkg, iGpkgSize, poSrs); if ( ! poGeom ) { // Try also spatialite geometry blobs if( OGRSQLiteLayer::ImportSpatiaLiteGeometry( pabyGpkg, iGpkgSize, &poGeom ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to read geometry"); } } poFeature->SetGeometryDirectly( poGeom ); } } /* -------------------------------------------------------------------- */ /* set the fields. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < m_poFeatureDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = m_poFeatureDefn->GetFieldDefn( iField ); if ( poFieldDefn->IsIgnored() ) continue; int iRawField = panFieldOrdinals[iField]; if( sqlite3_column_type( hStmt, iRawField ) == SQLITE_NULL ) continue; switch( poFieldDefn->GetType() ) { case OFTInteger: poFeature->SetField( iField, sqlite3_column_int( hStmt, iRawField ) ); break; case OFTInteger64: poFeature->SetField( iField, sqlite3_column_int64( hStmt, iRawField ) ); break; case OFTReal: poFeature->SetField( iField, sqlite3_column_double( hStmt, iRawField ) ); break; case OFTBinary: { const int nBytes = sqlite3_column_bytes( hStmt, iRawField ); poFeature->SetField( iField, nBytes, (GByte*)sqlite3_column_blob( hStmt, iRawField ) ); break; } case OFTDate: { const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField ); int nYear, nMonth, nDay; if( sscanf(pszTxt, "%d-%d-%d", &nYear, &nMonth, &nDay) == 3 ) poFeature->SetField(iField, nYear, nMonth, nDay, 0, 0, 0, 0); break; } case OFTDateTime: { const char* pszTxt = (const char*)sqlite3_column_text( hStmt, iRawField ); OGRField sField; if( OGRParseXMLDateTime(pszTxt, &sField) ) poFeature->SetField(iField, &sField); break; } case OFTString: poFeature->SetField( iField, (const char *) sqlite3_column_text( hStmt, iRawField ) ); break; default: break; } } return poFeature; }
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; }
static void ReportOnLayer( OGRLayer * poLayer, const char *pszWHERE, const char* pszGeomField, OGRGeometry *poSpatialFilter, bool bListMDD, bool bShowMetadata, char** papszExtraMDDomains, bool bFeatureCount, bool bExtent, const char* pszWKTFormat ) { OGRFeatureDefn *poDefn = poLayer->GetLayerDefn(); /* -------------------------------------------------------------------- */ /* Set filters if provided. */ /* -------------------------------------------------------------------- */ if( pszWHERE != nullptr ) { if( poLayer->SetAttributeFilter(pszWHERE) != OGRERR_NONE ) { printf("FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE); exit(1); } } if( poSpatialFilter != nullptr ) { if( pszGeomField != nullptr ) { const int iGeomField = poDefn->GetGeomFieldIndex(pszGeomField); if( iGeomField >= 0 ) poLayer->SetSpatialFilter(iGeomField, poSpatialFilter); else printf("WARNING: Cannot find geometry field %s.\n", pszGeomField); } else { poLayer->SetSpatialFilter(poSpatialFilter); } } /* -------------------------------------------------------------------- */ /* Report various overall information. */ /* -------------------------------------------------------------------- */ if( !bSuperQuiet ) { printf("\n"); printf("Layer name: %s\n", poLayer->GetName()); } GDALInfoReportMetadata(static_cast<GDALMajorObjectH>(poLayer), bListMDD, bShowMetadata, papszExtraMDDomains); if( bVerbose ) { const int nGeomFieldCount = poLayer->GetLayerDefn()->GetGeomFieldCount(); if( nGeomFieldCount > 1 ) { for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); printf("Geometry (%s): %s\n", poGFldDefn->GetNameRef(), OGRGeometryTypeToName(poGFldDefn->GetType())); } } else { printf("Geometry: %s\n", OGRGeometryTypeToName(poLayer->GetGeomType())); } if( bFeatureCount ) printf("Feature Count: " CPL_FRMT_GIB "\n", poLayer->GetFeatureCount()); OGREnvelope oExt; if( bExtent && nGeomFieldCount > 1 ) { for( int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { if( poLayer->GetExtent(iGeom, &oExt, TRUE) == OGRERR_NONE ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); CPLprintf("Extent (%s): (%f, %f) - (%f, %f)\n", poGFldDefn->GetNameRef(), oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY); } } } else if( bExtent && poLayer->GetExtent(&oExt, TRUE) == OGRERR_NONE ) { CPLprintf("Extent: (%f, %f) - (%f, %f)\n", oExt.MinX, oExt.MinY, oExt.MaxX, oExt.MaxY); } const auto displayDataAxisMapping = [](const OGRSpatialReference* poSRS) { const auto mapping = poSRS->GetDataAxisToSRSAxisMapping(); printf("Data axis to CRS axis mapping: "); for( size_t i = 0; i < mapping.size(); i++ ) { if( i > 0 ) { printf(","); } printf("%d", mapping[i]); } printf("\n"); }; if( nGeomFieldCount > 1 ) { for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); OGRSpatialReference* poSRS = poGFldDefn->GetSpatialRef(); char *pszWKT = nullptr; if( poSRS == nullptr ) { pszWKT = CPLStrdup("(unknown)"); } else { CPLString osWKTFormat("FORMAT="); osWKTFormat += pszWKTFormat; const char* const apszWKTOptions[] = { osWKTFormat.c_str(), "MULTILINE=YES", nullptr }; poSRS->exportToWkt(&pszWKT, apszWKTOptions); } printf("SRS WKT (%s):\n%s\n", poGFldDefn->GetNameRef(), pszWKT); CPLFree(pszWKT); if( poSRS ) { displayDataAxisMapping(poSRS); } } } else { char *pszWKT = nullptr; auto poSRS = poLayer->GetSpatialRef(); if( poSRS == nullptr ) { pszWKT = CPLStrdup("(unknown)"); } else { poSRS->exportToPrettyWkt(&pszWKT); } printf("Layer SRS WKT:\n%s\n", pszWKT); CPLFree(pszWKT); if( poSRS ) { displayDataAxisMapping(poSRS); } } if( strlen(poLayer->GetFIDColumn()) > 0 ) printf("FID Column = %s\n", poLayer->GetFIDColumn()); for(int iGeom = 0;iGeom < nGeomFieldCount; iGeom ++ ) { OGRGeomFieldDefn* poGFldDefn = poLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom); if( nGeomFieldCount == 1 && EQUAL(poGFldDefn->GetNameRef(), "") && poGFldDefn->IsNullable() ) break; printf("Geometry Column "); if( nGeomFieldCount > 1 ) printf("%d ", iGeom + 1); if( !poGFldDefn->IsNullable() ) printf("NOT NULL "); printf("= %s\n", poGFldDefn->GetNameRef()); } for( int iAttr = 0; iAttr < poDefn->GetFieldCount(); iAttr++ ) { OGRFieldDefn *poField = poDefn->GetFieldDefn(iAttr); const char* pszType = (poField->GetSubType() != OFSTNone) ? CPLSPrintf( "%s(%s)", poField->GetFieldTypeName(poField->GetType()), poField->GetFieldSubTypeName(poField->GetSubType())) : poField->GetFieldTypeName(poField->GetType()); printf("%s: %s (%d.%d)", poField->GetNameRef(), pszType, poField->GetWidth(), poField->GetPrecision()); if( !poField->IsNullable() ) printf(" NOT NULL"); if( poField->GetDefault() != nullptr ) printf(" DEFAULT %s", poField->GetDefault()); printf("\n"); } } /* -------------------------------------------------------------------- */ /* Read, and dump features. */ /* -------------------------------------------------------------------- */ if( nFetchFID == OGRNullFID && !bSummaryOnly ) { OGRFeature *poFeature = nullptr; while( (poFeature = poLayer->GetNextFeature()) != nullptr ) { if( !bSuperQuiet ) poFeature->DumpReadable(nullptr, papszOptions); OGRFeature::DestroyFeature(poFeature); } } else if( nFetchFID != OGRNullFID ) { OGRFeature *poFeature = poLayer->GetFeature(nFetchFID); if( poFeature == nullptr ) { printf("Unable to locate feature id " CPL_FRMT_GIB " on this layer.\n", nFetchFID); } else { poFeature->DumpReadable(nullptr, papszOptions); OGRFeature::DestroyFeature(poFeature); } } }
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; }