diff --git a/gdal/apps/ogr2ogr.cpp b/gdal/apps/ogr2ogr.cpp index a06bb7aaacd1..a8fe474b2664 100644 --- a/gdal/apps/ogr2ogr.cpp +++ b/gdal/apps/ogr2ogr.cpp @@ -91,7 +91,8 @@ static TargetLayerInfo* SetupTargetLayer( OGRDataSource *poSrcDS, int bExplodeCollections, const char* pszZField, char **papszFieldMap, - const char* pszWHERE ); + const char* pszWHERE, + int bExactFieldNameMatch ); static void FreeTargetLayerInfo(TargetLayerInfo* psInfo); @@ -866,6 +867,7 @@ int main( int nArgc, char ** papszArgv ) const char *pszSourceSRSDef = NULL; OGRSpatialReference *poOutputSRS = NULL; int bNullifyOutputSRS = FALSE; + int bExactFieldNameMatch = TRUE; OGRSpatialReference *poSourceSRS = NULL; char *pszNewLayerName = NULL; const char *pszWHERE = NULL; @@ -992,6 +994,10 @@ int main( int nArgc, char ** papszArgv ) { bUpdate = TRUE; } + else if( EQUAL(papszArgv[iArg],"-relaxedFieldNameMatch") ) + { + bExactFieldNameMatch = FALSE; + } else if( EQUAL(papszArgv[iArg],"-fid") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); @@ -1409,7 +1415,7 @@ int main( int nArgc, char ** papszArgv ) } if (pszFieldMap && bAddMissingFields) -{ + { Usage("if -addfields is specified, -fieldmap cannot be used."); } @@ -1770,7 +1776,8 @@ int main( int nArgc, char ** papszArgv ) bExplodeCollections, pszZField, papszFieldMap, - pszWHERE ); + pszWHERE, + bExactFieldNameMatch ); poPassedLayer->ResetReading(); @@ -1925,7 +1932,8 @@ int main( int nArgc, char ** papszArgv ) bExplodeCollections, pszZField, papszFieldMap, - pszWHERE ); + pszWHERE, + bExactFieldNameMatch ); if( psInfo == NULL && !bSkipFailures ) exit(1); @@ -2199,7 +2207,8 @@ int main( int nArgc, char ** papszArgv ) bExplodeCollections, pszZField, papszFieldMap, - pszWHERE ); + pszWHERE, + bExactFieldNameMatch ); poPassedLayer->ResetReading(); @@ -2319,6 +2328,7 @@ static void Usage(const char* pszAdditionalMsg, int bShort) " [-wrapdateline][-datelineoffset val]\n" " [[-simplify tolerance] | [-segmentize max_dist]]\n" " [-addfields]\n" + " [-relaxedFieldNameMatch]\n" " [-fieldTypeToString All|(type1[,type2]*)] [-unsetFieldWidth]\n" " [-fieldmap identity | index1[,index2]*]\n" " [-splitlistfields] [-maxsubfields val]\n" @@ -2483,7 +2493,8 @@ static TargetLayerInfo* SetupTargetLayer( OGRDataSource *poSrcDS, int bExplodeCollections, const char* pszZField, char **papszFieldMap, - const char* pszWHERE ) + const char* pszWHERE, + int bExactFieldNameMatch ) { OGRLayer *poDstLayer; OGRFeatureDefn *poSrcFDefn; @@ -3019,7 +3030,7 @@ static TargetLayerInfo* SetupTargetLayer( OGRDataSource *poSrcDS, for( iField = 0; iField < nSrcFieldCount; iField++ ) { OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField); - int iDstField = poDstFDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef()); + int iDstField = poDstLayer->FindFieldIndex(poSrcFieldDefn->GetNameRef(), bExactFieldNameMatch); if (iDstField >= 0) panMap[iField] = iDstField; else diff --git a/gdal/ogr/ogr_api.h b/gdal/ogr/ogr_api.h index 824cbb61ecaf..97b77cfbbbd2 100644 --- a/gdal/ogr/ogr_api.h +++ b/gdal/ogr/ogr_api.h @@ -412,6 +412,7 @@ OGRErr CPL_DLL OGR_L_CreateFeature( OGRLayerH, OGRFeatureH ); OGRErr CPL_DLL OGR_L_DeleteFeature( OGRLayerH, long ); OGRFeatureDefnH CPL_DLL OGR_L_GetLayerDefn( OGRLayerH ); OGRSpatialReferenceH CPL_DLL OGR_L_GetSpatialRef( OGRLayerH ); +int CPL_DLL OGR_L_FindFieldIndex( OGRLayerH, const char *, int bExactMatch ); int CPL_DLL OGR_L_GetFeatureCount( OGRLayerH, int ); OGRErr CPL_DLL OGR_L_GetExtent( OGRLayerH, OGREnvelope *, int ); OGRErr CPL_DLL OGR_L_GetExtentEx( OGRLayerH, int iGeomField, diff --git a/gdal/ogr/ogrsf_frmts/generic/ogrlayer.cpp b/gdal/ogr/ogrsf_frmts/generic/ogrlayer.cpp index 69bea7ebef6d..fe93e82d9e2d 100644 --- a/gdal/ogr/ogrsf_frmts/generic/ogrlayer.cpp +++ b/gdal/ogr/ogrsf_frmts/generic/ogrlayer.cpp @@ -842,6 +842,26 @@ OGRFeatureDefnH OGR_L_GetLayerDefn( OGRLayerH hLayer ) return (OGRFeatureDefnH) ((OGRLayer *)hLayer)->GetLayerDefn(); } +/************************************************************************/ +/* OGR_L_FindFieldIndex() */ +/************************************************************************/ + +int OGR_L_FindFieldIndex( OGRLayerH hLayer, const char *pszFieldName, int bExactMatch ) + +{ + VALIDATE_POINTER1( hLayer, "OGR_L_FindFieldIndex", NULL ); + + return ((OGRLayer *)hLayer)->FindFieldIndex( pszFieldName, bExactMatch ); +} + +/************************************************************************/ +/* FindFieldIndex() */ +/************************************************************************/ + +int OGRLayer::FindFieldIndex( const char *pszFieldName, int bExactMatch ) +{ + return GetLayerDefn()->GetFieldIndex( pszFieldName ); +} /************************************************************************/ /* GetSpatialRef() */ diff --git a/gdal/ogr/ogrsf_frmts/nas/ogrnasdatasource.cpp b/gdal/ogr/ogrsf_frmts/nas/ogrnasdatasource.cpp index 88c41720171d..5eec362b9984 100644 --- a/gdal/ogr/ogrsf_frmts/nas/ogrnasdatasource.cpp +++ b/gdal/ogr/ogrsf_frmts/nas/ogrnasdatasource.cpp @@ -138,6 +138,8 @@ int OGRNASDataSource::Open( const char * pszNewName, int bTestOpen ) strstr(szPtr,"NAS-Operationen_optional.xsd") == NULL && strstr(szPtr,"AAA-Fachschema.xsd") == NULL ) ) { + CPLDebug( "NAS", + "Skipping. No chevrons of NAS found [%s]\n", szPtr ); VSIFClose( fp ); return FALSE; } diff --git a/gdal/ogr/ogrsf_frmts/oci/ogr_oci.h b/gdal/ogr/ogrsf_frmts/oci/ogr_oci.h index 8c6335790925..6475b9f4d167 100644 --- a/gdal/ogr/ogrsf_frmts/oci/ogr_oci.h +++ b/gdal/ogr/ogrsf_frmts/oci/ogr_oci.h @@ -252,6 +252,7 @@ class OGROCILayer : public OGRLayer public: OGROCILayer(); virtual ~OGROCILayer(); + virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch ) { return OGRLayer::FindFieldIndex( pszFieldName, bExactMatch ); } virtual void ResetReading(); virtual OGRFeature *GetNextRawFeature(); @@ -312,6 +313,7 @@ class OGROCIWritableLayer : public OGROCILayer virtual OGRSpatialReference *GetSpatialRef() { return poSRS; } virtual OGRErr CreateField( OGRFieldDefn *poField, int bApproxOK = TRUE ); + virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch ); // following methods are not base class overrides void SetOptions( char ** ); diff --git a/gdal/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp b/gdal/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp index 9e8bd25af2b5..0c8a826ada02 100644 --- a/gdal/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp +++ b/gdal/ogr/ogrsf_frmts/oci/ogrociwritablelayer.cpp @@ -492,3 +492,23 @@ OGRErr OGROCIWritableLayer::TranslateToSDOGeometry( OGRGeometry * poGeometry, return OGRERR_FAILURE; } +int OGROCIWritableLayer::FindFieldIndex( const char *pszFieldName, int bExactMatch ) +{ + int iField = GetLayerDefn()->GetFieldIndex( pszFieldName ); + + if( !bExactMatch && iField < 0 ) + { + // try laundered version + OGROCISession *poSession = poDS->GetSession(); + char *pszSafeName = CPLStrdup( pszFieldName ); + + poSession->CleanName( pszSafeName ); + + iField = GetLayerDefn()->GetFieldIndex( pszSafeName ); + + CPLFree( pszSafeName ); + } + + return iField; +} + diff --git a/gdal/ogr/ogrsf_frmts/ogrsf_frmts.dox b/gdal/ogr/ogrsf_frmts/ogrsf_frmts.dox index 8b65a2ac8f11..4f021f6373ed 100644 --- a/gdal/ogr/ogrsf_frmts/ogrsf_frmts.dox +++ b/gdal/ogr/ogrsf_frmts/ogrsf_frmts.dox @@ -2068,6 +2068,44 @@ by the OGRSFDriverManager. */ +/** + + \fn int OGR_L_FindFieldIndex( OGRLayerH hLayer, const char *, int bExactMatch ); + + \brief Find the index of field in a layer. + + The returned number is the index of the field in the layers, or -1 if the + field doesn't exist. + + If bExactMatch is set to FALSE and the field doesn't exists in the given form + the driver might apply some changes to make it match, like those it might do + if the layer was created (eg. like LAUNDER in the OCI driver). + + This method is the same as the C++ method OGRLayer::FindFieldIndex(). + + @return field index, or -1 if the field doesn't exist + +*/ + +/** + + \fn int OGRLayer::FindFieldIndex( const char *, int bExactMatch ); + + \brief Find the index of field in the layer. + + The returned number is the index of the field in the layers, or -1 if the + field doesn't exist. + + If bExactMatch is set to FALSE and the field doesn't exists in the given form + the driver might apply some changes to make it match, like those it might do + if the layer was created (eg. like LAUNDER in the OCI driver). + + This method is the same as the C function OGR_L_FindFieldIndex(). + + @return field index, or -1 if the field doesn't exist + +*/ + /** \fn OGRSpatialReference *OGRLayer::GetSpatialRef(); diff --git a/gdal/ogr/ogrsf_frmts/ogrsf_frmts.h b/gdal/ogr/ogrsf_frmts/ogrsf_frmts.h index 42493b3a86fb..8e8f28bdc3f6 100644 --- a/gdal/ogr/ogrsf_frmts/ogrsf_frmts.h +++ b/gdal/ogr/ogrsf_frmts/ogrsf_frmts.h @@ -98,6 +98,7 @@ class CPL_DLL OGRLayer virtual const char *GetName(); virtual OGRwkbGeometryType GetGeomType(); virtual OGRFeatureDefn *GetLayerDefn() = 0; + virtual int FindFieldIndex( const char *pszFieldName, int bExactMatch ); virtual OGRSpatialReference *GetSpatialRef(); diff --git a/gdal/swig/include/ogr.i b/gdal/swig/include/ogr.i index b6d1b337d6ee..789f8315b625 100644 --- a/gdal/swig/include/ogr.i +++ b/gdal/swig/include/ogr.i @@ -746,6 +746,10 @@ public: OGRErr RollbackTransaction() { return OGR_L_RollbackTransaction(self); } + + int FindFieldIndex( const char *pszFieldName, int bExactMatch ) { + return OGR_L_FindFieldIndex(self, pszFieldName, bExactMatch ); + } %newobject GetSpatialRef; OSRSpatialReferenceShadow *GetSpatialRef() {