OGRErr OGRS57Layer::GetExtent( OGREnvelope *psExtent, int bForce ) { if( GetGeomType() == wkbNone ) return OGRERR_FAILURE; return poDS->GetDSExtent( psExtent, bForce ); }
OGRFeatureDefn *OGRFeatureDefn::Clone() { OGRFeatureDefn *poCopy; poCopy = new OGRFeatureDefn( GetName() ); poCopy->SetGeomType( GetGeomType() ); for( int i = 0; i < GetFieldCount(); i++ ) poCopy->AddFieldDefn( GetFieldDefn( i ) ); return poCopy; }
OGRErr OGRSQLiteSelectLayer::GetExtent(OGREnvelope *psExtent, int bForce) { if (GetGeomType() == wkbNone) return OGRERR_FAILURE; /* Caching of extent by SQL string is interesting to speed-up the */ /* establishment of the WFS GetCapabilities document for a MapServer mapfile */ /* which has several layers, only differing by scale rules */ const OGREnvelope* psCachedExtent = poDS->GetEnvelopeFromSQL(osSQLBase); if (psCachedExtent) { memcpy(psExtent, psCachedExtent, sizeof(*psCachedExtent)); return OGRERR_NONE; } CPLString osSQLCommand = osSQLBase; /* ORDER BY are costly to evaluate and are not necessary to establish */ /* the layer extent. */ size_t nOrderByPos = osSQLCommand.ifind(" ORDER BY "); if( osSQLCommand.ifind("SELECT ") == 0 && nOrderByPos != std::string::npos && osSQLCommand.ifind(" LIMIT ") == std::string::npos && osSQLCommand.ifind(" UNION ") == std::string::npos && osSQLCommand.ifind(" INTERSECT ") == std::string::npos && osSQLCommand.ifind(" EXCEPT ") == std::string::npos) { osSQLCommand.resize(nOrderByPos); OGRLayer* poTmpLayer = poDS->ExecuteSQL(osSQLCommand.c_str(), NULL, NULL); if (poTmpLayer) { OGRErr eErr = poTmpLayer->GetExtent(psExtent, bForce); poDS->ReleaseResultSet(poTmpLayer); return eErr; } } OGRErr eErr = OGRSQLiteLayer::GetExtent(psExtent, bForce); if (eErr == OGRERR_NONE && poDS->GetUpdate() == FALSE) poDS->SetEnvelopeForSQL(osSQLBase, *psExtent); return eErr; }
OGRErr OGRGMLLayer::GetExtent(OGREnvelope *psExtent, int bForce ) { double dfXMin, dfXMax, dfYMin, dfYMax; if( GetGeomType() == wkbNone ) return OGRERR_FAILURE; if( poFClass != NULL && poFClass->GetExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax ) ) { psExtent->MinX = dfXMin; psExtent->MaxX = dfXMax; psExtent->MinY = dfYMin; psExtent->MaxY = dfYMax; return OGRERR_NONE; } else return OGRLayer::GetExtent( psExtent, bForce ); }
OGRErr OGRCARTODBTableLayer::ICreateFeature( OGRFeature *poFeature ) { int i; if( bDeferedCreation ) { if( RunDeferedCreationIfNecessary() != OGRERR_NONE ) return OGRERR_FAILURE; } GetLayerDefn(); int bHasUserFieldMatchingFID = FALSE; if( osFIDColName.size() ) bHasUserFieldMatchingFID = poFeatureDefn->GetFieldIndex(osFIDColName) >= 0; if (!poDS->IsReadWrite()) { CPLError(CE_Failure, CPLE_AppDefined, "Operation not available in read-only mode"); return OGRERR_FAILURE; } CPLString osSQL; int bHasJustGotNextFID = FALSE; if( !bHasUserFieldMatchingFID && bInDeferedInsert && nNextFID < 0 && osFIDColName.size() ) { osSQL.Printf("SELECT nextval('%s') AS nextid", OGRCARTODBEscapeLiteral(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str())).c_str()); json_object* poObj = poDS->RunSQL(osSQL); json_object* poRowObj = OGRCARTODBGetSingleRow(poObj); if( poRowObj != NULL ) { json_object* poID = json_object_object_get(poRowObj, "nextid"); if( poID != NULL && json_object_get_type(poID) == json_type_int ) { nNextFID = json_object_get_int64(poID); bHasJustGotNextFID = TRUE; } } if( poObj != NULL ) json_object_put(poObj); } osSQL.Printf("INSERT INTO %s ", OGRCARTODBEscapeIdentifier(osName).c_str()); int bMustComma = FALSE; for(i = 0; i < poFeatureDefn->GetFieldCount(); i++) { if( !poFeature->IsFieldSet(i) ) continue; if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetFieldDefn(i)->GetNameRef()); } for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++) { if( poFeature->GetGeomFieldRef(i) == NULL ) continue; if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(poFeatureDefn->GetGeomFieldDefn(i)->GetNameRef()); } if( !bHasUserFieldMatchingFID && osFIDColName.size() && (poFeature->GetFID() != OGRNullFID || nNextFID >= 0) ) { if( bMustComma ) osSQL += ", "; else { osSQL += "("; bMustComma = TRUE; } osSQL += OGRCARTODBEscapeIdentifier(osFIDColName); } if( !bMustComma ) osSQL += " DEFAULT VALUES"; else { osSQL += ") VALUES ("; bMustComma = FALSE; for(i = 0; i < poFeatureDefn->GetFieldCount(); i++) { if( !poFeature->IsFieldSet(i) ) continue; if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; OGRFieldType eType = poFeatureDefn->GetFieldDefn(i)->GetType(); if( eType == OFTString || eType == OFTDateTime || eType == OFTDate || eType == OFTTime ) { osSQL += "'"; osSQL += OGRCARTODBEscapeLiteral(poFeature->GetFieldAsString(i)); osSQL += "'"; } else if( (eType == OFTInteger || eType == OFTInteger64) && poFeatureDefn->GetFieldDefn(i)->GetSubType() == OFSTBoolean ) { osSQL += poFeature->GetFieldAsInteger(i) ? "'t'" : "'f'"; } else osSQL += poFeature->GetFieldAsString(i); } for(i = 0; i < poFeatureDefn->GetGeomFieldCount(); i++) { OGRGeometry* poGeom = poFeature->GetGeomFieldRef(i); if( poGeom == NULL ) continue; if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; OGRCartoDBGeomFieldDefn* poGeomFieldDefn = (OGRCartoDBGeomFieldDefn *)poFeatureDefn->GetGeomFieldDefn(i); int nSRID = poGeomFieldDefn->nSRID; if( nSRID == 0 ) nSRID = 4326; char* pszEWKB; if( wkbFlatten(poGeom->getGeometryType()) == wkbPolygon && wkbFlatten(GetGeomType()) == wkbMultiPolygon ) { OGRMultiPolygon* poNewGeom = new OGRMultiPolygon(); poNewGeom->addGeometry(poGeom); pszEWKB = OGRGeometryToHexEWKB(poNewGeom, nSRID, FALSE); delete poNewGeom; } else pszEWKB = OGRGeometryToHexEWKB(poGeom, nSRID, FALSE); osSQL += "'"; osSQL += pszEWKB; osSQL += "'"; CPLFree(pszEWKB); } if( !bHasUserFieldMatchingFID ) { if( osFIDColName.size() && nNextFID >= 0 ) { if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; if( bHasJustGotNextFID ) { osSQL += CPLSPrintf(CPL_FRMT_GIB, nNextFID); } else { osSQL += CPLSPrintf("nextval('%s')", OGRCARTODBEscapeLiteral(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str())).c_str()); } poFeature->SetFID(nNextFID); nNextFID ++; } else if( osFIDColName.size() && poFeature->GetFID() != OGRNullFID ) { if( bMustComma ) osSQL += ", "; else bMustComma = TRUE; osSQL += CPLSPrintf(CPL_FRMT_GIB, poFeature->GetFID()); } } osSQL += ")"; } if( bInDeferedInsert ) { OGRErr eRet = OGRERR_NONE; if( osDeferedInsertSQL.size() != 0 && (int)osDeferedInsertSQL.size() + (int)osSQL.size() > nMaxChunkSize ) { osDeferedInsertSQL = "BEGIN;" + osDeferedInsertSQL + "COMMIT;"; json_object* poObj = poDS->RunSQL(osDeferedInsertSQL); if( poObj != NULL ) json_object_put(poObj); else { bInDeferedInsert = FALSE; eRet = OGRERR_FAILURE; } osDeferedInsertSQL = ""; } osDeferedInsertSQL += osSQL; osDeferedInsertSQL += ";"; if( (int)osDeferedInsertSQL.size() > nMaxChunkSize ) { osDeferedInsertSQL = "BEGIN;" + osDeferedInsertSQL + "COMMIT;"; json_object* poObj = poDS->RunSQL(osDeferedInsertSQL); if( poObj != NULL ) json_object_put(poObj); else { bInDeferedInsert = FALSE; eRet = OGRERR_FAILURE; } osDeferedInsertSQL = ""; } return eRet; } if( osFIDColName.size() ) { osSQL += " RETURNING "; osSQL += OGRCARTODBEscapeIdentifier(osFIDColName); json_object* poObj = poDS->RunSQL(osSQL); json_object* poRowObj = OGRCARTODBGetSingleRow(poObj); if( poRowObj == NULL ) { if( poObj != NULL ) json_object_put(poObj); return OGRERR_FAILURE; } json_object* poID = json_object_object_get(poRowObj, osFIDColName); if( poID != NULL && json_object_get_type(poID) == json_type_int ) { poFeature->SetFID(json_object_get_int64(poID)); } if( poObj != NULL ) json_object_put(poObj); return OGRERR_NONE; } else { OGRErr eRet = OGRERR_FAILURE; json_object* poObj = poDS->RunSQL(osSQL); if( poObj != NULL ) { json_object* poTotalRows = json_object_object_get(poObj, "total_rows"); if( poTotalRows != NULL && json_object_get_type(poTotalRows) == json_type_int ) { int nTotalRows = json_object_get_int(poTotalRows); if( nTotalRows == 1 ) { eRet = OGRERR_NONE; } } json_object_put(poObj); } return eRet; } }
OGRErr OGRCARTODBTableLayer::RunDeferedCreationIfNecessary() { if( !bDeferedCreation ) return OGRERR_NONE; bDeferedCreation = FALSE; CPLString osSQL; osSQL.Printf("CREATE TABLE %s ( %s SERIAL,", OGRCARTODBEscapeIdentifier(osName).c_str(), osFIDColName.c_str()); int nSRID = 0; OGRwkbGeometryType eGType = GetGeomType(); if( eGType != wkbNone ) { CPLString osGeomType = OGRToOGCGeomType(eGType); if( wkbHasZ(eGType) ) osGeomType += "Z"; OGRCartoDBGeomFieldDefn *poFieldDefn = (OGRCartoDBGeomFieldDefn *)poFeatureDefn->GetGeomFieldDefn(0); nSRID = poFieldDefn->nSRID; osSQL += CPLSPrintf("%s GEOMETRY(%s, %d)%s, %s GEOMETRY(%s, %d),", "the_geom", osGeomType.c_str(), nSRID, (!poFieldDefn->IsNullable()) ? " NOT NULL" : "", "the_geom_webmercator", osGeomType.c_str(), 3857); } for( int i = 0; i < poFeatureDefn->GetFieldCount(); i++ ) { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i); if( strcmp(poFieldDefn->GetNameRef(), osFIDColName) != 0 ) { osSQL += OGRCARTODBEscapeIdentifier(poFieldDefn->GetNameRef()); osSQL += " "; osSQL += OGRPGCommonLayerGetType(*poFieldDefn, FALSE, TRUE); if( !poFieldDefn->IsNullable() ) osSQL += " NOT NULL"; if( poFieldDefn->GetDefault() != NULL && !poFieldDefn->IsDefaultDriverSpecific() ) { osSQL += " DEFAULT "; osSQL += poFieldDefn->GetDefault(); } osSQL += ","; } } osSQL += CPLSPrintf("PRIMARY KEY (%s) )", osFIDColName.c_str()); CPLString osSeqName(OGRCARTODBEscapeIdentifier(CPLSPrintf("%s_%s_seq", osName.c_str(), osFIDColName.c_str()))); osSQL += ";"; osSQL += CPLSPrintf("DROP SEQUENCE IF EXISTS %s CASCADE", osSeqName.c_str()); osSQL += ";"; osSQL += CPLSPrintf("CREATE SEQUENCE %s START 1", osSeqName.c_str()); osSQL += ";"; osSQL += CPLSPrintf("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval('%s')", OGRCARTODBEscapeIdentifier(osName).c_str(), osFIDColName.c_str(), osSeqName.c_str()); json_object* poObj = poDS->RunSQL(osSQL); if( poObj == NULL ) return OGRERR_FAILURE; json_object_put(poObj); if( bCartoDBify ) { if( nSRID != 4326 ) { if( eGType != wkbNone ) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot register table in dashboard with " "cdb_cartodbfytable() since its SRS is not EPSG:4326"); } } else { if( poDS->GetCurrentSchema() == "public" ) osSQL.Printf("SELECT cdb_cartodbfytable('%s')", OGRCARTODBEscapeLiteral(osName).c_str()); else osSQL.Printf("SELECT cdb_cartodbfytable('%s', '%s')", OGRCARTODBEscapeLiteral(poDS->GetCurrentSchema()).c_str(), OGRCARTODBEscapeLiteral(osName).c_str()); poObj = poDS->RunSQL(osSQL); if( poObj == NULL ) return OGRERR_FAILURE; json_object_put(poObj); } } return OGRERR_NONE; }
OGRFeature *OGRGMLLayer::GetNextFeature() { if (bWriter) { CPLError(CE_Failure, CPLE_NotSupported, "Cannot read features when writing a GML file"); return NULL; } if( poDS->GetLastReadLayer() != this ) { if( poDS->GetReadMode() != INTERLEAVED_LAYERS ) ResetReading(); poDS->SetLastReadLayer(this); } /* ==================================================================== */ /* Loop till we find and translate a feature meeting all our */ /* requirements. */ /* ==================================================================== */ while( true ) { GMLFeature *poGMLFeature = NULL; OGRGeometry *poGeom = NULL; poGMLFeature = poDS->PeekStoredGMLFeature(); if (poGMLFeature != NULL) poDS->SetStoredGMLFeature(NULL); else { poGMLFeature = poDS->GetReader()->NextFeature(); if( poGMLFeature == NULL ) return NULL; // We count reading low level GML features as a feature read for // work checking purposes, though at least we didn't necessary // have to turn it into an OGRFeature. m_nFeaturesRead++; } /* -------------------------------------------------------------------- */ /* Is it of the proper feature class? */ /* -------------------------------------------------------------------- */ if( poGMLFeature->GetClass() != poFClass ) { if( poDS->GetReadMode() == INTERLEAVED_LAYERS || (poDS->GetReadMode() == SEQUENTIAL_LAYERS && iNextGMLId != 0) ) { CPLAssert(poDS->PeekStoredGMLFeature() == NULL); poDS->SetStoredGMLFeature(poGMLFeature); return NULL; } else { delete poGMLFeature; continue; } } /* -------------------------------------------------------------------- */ /* Extract the fid: */ /* -Assumes the fids are non-negative integers with an optional */ /* prefix */ /* -If a prefix differs from the prefix of the first feature from */ /* the poDS then the fids from the poDS are ignored and are */ /* assigned serially thereafter */ /* -------------------------------------------------------------------- */ GIntBig nFID = -1; const char * pszGML_FID = poGMLFeature->GetFID(); if( bInvalidFIDFound ) { nFID = iNextGMLId++; } else if( pszGML_FID == NULL ) { bInvalidFIDFound = true; nFID = iNextGMLId++; } else if( iNextGMLId == 0 ) { int j = 0; int i = static_cast<int>(strlen( pszGML_FID ))-1; while( i >= 0 && pszGML_FID[i] >= '0' && pszGML_FID[i] <= '9' && j<20) i--, j++; /* i points the last character of the fid */ if( i >= 0 && j < 20 && pszFIDPrefix == NULL) { pszFIDPrefix = (char *) CPLMalloc(i+2); pszFIDPrefix[i+1] = '\0'; strncpy(pszFIDPrefix, pszGML_FID, i+1); } /* pszFIDPrefix now contains the prefix or NULL if no prefix is found */ if( j < 20 && sscanf(pszGML_FID+i+1, CPL_FRMT_GIB, &nFID)==1) { if( iNextGMLId <= nFID ) iNextGMLId = nFID + 1; } else { bInvalidFIDFound = true; nFID = iNextGMLId++; } } else if( iNextGMLId != 0 ) { const char* pszFIDPrefix_notnull = pszFIDPrefix; if (pszFIDPrefix_notnull == NULL) pszFIDPrefix_notnull = ""; int nLenPrefix = static_cast<int>(strlen(pszFIDPrefix_notnull)); if( strncmp(pszGML_FID, pszFIDPrefix_notnull, nLenPrefix) == 0 && strlen(pszGML_FID+nLenPrefix) < 20 && sscanf(pszGML_FID+nLenPrefix, CPL_FRMT_GIB, &nFID) == 1 ) { /* fid with the prefix. Using its numerical part */ if( iNextGMLId < nFID ) iNextGMLId = nFID + 1; } else { /* fid without the aforementioned prefix or a valid numerical part */ bInvalidFIDFound = true; nFID = iNextGMLId++; } } /* -------------------------------------------------------------------- */ /* Does it satisfy the spatial query, if there is one? */ /* -------------------------------------------------------------------- */ OGRGeometry** papoGeometries = NULL; const CPLXMLNode* const * papsGeometry = poGMLFeature->GetGeometryList(); if( poFeatureDefn->GetGeomFieldCount() > 1 ) { papoGeometries = (OGRGeometry**) CPLCalloc( poFeatureDefn->GetGeomFieldCount(), sizeof(OGRGeometry*) ); const char* pszSRSName = poDS->GetGlobalSRSName(); for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ ) { const CPLXMLNode* psGeom = poGMLFeature->GetGeometryRef(i); if( psGeom != NULL ) { const CPLXMLNode* myGeometryList[2]; myGeometryList[0] = psGeom; myGeometryList[1] = NULL; poGeom = GML_BuildOGRGeometryFromList(myGeometryList, true, poDS->GetInvertAxisOrderIfLatLong(), pszSRSName, poDS->GetConsiderEPSGAsURN(), poDS->GetSecondaryGeometryOption(), hCacheSRS, bFaceHoleNegative ); /* Do geometry type changes if needed to match layer geometry type */ if (poGeom != NULL) { papoGeometries[i] = OGRGeometryFactory::forceTo(poGeom, poFeatureDefn->GetGeomFieldDefn(i)->GetType()); poGeom = NULL; } else // We assume the createFromGML() function would have already // reported the error. { for( i=0; i < poFeatureDefn->GetGeomFieldCount(); i++) { delete papoGeometries[i]; } CPLFree(papoGeometries); delete poGMLFeature; return NULL; } } } if( m_poFilterGeom != NULL && m_iGeomFieldFilter >= 0 && m_iGeomFieldFilter < poFeatureDefn->GetGeomFieldCount() && papoGeometries[m_iGeomFieldFilter] && !FilterGeometry( papoGeometries[m_iGeomFieldFilter] ) ) { for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ ) { delete papoGeometries[i]; } CPLFree(papoGeometries); delete poGMLFeature; continue; } } else if (papsGeometry[0] != NULL) { const char* pszSRSName = poDS->GetGlobalSRSName(); poGeom = GML_BuildOGRGeometryFromList(papsGeometry, true, poDS->GetInvertAxisOrderIfLatLong(), pszSRSName, poDS->GetConsiderEPSGAsURN(), poDS->GetSecondaryGeometryOption(), hCacheSRS, bFaceHoleNegative ); /* Do geometry type changes if needed to match layer geometry type */ if (poGeom != NULL) { poGeom = OGRGeometryFactory::forceTo(poGeom, GetGeomType()); } else // We assume the createFromGML() function would have already // reported the error. { delete poGMLFeature; return NULL; } if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) ) { delete poGMLFeature; delete poGeom; continue; } } /* -------------------------------------------------------------------- */ /* Convert the whole feature into an OGRFeature. */ /* -------------------------------------------------------------------- */ int iField; int iDstField = 0; OGRFeature *poOGRFeature = new OGRFeature( poFeatureDefn ); poOGRFeature->SetFID( nFID ); if (poDS->ExposeId()) { if (pszGML_FID) poOGRFeature->SetField( iDstField, pszGML_FID ); iDstField ++; } int nPropertyCount = poFClass->GetPropertyCount(); for( iField = 0; iField < nPropertyCount; iField++, iDstField ++ ) { const GMLProperty *psGMLProperty = poGMLFeature->GetProperty( iField ); if( psGMLProperty == NULL || psGMLProperty->nSubProperties == 0 ) continue; switch( poFClass->GetProperty(iField)->GetType() ) { case GMLPT_Real: { poOGRFeature->SetField( iDstField, CPLAtof(psGMLProperty->papszSubProperties[0]) ); } break; case GMLPT_IntegerList: { int nCount = psGMLProperty->nSubProperties; int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount ); for( int i = 0; i < nCount; i++ ) panIntList[i] = atoi(psGMLProperty->papszSubProperties[i]); poOGRFeature->SetField( iDstField, nCount, panIntList ); CPLFree( panIntList ); } break; case GMLPT_Integer64List: { int nCount = psGMLProperty->nSubProperties; GIntBig *panIntList = (GIntBig *) CPLMalloc(sizeof(GIntBig) * nCount ); for( int i = 0; i < nCount; i++ ) panIntList[i] = CPLAtoGIntBig(psGMLProperty->papszSubProperties[i]); poOGRFeature->SetField( iDstField, nCount, panIntList ); CPLFree( panIntList ); } break; case GMLPT_RealList: { int nCount = psGMLProperty->nSubProperties; double *padfList = (double *)CPLMalloc(sizeof(double)*nCount); for( int i = 0; i < nCount; i++ ) padfList[i] = CPLAtof(psGMLProperty->papszSubProperties[i]); poOGRFeature->SetField( iDstField, nCount, padfList ); CPLFree( padfList ); } break; case GMLPT_StringList: case GMLPT_FeaturePropertyList: { poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties ); } break; case GMLPT_Boolean: { if( strcmp(psGMLProperty->papszSubProperties[0], "true") == 0 || strcmp(psGMLProperty->papszSubProperties[0], "1") == 0 ) { poOGRFeature->SetField( iDstField, 1); } else if( strcmp(psGMLProperty->papszSubProperties[0], "false") == 0 || strcmp(psGMLProperty->papszSubProperties[0], "0") == 0 ) { poOGRFeature->SetField( iDstField, 0); } else poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties[0] ); break; } case GMLPT_BooleanList: { int nCount = psGMLProperty->nSubProperties; int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount ); for( int i = 0; i < nCount; i++ ) { panIntList[i] = ( strcmp(psGMLProperty->papszSubProperties[i], "true") == 0 || strcmp(psGMLProperty->papszSubProperties[i], "1") == 0 ); } poOGRFeature->SetField( iDstField, nCount, panIntList ); CPLFree( panIntList ); break; } default: poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties[0] ); break; } } delete poGMLFeature; poGMLFeature = NULL; /* Assign the geometry before the attribute filter because */ /* the attribute filter may use a special field like OGR_GEOMETRY */ if( papoGeometries != NULL ) { for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ ) { poOGRFeature->SetGeomFieldDirectly( i, papoGeometries[i] ); } CPLFree(papoGeometries); papoGeometries = NULL; } else poOGRFeature->SetGeometryDirectly( poGeom ); /* Assign SRS */ for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ ) { poGeom = poOGRFeature->GetGeomFieldRef(i); if( poGeom != NULL ) { OGRSpatialReference* poSRS = poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef(); if (poSRS != NULL) poGeom->assignSpatialReference(poSRS); } } /* -------------------------------------------------------------------- */ /* Test against the attribute query. */ /* -------------------------------------------------------------------- */ if( m_poAttrQuery != NULL && !m_poAttrQuery->Evaluate( poOGRFeature ) ) { delete poOGRFeature; continue; } /* -------------------------------------------------------------------- */ /* Wow, we got our desired feature. Return it. */ /* -------------------------------------------------------------------- */ return poOGRFeature; } return NULL; }
OGRFeatureDefn *OGRUnionLayer::GetLayerDefn() { if( poFeatureDefn != NULL ) return poFeatureDefn; poFeatureDefn = new OGRFeatureDefn( osName ); poFeatureDefn->Reference(); int iCompareFirstIndex = 0; if( osSourceLayerFieldName.size() ) { OGRFieldDefn oField(osSourceLayerFieldName, OFTString); poFeatureDefn->AddFieldDefn(&oField); iCompareFirstIndex = 1; } if( eFieldStrategy == FIELD_SPECIFIED ) { for(int i = 0; i < nFields; i++) poFeatureDefn->AddFieldDefn(papoFields[i]); } else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER ) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn(); for(int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++) poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i)); } else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS ) { for(int iLayer = 0; iLayer < nSrcLayers; iLayer++) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); /* Add any field that is found in the source layers */ for(int 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); } } } } 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)); /* Remove any field that is not found in the source layers */ for(int iLayer = 1; iLayer < nSrcLayers; iLayer++) { OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iLayer]->GetLayerDefn(); for(i = iCompareFirstIndex; i < poFeatureDefn->GetFieldCount();) { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i); int nSrcIndex = poSrcFeatureDefn->GetFieldIndex( poFieldDefn->GetNameRef()); if( nSrcIndex < 0 ) { poFeatureDefn->DeleteFieldDefn(i); } else { OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(nSrcIndex); MergeFieldDefn(poFieldDefn, poSrcFieldDefn); i ++; } } } } poFeatureDefn->SetGeomType(GetGeomType()); return poFeatureDefn; }