[gdal-dev] ogr2ogr and RFC41
Martin Landa
landa.martin at gmail.com
Sun Oct 26 08:10:48 PDT 2014
Hi,
2014-10-24 9:46 GMT+02:00 Martin Landa <landa.martin at gmail.com>:
>> So perhaps something like ?
>> --select *,!geom1,!attr1
>
> yes, it would be nice to have it... Martin
the attached patch shows a way, I am sure that it's possible to
simplily it. Anyway combination as (assuming that a source layer has
three geometry columns) seems to work:
$ ogr2ogr -f PostgreSQL -select '*' PG:dbname=vfr_10 PG:dbname=vfr
staty -overwrite
-> OK all attributes + geom1
$ ogr2ogr -f PostgreSQL -select '*,!geom1' PG:dbname=vfr_10
PG:dbname=vfr staty -overwrite
-> OK, all atributes + geom2
$ ogr2ogr -f PostgreSQL -select '*,!geom1,!geom2' PG:dbname=vfr_10
PG:dbname=vfr staty -overwrite
-> OK, all atributes + geom3
BTW, I would assume that if the destination datasource supports RFC41
than ogr2ogr transfers all geometry columns, but it doesn't seems to
be true, eg.:
$ ogrinfo PG:dbname=vfr staty | grep Geometry
Geometry (definicnibod): Point
Geometry (originalnihranice): Multi Polygon
Geometry (generalizovanehranice): Multi Polygon
Geometry Column 1 = definicnibod
Geometry Column 2 = originalnihranice
Geometry Column 3 = generalizovanehranice
$ ogr2ogr -f PostgreSQL PG:dbname=vfr_10 PG:dbname=vfr staty -overwrite
$ ogrinfo PG:dbname=vfr_10 staty | grep Geometry
Geometry: Unknown (any)
Geometry Column = GEOMETRY
Martin
--
Martin Landa * http://geo.fsv.cvut.cz/gwiki/Landa *
http://www.gismentors.eu/mentors/landa
-------------- next part --------------
Index: apps/ogr2ogr.cpp
===================================================================
--- apps/ogr2ogr.cpp (revision 27908)
+++ apps/ogr2ogr.cpp (working copy)
@@ -38,6 +38,7 @@
#include "commonutils.h"
#include <map>
#include <vector>
+#include <algorithm>
CPL_CVSID("$Id$");
@@ -76,6 +77,9 @@
TargetLayerInfo *psInfo;
} AssociatedLayers;
+static std::vector<CPLString> FilterSelectFields(OGRFeatureDefn *poSrcFDefn,
+ char **papszSelFields, bool);
+
static OGRLayer* GetLayerAndOverwriteIfNecessary(GDALDataset *poDstDS,
const char* pszNewLayerName,
int bOverwrite,
@@ -2561,6 +2565,8 @@
OGRFeatureDefn *poSrcFDefn;
OGRFeatureDefn *poDstFDefn = NULL;
+ std::vector<CPLString> oSelFields;
+
if( pszNewLayerName == NULL )
pszNewLayerName = poSrcLayer->GetName();
@@ -2570,15 +2576,22 @@
poSrcFDefn = poSrcLayer->GetLayerDefn();
/* -------------------------------------------------------------------- */
+/* Filter select fields (*, !col). */
+/* -------------------------------------------------------------------- */
+ if (papszSelFields)
+ oSelFields = FilterSelectFields(poSrcFDefn, papszSelFields,
+ poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer));
+
+/* -------------------------------------------------------------------- */
/* Find requested geometry fields. */
/* -------------------------------------------------------------------- */
std::vector<int> anRequestedGeomFields;
int nSrcGeomFieldCount = poSrcFDefn->GetGeomFieldCount();
- if (papszSelFields && !bAppend )
+ if (oSelFields.size() > 0 && !bAppend )
{
- for( int iField=0; papszSelFields[iField] != NULL; iField++)
+ for( size_t iField=0; iField < oSelFields.size(); iField++)
{
- int iSrcField = poSrcFDefn->GetFieldIndex(papszSelFields[iField]);
+ int iSrcField = poSrcFDefn->GetFieldIndex(oSelFields[iField]);
if (iSrcField >= 0)
{
/* do nothing */
@@ -2585,7 +2598,7 @@
}
else
{
- iSrcField = poSrcFDefn->GetGeomFieldIndex(papszSelFields[iField]);
+ iSrcField = poSrcFDefn->GetGeomFieldIndex(oSelFields[iField]);
if( iSrcField >= 0)
{
anRequestedGeomFields.push_back(iSrcField);
@@ -2593,7 +2606,7 @@
else
{
fprintf( stderr, "Field '%s' not found in source layer.\n",
- papszSelFields[iField] );
+ oSelFields[iField].c_str() );
if( !bSkipFailures )
return NULL;
}
@@ -2797,8 +2810,8 @@
/* the selected fields, and in the order that they were */
/* selected. */
/* -------------------------------------------------------------------- */
- int nSrcFieldCount = poSrcFDefn->GetFieldCount();
- int iField, *panMap;
+ int nSrcFieldCount = poSrcFDefn->GetFieldCount();
+ int iField, *panMap;
// Initialize the index-to-index map to -1's
panMap = (int *) VSIMalloc( sizeof(int) * nSrcFieldCount );
@@ -2834,14 +2847,14 @@
}
}
}
- else if (papszSelFields && !bAppend )
+ else if (oSelFields.size() > 0 && !bAppend )
{
int nDstFieldCount = 0;
if (poDstFDefn)
nDstFieldCount = poDstFDefn->GetFieldCount();
- for( iField=0; papszSelFields[iField] != NULL; iField++)
+ for( iField=0; iField < (int) oSelFields.size(); iField++)
{
- int iSrcField = poSrcFDefn->GetFieldIndex(papszSelFields[iField]);
+ int iSrcField = poSrcFDefn->GetFieldIndex(oSelFields[iField]);
if (iSrcField >= 0)
{
OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iSrcField);
@@ -2920,9 +2933,9 @@
const char* pszFieldName =
poSrcFDefn->GetFieldDefn(iSrcField)->GetNameRef();
int bFieldRequested = FALSE;
- for( iField=0; papszSelFields[iField] != NULL; iField++)
+ for( iField=0; iField < (int) oSelFields.size(); iField++)
{
- if (EQUAL(pszFieldName, papszSelFields[iField]))
+ if (EQUAL(pszFieldName, oSelFields[iField]))
{
bFieldRequested = TRUE;
break;
@@ -3658,3 +3671,104 @@
return TRUE;
}
+
+/* -------------------------------------------------------------------- */
+/* Filter select fields (*, !col). */
+/* -------------------------------------------------------------------- */
+std::vector<CPLString> FilterSelectFields(OGRFeatureDefn *poSrcFDefn, char **papszSelFields,
+ bool bCreateGeom)
+{
+ std::vector<CPLString> oSelFields;
+ int iSrcField, nFCount;
+ const char *pszSrcFieldName;
+
+ // first pass - append requested columns (*)
+ for( int iField = 0; papszSelFields[iField] != NULL; iField++)
+ {
+ const char *pszFieldName = papszSelFields[iField];
+ if( EQUAL(pszFieldName, "*" ) )
+ {
+ // append all attributes
+ nFCount = poSrcFDefn->GetFieldCount();
+ for( iSrcField = 0; iSrcField < nFCount; iSrcField++ )
+ {
+ pszSrcFieldName = poSrcFDefn->GetFieldDefn(iSrcField)->GetNameRef();
+ if( std::find( oSelFields.begin(), oSelFields.end(),
+ pszFieldName) == oSelFields.end() )
+ oSelFields.push_back( pszSrcFieldName );
+ }
+
+ // append also geometrie attributes
+ nFCount = poSrcFDefn->GetGeomFieldCount();
+ for( iSrcField = 0; iSrcField < nFCount; iSrcField++ )
+ {
+ pszSrcFieldName = poSrcFDefn->GetGeomFieldDefn(iSrcField)->GetNameRef();
+ if( std::find( oSelFields.begin(), oSelFields.end(),
+ pszFieldName) == oSelFields.end() )
+ oSelFields.push_back( pszSrcFieldName );
+ }
+ }
+ else if( pszFieldName && pszFieldName[0] == '!' )
+ {
+ continue; // skip
+ }
+ else
+ {
+ if( std::find( oSelFields.begin(), oSelFields.end(),
+ pszFieldName) == oSelFields.end() )
+ oSelFields.push_back(pszFieldName);
+ }
+ }
+
+ // second pass - include all geometry attributes
+ nFCount = poSrcFDefn->GetGeomFieldCount();
+ for( iSrcField = 0; iSrcField < nFCount; iSrcField++ )
+ {
+ pszSrcFieldName = poSrcFDefn->GetGeomFieldDefn(iSrcField)->GetNameRef();
+ if( std::find( oSelFields.begin(), oSelFields.end(),
+ pszSrcFieldName) == oSelFields.end() )
+ oSelFields.push_back( pszSrcFieldName );
+ }
+
+ // third pass - pop requested columns (!col)
+ for( int iField = 0; papszSelFields[iField] != NULL; iField++)
+ {
+ pszSrcFieldName = papszSelFields[iField];
+ if( pszSrcFieldName && pszSrcFieldName[0] == '!' )
+ {
+ CPLString osFieldName(pszSrcFieldName);
+ osFieldName.erase( osFieldName.begin());
+
+ std::vector<CPLString>::iterator iItem = std::remove( oSelFields.begin(),
+ oSelFields.end(), osFieldName );
+ oSelFields.erase( iItem, oSelFields.end() );
+ }
+ }
+
+ // fourth pass - check multiple geometry attributes
+ if ( !bCreateGeom )
+ {
+ bool bFirst = TRUE;
+ nFCount = poSrcFDefn->GetGeomFieldCount();
+ for( iSrcField = 0; iSrcField < nFCount; iSrcField++ )
+ {
+ CPLString osFieldName(poSrcFDefn->GetGeomFieldDefn(iSrcField)->GetNameRef());
+
+ if( std::find( oSelFields.begin(), oSelFields.end(),
+ osFieldName) != oSelFields.end() )
+ {
+
+ if (bFirst)
+ bFirst = FALSE;
+ else
+ {
+ std::vector<CPLString>::iterator iItem = std::remove( oSelFields.begin(),
+ oSelFields.end(), osFieldName );
+ oSelFields.erase( iItem, oSelFields.end() );
+ }
+ }
+ }
+ }
+
+ return oSelFields;
+}
More information about the gdal-dev
mailing list