int OGRGFTResultLayer::RunSQL() { CPLString osChangedSQL(osSQL); int bHasSetLimit = FALSE; OGRGFTTableLayer* poTableLayer = NULL; OGRFeatureDefn* poTableDefn = NULL; CPLString osTableId; if (EQUALN(osSQL.c_str(), "SELECT", 6)) { size_t nPosFROM = osSQL.ifind(" FROM "); if (nPosFROM == std::string::npos) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed. Missing FROM in SELECT"); return FALSE; } CPLString osReminder; nPosFROM += 6; osTableId = OGRGFTExtractTableID(osSQL.c_str() + nPosFROM, osReminder); poTableLayer = (OGRGFTTableLayer*) poDS->GetLayerByName(osTableId); if (poTableLayer != NULL) poTableDefn = poTableLayer->GetLayerDefn(); if (poTableLayer != NULL && poTableLayer->GetTableId().size() && !EQUAL(osTableId, poTableLayer->GetTableId())) { osChangedSQL = osSQL; osChangedSQL.resize(nPosFROM); osChangedSQL += poTableLayer->GetTableId(); osChangedSQL += osReminder; osSQL = osChangedSQL; CPLDebug("GFT", "Patching table name (%s) to table id (%s)", osTableId.c_str(), poTableLayer->GetTableId().c_str()); } int nFeaturesToFetch = GetFeaturesToFetch(); if (osSQL.ifind(" OFFSET ") == std::string::npos && osSQL.ifind(" LIMIT ") == std::string::npos && nFeaturesToFetch > 0) { osChangedSQL += CPLSPrintf(" LIMIT %d", nFeaturesToFetch); bHasSetLimit = TRUE; } } else { bGotAllRows = bEOF = TRUE; poFeatureDefn->SetGeomType( wkbNone ); } CPLHTTPResult * psResult = poDS->RunSQL(osChangedSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLError(CE_Failure, CPLE_AppDefined, "RunSQL() failed"); CPLHTTPDestroyResult(psResult); return FALSE; } if (EQUALN(osSQL.c_str(), "SELECT", 6) || EQUAL(osSQL.c_str(), "SHOW TABLES") || EQUALN(osSQL.c_str(), "DESCRIBE", 8)) { ParseCSVResponse(pszLine, aosRows); if (aosRows.size() > 0) { char** papszTokens = OGRGFTCSVSplitLine(aosRows[0], ','); for(int i=0;papszTokens && papszTokens[i];i++) { CPLString osLaunderedColName(LaunderColName(papszTokens[i])); int iIndex = (poTableDefn) ? poTableDefn->GetFieldIndex(osLaunderedColName) : -1; if (iIndex >= 0) { poFeatureDefn->AddFieldDefn(poTableDefn->GetFieldDefn(iIndex)); if (iIndex == poTableLayer->GetGeometryFieldIndex()) iGeometryField = i; if (iIndex == poTableLayer->GetLatitudeFieldIndex()) iLatitudeField = i; if (iIndex == poTableLayer->GetLongitudeFieldIndex()) iLongitudeField = i; } else { OGRFieldType eType = OFTString; if (EQUAL(osLaunderedColName, "COUNT()")) eType = OFTInteger; OGRFieldDefn oFieldDefn(osLaunderedColName, eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } } CSLDestroy(papszTokens); aosRows.erase(aosRows.begin()); } if (iLatitudeField >= 0 && iLongitudeField >= 0) { iGeometryField = iLatitudeField; poFeatureDefn->SetGeomType( wkbPoint ); } if (bHasSetLimit) bGotAllRows = bEOF = (int)aosRows.size() < GetFeaturesToFetch(); else bGotAllRows = bEOF = TRUE; } CPLHTTPDestroyResult(psResult); return TRUE; }
/********************************************************************** * CreateIndex() * * Create index for specified field in an existing TAB dataset. **********************************************************************/ static int CreateIndex(const char *pszSrcFname, const char *pszField) { IMapInfoFile *poSrcFile = NULL; int nFeatureId, iField; TABFeature *poFeature; TABINDFile *poINDFile; /*--------------------------------------------------------------------- * Try to open source file *--------------------------------------------------------------------*/ if ((poSrcFile = IMapInfoFile::SmartOpen(pszSrcFname)) == NULL) { printf("Failed to open %s\n", pszSrcFname); return -1; } if (poSrcFile->GetFileClass() != TABFC_TABFile) { printf("Indexes cannot be added to this type of TAB datasets\n"); poSrcFile->Close(); delete poSrcFile; return -1; } /*--------------------------------------------------------------------- * Make sure field exists and is not already indexed *--------------------------------------------------------------------*/ OGRFeatureDefn *poDefn = poSrcFile->GetLayerDefn(); if ( poDefn == NULL || (iField = poDefn->GetFieldIndex(pszField)) == -1 || poSrcFile->IsFieldIndexed(iField)) { printf("Cannot create index: field '%s' not found or is already indexed.\n", pszField); poSrcFile->Close(); delete poSrcFile; return -1; } /*--------------------------------------------------------------------- * Things seem OK... open IND file for update * (Note that TABINDFile automagically adjusts file extension) *--------------------------------------------------------------------*/ poINDFile = new TABINDFile; if ( poINDFile->Open(pszSrcFname, "r+", TRUE) != 0 && poINDFile->Open(pszSrcFname, "w", TRUE) != 0) { printf("Unable to create IND file for %s.\n", pszSrcFname); delete poINDFile; poSrcFile->Close(); delete poSrcFile; return -1; } int nNewIndexNo = -1; OGRFieldDefn *poFieldDefn = poDefn->GetFieldDefn(iField); TABFieldType eFieldType = poSrcFile->GetNativeFieldType(iField); if (poFieldDefn == NULL || (nNewIndexNo = poINDFile->CreateIndex(eFieldType, poFieldDefn->GetWidth()) ) < 1) { // Failed... an error has already been reported. delete poINDFile; poSrcFile->Close(); delete poSrcFile; return -1; } printf("Index number %d will be created for field %s...\n\n" "This program does not update the TAB header file (yet!) so you \n" "should edit %s and add 'Index %d' at the end of the definition \n" "of field %s.\n\n", nNewIndexNo, pszField, pszSrcFname, nNewIndexNo, pszField); /*--------------------------------------------------------------------- * Add index entries until we reach EOF *--------------------------------------------------------------------*/ nFeatureId = -1; while ( (nFeatureId = poSrcFile->GetNextFeatureId(nFeatureId)) != -1 ) { poFeature = poSrcFile->GetFeatureRef(nFeatureId); if (poFeature) { GByte *pKey = NULL; switch(eFieldType) { case TABFChar: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsString(iField)); break; case TABFInteger: case TABFSmallInt: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsInteger(iField)); break; case TABFDecimal: case TABFFloat: case TABFLogical: pKey = poINDFile->BuildKey(nNewIndexNo, poFeature->GetFieldAsDouble(iField)); break; default: case TABFDate: CPLAssert(FALSE); // Unsupported for now. } if (poINDFile->AddEntry(nNewIndexNo, pKey, nFeatureId) != 0) return -1; } else break; // GetFeatureRef() failed: Abort the loop } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ poINDFile->Close(); delete poINDFile; poSrcFile->Close(); delete poSrcFile; MITABFreeCoordSysTable(); return 0; }
bool OGRGeoJSONReader::GenerateFeatureDefn( json_object* poObj ) { OGRFeatureDefn* poDefn = poLayer_->GetLayerDefn(); CPLAssert( NULL != poDefn ); bool bSuccess = false; /* -------------------------------------------------------------------- */ /* Read collection of properties. */ /* -------------------------------------------------------------------- */ json_object* poObjProps = NULL; poObjProps = OGRGeoJSONFindMemberByName( poObj, "properties" ); if( NULL != poObjProps && json_object_get_type(poObjProps) == json_type_object ) { if (bIsGeocouchSpatiallistFormat) { poObjProps = json_object_object_get(poObjProps, "properties"); if( NULL == poObjProps || json_object_get_type(poObjProps) != json_type_object ) { return true; } } json_object_iter it; it.key = NULL; it.val = NULL; it.entry = NULL; json_object_object_foreachC( poObjProps, it ) { int nFldIndex = poDefn->GetFieldIndex( it.key ); if( -1 == nFldIndex ) { /* Detect the special kind of GeoJSON output by a spatiallist of GeoCouch */ /* such as http://gd.iriscouch.com/cphosm/_design/geo/_rewrite/data?bbox=12.53%2C55.73%2C12.54%2C55.73 */ if (strcmp(it.key, "_id") == 0) bFoundId = true; else if (bFoundId && strcmp(it.key, "_rev") == 0) bFoundRev = true; else if (bFoundRev && strcmp(it.key, "type") == 0 && it.val != NULL && json_object_get_type(it.val) == json_type_string && strcmp(json_object_get_string(it.val), "Feature") == 0) bFoundTypeFeature = true; else if (bFoundTypeFeature && strcmp(it.key, "properties") == 0 && it.val != NULL && json_object_get_type(it.val) == json_type_object) { if (bFlattenGeocouchSpatiallistFormat < 0) bFlattenGeocouchSpatiallistFormat = CSLTestBoolean( CPLGetConfigOption("GEOJSON_FLATTEN_GEOCOUCH", "TRUE")); if (bFlattenGeocouchSpatiallistFormat) { poDefn->DeleteFieldDefn(poDefn->GetFieldIndex("type")); bIsGeocouchSpatiallistFormat = true; return GenerateFeatureDefn(poObj); } } OGRFieldDefn fldDefn( it.key, GeoJSONPropertyToFieldType( it.val ) ); poDefn->AddFieldDefn( &fldDefn ); } else { OGRFieldDefn* poFDefn = poDefn->GetFieldDefn(nFldIndex); OGRFieldType eType = poFDefn->GetType(); if( eType == OFTInteger ) { OGRFieldType eNewType = GeoJSONPropertyToFieldType( it.val ); if( eNewType == OFTReal ) poFDefn->SetType(eNewType); } } } bSuccess = true; // SUCCESS }
/********************************************************************** * TABSeamless::OpenForRead() * * Open for reading * * Returns 0 on success, -1 on error. **********************************************************************/ int TABSeamless::OpenForRead(const char *pszFname, GBool bTestOpenNoError /*= FALSE*/ ) { int nFnameLen = 0; m_eAccessMode = TABRead; /*----------------------------------------------------------------- * Read main .TAB (text) file *----------------------------------------------------------------*/ m_pszFname = CPLStrdup(pszFname); #ifndef _WIN32 /*----------------------------------------------------------------- * On Unix, make sure extension uses the right cases * We do it even for write access because if a file with the same * extension already exists we want to overwrite it. *----------------------------------------------------------------*/ TABAdjustFilenameExtension(m_pszFname); #endif /*----------------------------------------------------------------- * Open .TAB file... since it's a small text file, we will just load * it as a stringlist in memory. *----------------------------------------------------------------*/ char **papszTABFile = TAB_CSLLoad(m_pszFname); if (papszTABFile == NULL) { if (!bTestOpenNoError) { CPLError(CE_Failure, CPLE_FileIO, "Failed opening %s.", m_pszFname); } CPLFree(m_pszFname); CSLDestroy(papszTABFile); return -1; } /*------------------------------------------------------------- * Look for a metadata line with "\IsSeamless" = "TRUE". * If there is no such line, then we may have a valid .TAB file, * but we do not support it in this class. *------------------------------------------------------------*/ GBool bSeamlessFound = FALSE; for (int i=0; !bSeamlessFound && papszTABFile && papszTABFile[i]; i++) { const char *pszStr = papszTABFile[i]; while(*pszStr != '\0' && isspace(*pszStr)) pszStr++; if (EQUALN(pszStr, "\"\\IsSeamless\" = \"TRUE\"", 21)) bSeamlessFound = TRUE; } CSLDestroy(papszTABFile); if ( !bSeamlessFound ) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "%s does not appear to be a Seamless TAB File. " "This type of .TAB file cannot be read by this library.", m_pszFname); else CPLErrorReset(); CPLFree(m_pszFname); return -1; } /*----------------------------------------------------------------- * OK, this appears to be a valid seamless TAB dataset... * Extract the path component from the main .TAB filename * to build the filename of the base tables *----------------------------------------------------------------*/ m_pszPath = CPLStrdup(m_pszFname); nFnameLen = strlen(m_pszPath); for( ; nFnameLen > 0; nFnameLen--) { if (m_pszPath[nFnameLen-1] == '/' || m_pszPath[nFnameLen-1] == '\\' ) { break; } m_pszPath[nFnameLen-1] = '\0'; } /*----------------------------------------------------------------- * Open the main Index table and look for the "Table" field that * should contain the path to the base table for each rectangle MBR *----------------------------------------------------------------*/ m_poIndexTable = new TABFile; if (m_poIndexTable->Open(m_pszFname, "rb", bTestOpenNoError) != 0) { // Open Failed... an error has already been reported, just return. if (bTestOpenNoError) CPLErrorReset(); Close(); return -1; } OGRFeatureDefn *poDefn = m_poIndexTable->GetLayerDefn(); if (poDefn == NULL || (m_nTableNameField = poDefn->GetFieldIndex("Table")) == -1) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "Open Failed: Field 'Table' not found in Seamless " "Dataset '%s'. This is type of file not currently " "supported.", m_pszFname); Close(); return -1; } /*----------------------------------------------------------------- * Check number of features in index table to make sure we won't * overflow the number of bytes used for table ids in the encoded * feature ids. We currently use 12 bits for table id + 20 bits for FID *----------------------------------------------------------------*/ if (m_poIndexTable->GetFeatureCount(FALSE) > 0x7ff) { if (!bTestOpenNoError) CPLError(CE_Failure, CPLE_NotSupported, "Open Failed: The current implementation is limited " "to 2047 base tables. The seamless file '%s' contains " "%d tables and cannot be opened.", m_pszFname, m_poIndexTable->GetFeatureCount(FALSE)); Close(); return -1; } /*----------------------------------------------------------------- * We need to open the first table to get its FeatureDefn *----------------------------------------------------------------*/ if (OpenBaseTable(-1, bTestOpenNoError) != 0 ) { // Open Failed... an error has already been reported, just return. if (bTestOpenNoError) CPLErrorReset(); Close(); return -1; } CPLAssert(m_poCurBaseTable); m_poFeatureDefnRef = m_poCurBaseTable->GetLayerDefn(); m_poFeatureDefnRef->Reference(); return 0; }
OGRFeatureDefn * OGROCISelectLayer::ReadTableDefinition( OGROCIStatement *poCommand ) { OGROCISession *poSession = poDS->GetSession(); /* -------------------------------------------------------------------- */ /* Parse the returned table information. */ /* -------------------------------------------------------------------- */ for( int iParm = 0; TRUE; iParm++ ) { OGRFieldDefn oField( "", OFTString ); int nStatus; OCIParam *hParmDesc; ub2 nOCIType; ub4 nOCILen; nStatus = OCIParamGet( poCommand->GetStatement(), OCI_HTYPE_STMT, poSession->hError, (dvoid**)&hParmDesc, (ub4) iParm+1 ); if( nStatus == OCI_ERROR ) break; if( poSession->GetParmInfo( hParmDesc, &oField, &nOCIType, &nOCILen ) != CE_None ) break; if( oField.GetType() == OFTBinary && nOCIType == 108 ) { CPLFree( pszGeomName ); pszGeomName = CPLStrdup( oField.GetNameRef() ); iGeomColumn = iParm; break; } } /* -------------------------------------------------------------------- */ /* Use the schema off the statement. */ /* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn; poDefn = poCommand->GetResultDefn(); if( iGeomColumn >= 0 ) poDefn->SetGeomType(wkbUnknown); poDefn->Reference(); /* -------------------------------------------------------------------- */ /* Do we have an FID? */ /* -------------------------------------------------------------------- */ const char *pszExpectedFIDName = CPLGetConfigOption( "OCI_FID", "OGR_FID" ); if( poDefn->GetFieldIndex(pszExpectedFIDName) > -1 ) { iFIDColumn = poDefn->GetFieldIndex(pszExpectedFIDName); pszFIDName = CPLStrdup(poDefn->GetFieldDefn(iFIDColumn)->GetNameRef()); } if( EQUAL(pszExpectedFIDName, "OGR_FID") && pszFIDName ) { for(int i=0;i<poDefn->GetFieldCount();i++) { // This is presumably a Integer since we always create Integer64 with a // defined precision if( poDefn->GetFieldDefn(i)->GetType() == OFTInteger64 && poDefn->GetFieldDefn(i)->GetWidth() == 0 ) { poDefn->GetFieldDefn(i)->SetType(OFTInteger); } } } return poDefn; }
void readQuadIndex(int series, QString file, QString layerName, Projection *pj) { OGRDataSource *ds = OGRSFDriverRegistrar::Open(file.toLatin1().data(), false); if (!ds) { fprintf(stderr, "Could not open quad index '%s'.\n", file.toLatin1().data()); exit(-1); } OGRLayer *layer; layer = ds->GetLayerByName(layerName.toLatin1().data()); if (!layer) { fprintf(stderr, "Could not read layer '%s'.\n", layerName.toLatin1().data()); exit(-1); } OGRSpatialReference *srs = layer->GetSpatialRef(); if (!srs) { fprintf(stderr, "Missing spatial reference for layer '%s'.\n", layerName.toLatin1().data()); exit(-1); } char *proj = NULL; srs->exportToProj4(&proj); if (!proj) { fprintf(stderr, "Error computing PROJ4 spatial reference for layer '%s'.\n", layerName.toLatin1().data()); exit(-1); } Projection pjIndex(proj); CPLFree(proj); layer->ResetReading(); OGRFeatureDefn *def = layer->GetLayerDefn(); int idFieldNr = def->GetFieldIndex("ID"); int nameFieldNr = def->GetFieldIndex("NAME"); if (idFieldNr < 0 || nameFieldNr < 0) { fprintf(stderr, "Missing index layer fields.\n"); exit(-1); } OGRFeature *f; while ((f = layer->GetNextFeature()) != NULL) { QString id(f->GetFieldAsString(idFieldNr)); QString name(f->GetFieldAsString(nameFieldNr)); // printf("Quad id: %s; name: %s\n", id.toLatin1().data(), name.toLatin1().data()); OGRGeometry *g; g = f->GetGeometryRef(); if (g != NULL && wkbFlatten(g->getGeometryType()) == wkbPolygon) { OGRPolygon *p = (OGRPolygon *)g; OGRLinearRing *r = p->getExteriorRing(); if (!r) { fprintf(stderr, "Quad has no exterior polygon ring %s\n", id.toLatin1().data()); continue; } int size = r->getNumPoints(); QPolygonF boundary; for (int i = 0; i < size; i++) { OGRPoint p; r->getPoint(i, &p); boundary << QPointF(p.getX(), p.getY()); } QPolygonF projBoundary = pj->transformFrom(&pjIndex, boundary); quads[id] = Quad(series, id, name, projBoundary); } else { fprintf(stderr, "Missing or invalid geometry for quad %s\n", id.toLatin1().data()); } } OGRDataSource::DestroyDataSource(ds); }
void OgrWriter::_createLayer(shared_ptr<const Layer> layer) { OGRLayer *poLayer; OGRwkbGeometryType gtype; switch(layer->getGeometryType()) { case GEOS_POINT: gtype = wkbPoint; break; case GEOS_LINESTRING: gtype = wkbLineString; break; case GEOS_POLYGON: gtype = wkbPolygon; break; default: throw HootException("Unexpected geometry type."); } OgrOptions options; if (_ds->GetDriver()) { // if this is a CSV file if (_ds->GetDriver()->GetName() == QString("CSV")) { // if we're exporting point data, then export with x/y at the front if (gtype == wkbPoint) { options["GEOMETRY"] = "AS_XY"; } // if we're exporting other geometries then export w/ WKT at the front. else { options["GEOMETRY"] = "AS_WKT"; } options["CREATE_CSVT"] = "YES"; } if (_ds->GetDriver()->GetName() == QString("ESRI Shapefile")) { options["ENCODING"] = "UTF-8"; } // Add a Feature Dataset to a ESRI File GeoDatabase if requested if (_ds->GetDriver()->GetName() == QString("FileGDB")) { if (layer->getFdName() != "") { options["FEATURE_DATASET"] = layer->getFdName(); // speed up bulk inserts. options["FGDB_BULK_LOAD"] = "YES"; } } } QString layerName = _prependLayerName + layer->getName(); // Check if the layer exists in the output. poLayer = _ds->GetLayerByName(layerName.toAscii()); // We only want to add to a layer IFF the config option "ogr.append.data" set if (poLayer != NULL && _appendData) { // Layer exists _layers[layer->getName()] = poLayer; // Loop through the fields making sure that they exist in the output. Print a warning if // they don't exist OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); shared_ptr<const FeatureDefinition> fd = layer->getFeatureDefinition(); for (size_t i = 0; i < fd->getFieldCount(); i++) { shared_ptr<const FieldDefinition> f = fd->getFieldDefinition(i); if (poFDefn->GetFieldIndex(f->getName().toAscii()) == -1) { // throw HootException(QString("Error: Unable to find output field: %1 in layer %2.").arg(f->getName()).arg(layerName)); LOG_WARN("Unable to find field: " << QString(f->getName()) << " in layer " << layerName); } } } else { // Layer does not exist poLayer = _ds->CreateLayer(layerName.toAscii(), MapReprojector::createWgs84Projection()->Clone(), gtype, options.getCrypticOptions()); if( poLayer == NULL ) { throw HootException(QString("Layer creation failed. %1").arg(layerName)); } _layers[layer->getName()] = poLayer; shared_ptr<const FeatureDefinition> fd = layer->getFeatureDefinition(); for (size_t i = 0; i < fd->getFieldCount(); i++) { shared_ptr<const FieldDefinition> f = fd->getFieldDefinition(i); OGRFieldDefn oField(f->getName().toAscii(), toOgrFieldType(f->getType())); if (f->getWidth() > 0) { oField.SetWidth(f->getWidth()); } int errCode = poLayer->CreateField(&oField); if (errCode != OGRERR_NONE) { throw HootException( QString("Error creating field (%1) OGR Error Code: (%2).").arg(f->getName()).arg(QString::number(errCode))); } } } // End layer does not exist }
void OGRUnionLayer::ConfigureActiveLayer() { AutoWarpLayerIfNecessary(iCurLayer); ApplyAttributeFilterToSrcLayer(iCurLayer); SetSpatialFilterToSourceLayer(papoSrcLayers[iCurLayer]); papoSrcLayers[iCurLayer]->ResetReading(); /* Establish map */ OGRFeatureDefn* poFeatureDefn = GetLayerDefn(); OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iCurLayer]->GetLayerDefn(); CPLFree(panMap); panMap = (int*) CPLMalloc(poSrcFeatureDefn->GetFieldCount() * sizeof(int)); for(int i=0; i < poSrcFeatureDefn->GetFieldCount(); i++) { OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i); if( CSLFindString(papszIgnoredFields, poSrcFieldDefn->GetNameRef() ) == -1 ) { panMap[i] = poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef()); } else { panMap[i] = -1; } } if( papoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields) ) { char** papszIter = papszIgnoredFields; char** papszFieldsSrc = NULL; while ( papszIter != NULL && *papszIter != NULL ) { const char* pszFieldName = *papszIter; if ( EQUAL(pszFieldName, "OGR_GEOMETRY") || EQUAL(pszFieldName, "OGR_STYLE") || poSrcFeatureDefn->GetFieldIndex(pszFieldName) >= 0 || poSrcFeatureDefn->GetGeomFieldIndex(pszFieldName) >= 0 ) { papszFieldsSrc = CSLAddString(papszFieldsSrc, pszFieldName); } papszIter++; } /* Attribute fields */ int* panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int), poSrcFeatureDefn->GetFieldCount()); for(int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++) { OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iField); int iSrcField = poSrcFeatureDefn->GetFieldIndex(poFieldDefn->GetNameRef()); if (iSrcField >= 0) panSrcFieldsUsed[iSrcField] = TRUE; } for(int iSrcField = 0; iSrcField < poSrcFeatureDefn->GetFieldCount(); iSrcField ++) { if( !panSrcFieldsUsed[iSrcField] ) { OGRFieldDefn *poSrcDefn = poSrcFeatureDefn->GetFieldDefn( iSrcField ); papszFieldsSrc = CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef()); } } CPLFree(panSrcFieldsUsed); /* geometry fields now */ panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int), poSrcFeatureDefn->GetGeomFieldCount()); for(int iField = 0; iField < poFeatureDefn->GetGeomFieldCount(); iField++) { OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(iField); int iSrcField = poSrcFeatureDefn->GetGeomFieldIndex(poFieldDefn->GetNameRef()); if (iSrcField >= 0) panSrcFieldsUsed[iSrcField] = TRUE; } for(int iSrcField = 0; iSrcField < poSrcFeatureDefn->GetGeomFieldCount(); iSrcField ++) { if( !panSrcFieldsUsed[iSrcField] ) { OGRGeomFieldDefn *poSrcDefn = poSrcFeatureDefn->GetGeomFieldDefn( iSrcField ); papszFieldsSrc = CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef()); } } CPLFree(panSrcFieldsUsed); papoSrcLayers[iCurLayer]->SetIgnoredFields((const char**)papszFieldsSrc); CSLDestroy(papszFieldsSrc); } }
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* 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 ++; } } for(i = 0; i < poFeatureDefn->GetGeomFieldCount();) { OGRGeomFieldDefn* poFieldDefn = poFeatureDefn->GetGeomFieldDefn(i); int nSrcIndex = poSrcFeatureDefn->GetGeomFieldIndex( poFieldDefn->GetNameRef()); if( nSrcIndex < 0 ) { poFeatureDefn->DeleteGeomFieldDefn(i); } else { /* TODO: merge type, SRS, extent ? */ i ++; } } } } return poFeatureDefn; }
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; }