void OGREDIGEOLayer::AddFieldDefn(const CPLString& osName, OGRFieldType eType, const CPLString& osRID) { if (osRID.size() != 0) mapAttributeToIndex[osRID] = poFeatureDefn->GetFieldCount(); OGRFieldDefn oFieldDefn(osName, eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); }
void OGRSVGLayer::startElementLoadSchemaCbk(const char *pszName, const char **ppszAttr) { if (bStopParsing) return; nWithoutEventCounter = 0; if (strcmp(pszName, "circle") == 0 && strcmp(OGRSVGGetClass(ppszAttr), "point") == 0) { poCurLayer = (OGRSVGLayer*)poDS->GetLayer(0); poCurLayer->nTotalFeatures ++; inInterestingElement = TRUE; interestingDepthLevel = depthLevel; } else if (strcmp(pszName, "path") == 0 && strcmp(OGRSVGGetClass(ppszAttr), "line") == 0) { poCurLayer = (OGRSVGLayer*)poDS->GetLayer(1); poCurLayer->nTotalFeatures ++; inInterestingElement = TRUE; interestingDepthLevel = depthLevel; } else if (strcmp(pszName, "path") == 0 && strcmp(OGRSVGGetClass(ppszAttr), "polygon") == 0) { poCurLayer = (OGRSVGLayer*)poDS->GetLayer(2); poCurLayer->nTotalFeatures ++; inInterestingElement = TRUE; interestingDepthLevel = depthLevel; } else if (inInterestingElement) { if (depthLevel == interestingDepthLevel + 1 && STARTS_WITH(pszName, "cm:")) { pszName += 3; if (poCurLayer->poFeatureDefn->GetFieldIndex(pszName) < 0) { OGRFieldDefn oFieldDefn(pszName, OFTString); if (strcmp(pszName, "timestamp") == 0) oFieldDefn.SetType(OFTDateTime); else if (strcmp(pszName, "way_area") == 0 || strcmp(pszName, "area") == 0) oFieldDefn.SetType(OFTReal); else if (strcmp(pszName, "z_order") == 0) oFieldDefn.SetType(OFTInteger); poCurLayer->poFeatureDefn->AddFieldDefn(&oFieldDefn); } } } depthLevel++; }
OGRSelafinLayer::OGRSelafinLayer( const char *pszLayerNameP, int bUpdateP,OGRSpatialReference *poSpatialRefP,Selafin::Header *poHeaderP,int nStepNumberP,SelafinTypeDef eTypeP):eType(eTypeP),bUpdate(bUpdateP),nStepNumber(nStepNumberP),poHeader(poHeaderP),poSpatialRef(poSpatialRefP),nCurrentId(-1) { //CPLDebug("Selafin","Opening layer %s",pszLayerNameP); poFeatureDefn = new OGRFeatureDefn( CPLGetBasename( pszLayerNameP ) ); SetDescription( poFeatureDefn->GetName() ); poFeatureDefn->Reference(); if (eType==POINTS) poFeatureDefn->SetGeomType( wkbPoint ); else poFeatureDefn->SetGeomType(wkbPolygon); for (int i=0;i<poHeader->nVar;++i) { OGRFieldDefn oFieldDefn(poHeader->papszVariables[i],OFTReal); poFeatureDefn->AddFieldDefn(&oFieldDefn); } }
OGRIdrisiLayer::OGRIdrisiLayer( const char* pszFilename, const char* pszLayerName, VSILFILE* fp, OGRwkbGeometryType eGeomType, const char* pszWTKString ) { this->fp = fp; this->eGeomType = eGeomType; nNextFID = 1; bEOF = FALSE; fpAVL = NULL; if (pszWTKString) { poSRS = new OGRSpatialReference(); char* pszTmp = (char*)pszWTKString; poSRS->importFromWkt(&pszTmp); } else poSRS = NULL; poFeatureDefn = new OGRFeatureDefn( pszLayerName ); SetDescription( poFeatureDefn->GetName() ); poFeatureDefn->Reference(); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); poFeatureDefn->SetGeomType( eGeomType ); OGRFieldDefn oFieldDefn("id", OFTReal); poFeatureDefn->AddFieldDefn( &oFieldDefn ); bExtentValid = FALSE; dfMinX = dfMinY = dfMaxX = dfMaxY = 0.0; VSIFSeekL( fp, 1, SEEK_SET ); if (VSIFReadL( &nTotalFeatures, sizeof(unsigned int), 1, fp ) != 1) nTotalFeatures = 0; CPL_LSBPTR32(&nTotalFeatures); if (nTotalFeatures != 0) { if (!Detect_AVL_ADC(pszFilename)) { if( fpAVL != NULL ) VSIFCloseL( fpAVL ); fpAVL = NULL; } } ResetReading(); }
int OGRIdrisiLayer::Detect_AVL_ADC(const char* pszFilename) { // -------------------------------------------------------------------- // Look for .adc file // -------------------------------------------------------------------- const char* pszADCFilename = CPLResetExtension(pszFilename, "adc"); VSILFILE* fpADC = VSIFOpenL(pszADCFilename, "rb"); if (fpADC == NULL) { pszADCFilename = CPLResetExtension(pszFilename, "ADC"); fpADC = VSIFOpenL(pszADCFilename, "rb"); } char** papszADC = NULL; if (fpADC != NULL) { VSIFCloseL(fpADC); fpADC = NULL; CPLPushErrorHandler(CPLQuietErrorHandler); papszADC = CSLLoad2(pszADCFilename, 1024, 256, NULL); CPLPopErrorHandler(); CPLErrorReset(); } if (papszADC == NULL) return FALSE; CSLSetNameValueSeparator( papszADC, ":" ); const char *pszVersion = CSLFetchNameValue( papszADC, "file format " ); if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Values A.1" ) ) { CSLDestroy( papszADC ); return FALSE; } const char *pszFileType = CSLFetchNameValue( papszADC, "file type " ); if( pszFileType == NULL || !EQUAL( pszFileType, "ascii" ) ) { CPLDebug("IDRISI", ".adc file found, but file type != ascii"); CSLDestroy( papszADC ); return FALSE; } const char* pszRecords = CSLFetchNameValue( papszADC, "records " ); if( pszRecords == NULL || atoi(pszRecords) != (int)nTotalFeatures ) { CPLDebug("IDRISI", ".adc file found, but 'records' not found or not " "consistent with feature number declared in .vdc"); CSLDestroy( papszADC ); return FALSE; } const char* pszFields = CSLFetchNameValue( papszADC, "fields " ); if( pszFields == NULL || atoi(pszFields) <= 1 ) { CPLDebug("IDRISI", ".adc file found, but 'fields' not found or invalid"); CSLDestroy( papszADC ); return FALSE; } // -------------------------------------------------------------------- // Look for .avl file // -------------------------------------------------------------------- const char* pszAVLFilename = CPLResetExtension(pszFilename, "avl"); fpAVL = VSIFOpenL(pszAVLFilename, "rb"); if (fpAVL == NULL) { pszAVLFilename = CPLResetExtension(pszFilename, "AVL"); fpAVL = VSIFOpenL(pszAVLFilename, "rb"); } if (fpAVL == NULL) { CSLDestroy( papszADC ); return FALSE; } // -------------------------------------------------------------------- // Build layer definition // -------------------------------------------------------------------- int iCurField; char szKey[32]; iCurField = 0; sprintf(szKey, "field %d ", iCurField); char** papszIter = papszADC; const char* pszLine; int bFieldFound = FALSE; CPLString osFieldName; while((pszLine = *papszIter) != NULL) { //CPLDebug("IDRISI", "%s", pszLine); if (strncmp(pszLine, szKey, strlen(szKey)) == 0) { const char* pszColon = strchr(pszLine, ':'); if (pszColon) { osFieldName = pszColon + 1; bFieldFound = TRUE; } } else if (bFieldFound && strncmp(pszLine, "data type :", strlen("data type :")) == 0) { const char* pszFieldType = pszLine + strlen("data type :"); OGRFieldDefn oFieldDefn(osFieldName.c_str(), EQUAL(pszFieldType, "integer") ? OFTInteger : EQUAL(pszFieldType, "real") ? OFTReal : OFTString); if( iCurField == 0 && oFieldDefn.GetType() != OFTInteger ) { CSLDestroy( papszADC ); return FALSE; } if( iCurField != 0 ) poFeatureDefn->AddFieldDefn( &oFieldDefn ); iCurField ++; sprintf(szKey, "field %d ", iCurField); } papszIter++; } CSLDestroy(papszADC); return TRUE; }
int OGRGMELayer::FetchDescribe() { CPLString osRequest = "tables/" + osTableId; CPLHTTPResult *psDescribe = poDS->MakeRequest(osRequest); if (psDescribe == NULL) return FALSE; CPLDebug("GME", "table doc = %s\n", psDescribe->pabyData); json_object *table_doc = OGRGMEParseJSON((const char *) psDescribe->pabyData); CPLHTTPDestroyResult(psDescribe); osTableName = OGRGMEGetJSONString(table_doc, "name"); poFeatureDefn = new OGRFeatureDefn(osTableName); poFeatureDefn->Reference(); json_object *schema_doc = json_object_object_get(table_doc, "schema"); json_object *columns_doc = json_object_object_get(schema_doc, "columns"); array_list *column_list = json_object_get_array(columns_doc); CPLString osLastGeomColumn; int field_count = array_list_length(column_list); for( int i = 0; i < field_count; i++ ) { OGRwkbGeometryType eFieldGeomType = wkbNone; json_object *field_obj = (json_object*) array_list_get_idx(column_list, i); const char* name = OGRGMEGetJSONString(field_obj, "name"); OGRFieldDefn oFieldDefn(name, OFTString); const char *type = OGRGMEGetJSONString(field_obj, "type"); if (EQUAL(type, "integer")) oFieldDefn.SetType(OFTInteger); else if (EQUAL(type, "double")) oFieldDefn.SetType(OFTReal); else if (EQUAL(type, "boolean")) oFieldDefn.SetType(OFTInteger); else if (EQUAL(type, "string")) oFieldDefn.SetType(OFTString); else if (EQUAL(type, "string")) { if (EQUAL(name, "gx_id")) { iGxIdField = i; } oFieldDefn.SetType(OFTString); } else if (EQUAL(type, "points")) eFieldGeomType = wkbPoint; else if (EQUAL(type, "linestrings")) eFieldGeomType = wkbLineString; else if (EQUAL(type, "polygons")) eFieldGeomType = wkbPolygon; else if (EQUAL(type, "mixedGeometry")) eFieldGeomType = wkbGeometryCollection; if (eFieldGeomType == wkbNone) { poFeatureDefn->AddFieldDefn(&oFieldDefn); } else { CPLAssert(EQUAL(osGeomColumnName,"")); osGeomColumnName = oFieldDefn.GetNameRef(); poFeatureDefn->SetGeomType(eFieldGeomType); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); } } json_object_put(table_doc); return TRUE; }
int OGRGFTTableLayer::FetchDescribe() { poFeatureDefn = new OGRFeatureDefn( osTableName ); poFeatureDefn->Reference(); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); const CPLString& osAuth = poDS->GetAccessToken(); std::vector<CPLString> aosHeaderAndFirstDataLine; if (osAuth.size()) { CPLString osSQL("DESCRIBE "); osSQL += osTableId; CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL || strncmp(pszLine, "column id,name,type", strlen("column id,name,type")) != 0) { CPLHTTPDestroyResult(psResult); return FALSE; } pszLine = OGRGFTGotoNextLine(pszLine); std::vector<CPLString> aosLines; ParseCSVResponse(pszLine, aosLines); for(int i=0;i<(int)aosLines.size();i++) { char** papszTokens = OGRGFTCSVSplitLine(aosLines[i], ','); if (CSLCount(papszTokens) == 3) { aosColumnInternalName.push_back(papszTokens[0]); //CPLDebug("GFT", "%s %s %s", papszTokens[0], papszTokens[1], papszTokens[2]); OGRFieldType eType = OFTString; if (EQUAL(papszTokens[2], "number")) eType = OFTReal; else if (EQUAL(papszTokens[2], "datetime")) eType = OFTDateTime; if (EQUAL(papszTokens[2], "location") && osGeomColumnName.size() == 0) { if (iGeometryField < 0) iGeometryField = poFeatureDefn->GetFieldCount(); else CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } CPLString osLaunderedColName(LaunderColName(papszTokens[1])); OGRFieldDefn oFieldDefn(osLaunderedColName, eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } CSLDestroy(papszTokens); } CPLHTTPDestroyResult(psResult); } else { /* http://code.google.com/intl/fr/apis/fusiontables/docs/developers_guide.html#Exploring states */ /* that DESCRIBE should work on public tables without authentication, but it is not true... */ CPLString osSQL("SELECT * FROM "); osSQL += osTableId; osSQL += " OFFSET 0 LIMIT 1"; CPLHTTPResult * psResult = poDS->RunSQL(osSQL); if (psResult == NULL) return FALSE; char* pszLine = (char*) psResult->pabyData; if (pszLine == NULL || psResult->pszErrBuf != NULL) { CPLHTTPDestroyResult(psResult); return FALSE; } ParseCSVResponse(pszLine, aosHeaderAndFirstDataLine); if (aosHeaderAndFirstDataLine.size() > 0) { char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[0], ','); for(int i=0;papszTokens && papszTokens[i];i++) { CPLString osLaunderedColName(LaunderColName(papszTokens[i])); OGRFieldDefn oFieldDefn(osLaunderedColName, OFTString); poFeatureDefn->AddFieldDefn(&oFieldDefn); } CSLDestroy(papszTokens); } CPLHTTPDestroyResult(psResult); } if (osGeomColumnName.size() > 0) { iGeometryField = poFeatureDefn->GetFieldIndex(osGeomColumnName); if (iGeometryField < 0) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find column called %s", osGeomColumnName.c_str()); } } for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { const char* pszName = poFeatureDefn->GetFieldDefn(i)->GetNameRef(); if (EQUAL(pszName, "latitude") || EQUAL(pszName, "lat") || EQUAL(pszName, "latdec")) iLatitudeField = i; else if (EQUAL(pszName, "longitude") || EQUAL(pszName, "lon") || EQUAL(pszName, "londec") || EQUAL(pszName, "long")) iLongitudeField = i; } if (iLatitudeField >= 0 && iLongitudeField >= 0) { if (iGeometryField < 0) iGeometryField = iLatitudeField; poFeatureDefn->GetFieldDefn(iLatitudeField)->SetType(OFTReal); poFeatureDefn->GetFieldDefn(iLongitudeField)->SetType(OFTReal); poFeatureDefn->SetGeomType( wkbPoint ); } else if (iGeometryField < 0 && osGeomColumnName.size() == 0) { iLatitudeField = iLongitudeField = -1; /* In the unauthentified case, we try to parse the first record to */ /* autodetect the geometry field */ OGRwkbGeometryType eType = wkbUnknown; if (aosHeaderAndFirstDataLine.size() == 2) { char** papszTokens = OGRGFTCSVSplitLine(aosHeaderAndFirstDataLine[1], ','); if (CSLCount(papszTokens) == poFeatureDefn->GetFieldCount()) { for(int i=0;i<poFeatureDefn->GetFieldCount();i++) { const char* pszVal = papszTokens[i]; if (pszVal != NULL && (strncmp(pszVal, "<Point>", 7) == 0 || strncmp(pszVal, "<LineString>", 12) == 0 || strncmp(pszVal, "<Polygon>", 9) == 0 || strncmp(pszVal, "<MultiGeometry>", 15) == 0)) { if (iGeometryField < 0) { iGeometryField = i; } else { CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } } else if (pszVal) { /* http://www.google.com/fusiontables/DataSource?dsrcid=423292 */ char** papszTokens2 = CSLTokenizeString2(pszVal, " ,", 0); if (CSLCount(papszTokens2) == 2 && CPLGetValueType(papszTokens2[0]) == CPL_VALUE_REAL && CPLGetValueType(papszTokens2[1]) == CPL_VALUE_REAL && fabs(CPLAtof(papszTokens2[0])) <= 90 && fabs(CPLAtof(papszTokens2[1])) <= 180 ) { if (iGeometryField < 0) { iGeometryField = i; eType = wkbPoint; } else { CPLDebug("GFT", "Multiple geometry fields detected. " "Only first encountered one is handled"); } } CSLDestroy(papszTokens2); } } } CSLDestroy(papszTokens); } if (iGeometryField < 0) poFeatureDefn->SetGeomType( wkbNone ); else poFeatureDefn->SetGeomType( eType ); } SetGeomFieldName(); return TRUE; }
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; } SetGeomFieldName(); CPLHTTPDestroyResult(psResult); return TRUE; }
int ILI1Reader::ReadTable(const char *layername) { char **tokens = NULL; const char *firsttok = NULL; int ret = TRUE; int warned = FALSE; int fIndex; int geomIdx; // curLayer is NULL if we have more than one // point geometry column if(curLayer == NULL) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { if(EQUAL(layername, metaFeature->GetFieldAsString(0))) { const char *geomlayername = metaFeature->GetFieldAsString(2); curLayer = GetLayerByName(geomlayername); break; } } } OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; // get the geometry index of the current layer // only if the model is read if(featureDef->GetFieldCount() != 0) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { if(EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) { geomIdx = metaFeature->GetFieldAsInteger(1); } } } long fpos = VSIFTell(fpItf); while (ret && (tokens = ReadParseLine())) { firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { //Check for features spread over multiple objects if (featureDef->GetGeomType() == wkbPolygon) { //Multiple polygon rings feature = curLayer->GetFeatureRef(atol(CSLGetField(tokens, 2))); } else if (featureDef->GetGeomType() == wkbGeometryCollection) { //AREA lines spread over mutltiple objects } else { feature = NULL; } if (feature == NULL) { if (featureDef->GetFieldCount() == 0) { CPLDebug( "OGR_ILI", "No field definition found for table: %s", featureDef->GetName() ); //Model not read - use heuristics for (fIndex=1; fIndex<CSLCount(tokens); fIndex++) { char szFieldName[32]; sprintf(szFieldName, "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature feature = new OGRFeature(featureDef); int fieldno = 0; for (fIndex=1; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++) { if (!EQUAL(tokens[fIndex], "@")) { //CPLDebug( "READ TABLE OGR_ILI", "Adding Field %d: %s", fieldno, tokens[fIndex]); feature->SetField(fieldno, tokens[fIndex]); if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal && featureDef->GetGeomType() == wkbPoint /* // if there is no ili model read, // we have no chance to detect the // geometry column!! */ && (fieldno-2) == geomIdx) { //add Point geometry OGRPoint *ogrPoint = new OGRPoint(atof(tokens[fIndex-1]), atof(tokens[fIndex])); feature->SetGeometryDirectly(ogrPoint); } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1 && !(featureDef->GetFieldCount() == CSLCount(tokens) && EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry"))) { CPLDebug( "OGR_ILI", "Field count doesn't match. %d declared, %d found", featureDef->GetFieldCount(), CSLCount(tokens)-1); warned = TRUE; } if (featureDef->GetGeomType() == wkbPolygon) feature->SetFID(atol(feature->GetFieldAsString(1))); else if (feature->GetFieldCount() > 0) feature->SetFID(atol(feature->GetFieldAsString(0))); curLayer->AddFeature(feature); } } else if (EQUAL(firsttok, "STPT")) { ReadGeom(tokens, featureDef->GetGeomType(), feature); if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry")) { AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos); //TODO: append multi-OBJECT geometries } } else if (EQUAL(firsttok, "ELIN")) { //empty geom } else if (EQUAL(firsttok, "EDGE")) { tokens = ReadParseLine(); //STPT ReadGeom(tokens, wkbMultiLineString, feature); if (EQUAL(featureDef->GetFieldDefn(featureDef->GetFieldCount()-1)->GetNameRef(), "ILI_Geometry")) { AddIliGeom(feature, featureDef->GetFieldCount()-1, fpos); } } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { if(HasMultiplePointGeom(layername) > 0) { OGRFeature *metaFeature = NULL; metaLayer->ResetReading(); while((metaFeature = metaLayer->GetNextFeature()) != NULL ) { int pntCln = 1; if(EQUAL(layername, metaFeature->GetFieldAsString(0)) && !EQUAL(curLayer->GetLayerDefn()->GetName(), metaFeature->GetFieldAsString(2))) { pntCln++; OGRILI1Layer *curLayerTmp = GetLayerByName(metaFeature->GetFieldAsString(2)); OGRFeature *tmpFeature = NULL; int geomIdxTmp = metaFeature->GetFieldAsInteger(1); curLayer->ResetReading(); while((tmpFeature = curLayer->GetNextFeature()) != NULL ) { OGRPoint *ogrPoint = new OGRPoint(atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln)), atof(tmpFeature->GetFieldAsString(geomIdxTmp + pntCln + 1))); tmpFeature->SetGeometryDirectly(ogrPoint); curLayerTmp->AddFeature(tmpFeature); } } } } CSLDestroy(tokens); return TRUE; } else { CPLDebug( "OGR_ILI", "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); fpos = VSIFTell(fpItf); } return ret; }
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode, char chDelimiter, const char* pszNfdcGeomField, const char* pszGeonamesGeomFieldPrefix) { fpCSV = fp; iWktGeomReadField = -1; iNfdcLatitudeS = iNfdcLongitudeS = -1; iLatitudeField = iLongitudeField = -1; this->bInWriteMode = bInWriteMode; this->bNew = bNew; this->pszFilename = CPLStrdup(pszFilename); this->chDelimiter = chDelimiter; bFirstFeatureAppendedDuringSession = TRUE; bUseCRLF = FALSE; bNeedRewindBeforeRead = FALSE; eGeometryFormat = OGR_CSV_GEOM_NONE; nNextFID = 1; poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType( wkbNone ); bCreateCSVT = FALSE; bDontHonourStrings = FALSE; bWriteBOM = FALSE; bIsEurostatTSV = FALSE; nEurostatDims = 0; nTotalFeatures = -1; /* -------------------------------------------------------------------- */ /* If this is not a new file, read ahead to establish if it is */ /* already in CRLF (DOS) mode, or just a normal unix CR mode. */ /* -------------------------------------------------------------------- */ if( !bNew && bInWriteMode ) { int nBytesRead = 0; char chNewByte; while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 ) { if( chNewByte == 13 ) { bUseCRLF = TRUE; break; } nBytesRead ++; } VSIRewindL( fpCSV ); } /* -------------------------------------------------------------------- */ /* Check if the first record seems to be field definitions or */ /* not. We assume it is field definitions if none of the */ /* values are strictly numeric. */ /* -------------------------------------------------------------------- */ char **papszTokens = NULL; int nFieldCount=0, iField; CPLValueType eType; if( !bNew ) { const char *pszLine = NULL; char szDelimiter[2]; szDelimiter[0] = chDelimiter; szDelimiter[1] = '\0'; pszLine = CPLReadLineL( fpCSV ); if ( pszLine != NULL ) { /* Detect and remove UTF-8 BOM marker if found (#4623) */ if (pszLine[0] == (char)0xEF && pszLine[1] == (char)0xBB && pszLine[2] == (char)0xBF) { pszLine += 3; } /* tokenize the strings and preserve quotes, so we can separate string from numeric */ /* this is only used in the test for bHasFeldNames (bug #4361) */ papszTokens = CSLTokenizeString2( pszLine, szDelimiter, (CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS | CSLT_PRESERVEQUOTES) ); nFieldCount = CSLCount( papszTokens ); bHasFieldNames = TRUE; for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ ) { eType = CPLGetValueType(papszTokens[iField]); if ( (eType == CPL_VALUE_INTEGER || eType == CPL_VALUE_REAL) ) { /* we have a numeric field, therefore do not consider the first line as field names */ bHasFieldNames = FALSE; } } CPLString osExt = OGRCSVDataSource::GetRealExtension(pszFilename); /* Eurostat .tsv files */ if( EQUAL(osExt, "tsv") && nFieldCount > 1 && strchr(papszTokens[0], ',') != NULL && strchr(papszTokens[0], '\\') != NULL ) { bHasFieldNames = TRUE; bIsEurostatTSV = TRUE; } /* tokenize without quotes to get the actual values */ CSLDestroy( papszTokens ); // papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE ); papszTokens = CSLTokenizeString2( pszLine, szDelimiter, (CSLT_HONOURSTRINGS | CSLT_ALLOWEMPTYTOKENS)); nFieldCount = CSLCount( papszTokens ); } } else bHasFieldNames = FALSE; if( !bNew && !bHasFieldNames ) VSIRewindL( fpCSV ); /* -------------------------------------------------------------------- */ /* Check for geonames.org tables */ /* -------------------------------------------------------------------- */ if( !bHasFieldNames && nFieldCount == 19 ) { if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER && CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL && CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL && CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 && CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180) { bHasFieldNames = TRUE; CSLDestroy(papszTokens); papszTokens = NULL; static const struct { const char* pszName; OGRFieldType eType; } asGeonamesFieldDesc[] = { { "GEONAMEID", OFTString }, { "NAME", OFTString }, { "ASCIINAME", OFTString }, { "ALTNAMES", OFTString }, { "LATITUDE", OFTReal }, { "LONGITUDE", OFTReal }, { "FEATCLASS", OFTString }, { "FEATCODE", OFTString }, { "COUNTRY", OFTString }, { "CC2", OFTString }, { "ADMIN1", OFTString }, { "ADMIN2", OFTString }, { "ADMIN3", OFTString }, { "ADMIN4", OFTString }, { "POPULATION", OFTReal }, { "ELEVATION", OFTInteger }, { "GTOPO30", OFTInteger }, { "TIMEZONE", OFTString }, { "MODDATE", OFTString } }; for(iField = 0; iField < nFieldCount; iField++) { OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName, asGeonamesFieldDesc[iField].eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } iLatitudeField = 4; iLongitudeField = 5; nFieldCount = 0; } } /* -------------------------------------------------------------------- */ /* Search a csvt file for types */ /* -------------------------------------------------------------------- */ char** papszFieldTypes = NULL; if (!bNew) { char* dname = strdup(CPLGetDirname(pszFilename)); char* fname = strdup(CPLGetBasename(pszFilename)); VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r"); free(dname); free(fname); if (fpCSVT!=NULL) { VSIRewindL(fpCSVT); papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE); VSIFCloseL(fpCSVT); } } /* -------------------------------------------------------------------- */ /* Build field definitions. */ /* -------------------------------------------------------------------- */ for( iField = 0; !bIsEurostatTSV && iField < nFieldCount; iField++ ) { char *pszFieldName = NULL; char szFieldNameBuffer[100]; if( bHasFieldNames ) { pszFieldName = papszTokens[iField]; // trim white space. while( *pszFieldName == ' ' ) pszFieldName++; while( pszFieldName[0] != '\0' && pszFieldName[strlen(pszFieldName)-1] == ' ' ) pszFieldName[strlen(pszFieldName)-1] = '\0'; if (*pszFieldName == '\0') pszFieldName = NULL; } if (pszFieldName == NULL) { /* Re-read single column CSV files that have a trailing comma */ /* in the header line */ if( iField == 1 && nFieldCount == 2 && papszTokens[1][0] == '\0' ) { nFieldCount = 1; break; } pszFieldName = szFieldNameBuffer; sprintf( szFieldNameBuffer, "field_%d", iField+1 ); } OGRFieldDefn oField(pszFieldName, OFTString); if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) { char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '('); if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] && pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9') { int nWidth = 0; int nPrecision = 0; char* pszDot = strchr(pszLeftParenthesis, '.'); if (pszDot) *pszDot = 0; *pszLeftParenthesis = 0; if (pszLeftParenthesis[-1] == ' ') pszLeftParenthesis[-1] = 0; nWidth = atoi(pszLeftParenthesis+1); if (pszDot) nPrecision = atoi(pszDot+1); oField.SetWidth(nWidth); oField.SetPrecision(nPrecision); } if (EQUAL(papszFieldTypes[iField], "Integer")) oField.SetType(OFTInteger); else if (EQUAL(papszFieldTypes[iField], "Real")) oField.SetType(OFTReal); else if (EQUAL(papszFieldTypes[iField], "String")) oField.SetType(OFTString); else if (EQUAL(papszFieldTypes[iField], "Date")) oField.SetType(OFTDate); else if (EQUAL(papszFieldTypes[iField], "Time")) oField.SetType(OFTTime); else if (EQUAL(papszFieldTypes[iField], "DateTime")) oField.SetType(OFTDateTime); else CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]); } if( EQUAL(oField.GetNameRef(),"WKT") && oField.GetType() == OFTString && iWktGeomReadField == -1 ) { iWktGeomReadField = iField; poFeatureDefn->SetGeomType( wkbUnknown ); } /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */ if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") ) iNfdcLatitudeS = iField; else if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") ) iNfdcLongitudeS = iField; /* GNIS specific */ else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) ) { oField.SetType(OFTReal); iLatitudeField = iField; } else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) ) { oField.SetType(OFTReal); iLongitudeField = iField; } poFeatureDefn->AddFieldDefn( &oField ); } if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 ) { bDontHonourStrings = TRUE; poFeatureDefn->SetGeomType( wkbPoint ); } else if ( iLatitudeField != -1 && iLongitudeField != -1 ) { poFeatureDefn->SetGeomType( wkbPoint ); } /* -------------------------------------------------------------------- */ /* Build field definitions for Eurostat TSV files. */ /* -------------------------------------------------------------------- */ CPLString osSeqDim; for( iField = 0; bIsEurostatTSV && iField < nFieldCount; iField++ ) { if( iField == 0 ) { char** papszDims = CSLTokenizeString2( papszTokens[0], ",\\", 0 ); nEurostatDims = CSLCount(papszDims) - 1; for(int iSubField = 0; iSubField < nEurostatDims; iSubField++) { OGRFieldDefn oField(papszDims[iSubField], OFTString); poFeatureDefn->AddFieldDefn( &oField ); } osSeqDim = papszDims[nEurostatDims]; CSLDestroy(papszDims); } else { if( papszTokens[iField][0] != '\0' && papszTokens[iField][strlen(papszTokens[iField])-1] == ' ' ) papszTokens[iField][strlen(papszTokens[iField])-1] = '\0'; OGRFieldDefn oField(CPLSPrintf("%s_%s", osSeqDim.c_str(), papszTokens[iField]), OFTReal); poFeatureDefn->AddFieldDefn( &oField ); OGRFieldDefn oField2(CPLSPrintf("%s_%s_flag", osSeqDim.c_str(), papszTokens[iField]), OFTString); poFeatureDefn->AddFieldDefn( &oField2 ); } } /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ CSLDestroy( papszTokens ); CSLDestroy( papszFieldTypes ); }
OGRErr OGRCSVEditableLayerSynchronizer::EditableSyncToDisk(OGRLayer* poEditableLayer, OGRLayer** ppoDecoratedLayer) { CPLAssert( m_poCSVLayer == *ppoDecoratedLayer ); CPLString osLayerName(m_poCSVLayer->GetName()); CPLString osFilename(m_poCSVLayer->GetFilename()); const bool bCreateCSVT = m_poCSVLayer->GetCreateCSVT(); CPLString osCSVTFilename(CPLResetExtension(osFilename, "csvt")); VSIStatBufL sStatBuf; const bool bHasCSVT = VSIStatL(osCSVTFilename, &sStatBuf) == 0; CPLString osTmpFilename(osFilename); CPLString osTmpCSVTFilename(osFilename); if( VSIStatL(osFilename, &sStatBuf) == 0 ) { osTmpFilename += "_ogr_tmp.csv"; osTmpCSVTFilename += "_ogr_tmp.csvt"; } const char chDelimiter = m_poCSVLayer->GetDelimiter(); OGRCSVLayer* poCSVTmpLayer = new OGRCSVLayer( osLayerName, NULL, osTmpFilename, true, true, chDelimiter ); poCSVTmpLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions); poCSVTmpLayer->SetCRLF( m_poCSVLayer->GetCRLF() ); poCSVTmpLayer->SetCreateCSVT( bCreateCSVT || bHasCSVT ); poCSVTmpLayer->SetWriteBOM( m_poCSVLayer->GetWriteBOM() ); if( m_poCSVLayer->GetGeometryFormat() == OGR_CSV_GEOM_AS_WKT ) poCSVTmpLayer->SetWriteGeometry( wkbNone, OGR_CSV_GEOM_AS_WKT, NULL ); OGRErr eErr = OGRERR_NONE; OGRFeatureDefn* poEditableFDefn = poEditableLayer->GetLayerDefn(); for( int i=0; eErr == OGRERR_NONE && i < poEditableFDefn->GetFieldCount(); i++ ) { OGRFieldDefn oFieldDefn(poEditableFDefn->GetFieldDefn(i)); int iGeomFieldIdx = 0; if( (EQUAL(oFieldDefn.GetNameRef(), "WKT") && (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex("")) >= 0) || (iGeomFieldIdx = poEditableFDefn->GetGeomFieldIndex(oFieldDefn.GetNameRef())) >= 0 ) { OGRGeomFieldDefn oGeomFieldDefn( poEditableFDefn->GetGeomFieldDefn(iGeomFieldIdx) ); eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn ); } else { eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } } const bool bHasXY = ( !m_poCSVLayer->GetXField().empty() && !m_poCSVLayer->GetYField().empty() ); const bool bHasZ = ( !m_poCSVLayer->GetZField().empty() ); if( bHasXY && !CPLFetchBool(m_papszOpenOptions, "KEEP_GEOM_COLUMNS", true) ) { if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetXField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetXField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } if( poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetYField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetYField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } if( bHasZ && poCSVTmpLayer->GetLayerDefn()->GetFieldIndex(m_poCSVLayer->GetZField()) < 0 ) { OGRFieldDefn oFieldDefn(m_poCSVLayer->GetZField(), OFTReal); if( eErr == OGRERR_NONE ) eErr = poCSVTmpLayer->CreateField( &oFieldDefn ); } } int nFirstGeomColIdx = 0; if( m_poCSVLayer->HasHiddenWKTColumn() ) { poCSVTmpLayer->SetWriteGeometry( poEditableFDefn->GetGeomFieldDefn(0)->GetType(), OGR_CSV_GEOM_AS_WKT, poEditableFDefn->GetGeomFieldDefn(0)->GetNameRef()); nFirstGeomColIdx = 1; } if( !(poEditableFDefn->GetGeomFieldCount() == 1 && bHasXY) ) { for( int i=nFirstGeomColIdx; eErr == OGRERR_NONE && i < poEditableFDefn->GetGeomFieldCount(); i++ ) { OGRGeomFieldDefn oGeomFieldDefn( poEditableFDefn->GetGeomFieldDefn(i) ); if( poCSVTmpLayer->GetLayerDefn()->GetGeomFieldIndex(oGeomFieldDefn.GetNameRef()) >= 0 ) continue; eErr = poCSVTmpLayer->CreateGeomField( &oGeomFieldDefn ); } } OGRFeature* poFeature = NULL; poEditableLayer->ResetReading(); while( eErr == OGRERR_NONE && (poFeature = poEditableLayer->GetNextFeature()) != NULL ) { OGRFeature* poNewFeature = new OGRFeature( poCSVTmpLayer->GetLayerDefn() ); poNewFeature->SetFrom(poFeature); if( bHasXY ) { OGRGeometry* poGeom = poFeature->GetGeometryRef(); if( poGeom != NULL && wkbFlatten(poGeom->getGeometryType()) == wkbPoint ) { poNewFeature->SetField( m_poCSVLayer->GetXField(), static_cast<OGRPoint*>(poGeom)->getX()); poNewFeature->SetField( m_poCSVLayer->GetYField(), static_cast<OGRPoint*>(poGeom)->getY()); if( bHasZ ) { poNewFeature->SetField( m_poCSVLayer->GetZField(), static_cast<OGRPoint*>(poGeom)->getZ()); } } } eErr = poCSVTmpLayer->CreateFeature(poNewFeature); delete poFeature; delete poNewFeature; } delete poCSVTmpLayer; if( eErr != OGRERR_NONE ) { CPLError(CE_Failure, CPLE_AppDefined, "Error while creating %s", osTmpFilename.c_str()); VSIUnlink( osTmpFilename ); VSIUnlink( CPLResetExtension(osTmpFilename, "csvt") ); return eErr; } delete m_poCSVLayer; if( osFilename != osTmpFilename ) { CPLString osTmpOriFilename(osFilename + ".ogr_bak"); CPLString osTmpOriCSVTFilename(osCSVTFilename + ".ogr_bak"); if( VSIRename( osFilename, osTmpOriFilename ) != 0 || (bHasCSVT && VSIRename( osCSVTFilename, osTmpOriCSVTFilename ) != 0 ) || VSIRename( osTmpFilename, osFilename) != 0 || (bHasCSVT && VSIRename( osTmpCSVTFilename, osCSVTFilename ) != 0) ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot rename files"); *ppoDecoratedLayer = NULL; m_poCSVLayer = NULL; return OGRERR_FAILURE; } VSIUnlink( osTmpOriFilename ); if( bHasCSVT ) VSIUnlink( osTmpOriCSVTFilename ); } VSILFILE* fp = VSIFOpenL( osFilename, "rb+" ); if( fp == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot reopen updated %s", osFilename.c_str()); *ppoDecoratedLayer = NULL; m_poCSVLayer = NULL; return OGRERR_FAILURE; } m_poCSVLayer = new OGRCSVLayer( osLayerName, fp, osFilename, false, /* new */ true, /* update */ chDelimiter ); m_poCSVLayer->BuildFeatureDefn(NULL, NULL, m_papszOpenOptions); *ppoDecoratedLayer = m_poCSVLayer; return OGRERR_NONE; }
int ILI1Reader::ReadTable(CPL_UNUSED const char *layername) { char **tokens = NULL; int ret = TRUE; int warned = FALSE; int geomIdx = -1; OGRFeatureDefn *featureDef = curLayer->GetLayerDefn(); OGRFeature *feature = NULL; bool bFeatureAdded = false; while (ret && (tokens = ReadParseLine()) != NULL) { const char *firsttok = CSLGetField(tokens, 0); if (EQUAL(firsttok, "OBJE")) { if (featureDef->GetFieldCount() == 0 && curLayer->GetFeatureCount() == 0) { CPLError( CE_Warning, CPLE_AppDefined, "No field definition found for table: %s", featureDef->GetName() ); // Model not read - use heuristics. for( int fIndex=1; fIndex<CSLCount(tokens); fIndex++ ) { char szFieldName[32]; snprintf(szFieldName, sizeof(szFieldName), "Field%02d", fIndex); OGRFieldDefn oFieldDefn(szFieldName, OFTString); featureDef->AddFieldDefn(&oFieldDefn); } } //start new feature if( !bFeatureAdded ) delete feature; feature = new OGRFeature(featureDef); for( int fIndex=1, fieldno = 0; fIndex<CSLCount(tokens) && fieldno < featureDef->GetFieldCount(); fIndex++, fieldno++ ) { if (!(tokens[fIndex][0] == codeUndefined && tokens[fIndex][1] == '\0')) { #ifdef DEBUG_VERBOSE CPLDebug( "READ TABLE OGR_ILI", "Setting Field %d (Type %d): %s", fieldno, featureDef->GetFieldDefn(fieldno)->GetType(), tokens[fIndex] ); #endif if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTString) { // Interlis 1 encoding is ISO 8859-1 (Latin1) -> Recode to UTF-8 char* pszRecoded = CPLRecode( tokens[fIndex], CPL_ENC_ISO8859_1, CPL_ENC_UTF8); // Replace space marks for( char* pszString = pszRecoded; *pszString != '\0'; pszString++ ) { if (*pszString == codeBlank) *pszString = ' '; } feature->SetField(fieldno, pszRecoded); CPLFree(pszRecoded); } else { feature->SetField(fieldno, tokens[fIndex]); } if (featureDef->GetFieldDefn(fieldno)->GetType() == OFTReal && fieldno > 0 && featureDef->GetFieldDefn(fieldno-1)->GetType() == OFTReal) { // Check for Point geometry (Coord type). // If there is no ili model read, // we have no chance to detect the // geometry column. CPLString geomfldname = featureDef->GetFieldDefn(fieldno)->GetNameRef(); // Check if name ends with _1. if (geomfldname.size() >= 2 && geomfldname[geomfldname.size()-2] == '_') { geomfldname = geomfldname.substr(0, geomfldname.size()-2); geomIdx = featureDef->GetGeomFieldIndex(geomfldname.c_str()); if (geomIdx == -1) { CPLError( CE_Warning, CPLE_AppDefined, "No matching definition for field '%s' of " "table %s found", geomfldname.c_str(), featureDef->GetName() ); } } else { geomIdx = -1; } if (geomIdx >= 0) { if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { // Add Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex])); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } else if (featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint25D && fieldno > 1 && featureDef->GetFieldDefn(fieldno-2)->GetType() == OFTReal) { // Add 3D Point geometry. OGRPoint *ogrPoint = new OGRPoint( CPLAtof(tokens[fIndex-2]), CPLAtof(tokens[fIndex-1]), CPLAtof(tokens[fIndex]) ); feature->SetGeomFieldDirectly(geomIdx, ogrPoint); } } } } } if (!warned && featureDef->GetFieldCount() != CSLCount(tokens)-1) { CPLError( CE_Warning, CPLE_AppDefined, "Field count of table %s doesn't match. %d declared, " "%d found (e.g. ignored LINEATTR)", featureDef->GetName(), featureDef->GetFieldCount(), CSLCount(tokens) - 1 ); warned = TRUE; } if (feature->GetFieldCount() > 0) { // USE _TID as FID. TODO: respect IDENT field from model. feature->SetFID(feature->GetFieldAsInteger64(0)); } curLayer->AddFeature(feature); bFeatureAdded = true; geomIdx = -1; //Reset } else if (EQUAL(firsttok, "STPT") && feature != NULL) { //Find next non-Point geometry if (geomIdx < 0) geomIdx = 0; while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint) { geomIdx++; } OGRwkbGeometryType geomType = (geomIdx < featureDef->GetGeomFieldCount()) ? featureDef->GetGeomFieldDefn(geomIdx)->GetType() : wkbNone; if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, geomType, feature); } else if (EQUAL(firsttok, "ELIN")) { // Empty geom. } else if (EQUAL(firsttok, "EDGE") && feature != NULL) { CSLDestroy(tokens); tokens = ReadParseLine(); //STPT //Find next non-Point geometry do { geomIdx++; } while (geomIdx < featureDef->GetGeomFieldCount() && featureDef->GetGeomFieldDefn(geomIdx)->GetType() == wkbPoint); if( CSLCount(tokens) >= 3 ) ReadGeom(tokens, geomIdx, wkbMultiLineString, feature); } else if (EQUAL(firsttok, "PERI")) { } else if (EQUAL(firsttok, "ETAB")) { CPLDebug( "OGR_ILI", "Total features: " CPL_FRMT_GIB, curLayer->GetFeatureCount() ); CSLDestroy(tokens); if( !bFeatureAdded ) delete feature; return TRUE; } else { CPLError( CE_Warning, CPLE_AppDefined, "Unexpected token: %s", firsttok ); } CSLDestroy(tokens); } if( !bFeatureAdded ) delete feature; return ret; }
bool GdaCache::CacheLayer(std::string ext_ds_name, OGRLayerProxy* ext_layer_proxy) { OGRLayer* poSrcLayer = ext_layer_proxy->layer; // get information from current layer: geomtype, layer_name // (NOTE: we don't consider coodinator system and translation here) OGRFeatureDefn *poSrcFDefn = poSrcLayer->GetLayerDefn(); int eGType = poSrcFDefn->GetGeomType(); const char* pszNewLayerName = poSrcLayer->GetName(); int bForceToPolygon = FALSE; int bForceToMultiPolygon = FALSE; int bForceToMultiLineString = FALSE; if( wkbFlatten(eGType) == wkbPolygon ) bForceToPolygon = TRUE; else if( wkbFlatten(eGType) == wkbMultiPolygon ) bForceToMultiPolygon = TRUE; else if( wkbFlatten(eGType) == wkbMultiLineString ) bForceToMultiLineString = TRUE; //Setup coordinate transformation if we need it. OGRCoordinateTransformation *poCT = NULL; bool bTransform = FALSE; OGRSpatialReference *poSourceSRS = NULL; // todo OGRSpatialReference *poOutputSRS = new OGRSpatialReference("EPSG:4326"); // Cache char *papszLCO[] = {"OVERWRITE=yes","FORMAT=Spatialite"}; std::string cache_layer_name = ext_ds_name + "_"+ext_layer_proxy->name; OGRDataSource *poDstDS = cach_ds_proxy->ds; OGRLayer *poDstLayer = poDstDS->CreateLayer(cache_layer_name.c_str(), poOutputSRS, (OGRwkbGeometryType)eGType, papszLCO); if (poDstLayer == NULL) { // raise create cache failed. return false; } // Process Layer style table poDstLayer->SetStyleTable( poSrcLayer->GetStyleTable () ); // Add fields. here to copy all field. int nSrcFieldCount = poSrcFDefn->GetFieldCount(); int iField; OGRFeatureDefn *poDstFDefn = poDstLayer->GetLayerDefn(); for( iField = 0; iField < nSrcFieldCount; iField++ ) { OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField); OGRFieldDefn oFieldDefn( poSrcFieldDefn ); // The field may have been already created at layer creation if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE) { // now that we've created a field, GetLayerDefn() won't return NULL if (poDstFDefn == NULL) poDstFDefn = poDstLayer->GetLayerDefn(); } } // Transfer feature from Source Layer to Dest Layer OGRFeature *poFeature; GIntBig nFeaturesWritten = 0; poSrcLayer->ResetReading(); while (poFeature = poSrcLayer->GetNextFeature()) { OGRFeature *poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() ); poDstFeature->SetFrom(poFeature); OGRGeometry *poDstGeometry = poDstFeature->GetGeometryRef(); if (poDstGeometry != NULL) { if( bForceToPolygon ) { poDstFeature->SetGeometryDirectly( OGRGeometryFactory::forceToPolygon( poDstFeature->StealGeometry())); } else if( bForceToMultiPolygon ) { poDstFeature->SetGeometryDirectly( OGRGeometryFactory::forceToMultiPolygon( poDstFeature->StealGeometry() ) ); } else if ( bForceToMultiLineString ) { poDstFeature->SetGeometryDirectly( OGRGeometryFactory::forceToMultiLineString( poDstFeature->StealGeometry() ) ); } } if( poDstLayer->CreateFeature( poDstFeature ) == OGRERR_NONE ) { nFeaturesWritten ++; } OGRFeature::DestroyFeature( poDstFeature ); OGRFeature::DestroyFeature( poFeature ); } OGRDataSource::DestroyDataSource(poDstDS); // XXX // delete poDstLayer; return true; }
OGRLayer* OGRVRTDataSource::InstanciateUnionLayer( CPLXMLNode *psLTree, const char *pszVRTDirectory, int bUpdate, int nRecLevel) { CPLXMLNode *psSubNode; if( !EQUAL(psLTree->pszValue,"OGRVRTUnionLayer") ) return NULL; /* -------------------------------------------------------------------- */ /* Get layer name. */ /* -------------------------------------------------------------------- */ const char *pszLayerName = CPLGetXMLValue( psLTree, "name", NULL ); if( pszLayerName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing name attribute on OGRVRTUnionLayer" ); return FALSE; } /* -------------------------------------------------------------------- */ /* Do we have a fixed geometry type? If not derive from the */ /* source layer. */ /* -------------------------------------------------------------------- */ const char* pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL ); int bGlobalGeomTypeSet = FALSE; OGRwkbGeometryType eGlobalGeomType = wkbUnknown; if( pszGType != NULL ) { int bError; bGlobalGeomTypeSet = TRUE; eGlobalGeomType = OGRVRTGetGeometryType(pszGType, &bError); if( bError ) { CPLError( CE_Failure, CPLE_AppDefined, "GeometryType %s not recognised.", pszGType ); return NULL; } } /* -------------------------------------------------------------------- */ /* Apply a spatial reference system if provided */ /* -------------------------------------------------------------------- */ const char* pszLayerSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL ); OGRSpatialReference* poGlobalSRS = NULL; int bGlobalSRSSet = FALSE; if( pszLayerSRS != NULL ) { bGlobalSRSSet = TRUE; if( !EQUAL(pszLayerSRS,"NULL") ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import LayerSRS `%s'.", pszLayerSRS ); return FALSE; } poGlobalSRS = oSRS.Clone(); } } /* -------------------------------------------------------------------- */ /* Find field declarations. */ /* -------------------------------------------------------------------- */ OGRFieldDefn** papoFields = NULL; int nFields = 0; OGRUnionLayerGeomFieldDefn** papoGeomFields = NULL; int nGeomFields = 0; for( psSubNode=psLTree->psChild; psSubNode != NULL; psSubNode=psSubNode->psNext ) { if( psSubNode->eType != CXT_Element ) continue; if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"Field") ) { /* -------------------------------------------------------------------- */ /* Field name. */ /* -------------------------------------------------------------------- */ const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL ); if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify Field name." ); break; } OGRFieldDefn oFieldDefn( pszName, OFTString ); /* -------------------------------------------------------------------- */ /* Type */ /* -------------------------------------------------------------------- */ const char *pszArg = CPLGetXMLValue( psSubNode, "type", NULL ); if( pszArg != NULL ) { int iType; for( iType = 0; iType <= (int) OFTMaxType; iType++ ) { if( EQUAL(pszArg,OGRFieldDefn::GetFieldTypeName( (OGRFieldType)iType)) ) { oFieldDefn.SetType( (OGRFieldType) iType ); break; } } if( iType > (int) OFTMaxType ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify Field type '%s'.", pszArg ); break; } } /* -------------------------------------------------------------------- */ /* Width and precision. */ /* -------------------------------------------------------------------- */ int nWidth = atoi(CPLGetXMLValue( psSubNode, "width", "0" )); if (nWidth < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "Invalid width for field %s.", pszName ); break; } oFieldDefn.SetWidth(nWidth); int nPrecision = atoi(CPLGetXMLValue( psSubNode, "precision", "0" )); if (nPrecision < 0 || nPrecision > 1024) { CPLError( CE_Failure, CPLE_IllegalArg, "Invalid precision for field %s.", pszName ); break; } oFieldDefn.SetPrecision(nPrecision); papoFields = (OGRFieldDefn**) CPLRealloc(papoFields, sizeof(OGRFieldDefn*) * (nFields + 1)); papoFields[nFields] = new OGRFieldDefn(&oFieldDefn); nFields ++; } else if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"GeometryField") ) { const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL ); if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify GeometryField name." ); break; } pszGType = CPLGetXMLValue( psSubNode, "GeometryType", NULL ); if( pszGType == NULL && nGeomFields == 0 ) pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL ); OGRwkbGeometryType eGeomType = wkbUnknown; int bGeomTypeSet = FALSE; if( pszGType != NULL ) { int bError; eGeomType = OGRVRTGetGeometryType(pszGType, &bError); bGeomTypeSet = TRUE; if( bError || eGeomType == wkbNone ) { CPLError( CE_Failure, CPLE_AppDefined, "GeometryType %s not recognised.", pszGType ); break; } } const char* pszSRS = CPLGetXMLValue( psSubNode, "SRS", NULL ); if( pszSRS == NULL && nGeomFields == 0 ) pszSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL ); OGRSpatialReference* poSRS = NULL; int bSRSSet = FALSE; if( pszSRS != NULL ) { bSRSSet = TRUE; if( !EQUAL(pszSRS,"NULL") ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszSRS ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import SRS `%s'.", pszSRS ); break; } poSRS = oSRS.Clone(); } } OGRUnionLayerGeomFieldDefn* poFieldDefn = new OGRUnionLayerGeomFieldDefn(pszName, eGeomType); if( poSRS != NULL ) { poFieldDefn->SetSpatialRef(poSRS); poSRS->Dereference(); } poFieldDefn->bGeomTypeSet = bGeomTypeSet; poFieldDefn->bSRSSet = bSRSSet; const char* pszExtentXMin = CPLGetXMLValue( psSubNode, "ExtentXMin", NULL ); const char* pszExtentYMin = CPLGetXMLValue( psSubNode, "ExtentYMin", NULL ); const char* pszExtentXMax = CPLGetXMLValue( psSubNode, "ExtentXMax", NULL ); const char* pszExtentYMax = CPLGetXMLValue( psSubNode, "ExtentYMax", NULL ); if( pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL ) { poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin); poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin); poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax); poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax); } papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields, sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1)); papoGeomFields[nGeomFields] = poFieldDefn; nGeomFields ++; } } /* -------------------------------------------------------------------- */ /* Set Extent if provided */ /* -------------------------------------------------------------------- */ const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL ); const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL ); const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL ); const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL ); if( eGlobalGeomType != wkbNone && nGeomFields == 0 && (bGlobalGeomTypeSet || bGlobalSRSSet || (pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL)) ) { OGRUnionLayerGeomFieldDefn* poFieldDefn = new OGRUnionLayerGeomFieldDefn("", eGlobalGeomType); if( poGlobalSRS != NULL ) { poFieldDefn->SetSpatialRef(poGlobalSRS); poGlobalSRS->Dereference(); poGlobalSRS = NULL; } poFieldDefn->bGeomTypeSet = bGlobalGeomTypeSet; poFieldDefn->bSRSSet = bGlobalSRSSet; if( pszExtentXMin != NULL && pszExtentYMin != NULL && pszExtentXMax != NULL && pszExtentYMax != NULL ) { poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin); poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin); poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax); poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax); } papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields, sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1)); papoGeomFields[nGeomFields] = poFieldDefn; nGeomFields ++; } else { delete poGlobalSRS; poGlobalSRS = NULL; } /* -------------------------------------------------------------------- */ /* Find source layers */ /* -------------------------------------------------------------------- */ int nSrcLayers = 0; OGRLayer** papoSrcLayers = NULL; for( psSubNode=psLTree->psChild; psSubNode != NULL; psSubNode=psSubNode->psNext ) { if( psSubNode->eType != CXT_Element ) continue; OGRLayer* poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory, bUpdate, nRecLevel + 1); if( poSrcLayer != NULL ) { papoSrcLayers = (OGRLayer**) CPLRealloc(papoSrcLayers, sizeof(OGRLayer*) * (nSrcLayers + 1)); papoSrcLayers[nSrcLayers] = poSrcLayer; nSrcLayers ++; } } if( nSrcLayers == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot find source layers" ); int iField; for(iField = 0; iField < nFields; iField++) delete papoFields[iField]; CPLFree(papoFields); for(iField = 0; iField < nGeomFields; iField++) delete papoGeomFields[iField]; CPLFree(papoGeomFields); return NULL; } /* -------------------------------------------------------------------- */ /* Build the OGRUnionLayer. */ /* -------------------------------------------------------------------- */ OGRUnionLayer* poLayer = new OGRUnionLayer( pszLayerName, nSrcLayers, papoSrcLayers, TRUE ); /* -------------------------------------------------------------------- */ /* Set the source layer field name attribute. */ /* -------------------------------------------------------------------- */ const char* pszSourceLayerFieldName = CPLGetXMLValue( psLTree, "SourceLayerFieldName", NULL ); poLayer->SetSourceLayerFieldName(pszSourceLayerFieldName); /* -------------------------------------------------------------------- */ /* Set the PreserveSrcFID attribute. */ /* -------------------------------------------------------------------- */ int bPreserveSrcFID = FALSE; const char* pszPreserveFID = CPLGetXMLValue( psLTree, "PreserveSrcFID", NULL ); if( pszPreserveFID != NULL ) bPreserveSrcFID = CSLTestBoolean(pszPreserveFID); poLayer->SetPreserveSrcFID(bPreserveSrcFID); /* -------------------------------------------------------------------- */ /* Set fields */ /* -------------------------------------------------------------------- */ FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS; const char* pszFieldStrategy = CPLGetXMLValue( psLTree, "FieldStrategy", NULL ); if( pszFieldStrategy != NULL ) { if( EQUAL(pszFieldStrategy, "FirstLayer") ) eFieldStrategy = FIELD_FROM_FIRST_LAYER; else if( EQUAL(pszFieldStrategy, "Union") ) eFieldStrategy = FIELD_UNION_ALL_LAYERS; else if( EQUAL(pszFieldStrategy, "Intersection") ) eFieldStrategy = FIELD_INTERSECTION_ALL_LAYERS; else { CPLError( CE_Warning, CPLE_AppDefined, "Unhandled value for FieldStrategy `%s'.", pszFieldStrategy ); } } if( nFields != 0 || nGeomFields > 1 ) { if( pszFieldStrategy != NULL ) CPLError( CE_Warning, CPLE_AppDefined, "Ignoring FieldStrategy value, because explicit Field or GeometryField is provided") ; eFieldStrategy = FIELD_SPECIFIED; } poLayer->SetFields(eFieldStrategy, nFields, papoFields, (nGeomFields == 0 && eGlobalGeomType == wkbNone) ? -1 : nGeomFields, papoGeomFields); int iField; for(iField = 0; iField < nFields; iField++) delete papoFields[iField]; CPLFree(papoFields); for(iField = 0; iField < nGeomFields; iField++) delete papoGeomFields[iField]; CPLFree(papoGeomFields); /* -------------------------------------------------------------------- */ /* Set FeatureCount if provided */ /* -------------------------------------------------------------------- */ const char* pszFeatureCount = CPLGetXMLValue( psLTree, "FeatureCount", NULL ); if( pszFeatureCount != NULL ) { poLayer->SetFeatureCount(atoi(pszFeatureCount)); } return poLayer; }
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode, char chDelimiter, const char* pszNfdcGeomField, const char* pszGeonamesGeomFieldPrefix) { fpCSV = fp; iWktGeomReadField = -1; iNfdcLatitudeS = iNfdcLongitudeS = -1; iLatitudeField = iLongitudeField = -1; this->bInWriteMode = bInWriteMode; this->bNew = bNew; this->pszFilename = CPLStrdup(pszFilename); this->chDelimiter = chDelimiter; bFirstFeatureAppendedDuringSession = TRUE; bUseCRLF = FALSE; bNeedRewindBeforeRead = FALSE; eGeometryFormat = OGR_CSV_GEOM_NONE; nNextFID = 1; poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType( wkbNone ); bCreateCSVT = FALSE; bDontHonourStrings = FALSE; nTotalFeatures = -1; /* -------------------------------------------------------------------- */ /* If this is not a new file, read ahead to establish if it is */ /* already in CRLF (DOS) mode, or just a normal unix CR mode. */ /* -------------------------------------------------------------------- */ if( !bNew && bInWriteMode ) { int nBytesRead = 0; char chNewByte; while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 ) { if( chNewByte == 13 ) { bUseCRLF = TRUE; break; } } VSIRewindL( fpCSV ); } /* -------------------------------------------------------------------- */ /* Check if the first record seems to be field definitions or */ /* not. We assume it is field definitions if none of the */ /* values are strictly numeric. */ /* -------------------------------------------------------------------- */ char **papszTokens = NULL; int nFieldCount=0, iField; CPLValueType eType; if( !bNew ) { papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE ); nFieldCount = CSLCount( papszTokens ); bHasFieldNames = TRUE; } else bHasFieldNames = FALSE; for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ ) { eType = CPLGetValueType(papszTokens[iField]); if ( eType == CPL_VALUE_INTEGER || eType == CPL_VALUE_REAL ) { /* we have a numeric field, therefore do not consider the first line as field names */ bHasFieldNames = FALSE; } } if( !bNew && !bHasFieldNames ) VSIRewindL( fpCSV ); /* -------------------------------------------------------------------- */ /* Check for geonames.org tables */ /* -------------------------------------------------------------------- */ if( !bHasFieldNames && nFieldCount == 19 ) { if (CPLGetValueType(papszTokens[0]) == CPL_VALUE_INTEGER && CPLGetValueType(papszTokens[4]) == CPL_VALUE_REAL && CPLGetValueType(papszTokens[5]) == CPL_VALUE_REAL && CPLAtof(papszTokens[4]) >= -90 && CPLAtof(papszTokens[4]) <= 90 && CPLAtof(papszTokens[5]) >= -180 && CPLAtof(papszTokens[4]) <= 180) { bHasFieldNames = TRUE; CSLDestroy(papszTokens); papszTokens = NULL; static const struct { const char* pszName; OGRFieldType eType; } asGeonamesFieldDesc[] = { { "GEONAMEID", OFTString }, { "NAME", OFTString }, { "ASCIINAME", OFTString }, { "ALTNAMES", OFTString }, { "LATITUDE", OFTReal }, { "LONGITUDE", OFTReal }, { "FEATCLASS", OFTString }, { "FEATCODE", OFTString }, { "COUNTRY", OFTString }, { "CC2", OFTString }, { "ADMIN1", OFTString }, { "ADMIN2", OFTString }, { "ADMIN3", OFTString }, { "ADMIN4", OFTString }, { "POPULATION", OFTReal }, { "ELEVATION", OFTInteger }, { "GTOPO30", OFTInteger }, { "TIMEZONE", OFTString }, { "MODDATE", OFTString } }; for(iField = 0; iField < nFieldCount; iField++) { OGRFieldDefn oFieldDefn(asGeonamesFieldDesc[iField].pszName, asGeonamesFieldDesc[iField].eType); poFeatureDefn->AddFieldDefn(&oFieldDefn); } iLatitudeField = 4; iLongitudeField = 5; nFieldCount = 0; } } /* -------------------------------------------------------------------- */ /* Search a csvt file for types */ /* -------------------------------------------------------------------- */ char** papszFieldTypes = NULL; if (!bNew) { char* dname = strdup(CPLGetDirname(pszFilename)); char* fname = strdup(CPLGetBasename(pszFilename)); VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r"); free(dname); free(fname); if (fpCSVT!=NULL) { VSIRewindL(fpCSVT); papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE); VSIFCloseL(fpCSVT); } } /* -------------------------------------------------------------------- */ /* Build field definitions. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < nFieldCount; iField++ ) { char *pszFieldName = NULL; char szFieldNameBuffer[100]; if( bHasFieldNames ) { pszFieldName = papszTokens[iField]; // trim white space. while( *pszFieldName == ' ' ) pszFieldName++; while( pszFieldName[0] != '\0' && pszFieldName[strlen(pszFieldName)-1] == ' ' ) pszFieldName[strlen(pszFieldName)-1] = '\0'; if (*pszFieldName == '\0') pszFieldName = NULL; } if (pszFieldName == NULL) { pszFieldName = szFieldNameBuffer; sprintf( szFieldNameBuffer, "field_%d", iField+1 ); } OGRFieldDefn oField(pszFieldName, OFTString); if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) { char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '('); if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] && pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9') { int nWidth = 0; int nPrecision = 0; char* pszDot = strchr(pszLeftParenthesis, '.'); if (pszDot) *pszDot = 0; *pszLeftParenthesis = 0; if (pszLeftParenthesis[-1] == ' ') pszLeftParenthesis[-1] = 0; nWidth = atoi(pszLeftParenthesis+1); if (pszDot) nPrecision = atoi(pszDot+1); oField.SetWidth(nWidth); oField.SetPrecision(nPrecision); } if (EQUAL(papszFieldTypes[iField], "Integer")) oField.SetType(OFTInteger); else if (EQUAL(papszFieldTypes[iField], "Real")) oField.SetType(OFTReal); else if (EQUAL(papszFieldTypes[iField], "String")) oField.SetType(OFTString); else if (EQUAL(papszFieldTypes[iField], "Date")) oField.SetType(OFTDate); else if (EQUAL(papszFieldTypes[iField], "Time")) oField.SetType(OFTTime); else if (EQUAL(papszFieldTypes[iField], "DateTime")) oField.SetType(OFTDateTime); else CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]); } if( EQUAL(oField.GetNameRef(),"WKT") && oField.GetType() == OFTString && iWktGeomReadField == -1 ) { iWktGeomReadField = iField; poFeatureDefn->SetGeomType( wkbUnknown ); } /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */ if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") ) iNfdcLatitudeS = iField; else if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") ) iNfdcLongitudeS = iField; /* GNIS specific */ else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) ) { oField.SetType(OFTReal); iLatitudeField = iField; } else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) ) { oField.SetType(OFTReal); iLongitudeField = iField; } poFeatureDefn->AddFieldDefn( &oField ); } if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 ) { bDontHonourStrings = TRUE; poFeatureDefn->SetGeomType( wkbPoint ); } else if ( iLatitudeField != -1 && iLongitudeField != -1 ) { poFeatureDefn->SetGeomType( wkbPoint ); } CSLDestroy( papszTokens ); CSLDestroy( papszFieldTypes ); }
int OGRFMELayer::Initialize( IFMEFeature * poSchemaFeature, OGRSpatialReference *poSRS ) { IFMEString *poFMEString = NULL; poFMEString = poDS->GetFMESession()->createString(); poFMEFeature = poDS->GetFMESession()->createFeature(); if( poSRS != NULL ) poSpatialRef = poSRS->Clone(); /* -------------------------------------------------------------------- */ /* Create the definition with the definition name being the */ /* same as the FME feature type. */ /* -------------------------------------------------------------------- */ poSchemaFeature->getFeatureType( *poFMEString ); poFeatureDefn = new OGRFeatureDefn( poFMEString->data() ); SetDescription( poFeatureDefn->GetName() ); poFeatureDefn->Reference(); poDS->GetFMESession()->destroyString( poFMEString ); /* -------------------------------------------------------------------- */ /* Get the list of attribute names. */ /* -------------------------------------------------------------------- */ IFMEStringArray *poAttrNames; poAttrNames = poDS->GetFMESession()->createStringArray(); poSchemaFeature->getAllAttributeNames( *poAttrNames ); /* ==================================================================== */ /* Loop over attributes, adding them to our feature defn. */ /* ==================================================================== */ OGRwkbGeometryType eGeomType = wkbNone; IFMEString *poAttrValue; poAttrValue = poDS->GetFMESession()->createString(); for( int iAttr = 0; iAttr < (int)poAttrNames->entries(); iAttr++ ) { const char *pszAttrName = (*poAttrNames)(iAttr); /* -------------------------------------------------------------------- */ /* Get the attribute value. */ /* -------------------------------------------------------------------- */ if( !poSchemaFeature->getAttribute(pszAttrName,*poAttrValue) ) continue; /* -------------------------------------------------------------------- */ /* Handle geometry attributes. Use them to try and establish */ /* the geometry type of this layer. If we get conflicting */ /* geometries just fall back to the generic geometry type. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszAttrName,"fme_geometry",12) ) { OGRwkbGeometryType eAttrGeomType = wkbNone; if( EQUAL(poAttrValue->data(),"fme_point") ) eAttrGeomType = wkbPoint; else if( EQUAL(poAttrValue->data(),"fme_text") ) eAttrGeomType = wkbPoint; else if( EQUAL(poAttrValue->data(),"fme_area") ) eAttrGeomType = wkbPolygon; else if( EQUAL(poAttrValue->data(),"fme_polygon") ) eAttrGeomType = wkbPolygon; else if( EQUAL(poAttrValue->data(),"fme_rectangle") ) eAttrGeomType = wkbPolygon; else if( EQUAL(poAttrValue->data(),"fme_rounded_rectangle") ) eAttrGeomType = wkbPolygon; else if( EQUAL(poAttrValue->data(),"fme_line") ) eAttrGeomType = wkbLineString; else if( EQUAL(poAttrValue->data(),"fme_arc") ) eAttrGeomType = wkbLineString; else if( EQUAL(poAttrValue->data(),"fme_aggregate") ) eAttrGeomType = wkbGeometryCollection; else if( EQUAL(poAttrValue->data(),"fme_no_geom") ) eAttrGeomType = wkbNone; else { CPLDebug( "FME_OLEDB", "geometry field %s has unknown value %s, ignored.", pszAttrName, poAttrValue->data() ); continue; } if( eGeomType == wkbNone ) eGeomType = eAttrGeomType; else if( eGeomType != eAttrGeomType ) eGeomType = wkbUnknown; } /* -------------------------------------------------------------------- */ /* Skip '*' attributes which appear to be the raw attribute */ /* names from the source reader. The versions that don't start */ /* with * appear to be massaged suitably for use, with fme */ /* standard data types. */ /* -------------------------------------------------------------------- */ if( EQUALN(pszAttrName,"fme_geometry",12) || pszAttrName[0] == '*' || EQUALN(pszAttrName,"fme_geomattr",12) ) { continue; } /* -------------------------------------------------------------------- */ /* Parse the type into tokens for easier use. */ /* -------------------------------------------------------------------- */ char **papszTokens; papszTokens = CSLTokenizeStringComplex( poAttrValue->data(), "(,", FALSE, FALSE ); /* -------------------------------------------------------------------- */ /* Establish new fields. */ /* -------------------------------------------------------------------- */ OGRFieldType eType; int nWidth, nPrecision = 0; if( CSLCount(papszTokens) == 2 && EQUAL(papszTokens[0],"fme_char") ) { eType = OFTString; nWidth = atoi(papszTokens[1]); } else if( CSLCount(papszTokens) == 3 && EQUAL(papszTokens[0],"fme_decimal") ) { nWidth = atoi(papszTokens[1]); nPrecision = atoi(papszTokens[2]); if( nPrecision == 0 ) eType = OFTInteger; else eType = OFTReal; } else if( CSLCount(papszTokens) == 1 && EQUAL(papszTokens[0],"fme_int16") ) { nWidth = 6; nPrecision = 0; eType = OFTInteger; } else if( CSLCount(papszTokens) == 1 && EQUAL(papszTokens[0],"fme_int32") ) { nWidth = 0; nPrecision = 0; eType = OFTInteger; } else if( CSLCount(papszTokens) == 1 && (EQUAL(papszTokens[0],"fme_real32") || EQUAL(papszTokens[0],"fme_real64")) ) { nWidth = 0; nPrecision = 0; eType = OFTReal; } else if( CSLCount(papszTokens) == 1 && EQUAL(papszTokens[0],"fme_boolean") ) { nWidth = 1; nPrecision = 0; eType = OFTInteger; } else { printf( "Not able to translate field type: %s\n", poAttrValue->data() ); CSLDestroy( papszTokens ); continue; } /* -------------------------------------------------------------------- */ /* Add the field to the feature definition. */ /* -------------------------------------------------------------------- */ OGRFieldDefn oFieldDefn( pszAttrName, eType ); oFieldDefn.SetWidth( nWidth ); oFieldDefn.SetPrecision( nPrecision ); poFeatureDefn->AddFieldDefn( &oFieldDefn ); CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Assign the geometry type ... try to apply 3D-ness as well. */ /* -------------------------------------------------------------------- */ if( poSchemaFeature->getDimension() == FME_THREE_D ) eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit); poFeatureDefn->SetGeomType( eGeomType ); /* -------------------------------------------------------------------- */ /* Translate the spatial reference system. */ /* -------------------------------------------------------------------- */ if( poSchemaFeature->getCoordSys() != NULL && strlen(poSchemaFeature->getCoordSys()) > 0 && poSpatialRef == NULL ) { CPLDebug( "FME_OLEDB", "Layer %s has COORDSYS=%s on schema feature.", poFeatureDefn->GetName(), poSchemaFeature->getCoordSys() ); poSpatialRef = poDS->FME2OGRSpatialRef(poSchemaFeature->getCoordSys()); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ poDS->GetFMESession()->destroyString( poAttrValue ); poDS->GetFMESession()->destroyStringArray( poAttrNames ); return TRUE; }
OGRLayer* OGROpenFileGDBDataSource::ExecuteSQL( const char *pszSQLCommand, OGRGeometry *poSpatialFilter, const char *pszDialect ) { /* -------------------------------------------------------------------- */ /* Special case GetLayerDefinition */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerDefinition ", strlen("GetLayerDefinition "))) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerDefinition ")); if (poLayer) { OGRLayer* poRet = new OGROpenFileGDBSingleFeatureLayer( "LayerDefinition", poLayer->GetXMLDefinition().c_str() ); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLayerMetadata */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerMetadata ", strlen("GetLayerMetadata "))) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerMetadata ")); if (poLayer) { OGRLayer* poRet = new OGROpenFileGDBSingleFeatureLayer( "LayerMetadata", poLayer->GetXMLDocumentation().c_str() ); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLayerAttrIndexUse (only for debugging purposes) */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerAttrIndexUse ", strlen("GetLayerAttrIndexUse "))) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerAttrIndexUse ")); if (poLayer) { OGRLayer* poRet = new OGROpenFileGDBSingleFeatureLayer( "LayerAttrIndexUse", CPLSPrintf("%d", poLayer->GetAttrIndexUse()) ); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLayerSpatialIndexState (only for debugging purposes) */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerSpatialIndexState ", strlen("GetLayerSpatialIndexState "))) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerSpatialIndexState ")); if (poLayer) { OGRLayer* poRet = new OGROpenFileGDBSingleFeatureLayer( "LayerSpatialIndexState", CPLSPrintf("%d", poLayer->GetSpatialIndexState()) ); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLastSQLUsedOptimizedImplementation (only for debugging purposes) */ /* -------------------------------------------------------------------- */ if (EQUAL(pszSQLCommand, "GetLastSQLUsedOptimizedImplementation")) { OGRLayer* poRet = new OGROpenFileGDBSingleFeatureLayer( "GetLastSQLUsedOptimizedImplementation", CPLSPrintf("%d", bLastSQLUsedOptimizedImplementation) ); return poRet; } bLastSQLUsedOptimizedImplementation = FALSE; /* -------------------------------------------------------------------- */ /* Special cases for SQL optimizations */ /* -------------------------------------------------------------------- */ if( EQUALN(pszSQLCommand, "SELECT ", strlen("SELECT ")) && (pszDialect == NULL || EQUAL(pszDialect, "") || EQUAL(pszDialect, "OGRSQL")) && CSLTestBoolean(CPLGetConfigOption("OPENFILEGDB_USE_INDEX", "YES")) ) { swq_select oSelect; if( oSelect.preparse(pszSQLCommand) != CE_None ) return NULL; /* -------------------------------------------------------------------- */ /* MIN/MAX/SUM/AVG/COUNT optimization */ /* -------------------------------------------------------------------- */ if( oSelect.join_count == 0 && oSelect.poOtherSelect == NULL && oSelect.table_count == 1 && oSelect.order_specs == 0 && oSelect.query_mode != SWQM_DISTINCT_LIST ) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*)GetLayerByName( oSelect.table_defs[0].table_name); if( poLayer ) { OGRMemLayer* poMemLayer = NULL; int i; for(i = 0; i < oSelect.result_columns; i ++ ) { swq_col_func col_func = oSelect.column_defs[i].col_func; if( !(col_func == SWQCF_MIN || col_func == SWQCF_MAX || col_func == SWQCF_COUNT || col_func == SWQCF_AVG || col_func == SWQCF_SUM) ) break; if( oSelect.column_defs[i].field_name == NULL ) break; if( oSelect.column_defs[i].distinct_flag ) break; if( oSelect.column_defs[i].target_type != SWQ_OTHER ) break; int idx = poLayer->GetLayerDefn()->GetFieldIndex( oSelect.column_defs[i].field_name); if( idx < 0 ) break; OGRFieldDefn* poFieldDefn = poLayer->GetLayerDefn()->GetFieldDefn(idx); if( col_func == SWQCF_SUM && poFieldDefn->GetType() == OFTDateTime ) break; int eOutOGRType = -1; int nCount = 0; double dfSum = 0.0; const OGRField* psField = NULL; OGRField sField; if( col_func == SWQCF_MIN || col_func == SWQCF_MAX ) { psField = poLayer->GetMinMaxValue( poFieldDefn, col_func == SWQCF_MIN, eOutOGRType); if( eOutOGRType < 0 ) break; } else { double dfMin = 0.0, dfMax = 0.0; if( !poLayer->GetMinMaxSumCount(poFieldDefn, dfMin, dfMax, dfSum, nCount) ) break; psField = &sField; if( col_func == SWQCF_AVG ) { if( nCount == 0 ) { eOutOGRType = OFTReal; psField = NULL; } else { if( poFieldDefn->GetType() == OFTDateTime ) { eOutOGRType = OFTDateTime; FileGDBDoubleDateToOGRDate(dfSum / nCount, &sField); } else { eOutOGRType = OFTReal; sField.Real = dfSum / nCount; } } } else if( col_func == SWQCF_COUNT ) { sField.Integer = nCount; eOutOGRType = OFTInteger; } else { sField.Real = dfSum; eOutOGRType = OFTReal; } } if( poMemLayer == NULL ) { poMemLayer = new OGRMemLayer("SELECT", NULL, wkbNone); OGRFeature* poFeature = new OGRFeature(poMemLayer->GetLayerDefn()); poMemLayer->CreateFeature(poFeature); delete poFeature; } const char* pszMinMaxFieldName = CPLSPrintf( "%s_%s", (col_func == SWQCF_MIN) ? "MIN" : (col_func == SWQCF_MAX) ? "MAX" : (col_func == SWQCF_AVG) ? "AVG" : (col_func == SWQCF_SUM) ? "SUM" : "COUNT", oSelect.column_defs[i].field_name); OGRFieldDefn oFieldDefn(pszMinMaxFieldName, (OGRFieldType) eOutOGRType); poMemLayer->CreateField(&oFieldDefn); if( psField != NULL ) { OGRFeature* poFeature = poMemLayer->GetFeature(0); poFeature->SetField(oFieldDefn.GetNameRef(), (OGRField*) psField); poMemLayer->SetFeature(poFeature); delete poFeature; } } if( i != oSelect.result_columns ) { delete poMemLayer; } else { CPLDebug("OpenFileGDB", "Using optimized MIN/MAX/SUM/AVG/COUNT implementation"); bLastSQLUsedOptimizedImplementation = TRUE; return poMemLayer; } } } /* -------------------------------------------------------------------- */ /* ORDER BY optimization */ /* -------------------------------------------------------------------- */ if( oSelect.join_count == 0 && oSelect.poOtherSelect == NULL && oSelect.table_count == 1 && oSelect.order_specs == 1 && oSelect.query_mode != SWQM_DISTINCT_LIST ) { OGROpenFileGDBLayer* poLayer = (OGROpenFileGDBLayer*)GetLayerByName( oSelect.table_defs[0].table_name); if( poLayer != NULL && poLayer->HasIndexForField(oSelect.order_defs[0].field_name) ) { OGRErr eErr = OGRERR_NONE; if( oSelect.where_expr != NULL ) { /* The where must be a simple comparison on the column */ /* that is used for ordering */ if( oSelect.where_expr->eNodeType == SNT_OPERATION && OGROpenFileGDBIsComparisonOp(oSelect.where_expr->nOperation) && oSelect.where_expr->nOperation != SWQ_NE && oSelect.where_expr->nSubExprCount == 2 && (oSelect.where_expr->papoSubExpr[0]->eNodeType == SNT_COLUMN || oSelect.where_expr->papoSubExpr[0]->eNodeType == SNT_CONSTANT) && oSelect.where_expr->papoSubExpr[0]->field_type == SWQ_STRING && EQUAL(oSelect.where_expr->papoSubExpr[0]->string_value, oSelect.order_defs[0].field_name) && oSelect.where_expr->papoSubExpr[1]->eNodeType == SNT_CONSTANT ) { /* ok */ } else eErr = OGRERR_FAILURE; } if( eErr == OGRERR_NONE ) { int i; for(i = 0; i < oSelect.result_columns; i ++ ) { if( oSelect.column_defs[i].col_func != SWQCF_NONE ) break; if( oSelect.column_defs[i].field_name == NULL ) break; if( oSelect.column_defs[i].distinct_flag ) break; if( oSelect.column_defs[i].target_type != SWQ_OTHER ) break; if( strcmp(oSelect.column_defs[i].field_name, "*") != 0 && poLayer->GetLayerDefn()->GetFieldIndex( oSelect.column_defs[i].field_name) < 0 ) break; } if( i != oSelect.result_columns ) eErr = OGRERR_FAILURE; } if( eErr == OGRERR_NONE ) { int op = -1; swq_expr_node* poValue = NULL; if( oSelect.where_expr != NULL ) { op = oSelect.where_expr->nOperation; poValue = oSelect.where_expr->papoSubExpr[1]; } FileGDBIterator *poIter = poLayer->BuildIndex( oSelect.order_defs[0].field_name, oSelect.order_defs[0].ascending_flag, op, poValue); /* Check that they are no NULL values */ if( oSelect.where_expr == NULL && poIter->GetRowCount() != poLayer->GetFeatureCount(FALSE) ) { delete poIter; poIter = NULL; } if( poIter != NULL ) { CPLDebug("OpenFileGDB", "Using OGROpenFileGDBSimpleSQLLayer"); bLastSQLUsedOptimizedImplementation = TRUE; return new OGROpenFileGDBSimpleSQLLayer(poLayer, poIter, oSelect.result_columns, oSelect.column_defs); } } } } } return OGRDataSource::ExecuteSQL(pszSQLCommand, poSpatialFilter, pszDialect); }