LCOV - code coverage report
Current view: directory - apps - ogr2ogr.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1358 992 73.0 %
Date: 2013-03-30 Functions: 44 27 61.4 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr2ogr.cpp 25762 2013-03-16 22:50:35Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Simple client for translating between formats.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogrsf_frmts.h"
      31                 : #include "ogr_p.h"
      32                 : #include "cpl_conv.h"
      33                 : #include "cpl_string.h"
      34                 : #include "ogr_api.h"
      35                 : #include "gdal.h"
      36                 : #include "gdal_alg.h"
      37                 : #include "commonutils.h"
      38                 : 
      39                 : CPL_CVSID("$Id: ogr2ogr.cpp 25762 2013-03-16 22:50:35Z rouault $");
      40                 : 
      41                 : static int bSkipFailures = FALSE;
      42                 : static int nGroupTransactions = 200;
      43                 : static int bPreserveFID = FALSE;
      44                 : static int nFIDToFetch = OGRNullFID;
      45                 : 
      46                 : static void Usage(int bShort = TRUE);
      47                 : static void Usage(const char* pszAdditionalMsg, int bShort = TRUE);
      48                 : 
      49                 : typedef enum
      50                 : {
      51                 :     NONE,
      52                 :     SEGMENTIZE,
      53                 :     SIMPLIFY_PRESERVE_TOPOLOGY,
      54                 : } GeomOperation;
      55                 : 
      56                 : typedef struct
      57                 : {
      58                 :     GIntBig      nFeaturesRead;
      59                 :     int          bPerFeatureCT;
      60                 :     OGRLayer    *poDstLayer;
      61                 :     OGRCoordinateTransformation *poCT;
      62                 :     char       **papszTransformOptions;
      63                 :     int         *panMap;
      64                 :     int          iSrcZField;
      65                 : } TargetLayerInfo;
      66                 : 
      67                 : typedef struct
      68                 : {
      69                 :     OGRLayer         *poSrcLayer;
      70                 :     TargetLayerInfo  *psInfo;
      71                 : } AssociatedLayers;
      72                 : 
      73                 : static TargetLayerInfo* SetupTargetLayer( OGRDataSource *poSrcDS,
      74                 :                                                 OGRLayer * poSrcLayer,
      75                 :                                                 OGRDataSource *poDstDS,
      76                 :                                                 char **papszLCO,
      77                 :                                                 const char *pszNewLayerName,
      78                 :                                                 OGRSpatialReference *poOutputSRS,
      79                 :                                                 int bNullifyOutputSRS,
      80                 :                                                 char **papszSelFields,
      81                 :                                                 int bAppend, int eGType,
      82                 :                                                 int bPromoteToMulti,
      83                 :                                                 int nCoordDim, int bOverwrite,
      84                 :                                                 char** papszFieldTypesToString,
      85                 :                                                 int bExplodeCollections,
      86                 :                                                 const char* pszZField,
      87                 :                                                 char **papszFieldMap,
      88                 :                                                 const char* pszWHERE );
      89                 : 
      90                 : static void FreeTargetLayerInfo(TargetLayerInfo* psInfo);
      91                 : 
      92                 : static int TranslateLayer( TargetLayerInfo* psInfo,
      93                 :                            OGRDataSource *poSrcDS,
      94                 :                            OGRLayer * poSrcLayer,
      95                 :                            OGRDataSource *poDstDS,
      96                 :                            int bTransform,
      97                 :                            int bWrapDateline,
      98                 :                            const char* pszDateLineOffset,
      99                 :                            OGRSpatialReference *poOutputSRS,
     100                 :                            int bNullifyOutputSRS,
     101                 :                            OGRSpatialReference *poUserSourceSRS,
     102                 :                            OGRCoordinateTransformation *poGCPCoordTrans,
     103                 :                            int eGType,
     104                 :                            int bPromoteToMulti,
     105                 :                            int nCoordDim,
     106                 :                            GeomOperation eGeomOp,
     107                 :                            double dfGeomOpParam,
     108                 :                            long nCountLayerFeatures,
     109                 :                            OGRGeometry* poClipSrc,
     110                 :                            OGRGeometry *poClipDst,
     111                 :                            int bExplodeCollections,
     112                 :                            vsi_l_offset nSrcFileSize,
     113                 :                            GIntBig* pnReadFeatureCount,
     114                 :                            GDALProgressFunc pfnProgress,
     115                 :                            void *pProgressArg);
     116                 : 
     117                 : /* -------------------------------------------------------------------- */
     118                 : /*                  CheckDestDataSourceNameConsistency()                */
     119                 : /* -------------------------------------------------------------------- */
     120                 : 
     121                 : static
     122              43 : void CheckDestDataSourceNameConsistency(const char* pszDestFilename,
     123                 :                                         const char* pszDriverName)
     124                 : {
     125                 :     int i;
     126              43 :     char* pszDestExtension = CPLStrdup(CPLGetExtension(pszDestFilename));
     127                 : 
     128                 :     /* TODO: Would be good to have driver metadata like for GDAL drivers ! */
     129                 :     static const char* apszExtensions[][2] = { { "shp"    , "ESRI Shapefile" },
     130                 :                                                { "dbf"    , "ESRI Shapefile" },
     131                 :                                                { "sqlite" , "SQLite" },
     132                 :                                                { "db"     , "SQLite" },
     133                 :                                                { "mif"    , "MapInfo File" },
     134                 :                                                { "tab"    , "MapInfo File" },
     135                 :                                                { "s57"    , "S57" },
     136                 :                                                { "bna"    , "BNA" },
     137                 :                                                { "csv"    , "CSV" },
     138                 :                                                { "gml"    , "GML" },
     139                 :                                                { "kml"    , "KML/LIBKML" },
     140                 :                                                { "kmz"    , "LIBKML" },
     141                 :                                                { "json"   , "GeoJSON" },
     142                 :                                                { "geojson", "GeoJSON" },
     143                 :                                                { "dxf"    , "DXF" },
     144                 :                                                { "gdb"    , "FileGDB" },
     145                 :                                                { "pix"    , "PCIDSK" },
     146                 :                                                { "sql"    , "PGDump" },
     147                 :                                                { "gtm"    , "GPSTrackMaker" },
     148                 :                                                { "gmt"    , "GMT" },
     149                 :                                                { "pdf"    , "PDF" },
     150                 :                                                { NULL, NULL }
     151                 :                                               };
     152                 :     static const char* apszBeginName[][2] =  { { "PG:"      , "PG" },
     153                 :                                                { "MySQL:"   , "MySQL" },
     154                 :                                                { "CouchDB:" , "CouchDB" },
     155                 :                                                { "GFT:"     , "GFT" },
     156                 :                                                { "MSSQL:"   , "MSSQLSpatial" },
     157                 :                                                { "ODBC:"    , "ODBC" },
     158                 :                                                { "OCI:"     , "OCI" },
     159                 :                                                { "SDE:"     , "SDE" },
     160                 :                                                { "WFS:"     , "WFS" },
     161                 :                                                { NULL, NULL }
     162                 :                                              };
     163                 : 
     164             946 :     for(i=0; apszExtensions[i][0] != NULL; i++)
     165                 :     {
     166             903 :         if (EQUAL(pszDestExtension, apszExtensions[i][0]) && !EQUAL(pszDriverName, apszExtensions[i][1]))
     167                 :         {
     168                 :             fprintf(stderr,
     169                 :                     "Warning: The target file has a '%s' extension, which is normally used by the %s driver,\n"
     170                 :                     "but the requested output driver is %s. Is it really what you want ?\n",
     171                 :                     pszDestExtension,
     172                 :                     apszExtensions[i][1],
     173               0 :                     pszDriverName);
     174               0 :             break;
     175                 :         }
     176                 :     }
     177                 : 
     178             430 :     for(i=0; apszBeginName[i][0] != NULL; i++)
     179                 :     {
     180             387 :         if (EQUALN(pszDestFilename, apszBeginName[i][0], strlen(apszBeginName[i][0])) &&
     181                 :             !EQUAL(pszDriverName, apszBeginName[i][1]))
     182                 :         {
     183                 :             fprintf(stderr,
     184                 :                     "Warning: The target file has a name which is normally recognized by the %s driver,\n"
     185                 :                     "but the requested output driver is %s. Is it really what you want ?\n",
     186                 :                     apszBeginName[i][1],
     187               0 :                     pszDriverName);
     188               0 :             break;
     189                 :         }
     190                 :     }
     191                 : 
     192              43 :     CPLFree(pszDestExtension);
     193              43 : }
     194                 : 
     195                 : /************************************************************************/
     196                 : /*                            IsNumber()                               */
     197                 : /************************************************************************/
     198                 : 
     199               5 : static int IsNumber(const char* pszStr)
     200                 : {
     201               5 :     if (*pszStr == '-' || *pszStr == '+')
     202               0 :         pszStr ++;
     203               5 :     if (*pszStr == '.')
     204               0 :         pszStr ++;
     205               5 :     return (*pszStr >= '0' && *pszStr <= '9');
     206                 : }
     207                 : 
     208                 : /************************************************************************/
     209                 : /*                           LoadGeometry()                             */
     210                 : /************************************************************************/
     211                 : 
     212               2 : static OGRGeometry* LoadGeometry( const char* pszDS,
     213                 :                                   const char* pszSQL,
     214                 :                                   const char* pszLyr,
     215                 :                                   const char* pszWhere)
     216                 : {
     217                 :     OGRDataSource       *poDS;
     218                 :     OGRLayer            *poLyr;
     219                 :     OGRFeature          *poFeat;
     220               2 :     OGRGeometry         *poGeom = NULL;
     221                 :         
     222               2 :     poDS = OGRSFDriverRegistrar::Open( pszDS, FALSE );
     223               2 :     if (poDS == NULL)
     224               0 :         return NULL;
     225                 : 
     226               2 :     if (pszSQL != NULL)
     227               1 :         poLyr = poDS->ExecuteSQL( pszSQL, NULL, NULL ); 
     228               1 :     else if (pszLyr != NULL)
     229               0 :         poLyr = poDS->GetLayerByName(pszLyr);
     230                 :     else
     231               1 :         poLyr = poDS->GetLayer(0);
     232                 :         
     233               2 :     if (poLyr == NULL)
     234                 :     {
     235               0 :         fprintf( stderr, "Failed to identify source layer from datasource.\n" );
     236               0 :         OGRDataSource::DestroyDataSource(poDS);
     237               0 :         return NULL;
     238                 :     }
     239                 :     
     240               2 :     if (pszWhere)
     241               1 :         poLyr->SetAttributeFilter(pszWhere);
     242                 :         
     243               6 :     while ((poFeat = poLyr->GetNextFeature()) != NULL)
     244                 :     {
     245               2 :         OGRGeometry* poSrcGeom = poFeat->GetGeometryRef();
     246               2 :         if (poSrcGeom)
     247                 :         {
     248               2 :             OGRwkbGeometryType eType = wkbFlatten( poSrcGeom->getGeometryType() );
     249                 :             
     250               2 :             if (poGeom == NULL)
     251               2 :                 poGeom = OGRGeometryFactory::createGeometry( wkbMultiPolygon );
     252                 : 
     253               2 :             if( eType == wkbPolygon )
     254               2 :                 ((OGRGeometryCollection*)poGeom)->addGeometry( poSrcGeom );
     255               0 :             else if( eType == wkbMultiPolygon )
     256                 :             {
     257                 :                 int iGeom;
     258               0 :                 int nGeomCount = OGR_G_GetGeometryCount( (OGRGeometryH)poSrcGeom );
     259                 : 
     260               0 :                 for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
     261                 :                 {
     262                 :                     ((OGRGeometryCollection*)poGeom)->addGeometry(
     263               0 :                                 ((OGRGeometryCollection*)poSrcGeom)->getGeometryRef(iGeom) );
     264                 :                 }
     265                 :             }
     266                 :             else
     267                 :             {
     268               0 :                 fprintf( stderr, "ERROR: Geometry not of polygon type.\n" );
     269               0 :                 OGRGeometryFactory::destroyGeometry(poGeom);
     270               0 :                 OGRFeature::DestroyFeature(poFeat);
     271               0 :                 if( pszSQL != NULL )
     272               0 :                     poDS->ReleaseResultSet( poLyr );
     273               0 :                 OGRDataSource::DestroyDataSource(poDS);
     274               0 :                 return NULL;
     275                 :             }
     276                 :         }
     277                 :     
     278               2 :         OGRFeature::DestroyFeature(poFeat);
     279                 :     }
     280                 :     
     281               2 :     if( pszSQL != NULL )
     282               1 :         poDS->ReleaseResultSet( poLyr );
     283               2 :     OGRDataSource::DestroyDataSource(poDS);
     284                 :     
     285               2 :     return poGeom;
     286                 : }
     287                 : 
     288                 : 
     289                 : /************************************************************************/
     290                 : /*                     OGRSplitListFieldLayer                           */
     291                 : /************************************************************************/
     292                 : 
     293                 : typedef struct
     294                 : {
     295                 :     int          iSrcIndex;
     296                 :     OGRFieldType eType;
     297                 :     int          nMaxOccurences;
     298                 :     int          nWidth;
     299                 : } ListFieldDesc;
     300                 : 
     301                 : class OGRSplitListFieldLayer : public OGRLayer
     302                 : {
     303                 :     OGRLayer                    *poSrcLayer;
     304                 :     OGRFeatureDefn              *poFeatureDefn;
     305                 :     ListFieldDesc               *pasListFields;
     306                 :     int                          nListFieldCount;
     307                 :     int                          nMaxSplitListSubFields;
     308                 : 
     309                 :     OGRFeature                  *TranslateFeature(OGRFeature* poSrcFeature);
     310                 : 
     311                 :   public:
     312                 :                                  OGRSplitListFieldLayer(OGRLayer* poSrcLayer,
     313                 :                                                         int nMaxSplitListSubFields);
     314                 :                                 ~OGRSplitListFieldLayer();
     315                 : 
     316                 :     int                          BuildLayerDefn(GDALProgressFunc pfnProgress,
     317                 :                                                 void *pProgressArg);
     318                 : 
     319                 :     virtual OGRFeature          *GetNextFeature();
     320                 :     virtual OGRFeature          *GetFeature(long nFID);
     321                 :     virtual OGRFeatureDefn      *GetLayerDefn();
     322                 : 
     323               1 :     virtual void                 ResetReading() { poSrcLayer->ResetReading(); }
     324               0 :     virtual int                  TestCapability(const char*) { return FALSE; }
     325                 : 
     326               0 :     virtual int                  GetFeatureCount( int bForce = TRUE )
     327                 :     {
     328               0 :         return poSrcLayer->GetFeatureCount(bForce);
     329                 :     }
     330                 : 
     331               2 :     virtual OGRSpatialReference *GetSpatialRef()
     332                 :     {
     333               2 :         return poSrcLayer->GetSpatialRef();
     334                 :     }
     335                 : 
     336               0 :     virtual OGRGeometry         *GetSpatialFilter()
     337                 :     {
     338               0 :         return poSrcLayer->GetSpatialFilter();
     339                 :     }
     340                 : 
     341               1 :     virtual OGRStyleTable       *GetStyleTable()
     342                 :     {
     343               1 :         return poSrcLayer->GetStyleTable();
     344                 :     }
     345                 : 
     346               0 :     virtual void                 SetSpatialFilter( OGRGeometry *poGeom )
     347                 :     {
     348               0 :         poSrcLayer->SetSpatialFilter(poGeom);
     349               0 :     }
     350                 : 
     351               0 :     virtual void                 SetSpatialFilterRect( double dfMinX, double dfMinY,
     352                 :                                                        double dfMaxX, double dfMaxY )
     353                 :     {
     354               0 :         poSrcLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
     355               0 :     }
     356                 : 
     357               0 :     virtual OGRErr               SetAttributeFilter( const char *pszFilter )
     358                 :     {
     359               0 :         return poSrcLayer->SetAttributeFilter(pszFilter);
     360                 :     }
     361                 : };
     362                 : 
     363                 : /************************************************************************/
     364                 : /*                    OGRSplitListFieldLayer()                          */
     365                 : /************************************************************************/
     366                 : 
     367               1 : OGRSplitListFieldLayer::OGRSplitListFieldLayer(OGRLayer* poSrcLayer,
     368               1 :                                                int nMaxSplitListSubFields)
     369                 : {
     370               1 :     this->poSrcLayer = poSrcLayer;
     371               1 :     if (nMaxSplitListSubFields < 0)
     372               1 :         nMaxSplitListSubFields = INT_MAX;
     373               1 :     this->nMaxSplitListSubFields = nMaxSplitListSubFields;
     374               1 :     poFeatureDefn = NULL;
     375               1 :     pasListFields = NULL;
     376               1 :     nListFieldCount = 0;
     377               1 : }
     378                 : 
     379                 : /************************************************************************/
     380                 : /*                   ~OGRSplitListFieldLayer()                          */
     381                 : /************************************************************************/
     382                 : 
     383               1 : OGRSplitListFieldLayer::~OGRSplitListFieldLayer()
     384                 : {
     385               1 :     if( poFeatureDefn )
     386               1 :         poFeatureDefn->Release();
     387                 : 
     388               1 :     CPLFree(pasListFields);
     389               1 : }
     390                 : 
     391                 : /************************************************************************/
     392                 : /*                       BuildLayerDefn()                               */
     393                 : /************************************************************************/
     394                 : 
     395               1 : int  OGRSplitListFieldLayer::BuildLayerDefn(GDALProgressFunc pfnProgress,
     396                 :                                             void *pProgressArg)
     397                 : {
     398               1 :     CPLAssert(poFeatureDefn == NULL);
     399                 :     
     400               1 :     OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
     401                 :     
     402               1 :     int nSrcFields = poSrcFieldDefn->GetFieldCount();
     403                 :     pasListFields =
     404               1 :             (ListFieldDesc*)CPLCalloc(sizeof(ListFieldDesc), nSrcFields);
     405               1 :     nListFieldCount = 0;
     406                 :     int i;
     407                 :     
     408                 :     /* Establish the list of fields of list type */
     409               6 :     for(i=0;i<nSrcFields;i++)
     410                 :     {
     411               5 :         OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
     412               5 :         if (eType == OFTIntegerList ||
     413                 :             eType == OFTRealList ||
     414                 :             eType == OFTStringList)
     415                 :         {
     416               3 :             pasListFields[nListFieldCount].iSrcIndex = i;
     417               3 :             pasListFields[nListFieldCount].eType = eType;
     418               3 :             if (nMaxSplitListSubFields == 1)
     419               0 :                 pasListFields[nListFieldCount].nMaxOccurences = 1;
     420               3 :             nListFieldCount++;
     421                 :         }
     422                 :     }
     423                 : 
     424               1 :     if (nListFieldCount == 0)
     425               0 :         return FALSE;
     426                 : 
     427                 :     /* No need for full scan if the limit is 1. We just to have to create */
     428                 :     /* one and a single one field */
     429               1 :     if (nMaxSplitListSubFields != 1)
     430                 :     {
     431               1 :         poSrcLayer->ResetReading();
     432                 :         OGRFeature* poSrcFeature;
     433                 : 
     434               1 :         int nFeatureCount = 0;
     435               1 :         if (poSrcLayer->TestCapability(OLCFastFeatureCount))
     436               1 :             nFeatureCount = poSrcLayer->GetFeatureCount();
     437               1 :         int nFeatureIndex = 0;
     438                 : 
     439                 :         /* Scan the whole layer to compute the maximum number of */
     440                 :         /* items for each field of list type */
     441               3 :         while( (poSrcFeature = poSrcLayer->GetNextFeature()) != NULL )
     442                 :         {
     443               4 :             for(i=0;i<nListFieldCount;i++)
     444                 :             {
     445               3 :                 int nCount = 0;
     446                 :                 OGRField* psField =
     447               3 :                         poSrcFeature->GetRawFieldRef(pasListFields[i].iSrcIndex);
     448               3 :                 switch(pasListFields[i].eType)
     449                 :                 {
     450                 :                     case OFTIntegerList:
     451               1 :                         nCount = psField->IntegerList.nCount;
     452               1 :                         break;
     453                 :                     case OFTRealList:
     454               1 :                         nCount = psField->RealList.nCount;
     455               1 :                         break;
     456                 :                     case OFTStringList:
     457                 :                     {
     458               1 :                         nCount = psField->StringList.nCount;
     459               1 :                         char** paList = psField->StringList.paList;
     460                 :                         int j;
     461               3 :                         for(j=0;j<nCount;j++)
     462                 :                         {
     463               2 :                             int nWidth = strlen(paList[j]);
     464               2 :                             if (nWidth > pasListFields[i].nWidth)
     465               1 :                                 pasListFields[i].nWidth = nWidth;
     466                 :                         }
     467               1 :                         break;
     468                 :                     }
     469                 :                     default:
     470               0 :                         CPLAssert(0);
     471                 :                         break;
     472                 :                 }
     473               3 :                 if (nCount > pasListFields[i].nMaxOccurences)
     474                 :                 {
     475               3 :                     if (nCount > nMaxSplitListSubFields)
     476               0 :                         nCount = nMaxSplitListSubFields;
     477               3 :                     pasListFields[i].nMaxOccurences = nCount;
     478                 :                 }
     479                 :             }
     480               1 :             OGRFeature::DestroyFeature(poSrcFeature);
     481                 : 
     482               1 :             nFeatureIndex ++;
     483               1 :             if (pfnProgress != NULL && nFeatureCount != 0)
     484               0 :                 pfnProgress(nFeatureIndex * 1.0 / nFeatureCount, "", pProgressArg);
     485                 :         }
     486                 :     }
     487                 : 
     488                 :     /* Now let's build the target feature definition */
     489                 : 
     490                 :     poFeatureDefn =
     491               1 :             OGRFeatureDefn::CreateFeatureDefn( poSrcFieldDefn->GetName() );
     492               1 :     poFeatureDefn->Reference();
     493               1 :     poFeatureDefn->SetGeomType( poSrcFieldDefn->GetGeomType() );
     494                 : 
     495               1 :     int iListField = 0;
     496               6 :     for(i=0;i<nSrcFields;i++)
     497                 :     {
     498               5 :         OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
     499               8 :         if (eType == OFTIntegerList ||
     500                 :             eType == OFTRealList ||
     501                 :             eType == OFTStringList)
     502                 :         {
     503               3 :             int nMaxOccurences = pasListFields[iListField].nMaxOccurences;
     504               3 :             int nWidth = pasListFields[iListField].nWidth;
     505               3 :             iListField ++;
     506                 :             int j;
     507               3 :             if (nMaxOccurences == 1)
     508                 :             {
     509                 :                 OGRFieldDefn oFieldDefn(poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(),
     510                 :                                             (eType == OFTIntegerList) ? OFTInteger :
     511                 :                                             (eType == OFTRealList) ?    OFTReal :
     512               0 :                                                                         OFTString);
     513               0 :                 poFeatureDefn->AddFieldDefn(&oFieldDefn);
     514                 :             }
     515                 :             else
     516                 :             {
     517               9 :                 for(j=0;j<nMaxOccurences;j++)
     518                 :                 {
     519               6 :                     CPLString osFieldName;
     520                 :                     osFieldName.Printf("%s%d",
     521               6 :                         poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(), j+1);
     522                 :                     OGRFieldDefn oFieldDefn(osFieldName.c_str(),
     523                 :                                             (eType == OFTIntegerList) ? OFTInteger :
     524                 :                                             (eType == OFTRealList) ?    OFTReal :
     525               6 :                                                                         OFTString);
     526               6 :                     oFieldDefn.SetWidth(nWidth);
     527               6 :                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
     528                 :                 }
     529                 :             }
     530                 :         }
     531                 :         else
     532                 :         {
     533               2 :             poFeatureDefn->AddFieldDefn(poSrcFieldDefn->GetFieldDefn(i));
     534                 :         }
     535                 :     }
     536                 : 
     537               1 :     return TRUE;
     538                 : }
     539                 : 
     540                 : 
     541                 : /************************************************************************/
     542                 : /*                       TranslateFeature()                             */
     543                 : /************************************************************************/
     544                 : 
     545               2 : OGRFeature *OGRSplitListFieldLayer::TranslateFeature(OGRFeature* poSrcFeature)
     546                 : {
     547               2 :     if (poSrcFeature == NULL)
     548               1 :         return NULL;
     549               1 :     if (poFeatureDefn == NULL)
     550               0 :         return poSrcFeature;
     551                 : 
     552               1 :     OGRFeature* poFeature = OGRFeature::CreateFeature(poFeatureDefn);
     553               1 :     poFeature->SetFID(poSrcFeature->GetFID());
     554               1 :     poFeature->SetGeometryDirectly(poSrcFeature->StealGeometry());
     555               1 :     poFeature->SetStyleString(poFeature->GetStyleString());
     556                 : 
     557               1 :     OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
     558               1 :     int nSrcFields = poSrcFeature->GetFieldCount();
     559                 :     int iSrcField;
     560               1 :     int iDstField = 0;
     561               1 :     int iListField = 0;
     562                 :     int j;
     563               6 :     for(iSrcField=0;iSrcField<nSrcFields;iSrcField++)
     564                 :     {
     565               5 :         OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(iSrcField)->GetType();
     566               5 :         OGRField* psField = poSrcFeature->GetRawFieldRef(iSrcField);
     567               5 :         switch(eType)
     568                 :         {
     569                 :             case OFTIntegerList:
     570                 :             {
     571               1 :                 int nCount = psField->IntegerList.nCount;
     572               1 :                 if (nCount > nMaxSplitListSubFields)
     573               0 :                     nCount = nMaxSplitListSubFields;
     574               1 :                 int* paList = psField->IntegerList.paList;
     575               3 :                 for(j=0;j<nCount;j++)
     576               2 :                     poFeature->SetField(iDstField + j, paList[j]);
     577               1 :                 iDstField += pasListFields[iListField].nMaxOccurences;
     578               1 :                 iListField++;
     579               1 :                 break;
     580                 :             }
     581                 :             case OFTRealList:
     582                 :             {
     583               1 :                 int nCount = psField->RealList.nCount;
     584               1 :                 if (nCount > nMaxSplitListSubFields)
     585               0 :                     nCount = nMaxSplitListSubFields;
     586               1 :                 double* paList = psField->RealList.paList;
     587               3 :                 for(j=0;j<nCount;j++)
     588               2 :                     poFeature->SetField(iDstField + j, paList[j]);
     589               1 :                 iDstField += pasListFields[iListField].nMaxOccurences;
     590               1 :                 iListField++;
     591               1 :                 break;
     592                 :             }
     593                 :             case OFTStringList:
     594                 :             {
     595               1 :                 int nCount = psField->StringList.nCount;
     596               1 :                 if (nCount > nMaxSplitListSubFields)
     597               0 :                     nCount = nMaxSplitListSubFields;
     598               1 :                 char** paList = psField->StringList.paList;
     599               3 :                 for(j=0;j<nCount;j++)
     600               2 :                     poFeature->SetField(iDstField + j, paList[j]);
     601               1 :                 iDstField += pasListFields[iListField].nMaxOccurences;
     602               1 :                 iListField++;
     603               1 :                 break;
     604                 :             }
     605                 :             default:
     606               2 :                 poFeature->SetField(iDstField, psField);
     607               2 :                 iDstField ++;
     608                 :                 break;
     609                 :         }
     610                 :     }
     611                 : 
     612               1 :     OGRFeature::DestroyFeature(poSrcFeature);
     613                 : 
     614               1 :     return poFeature;
     615                 : }
     616                 : 
     617                 : /************************************************************************/
     618                 : /*                       GetNextFeature()                               */
     619                 : /************************************************************************/
     620                 : 
     621               2 : OGRFeature *OGRSplitListFieldLayer::GetNextFeature()
     622                 : {
     623               2 :     return TranslateFeature(poSrcLayer->GetNextFeature());
     624                 : }
     625                 : 
     626                 : /************************************************************************/
     627                 : /*                           GetFeature()                               */
     628                 : /************************************************************************/
     629                 : 
     630               0 : OGRFeature *OGRSplitListFieldLayer::GetFeature(long nFID)
     631                 : {
     632               0 :     return TranslateFeature(poSrcLayer->GetFeature(nFID));
     633                 : }
     634                 : 
     635                 : /************************************************************************/
     636                 : /*                        GetLayerDefn()                                */
     637                 : /************************************************************************/
     638                 : 
     639               2 : OGRFeatureDefn* OGRSplitListFieldLayer::GetLayerDefn()
     640                 : {
     641               2 :     if (poFeatureDefn == NULL)
     642               0 :         return poSrcLayer->GetLayerDefn();
     643               2 :     return poFeatureDefn;
     644                 : }
     645                 : 
     646                 : /************************************************************************/
     647                 : /*                            GCPCoordTransformation()                  */
     648                 : /*                                                                      */
     649                 : /*      Apply GCP Transform to points                                   */
     650                 : /************************************************************************/
     651                 : 
     652                 : class GCPCoordTransformation : public OGRCoordinateTransformation
     653                 : {
     654                 : public:
     655                 : 
     656                 :     void               *hTransformArg;
     657                 :     int                 bUseTPS;
     658                 :     OGRSpatialReference* poSRS;
     659                 : 
     660               5 :     GCPCoordTransformation( int nGCPCount,
     661                 :                             const GDAL_GCP *pasGCPList,
     662                 :                             int  nReqOrder,
     663                 :                             OGRSpatialReference* poSRS)
     664               5 :     {
     665               5 :         if( nReqOrder < 0 )
     666                 :         {
     667               1 :             bUseTPS = TRUE;
     668                 :             hTransformArg = 
     669               1 :                 GDALCreateTPSTransformer( nGCPCount, pasGCPList, FALSE );
     670                 :         }
     671                 :         else
     672                 :         {
     673               4 :             bUseTPS = FALSE;
     674                 :             hTransformArg = 
     675               4 :                 GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, FALSE );
     676                 :         }
     677               5 :         this->poSRS = poSRS;
     678               5 :         if( poSRS) 
     679               2 :             poSRS->Reference();
     680               5 :     }
     681                 : 
     682               5 :     int IsValid() const { return hTransformArg != NULL; }
     683                 : 
     684               5 :     virtual ~GCPCoordTransformation()
     685               5 :     {
     686               5 :         if( hTransformArg != NULL )
     687                 :         {
     688               5 :             if( bUseTPS )
     689               1 :                 GDALDestroyTPSTransformer(hTransformArg);
     690                 :             else
     691               4 :                 GDALDestroyGCPTransformer(hTransformArg);
     692                 :         }
     693               5 :         if( poSRS) 
     694               2 :             poSRS->Dereference();
     695               5 :     }
     696                 : 
     697               0 :     virtual OGRSpatialReference *GetSourceCS() { return poSRS; }
     698               8 :     virtual OGRSpatialReference *GetTargetCS() { return poSRS; }
     699                 : 
     700              10 :     virtual int Transform( int nCount, 
     701                 :                            double *x, double *y, double *z = NULL )
     702                 :     {
     703              10 :         int *pabSuccess = (int *) CPLMalloc(sizeof(int) * nCount );
     704                 :         int bOverallSuccess, i;
     705                 : 
     706              10 :         bOverallSuccess = TransformEx( nCount, x, y, z, pabSuccess );
     707                 : 
     708              20 :         for( i = 0; i < nCount; i++ )
     709                 :         {
     710              10 :             if( !pabSuccess[i] )
     711                 :             {
     712               0 :                 bOverallSuccess = FALSE;
     713               0 :                 break;
     714                 :             }
     715                 :         }
     716                 : 
     717              10 :         CPLFree( pabSuccess );
     718                 : 
     719              10 :         return bOverallSuccess;
     720                 :     }
     721                 : 
     722              10 :     virtual int TransformEx( int nCount, 
     723                 :                              double *x, double *y, double *z = NULL,
     724                 :                              int *pabSuccess = NULL )
     725                 :     {
     726              10 :         if( bUseTPS )
     727                 :             return GDALTPSTransform( hTransformArg, FALSE, 
     728               2 :                                  nCount, x, y, z, pabSuccess );
     729                 :         else
     730                 :             return GDALGCPTransform( hTransformArg, FALSE, 
     731               8 :                                  nCount, x, y, z, pabSuccess );
     732                 :     }
     733                 : };
     734                 : 
     735                 : /************************************************************************/
     736                 : /*                            CompositeCT                               */
     737                 : /************************************************************************/
     738                 : 
     739                 : class CompositeCT : public OGRCoordinateTransformation
     740                 : {
     741                 : public:
     742                 : 
     743                 :     OGRCoordinateTransformation* poCT1;
     744                 :     OGRCoordinateTransformation* poCT2;
     745                 : 
     746               1 :     CompositeCT( OGRCoordinateTransformation* poCT1, /* will not be deleted */
     747                 :                  OGRCoordinateTransformation* poCT2  /* deleted with OGRCoordinateTransformation::DestroyCT() */ )
     748               1 :     {
     749               1 :         this->poCT1 = poCT1;
     750               1 :         this->poCT2 = poCT2;
     751               1 :     }
     752                 : 
     753               1 :     virtual ~CompositeCT()
     754               1 :     {
     755               1 :         OGRCoordinateTransformation::DestroyCT(poCT2);
     756               1 :     }
     757                 : 
     758               0 :     virtual OGRSpatialReference *GetSourceCS()
     759                 :     {
     760               0 :         return poCT1 ? poCT1->GetSourceCS() :
     761               0 :                poCT2 ? poCT2->GetSourceCS() : NULL;
     762                 :     }
     763                 : 
     764               2 :     virtual OGRSpatialReference *GetTargetCS()
     765                 :     {
     766               2 :         return poCT2 ? poCT2->GetTargetCS() :
     767               4 :                poCT1 ? poCT1->GetTargetCS() : NULL;
     768                 :     }
     769                 : 
     770               2 :     virtual int Transform( int nCount, 
     771                 :                            double *x, double *y, double *z = NULL )
     772                 :     {
     773               2 :         int nResult = TRUE;
     774               2 :         if( poCT1 )
     775               2 :             nResult = poCT1->Transform(nCount, x, y, z);
     776               2 :         if( nResult && poCT2 )
     777               2 :             nResult = poCT2->Transform(nCount, x, y, z);
     778               2 :         return nResult;
     779                 :     }
     780                 : 
     781               0 :     virtual int TransformEx( int nCount, 
     782                 :                              double *x, double *y, double *z = NULL,
     783                 :                              int *pabSuccess = NULL )
     784                 :     {
     785               0 :         int nResult = TRUE;
     786               0 :         if( poCT1 )
     787               0 :             nResult = poCT1->TransformEx(nCount, x, y, z, pabSuccess);
     788               0 :         if( nResult && poCT2 )
     789               0 :             nResult = poCT2->TransformEx(nCount, x, y, z, pabSuccess);
     790               0 :         return nResult;
     791                 :     }
     792                 : };
     793                 : 
     794                 : /************************************************************************/
     795                 : /*                                main()                                */
     796                 : /************************************************************************/
     797                 : 
     798                 : #define CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(nExtraArg) \
     799                 :     do { if (iArg + nExtraArg >= nArgc) \
     800                 :         Usage(CPLSPrintf("%s option requires %d argument(s)", papszArgv[iArg], nExtraArg)); } while(0)
     801                 : 
     802              91 : int main( int nArgc, char ** papszArgv )
     803                 : 
     804                 : {
     805              91 :     int          nRetCode = 0;
     806              91 :     int          bQuiet = FALSE;
     807              91 :     int          bFormatExplicitelySet = FALSE;
     808              91 :     const char  *pszFormat = "ESRI Shapefile";
     809              91 :     const char  *pszDataSource = NULL;
     810              91 :     const char  *pszDestDataSource = NULL;
     811              91 :     char        **papszLayers = NULL;
     812              91 :     char        **papszDSCO = NULL, **papszLCO = NULL;
     813              91 :     int         bTransform = FALSE;
     814              91 :     int         bAppend = FALSE, bUpdate = FALSE, bOverwrite = FALSE;
     815              91 :     const char  *pszOutputSRSDef = NULL;
     816              91 :     const char  *pszSourceSRSDef = NULL;
     817              91 :     OGRSpatialReference *poOutputSRS = NULL;
     818              91 :     int         bNullifyOutputSRS = FALSE;
     819              91 :     OGRSpatialReference *poSourceSRS = NULL;
     820              91 :     char        *pszNewLayerName = NULL;
     821              91 :     const char  *pszWHERE = NULL;
     822              91 :     OGRGeometry *poSpatialFilter = NULL;
     823                 :     const char  *pszSelect;
     824              91 :     char        **papszSelFields = NULL;
     825              91 :     const char  *pszSQLStatement = NULL;
     826              91 :     const char  *pszDialect = NULL;
     827              91 :     int         eGType = -2;
     828              91 :     int          bPromoteToMulti = FALSE;
     829              91 :     GeomOperation eGeomOp = NONE;
     830              91 :     double       dfGeomOpParam = 0;
     831              91 :     char        **papszFieldTypesToString = NULL;
     832              91 :     int          bDisplayProgress = FALSE;
     833              91 :     GDALProgressFunc pfnProgress = NULL;
     834              91 :     void        *pProgressArg = NULL;
     835              91 :     int          bWrapDateline = FALSE;
     836              91 :     const char  *pszDateLineOffset = "10";
     837              91 :     int          bClipSrc = FALSE;
     838              91 :     OGRGeometry* poClipSrc = NULL;
     839              91 :     const char  *pszClipSrcDS = NULL;
     840              91 :     const char  *pszClipSrcSQL = NULL;
     841              91 :     const char  *pszClipSrcLayer = NULL;
     842              91 :     const char  *pszClipSrcWhere = NULL;
     843              91 :     OGRGeometry *poClipDst = NULL;
     844              91 :     const char  *pszClipDstDS = NULL;
     845              91 :     const char  *pszClipDstSQL = NULL;
     846              91 :     const char  *pszClipDstLayer = NULL;
     847              91 :     const char  *pszClipDstWhere = NULL;
     848              91 :     int          bSplitListFields = FALSE;
     849              91 :     int          nMaxSplitListSubFields = -1;
     850              91 :     int          bExplodeCollections = FALSE;
     851              91 :     const char  *pszZField = NULL;
     852              91 :     const char  *pszFieldMap = NULL;
     853              91 :     char        **papszFieldMap = NULL;
     854              91 :     int          nCoordDim = -1;
     855                 :  
     856              91 :     int          nGCPCount = 0;
     857              91 :     GDAL_GCP    *pasGCPs = NULL;
     858              91 :     int          nTransformOrder = 0;  /* Default to 0 for now... let the lib decide */
     859                 : 
     860                 :     /* Check strict compilation and runtime library version as we use C++ API */
     861              91 :     if (! GDAL_CHECK_VERSION(papszArgv[0]))
     862               0 :         exit(1);
     863                 : 
     864              91 :     EarlySetConfigOptions(nArgc, papszArgv);
     865                 : 
     866                 : /* -------------------------------------------------------------------- */
     867                 : /*      Register format(s).                                             */
     868                 : /* -------------------------------------------------------------------- */
     869              91 :     OGRRegisterAll();
     870                 : 
     871                 : /* -------------------------------------------------------------------- */
     872                 : /*      Processing command line arguments.                              */
     873                 : /* -------------------------------------------------------------------- */
     874              91 :     nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
     875                 :     
     876              91 :     if( nArgc < 1 )
     877               0 :         exit( -nArgc );
     878                 : 
     879             444 :     for( int iArg = 1; iArg < nArgc; iArg++ )
     880                 :     {
     881             355 :         if( EQUAL(papszArgv[iArg], "--utility_version") )
     882                 :         {
     883                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
     884               2 :                    papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     885               2 :             return 0;
     886                 :         }
     887             353 :         else if( EQUAL(papszArgv[iArg],"--help") )
     888               0 :             Usage();
     889             353 :         else if ( EQUAL(papszArgv[iArg], "--long-usage") )
     890                 :         {
     891               0 :             Usage(FALSE);
     892                 :         }
     893                 : 
     894             353 :         else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet") )
     895                 :         {
     896               0 :             bQuiet = TRUE;
     897                 :         }
     898             353 :         else if( EQUAL(papszArgv[iArg],"-f") )
     899                 :         {
     900              34 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     901              34 :             bFormatExplicitelySet = TRUE;
     902              34 :             pszFormat = papszArgv[++iArg];
     903                 :         }
     904             319 :         else if( EQUAL(papszArgv[iArg],"-dsco") )
     905                 :         {
     906               3 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     907               3 :             papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg] );
     908                 :         }
     909             316 :         else if( EQUAL(papszArgv[iArg],"-lco") )
     910                 :         {
     911               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     912               1 :             papszLCO = CSLAddString(papszLCO, papszArgv[++iArg] );
     913                 :         }
     914             315 :         else if( EQUAL(papszArgv[iArg],"-preserve_fid") )
     915                 :         {
     916               0 :             bPreserveFID = TRUE;
     917                 :         }
     918             315 :         else if( EQUALN(papszArgv[iArg],"-skip",5) )
     919                 :         {
     920               0 :             bSkipFailures = TRUE;
     921               0 :             nGroupTransactions = 1; /* #2409 */
     922                 :         }
     923             315 :         else if( EQUAL(papszArgv[iArg],"-append") )
     924                 :         {
     925               8 :             bAppend = TRUE;
     926               8 :             bUpdate = TRUE;
     927                 :         }
     928             307 :         else if( EQUAL(papszArgv[iArg],"-overwrite") )
     929                 :         {
     930              11 :             bOverwrite = TRUE;
     931              11 :             bUpdate = TRUE;
     932                 :         }
     933             296 :         else if( EQUAL(papszArgv[iArg],"-update") )
     934                 :         {
     935               4 :             bUpdate = TRUE;
     936                 :         }
     937             292 :         else if( EQUAL(papszArgv[iArg],"-fid") )
     938                 :         {
     939               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     940               1 :             nFIDToFetch = atoi(papszArgv[++iArg]);
     941                 :         }
     942             291 :         else if( EQUAL(papszArgv[iArg],"-sql") )
     943                 :         {
     944               7 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     945               7 :             pszSQLStatement = papszArgv[++iArg];
     946                 :         }
     947             284 :         else if( EQUAL(papszArgv[iArg],"-dialect") )
     948                 :         {
     949               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     950               0 :             pszDialect = papszArgv[++iArg];
     951                 :         }
     952             284 :         else if( EQUAL(papszArgv[iArg],"-nln") )
     953                 :         {
     954              13 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     955              13 :             pszNewLayerName = CPLStrdup(papszArgv[++iArg]);
     956                 :         }
     957             271 :         else if( EQUAL(papszArgv[iArg],"-nlt") )
     958                 :         {
     959               9 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     960               9 :             int bIs3D = FALSE;
     961               9 :             CPLString osGeomName = papszArgv[iArg+1];
     962              27 :             if (strlen(papszArgv[iArg+1]) > 3 &&
     963              18 :                 EQUALN(papszArgv[iArg+1] + strlen(papszArgv[iArg+1]) - 3, "25D", 3))
     964                 :             {
     965               1 :                 bIs3D = TRUE;
     966               1 :                 osGeomName.resize(osGeomName.size() - 3);
     967                 :             }
     968               9 :             if( EQUAL(osGeomName,"NONE") )
     969               0 :                 eGType = wkbNone;
     970               9 :             else if( EQUAL(osGeomName,"GEOMETRY") )
     971               0 :                 eGType = wkbUnknown;
     972               9 :             else if( EQUAL(osGeomName,"PROMOTE_TO_MULTI") )
     973               2 :                 bPromoteToMulti = TRUE;
     974                 :             else
     975                 :             {
     976               7 :                 eGType = OGRFromOGCGeomType(osGeomName);
     977               7 :                 if (eGType == wkbUnknown)
     978                 :                 {
     979                 :                     fprintf( stderr, "-nlt %s: type not recognised.\n",
     980               0 :                             papszArgv[iArg+1] );
     981               0 :                     exit( 1 );
     982                 :                 }
     983                 :             }
     984               9 :             if (eGType != -2 && eGType != wkbNone && bIs3D)
     985               1 :                 eGType |= wkb25DBit;
     986                 : 
     987               9 :             iArg++;
     988                 :         }
     989             262 :         else if( EQUAL(papszArgv[iArg],"-dim")  )
     990                 :         {
     991               2 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
     992               2 :             nCoordDim = atoi(papszArgv[iArg+1]);
     993               2 :             if( nCoordDim != 2 && nCoordDim != 3 )
     994                 :             {
     995                 :                 fprintf( stderr, "-dim %s: value not handled.\n",
     996               0 :                         papszArgv[iArg+1] );
     997               0 :                 exit( 1 );
     998                 :             }
     999               2 :             iArg ++;
    1000                 :         }
    1001             521 :         else if( EQUAL(papszArgv[iArg],"-tg") ||
    1002             260 :                  EQUAL(papszArgv[iArg],"-gt") )
    1003                 :         {
    1004               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1005               1 :             nGroupTransactions = atoi(papszArgv[++iArg]);
    1006                 :         }
    1007             259 :         else if( EQUAL(papszArgv[iArg],"-s_srs") )
    1008                 :         {
    1009               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1010               1 :             pszSourceSRSDef = papszArgv[++iArg];
    1011                 :         }
    1012             258 :         else if( EQUAL(papszArgv[iArg],"-a_srs") )
    1013                 :         {
    1014               3 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1015               3 :             pszOutputSRSDef = papszArgv[++iArg];
    1016               3 :             if (EQUAL(pszOutputSRSDef, "NULL") ||
    1017                 :                 EQUAL(pszOutputSRSDef, "NONE"))
    1018                 :             {
    1019               1 :                 pszOutputSRSDef = NULL;
    1020               1 :                 bNullifyOutputSRS = TRUE;
    1021                 :             }
    1022                 :         }
    1023             255 :         else if( EQUAL(papszArgv[iArg],"-t_srs") )
    1024                 :         {
    1025               4 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1026               4 :             pszOutputSRSDef = papszArgv[++iArg];
    1027               4 :             bTransform = TRUE;
    1028                 :         }
    1029             251 :         else if( EQUAL(papszArgv[iArg],"-spat") )
    1030                 :         {
    1031               2 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
    1032               2 :             OGRLinearRing  oRing;
    1033                 : 
    1034               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1035               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
    1036               2 :             oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
    1037               2 :             oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
    1038               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1039                 : 
    1040               2 :             poSpatialFilter = OGRGeometryFactory::createGeometry(wkbPolygon);
    1041               2 :             ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
    1042               2 :             iArg += 4;
    1043                 :         }
    1044             249 :         else if( EQUAL(papszArgv[iArg],"-where") )
    1045                 :         {
    1046               3 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1047               3 :             pszWHERE = papszArgv[++iArg];
    1048                 :         }
    1049             246 :         else if( EQUAL(papszArgv[iArg],"-select") )
    1050                 :         {
    1051               7 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1052               7 :             pszSelect = papszArgv[++iArg];
    1053                 :             papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,", 
    1054               7 :                                                       FALSE, FALSE );
    1055                 :         }
    1056             239 :         else if( EQUAL(papszArgv[iArg],"-segmentize") )
    1057                 :         {
    1058               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1059               1 :             eGeomOp = SEGMENTIZE;
    1060               1 :             dfGeomOpParam = atof(papszArgv[++iArg]);
    1061                 :         }
    1062             238 :         else if( EQUAL(papszArgv[iArg],"-simplify") )
    1063                 :         {
    1064               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1065               0 :             eGeomOp = SIMPLIFY_PRESERVE_TOPOLOGY;
    1066               0 :             dfGeomOpParam = atof(papszArgv[++iArg]);
    1067                 :         }
    1068             238 :         else if( EQUAL(papszArgv[iArg],"-fieldTypeToString") )
    1069                 :         {
    1070               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1071                 :             papszFieldTypesToString =
    1072               0 :                     CSLTokenizeStringComplex(papszArgv[++iArg], " ,", 
    1073               0 :                                              FALSE, FALSE );
    1074               0 :             char** iter = papszFieldTypesToString;
    1075               0 :             while(*iter)
    1076                 :             {
    1077               0 :                 if (EQUAL(*iter, "Integer") ||
    1078                 :                     EQUAL(*iter, "Real") ||
    1079                 :                     EQUAL(*iter, "String") ||
    1080                 :                     EQUAL(*iter, "Date") ||
    1081                 :                     EQUAL(*iter, "Time") ||
    1082                 :                     EQUAL(*iter, "DateTime") ||
    1083                 :                     EQUAL(*iter, "Binary") ||
    1084                 :                     EQUAL(*iter, "IntegerList") ||
    1085                 :                     EQUAL(*iter, "RealList") ||
    1086                 :                     EQUAL(*iter, "StringList"))
    1087                 :                 {
    1088                 :                     /* Do nothing */
    1089                 :                 }
    1090               0 :                 else if (EQUAL(*iter, "All"))
    1091                 :                 {
    1092               0 :                     CSLDestroy(papszFieldTypesToString);
    1093               0 :                     papszFieldTypesToString = NULL;
    1094               0 :                     papszFieldTypesToString = CSLAddString(papszFieldTypesToString, "All");
    1095               0 :                     break;
    1096                 :                 }
    1097                 :                 else
    1098                 :                 {
    1099                 :                     Usage(CPLSPrintf("Unhandled type for fieldtypeasstring option : %s",
    1100               0 :                             *iter));
    1101                 :                 }
    1102               0 :                 iter ++;
    1103                 :             }
    1104                 :         }
    1105             238 :         else if( EQUAL(papszArgv[iArg],"-progress") )
    1106                 :         {
    1107               5 :             bDisplayProgress = TRUE;
    1108                 :         }
    1109             233 :         else if( EQUAL(papszArgv[iArg],"-wrapdateline") )
    1110                 :         {
    1111               4 :             bWrapDateline = TRUE;
    1112                 :         }
    1113             229 :         else if( EQUAL(papszArgv[iArg],"-datelineoffset") && iArg < nArgc-1 )
    1114                 :         {
    1115               0 :             pszDateLineOffset = papszArgv[++iArg];
    1116                 :         }        
    1117             229 :         else if( EQUAL(papszArgv[iArg],"-clipsrc") )
    1118                 :         {
    1119               3 :             if (iArg + 1 >= nArgc)
    1120               0 :                 Usage(CPLSPrintf("%s option requires 1 or 4 arguments", papszArgv[iArg]));
    1121                 : 
    1122                 :             VSIStatBufL  sStat;
    1123               3 :             bClipSrc = TRUE;
    1124               3 :             if ( IsNumber(papszArgv[iArg+1])
    1125               0 :                  && papszArgv[iArg+2] != NULL 
    1126               0 :                  && papszArgv[iArg+3] != NULL 
    1127               0 :                  && papszArgv[iArg+4] != NULL)
    1128                 :             {
    1129               0 :                 OGRLinearRing  oRing;
    1130                 : 
    1131               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1132               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
    1133               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
    1134               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
    1135               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1136                 : 
    1137               0 :                 poClipSrc = OGRGeometryFactory::createGeometry(wkbPolygon);
    1138               0 :                 ((OGRPolygon *) poClipSrc)->addRing( &oRing );
    1139               0 :                 iArg += 4;
    1140                 :             }
    1141               6 :             else if ((EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
    1142               2 :                       EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12)) &&
    1143               1 :                       VSIStatL(papszArgv[iArg+1], &sStat) != 0)
    1144                 :             {
    1145               1 :                 char* pszTmp = (char*) papszArgv[iArg+1];
    1146               1 :                 OGRGeometryFactory::createFromWkt(&pszTmp, NULL, &poClipSrc);
    1147               1 :                 if (poClipSrc == NULL)
    1148                 :                 {
    1149               0 :                     Usage("Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT");
    1150                 :                 }
    1151               1 :                 iArg ++;
    1152                 :             }
    1153               2 :             else if (EQUAL(papszArgv[iArg+1], "spat_extent") )
    1154                 :             {
    1155               1 :                 iArg ++;
    1156                 :             }
    1157                 :             else
    1158                 :             {
    1159               1 :                 pszClipSrcDS = papszArgv[iArg+1];
    1160               1 :                 iArg ++;
    1161                 :             }
    1162                 :         }
    1163             226 :         else if( EQUAL(papszArgv[iArg],"-clipsrcsql")  )
    1164                 :         {
    1165               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1166               0 :             pszClipSrcSQL = papszArgv[iArg+1];
    1167               0 :             iArg ++;
    1168                 :         }
    1169             226 :         else if( EQUAL(papszArgv[iArg],"-clipsrclayer") )
    1170                 :         {
    1171               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1172               0 :             pszClipSrcLayer = papszArgv[iArg+1];
    1173               0 :             iArg ++;
    1174                 :         }
    1175             226 :         else if( EQUAL(papszArgv[iArg],"-clipsrcwhere") )
    1176                 :         {
    1177               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1178               1 :             pszClipSrcWhere = papszArgv[iArg+1];
    1179               1 :             iArg ++;
    1180                 :         }
    1181             225 :         else if( EQUAL(papszArgv[iArg],"-clipdst") )
    1182                 :         {
    1183               2 :             if (iArg + 1 >= nArgc)
    1184               0 :                 Usage(CPLSPrintf("%s option requires 1 or 4 arguments", papszArgv[iArg]));
    1185                 : 
    1186                 :             VSIStatBufL  sStat;
    1187               2 :             if ( IsNumber(papszArgv[iArg+1])
    1188               0 :                  && papszArgv[iArg+2] != NULL 
    1189               0 :                  && papszArgv[iArg+3] != NULL 
    1190               0 :                  && papszArgv[iArg+4] != NULL)
    1191                 :             {
    1192               0 :                 OGRLinearRing  oRing;
    1193                 : 
    1194               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1195               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
    1196               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
    1197               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
    1198               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
    1199                 : 
    1200               0 :                 poClipDst = OGRGeometryFactory::createGeometry(wkbPolygon);
    1201               0 :                 ((OGRPolygon *) poClipDst)->addRing( &oRing );
    1202               0 :                 iArg += 4;
    1203                 :             }
    1204               4 :             else if ((EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
    1205               1 :                       EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12)) &&
    1206               1 :                       VSIStatL(papszArgv[iArg+1], &sStat) != 0)
    1207                 :             {
    1208               1 :                 char* pszTmp = (char*) papszArgv[iArg+1];
    1209               1 :                 OGRGeometryFactory::createFromWkt(&pszTmp, NULL, &poClipDst);
    1210               1 :                 if (poClipDst == NULL)
    1211                 :                 {
    1212               0 :                     Usage("Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT");
    1213                 :                 }
    1214               1 :                 iArg ++;
    1215                 :             }
    1216                 :             else
    1217                 :             {
    1218               1 :                 pszClipDstDS = papszArgv[iArg+1];
    1219               1 :                 iArg ++;
    1220                 :             }
    1221                 :         }
    1222             223 :         else if( EQUAL(papszArgv[iArg],"-clipdstsql") )
    1223                 :         {
    1224               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1225               1 :             pszClipDstSQL = papszArgv[iArg+1];
    1226               1 :             iArg ++;
    1227                 :         }
    1228             222 :         else if( EQUAL(papszArgv[iArg],"-clipdstlayer") )
    1229                 :         {
    1230               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1231               0 :             pszClipDstLayer = papszArgv[iArg+1];
    1232               0 :             iArg ++;
    1233                 :         }
    1234             222 :         else if( EQUAL(papszArgv[iArg],"-clipdstwhere") )
    1235                 :         {
    1236               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1237               0 :             pszClipDstWhere = papszArgv[iArg+1];
    1238               0 :             iArg ++;
    1239                 :         }
    1240             222 :         else if( EQUAL(papszArgv[iArg],"-splitlistfields") )
    1241                 :         {
    1242               1 :             bSplitListFields = TRUE;
    1243                 :         }
    1244             221 :         else if ( EQUAL(papszArgv[iArg],"-maxsubfields") )
    1245                 :         {
    1246               0 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1247               0 :             if (IsNumber(papszArgv[iArg+1]))
    1248                 :             {
    1249               0 :                 int nTemp = atoi(papszArgv[iArg+1]);
    1250               0 :                 if (nTemp > 0)
    1251                 :                 {
    1252               0 :                     nMaxSplitListSubFields = nTemp;
    1253               0 :                     iArg ++;
    1254                 :                 }
    1255                 :             }
    1256                 :         }
    1257             221 :         else if( EQUAL(papszArgv[iArg],"-explodecollections") )
    1258                 :         {
    1259               1 :             bExplodeCollections = TRUE;
    1260                 :         }
    1261             220 :         else if( EQUAL(papszArgv[iArg],"-zfield") )
    1262                 :         {
    1263               3 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1264               3 :             pszZField = papszArgv[iArg+1];
    1265               3 :             iArg ++;
    1266                 :         }
    1267             217 :         else if( EQUAL(papszArgv[iArg],"-gcp") )
    1268                 :         {
    1269              15 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4);
    1270              15 :             char* endptr = NULL;
    1271                 :             /* -gcp pixel line easting northing [elev] */
    1272                 : 
    1273              15 :             nGCPCount++;
    1274                 :             pasGCPs = (GDAL_GCP *) 
    1275              15 :                 CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount );
    1276              15 :             GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
    1277                 : 
    1278              15 :             pasGCPs[nGCPCount-1].dfGCPPixel = atof(papszArgv[++iArg]);
    1279              15 :             pasGCPs[nGCPCount-1].dfGCPLine = atof(papszArgv[++iArg]);
    1280              15 :             pasGCPs[nGCPCount-1].dfGCPX = atof(papszArgv[++iArg]);
    1281              15 :             pasGCPs[nGCPCount-1].dfGCPY = atof(papszArgv[++iArg]);
    1282              43 :             if( papszArgv[iArg+1] != NULL 
    1283              28 :                 && (CPLStrtod(papszArgv[iArg+1], &endptr) != 0.0 || papszArgv[iArg+1][0] == '0') )
    1284                 :             {
    1285                 :                 /* Check that last argument is really a number and not a filename */
    1286                 :                 /* looking like a number (see ticket #863) */
    1287               0 :                 if (endptr && *endptr == 0)
    1288               0 :                     pasGCPs[nGCPCount-1].dfGCPZ = atof(papszArgv[++iArg]);
    1289                 :             }
    1290                 : 
    1291                 :             /* should set id and info? */
    1292                 :         }
    1293             202 :         else if( EQUAL(papszArgv[iArg],"-tps") )
    1294                 :         {
    1295               1 :             nTransformOrder = -1;
    1296                 :         }
    1297             201 :         else if( EQUAL(papszArgv[iArg],"-order") )
    1298                 :         {
    1299               1 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1300               1 :             nTransformOrder = atoi( papszArgv[++iArg] );
    1301                 :         }
    1302             202 :         else if( EQUAL(papszArgv[iArg],"-fieldmap") && papszArgv[iArg+1] != NULL)
    1303                 :         {
    1304               2 :             CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1);
    1305               2 :             pszFieldMap = papszArgv[++iArg];
    1306                 :             papszFieldMap = CSLTokenizeStringComplex(pszFieldMap, ",", 
    1307               2 :                                                       FALSE, FALSE );
    1308                 :         }
    1309             198 :         else if( papszArgv[iArg][0] == '-' )
    1310                 :         {
    1311               0 :             Usage(CPLSPrintf("Unkown option name '%s'", papszArgv[iArg]));
    1312                 :         }
    1313             198 :         else if( pszDestDataSource == NULL )
    1314              89 :             pszDestDataSource = papszArgv[iArg];
    1315             109 :         else if( pszDataSource == NULL )
    1316              89 :             pszDataSource = papszArgv[iArg];
    1317                 :         else
    1318              20 :             papszLayers = CSLAddString( papszLayers, papszArgv[iArg] );
    1319                 :     }
    1320                 : 
    1321              89 :     if( pszDataSource == NULL )
    1322                 :     {
    1323               0 :         if( pszDestDataSource == NULL )
    1324               0 :             Usage("no target datasource provided");
    1325                 :         else
    1326               0 :             Usage("no source datasource provided");
    1327                 :     }
    1328                 : 
    1329              89 :     if( bPreserveFID && bExplodeCollections )
    1330                 :     {
    1331               0 :         Usage("cannot use -preserve_fid and -explodecollections at the same time.");
    1332                 :     }
    1333                 : 
    1334              89 :     if (pszFieldMap && !bAppend)
    1335                 :     {
    1336               0 :         Usage("if -fieldmap is specified, -append must also be specified");
    1337                 :     }
    1338                 : 
    1339              90 :     if( bClipSrc && pszClipSrcDS != NULL)
    1340                 :     {
    1341               1 :         poClipSrc = LoadGeometry(pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere);
    1342               1 :         if (poClipSrc == NULL)
    1343                 :         {
    1344               0 :             Usage("cannot load source clip geometry");
    1345                 :         }
    1346                 :     }
    1347              88 :     else if( bClipSrc && poClipSrc == NULL )
    1348                 :     {
    1349               1 :         if (poSpatialFilter)
    1350               1 :             poClipSrc = poSpatialFilter->clone();
    1351               1 :         if (poClipSrc == NULL)
    1352                 :         {
    1353                 :             Usage("-clipsrc must be used with -spat option or a\n"
    1354               0 :                              "bounding box, WKT string or datasource must be specified");
    1355                 :         }
    1356                 :     }
    1357                 :     
    1358              89 :     if( pszClipDstDS != NULL)
    1359                 :     {
    1360               1 :         poClipDst = LoadGeometry(pszClipDstDS, pszClipDstSQL, pszClipDstLayer, pszClipDstWhere);
    1361               1 :         if (poClipDst == NULL)
    1362                 :         {
    1363               0 :             Usage("cannot load dest clip geometry");
    1364                 :         }
    1365                 :     }
    1366                 : 
    1367                 : /* -------------------------------------------------------------------- */
    1368                 : /*      Open data source.                                               */
    1369                 : /* -------------------------------------------------------------------- */
    1370                 :     OGRDataSource       *poDS;
    1371              89 :     OGRDataSource       *poODS = NULL;
    1372              89 :     OGRSFDriver         *poDriver = NULL;
    1373              89 :     int                  bCloseODS = TRUE;
    1374                 : 
    1375                 :     /* Avoid opening twice the same datasource if it is both the input and output */
    1376                 :     /* Known to cause problems with at least FGdb and SQlite drivers. See #4270 */
    1377              92 :     if (bUpdate && strcmp(pszDestDataSource, pszDataSource) == 0)
    1378                 :     {
    1379               3 :         poODS = poDS = OGRSFDriverRegistrar::Open( pszDataSource, TRUE, &poDriver );
    1380                 :         /* Restrict to those 2 drivers. For example it is known to break with */
    1381                 :         /* the PG driver due to the way it manages transactions... */
    1382               6 :         if (poDS && !(EQUAL(poDriver->GetName(), "FileGDB") ||
    1383               3 :                       EQUAL(poDriver->GetName(), "SQLite")))
    1384                 :         {
    1385               2 :             poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
    1386                 :         }
    1387                 :         else
    1388               1 :             bCloseODS = FALSE;
    1389               3 :         if (poDS)
    1390                 :         {
    1391               3 :             if (bOverwrite || bAppend)
    1392                 :             {
    1393                 :                 /* Various tests to avoid overwriting the source layer(s) */
    1394                 :                 /* or to avoid appending a layer to itself */
    1395               1 :                 int bError = FALSE;
    1396               1 :                 if (pszNewLayerName == NULL)
    1397               0 :                     bError = TRUE;
    1398               1 :                 else if (CSLCount(papszLayers) == 1)
    1399               1 :                     bError = strcmp(pszNewLayerName, papszLayers[0]) == 0;
    1400               0 :                 else if (pszSQLStatement == NULL)
    1401               0 :                     bError = TRUE;
    1402               1 :                 if (bError)
    1403                 :                 {
    1404                 :                     fprintf( stderr,
    1405                 :                              "ERROR: -nln name must be specified combined with "
    1406                 :                              "a single source layer name,\nor a -sql statement, and "
    1407               0 :                              "name must be different from an existing layer.\n");
    1408               0 :                     exit(1);
    1409                 :                 }
    1410                 :             }
    1411                 :         }
    1412                 :     }
    1413                 :     else
    1414              86 :         poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
    1415                 : 
    1416                 : /* -------------------------------------------------------------------- */
    1417                 : /*      Report failure                                                  */
    1418                 : /* -------------------------------------------------------------------- */
    1419              89 :     if( poDS == NULL )
    1420                 :     {
    1421               0 :         OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
    1422                 :         
    1423                 :         fprintf( stderr, "FAILURE:\n"
    1424                 :                 "Unable to open datasource `%s' with the following drivers.\n",
    1425               0 :                 pszDataSource );
    1426                 : 
    1427               0 :         for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
    1428                 :         {
    1429               0 :             fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
    1430                 :         }
    1431                 : 
    1432               0 :         exit( 1 );
    1433                 :     }
    1434                 : 
    1435                 : /* -------------------------------------------------------------------- */
    1436                 : /*      Try opening the output datasource as an existing, writable      */
    1437                 : /* -------------------------------------------------------------------- */
    1438                 : 
    1439              89 :     if( bUpdate && poODS == NULL )
    1440                 :     {
    1441              18 :         poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, TRUE, &poDriver );
    1442                 : 
    1443              18 :         if( poODS == NULL )
    1444                 :         {
    1445               1 :             if (bOverwrite || bAppend)
    1446                 :             {
    1447               1 :                 poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, FALSE, &poDriver );
    1448               1 :                 if (poODS == NULL)
    1449                 :                 {
    1450                 :                     /* ok the datasource doesn't exist at all */
    1451               1 :                     bUpdate = FALSE;
    1452                 :                 }
    1453                 :                 else
    1454                 :                 {
    1455               0 :                     OGRDataSource::DestroyDataSource(poODS);
    1456               0 :                     poODS = NULL;
    1457                 :                 }
    1458                 :             }
    1459                 : 
    1460               1 :             if (bUpdate)
    1461                 :             {
    1462                 :                 fprintf( stderr, "FAILURE:\n"
    1463                 :                         "Unable to open existing output datasource `%s'.\n",
    1464               0 :                         pszDestDataSource );
    1465               0 :                 exit( 1 );
    1466                 :             }
    1467                 :         }
    1468              17 :         else if( CSLCount(papszDSCO) > 0 )
    1469                 :         {
    1470                 :             fprintf( stderr, "WARNING: Datasource creation options ignored since an existing datasource\n"
    1471               0 :                     "         being updated.\n" );
    1472                 :         }
    1473                 :     }
    1474                 : 
    1475                 : /* -------------------------------------------------------------------- */
    1476                 : /*      Find the output driver.                                         */
    1477                 : /* -------------------------------------------------------------------- */
    1478              89 :     if( !bUpdate )
    1479                 :     {
    1480              69 :         if (!bQuiet && !bFormatExplicitelySet)
    1481              43 :             CheckDestDataSourceNameConsistency(pszDestDataSource, pszFormat);
    1482                 : 
    1483              69 :         OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
    1484                 :         int                  iDriver;
    1485                 : 
    1486              69 :         poDriver = poR->GetDriverByName(pszFormat);
    1487              69 :         if( poDriver == NULL )
    1488                 :         {
    1489               0 :             fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
    1490               0 :             fprintf( stderr,  "The following drivers are available:\n" );
    1491                 :         
    1492               0 :             for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
    1493                 :             {
    1494               0 :                 fprintf( stderr,  "  -> `%s'\n", poR->GetDriver(iDriver)->GetName() );
    1495                 :             }
    1496               0 :             exit( 1 );
    1497                 :         }
    1498                 : 
    1499              69 :         if( !poDriver->TestCapability( ODrCCreateDataSource ) )
    1500                 :         {
    1501                 :             fprintf( stderr,  "%s driver does not support data source creation.\n",
    1502               0 :                     pszFormat );
    1503               0 :             exit( 1 );
    1504                 :         }
    1505                 : 
    1506                 : /* -------------------------------------------------------------------- */
    1507                 : /*      Special case to improve user experience when translating        */
    1508                 : /*      a datasource with multiple layers into a shapefile. If the      */
    1509                 : /*      user gives a target datasource with .shp and it does not exist, */
    1510                 : /*      the shapefile driver will try to create a file, but this is not */
    1511                 : /*      appropriate because here we have several layers, so create      */
    1512                 : /*      a directory instead.                                            */
    1513                 : /* -------------------------------------------------------------------- */
    1514                 :         VSIStatBufL  sStat;
    1515             104 :         if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
    1516                 :             pszSQLStatement == NULL &&
    1517                 :             (CSLCount(papszLayers) > 1 ||
    1518              35 :              (CSLCount(papszLayers) == 0 && poDS->GetLayerCount() > 1)) &&
    1519                 :             pszNewLayerName == NULL &&
    1520                 :             EQUAL(CPLGetExtension(pszDestDataSource), "SHP") &&
    1521                 :             VSIStatL(pszDestDataSource, &sStat) != 0)
    1522                 :         {
    1523               1 :             if (VSIMkdir(pszDestDataSource, 0755) != 0)
    1524                 :             {
    1525                 :                 CPLError( CE_Failure, CPLE_AppDefined,
    1526                 :                       "Failed to create directory %s\n"
    1527                 :                       "for shapefile datastore.\n",
    1528               0 :                       pszDestDataSource );
    1529               0 :                 exit(1);
    1530                 :             }
    1531                 :         }
    1532                 : 
    1533                 : /* -------------------------------------------------------------------- */
    1534                 : /*      Create the output data source.                                  */
    1535                 : /* -------------------------------------------------------------------- */
    1536              69 :         poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
    1537              69 :         if( poODS == NULL )
    1538                 :         {
    1539                 :             fprintf( stderr,  "%s driver failed to create %s\n", 
    1540               0 :                     pszFormat, pszDestDataSource );
    1541               0 :             exit( 1 );
    1542                 :         }
    1543                 :     }
    1544                 : 
    1545                 : /* -------------------------------------------------------------------- */
    1546                 : /*      Parse the output SRS definition if possible.                    */
    1547                 : /* -------------------------------------------------------------------- */
    1548              89 :     if( pszOutputSRSDef != NULL )
    1549                 :     {
    1550               6 :         poOutputSRS = (OGRSpatialReference*)OSRNewSpatialReference(NULL);
    1551               6 :         if( poOutputSRS->SetFromUserInput( pszOutputSRSDef ) != OGRERR_NONE )
    1552                 :         {
    1553                 :             fprintf( stderr,  "Failed to process SRS definition: %s\n", 
    1554               0 :                     pszOutputSRSDef );
    1555               0 :             exit( 1 );
    1556                 :         }
    1557                 :     }
    1558                 : 
    1559                 : /* -------------------------------------------------------------------- */
    1560                 : /*      Parse the source SRS definition if possible.                    */
    1561                 : /* -------------------------------------------------------------------- */
    1562              89 :     if( pszSourceSRSDef != NULL )
    1563                 :     {
    1564               1 :         poSourceSRS = (OGRSpatialReference*)OSRNewSpatialReference(NULL);
    1565               1 :         if( poSourceSRS->SetFromUserInput( pszSourceSRSDef ) != OGRERR_NONE )
    1566                 :         {
    1567                 :             fprintf( stderr,  "Failed to process SRS definition: %s\n", 
    1568               0 :                     pszSourceSRSDef );
    1569               0 :             exit( 1 );
    1570                 :         }
    1571                 :     }
    1572                 :  
    1573                 : /* -------------------------------------------------------------------- */
    1574                 : /*      Create a transformation object from the source to               */
    1575                 : /*      destination coordinate system.                                  */
    1576                 : /* -------------------------------------------------------------------- */
    1577              89 :     GCPCoordTransformation *poGCPCoordTrans = NULL;
    1578              89 :     if( nGCPCount > 0 )
    1579                 :     {
    1580                 :         poGCPCoordTrans = new GCPCoordTransformation( nGCPCount, pasGCPs, 
    1581                 :                                                       nTransformOrder, 
    1582               5 :                                                       poSourceSRS ? poSourceSRS : poOutputSRS );
    1583               5 :         if( !(poGCPCoordTrans->IsValid()) )
    1584                 :         {
    1585               0 :             delete poGCPCoordTrans;
    1586               0 :             poGCPCoordTrans = NULL;
    1587                 :         }
    1588                 :     }
    1589                 : 
    1590                 : /* -------------------------------------------------------------------- */
    1591                 : /*      For OSM file.                                                   */
    1592                 : /* -------------------------------------------------------------------- */
    1593                 :     int         bSrcIsOSM = (poDS->GetDriver() != NULL &&
    1594              89 :                              strcmp(poDS->GetDriver()->GetName(), "OSM") == 0);
    1595              89 :     vsi_l_offset nSrcFileSize = 0;
    1596              89 :     if( bSrcIsOSM && strcmp(poDS->GetName(), "/vsistdin/") != 0)
    1597                 :     {
    1598                 :         VSIStatBufL sStat;
    1599               4 :         if( VSIStatL(poDS->GetName(), &sStat) == 0 )
    1600               4 :             nSrcFileSize = sStat.st_size;
    1601                 :     }
    1602                 : 
    1603                 : /* -------------------------------------------------------------------- */
    1604                 : /*      Special case for -sql clause.  No source layers required.       */
    1605                 : /* -------------------------------------------------------------------- */
    1606              89 :     if( pszSQLStatement != NULL )
    1607                 :     {
    1608                 :         OGRLayer *poResultSet;
    1609                 : 
    1610               7 :         if( pszWHERE != NULL )
    1611               0 :             fprintf( stderr,  "-where clause ignored in combination with -sql.\n" );
    1612               7 :         if( CSLCount(papszLayers) > 0 )
    1613               0 :             fprintf( stderr,  "layer names ignored in combination with -sql.\n" );
    1614                 :         
    1615                 :         poResultSet = poDS->ExecuteSQL( pszSQLStatement, poSpatialFilter, 
    1616               7 :                                         pszDialect );
    1617                 : 
    1618               7 :         if( poResultSet != NULL )
    1619                 :         {
    1620               7 :             long nCountLayerFeatures = 0;
    1621               7 :             if (bDisplayProgress)
    1622                 :             {
    1623               1 :                 if (bSrcIsOSM)
    1624                 :                 {
    1625               1 :                     pfnProgress = GDALTermProgress;
    1626                 :                 }
    1627               0 :                 else if (!poResultSet->TestCapability(OLCFastFeatureCount))
    1628                 :                 {
    1629               0 :                     fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
    1630               0 :                     bDisplayProgress = FALSE;
    1631                 :                 }
    1632                 :                 else
    1633                 :                 {
    1634               0 :                     nCountLayerFeatures = poResultSet->GetFeatureCount();
    1635               0 :                     pfnProgress = GDALTermProgress;
    1636                 :                 }
    1637                 :             }
    1638                 : 
    1639               7 :             OGRLayer* poPassedLayer = poResultSet;
    1640               7 :             if (bSplitListFields)
    1641                 :             {
    1642               0 :                 poPassedLayer = new OGRSplitListFieldLayer(poPassedLayer, nMaxSplitListSubFields);
    1643               0 :                 int nRet = ((OGRSplitListFieldLayer*)poPassedLayer)->BuildLayerDefn(NULL, NULL);
    1644               0 :                 if (!nRet)
    1645                 :                 {
    1646               0 :                     delete poPassedLayer;
    1647               0 :                     poPassedLayer = poResultSet;
    1648                 :                 }
    1649                 :             }
    1650                 : 
    1651                 : /* -------------------------------------------------------------------- */
    1652                 : /*      Special case to improve user experience when translating into   */
    1653                 : /*      single file shapefile and source has only one layer, and that   */
    1654                 : /*      the layer name isn't specified                                  */
    1655                 : /* -------------------------------------------------------------------- */
    1656                 :             VSIStatBufL  sStat;
    1657               7 :             if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
    1658                 :                 pszNewLayerName == NULL &&
    1659                 :                 VSIStatL(pszDestDataSource, &sStat) == 0 && VSI_ISREG(sStat.st_mode))
    1660                 :             {
    1661               0 :                 pszNewLayerName = CPLStrdup(CPLGetBasename(pszDestDataSource));
    1662                 :             }
    1663                 : 
    1664                 :             TargetLayerInfo* psInfo = SetupTargetLayer( poDS,
    1665                 :                                                 poPassedLayer,
    1666                 :                                                 poODS,
    1667                 :                                                 papszLCO,
    1668                 :                                                 pszNewLayerName,
    1669                 :                                                 poOutputSRS,
    1670                 :                                                 bNullifyOutputSRS,
    1671                 :                                                 papszSelFields,
    1672                 :                                                 bAppend, eGType,
    1673                 :                                                 bPromoteToMulti,
    1674                 :                                                 nCoordDim, bOverwrite,
    1675                 :                                                 papszFieldTypesToString,
    1676                 :                                                 bExplodeCollections,
    1677                 :                                                 pszZField,
    1678                 :                                                 papszFieldMap,
    1679               7 :                                                 pszWHERE );
    1680                 : 
    1681               7 :             poPassedLayer->ResetReading();
    1682                 : 
    1683               7 :             if( psInfo == NULL ||
    1684                 :                 !TranslateLayer( psInfo, poDS, poPassedLayer, poODS,
    1685                 :                                  bTransform, bWrapDateline, pszDateLineOffset,
    1686                 :                                  poOutputSRS, bNullifyOutputSRS,
    1687                 :                                  poSourceSRS,
    1688                 :                                  poGCPCoordTrans,
    1689                 :                                  eGType, bPromoteToMulti, nCoordDim,
    1690                 :                                  eGeomOp, dfGeomOpParam,
    1691                 :                                  nCountLayerFeatures,
    1692                 :                                  poClipSrc, poClipDst,
    1693                 :                                  bExplodeCollections,
    1694                 :                                  nSrcFileSize, NULL,
    1695                 :                                  pfnProgress, pProgressArg ))
    1696                 :             {
    1697                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    1698                 :                           "Terminating translation prematurely after failed\n"
    1699               0 :                           "translation from sql statement." );
    1700                 : 
    1701               0 :                 exit( 1 );
    1702                 :             }
    1703                 : 
    1704               7 :             FreeTargetLayerInfo(psInfo);
    1705                 : 
    1706               7 :             if (poPassedLayer != poResultSet)
    1707               0 :                 delete poPassedLayer;
    1708                 : 
    1709               7 :             poDS->ReleaseResultSet( poResultSet );
    1710                 :         }
    1711                 :         else
    1712                 :         {
    1713               0 :             if( CPLGetLastErrorNo() != 0 )
    1714               0 :                 nRetCode = 1;
    1715                 :         }
    1716                 :     }
    1717                 : 
    1718                 : /* -------------------------------------------------------------------- */
    1719                 : /*      Special case for layer interleaving mode.                       */
    1720                 : /* -------------------------------------------------------------------- */
    1721              82 :     else if( bSrcIsOSM &&
    1722                 :                 CSLTestBoolean(CPLGetConfigOption("OGR_INTERLEAVED_READING", "YES")) )
    1723                 :     {
    1724               3 :         CPLSetConfigOption("OGR_INTERLEAVED_READING", "YES");
    1725                 : 
    1726               3 :         if (bSplitListFields)
    1727                 :         {
    1728               0 :             fprintf( stderr, "FAILURE: -splitlistfields not supported in this mode\n" );
    1729               0 :             exit( 1 );
    1730                 :         }
    1731                 : 
    1732               3 :         int nSrcLayerCount = poDS->GetLayerCount();
    1733                 :         AssociatedLayers* pasAssocLayers =
    1734               3 :             (AssociatedLayers* ) CPLCalloc(nSrcLayerCount, sizeof(AssociatedLayers));
    1735                 : 
    1736                 : /* -------------------------------------------------------------------- */
    1737                 : /*      Special case to improve user experience when translating into   */
    1738                 : /*      single file shapefile and source has only one layer, and that   */
    1739                 : /*      the layer name isn't specified                                  */
    1740                 : /* -------------------------------------------------------------------- */
    1741                 :         VSIStatBufL  sStat;
    1742               3 :         if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
    1743                 :             (CSLCount(papszLayers) == 1 || nSrcLayerCount == 1) && pszNewLayerName == NULL &&
    1744                 :             VSIStatL(pszDestDataSource, &sStat) == 0 && VSI_ISREG(sStat.st_mode))
    1745                 :         {
    1746               0 :             pszNewLayerName = CPLStrdup(CPLGetBasename(pszDestDataSource));
    1747                 :         }
    1748                 : 
    1749               3 :         if ( bDisplayProgress && bSrcIsOSM )
    1750               3 :             pfnProgress = GDALTermProgress;
    1751                 : 
    1752                 : /* -------------------------------------------------------------------- */
    1753                 : /*      If no target layer specified, use all source layers.            */
    1754                 : /* -------------------------------------------------------------------- */
    1755                 :         int iLayer;
    1756               3 :         if ( CSLCount(papszLayers) == 0)
    1757                 :         {
    1758               0 :             papszLayers = (char**) CPLCalloc(sizeof(char*), nSrcLayerCount + 1);
    1759               0 :             for( iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
    1760                 :             {
    1761               0 :                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
    1762                 : 
    1763               0 :                 if( poLayer == NULL )
    1764                 :                 {
    1765                 :                     fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
    1766               0 :                             iLayer );
    1767               0 :                     exit( 1 );
    1768                 :                 }
    1769                 : 
    1770               0 :                 papszLayers[iLayer] = CPLStrdup(poLayer->GetName());
    1771                 :             }
    1772                 :         }
    1773                 :         else
    1774                 :         {
    1775               3 :             if ( bSrcIsOSM )
    1776                 :             {
    1777               3 :                 CPLString osInterestLayers = "SET interest_layers =";
    1778              18 :                 for( iLayer = 0; papszLayers[iLayer] != NULL; iLayer++ )
    1779                 :                 {
    1780              15 :                     if( iLayer != 0 ) osInterestLayers += ",";
    1781              15 :                     osInterestLayers += papszLayers[iLayer];
    1782                 :                 }
    1783                 : 
    1784               3 :                 poDS->ExecuteSQL(osInterestLayers.c_str(), NULL, NULL);
    1785                 :             }
    1786                 :         }
    1787                 : 
    1788                 : /* -------------------------------------------------------------------- */
    1789                 : /*      First pass to set filters and create target layers.             */
    1790                 : /* -------------------------------------------------------------------- */
    1791              18 :         for( iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
    1792                 :         {
    1793              15 :             OGRLayer        *poLayer = poDS->GetLayer(iLayer);
    1794              15 :             if( poLayer == NULL )
    1795                 :             {
    1796                 :                 fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
    1797               0 :                         iLayer );
    1798               0 :                 exit( 1 );
    1799                 :             }
    1800                 : 
    1801              15 :             pasAssocLayers[iLayer].poSrcLayer = poLayer;
    1802                 : 
    1803              15 :             if( CSLFindString(papszLayers, poLayer->GetName()) >= 0 )
    1804                 :             {
    1805              12 :                 if( pszWHERE != NULL )
    1806                 :                 {
    1807               0 :                     if( poLayer->SetAttributeFilter( pszWHERE ) != OGRERR_NONE )
    1808                 :                     {
    1809                 :                         fprintf( stderr, "FAILURE: SetAttributeFilter(%s) on layer '%s' failed.\n",
    1810               0 :                                  pszWHERE, poLayer->GetName() );
    1811               0 :                         if (!bSkipFailures)
    1812               0 :                             exit( 1 );
    1813                 :                     }
    1814                 :                 }
    1815                 : 
    1816              12 :                 if( poSpatialFilter != NULL )
    1817               0 :                     poLayer->SetSpatialFilter( poSpatialFilter );
    1818                 : 
    1819                 :                 TargetLayerInfo* psInfo = SetupTargetLayer( poDS,
    1820                 :                                                     poLayer,
    1821                 :                                                     poODS,
    1822                 :                                                     papszLCO,
    1823                 :                                                     pszNewLayerName,
    1824                 :                                                     poOutputSRS,
    1825                 :                                                     bNullifyOutputSRS,
    1826                 :                                                     papszSelFields,
    1827                 :                                                     bAppend, eGType,
    1828                 :                                                     bPromoteToMulti,
    1829                 :                                                     nCoordDim, bOverwrite,
    1830                 :                                                     papszFieldTypesToString,
    1831                 :                                                     bExplodeCollections,
    1832                 :                                                     pszZField,
    1833                 :                                                     papszFieldMap,
    1834              12 :                                                     pszWHERE );
    1835                 : 
    1836              12 :                 if( psInfo == NULL && !bSkipFailures )
    1837               0 :                     exit(1);
    1838                 : 
    1839              12 :                 pasAssocLayers[iLayer].psInfo = psInfo;
    1840                 :             }
    1841                 :             else
    1842                 :             {
    1843               3 :                 pasAssocLayers[iLayer].psInfo = NULL;
    1844                 :             }
    1845                 :         }
    1846                 : 
    1847                 : /* -------------------------------------------------------------------- */
    1848                 : /*      Second pass to process features in a interleaved layer mode.    */
    1849                 : /* -------------------------------------------------------------------- */
    1850                 :         int bHasLayersNonEmpty;
    1851               6 :         do
    1852                 :         {
    1853               6 :             bHasLayersNonEmpty = FALSE;
    1854                 : 
    1855              36 :             for( iLayer = 0; iLayer < nSrcLayerCount;  iLayer++ )
    1856                 :             {
    1857              30 :                 OGRLayer        *poLayer = pasAssocLayers[iLayer].poSrcLayer;
    1858              30 :                 TargetLayerInfo *psInfo = pasAssocLayers[iLayer].psInfo;
    1859              30 :                 GIntBig nReadFeatureCount = 0;
    1860                 : 
    1861              30 :                 if( psInfo )
    1862                 :                 {
    1863              24 :                     if( !TranslateLayer(psInfo, poDS, poLayer, poODS,
    1864                 :                                         bTransform, bWrapDateline, pszDateLineOffset,
    1865                 :                                         poOutputSRS, bNullifyOutputSRS,
    1866                 :                                         poSourceSRS,
    1867                 :                                         poGCPCoordTrans,
    1868                 :                                         eGType, bPromoteToMulti, nCoordDim,
    1869                 :                                         eGeomOp, dfGeomOpParam,
    1870                 :                                         0,
    1871                 :                                         poClipSrc, poClipDst,
    1872                 :                                         bExplodeCollections,
    1873                 :                                         nSrcFileSize,
    1874                 :                                         &nReadFeatureCount,
    1875                 :                                         pfnProgress, pProgressArg )
    1876                 :                         && !bSkipFailures )
    1877                 :                     {
    1878                 :                         CPLError( CE_Failure, CPLE_AppDefined,
    1879                 :                                 "Terminating translation prematurely after failed\n"
    1880                 :                                 "translation of layer %s (use -skipfailures to skip errors)\n",
    1881               0 :                                 poLayer->GetName() );
    1882                 : 
    1883               0 :                         exit( 1 );
    1884                 :                     }
    1885                 :                 }
    1886                 :                 else
    1887                 :                 {
    1888                 :                     /* No matching target layer : just consumes the features */
    1889                 : 
    1890                 :                     OGRFeature* poFeature;
    1891              12 :                     while( (poFeature = poLayer->GetNextFeature()) != NULL )
    1892                 :                     {
    1893               0 :                         nReadFeatureCount ++;
    1894               0 :                         OGRFeature::DestroyFeature(poFeature);
    1895                 :                     }
    1896                 :                 }
    1897                 : 
    1898              30 :                 if( nReadFeatureCount != 0 )
    1899              12 :                     bHasLayersNonEmpty = TRUE;
    1900                 :             }
    1901                 :         }
    1902                 :         while( bHasLayersNonEmpty );
    1903                 : 
    1904                 : /* -------------------------------------------------------------------- */
    1905                 : /*      Cleanup.                                                        */
    1906                 : /* -------------------------------------------------------------------- */
    1907              18 :         for( iLayer = 0; iLayer < nSrcLayerCount;  iLayer++ )
    1908                 :         {
    1909              15 :             if( pasAssocLayers[iLayer].psInfo )
    1910              12 :                 FreeTargetLayerInfo(pasAssocLayers[iLayer].psInfo);
    1911                 :         }
    1912               3 :         CPLFree(pasAssocLayers);
    1913                 :     }
    1914                 : 
    1915                 :     else
    1916                 :     {
    1917              79 :         int nLayerCount = 0;
    1918              79 :         OGRLayer** papoLayers = NULL;
    1919                 : 
    1920                 : /* -------------------------------------------------------------------- */
    1921                 : /*      Process each data source layer.                                 */
    1922                 : /* -------------------------------------------------------------------- */
    1923              79 :         if ( CSLCount(papszLayers) == 0)
    1924                 :         {
    1925              74 :             nLayerCount = poDS->GetLayerCount();
    1926              74 :             papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
    1927                 : 
    1928             180 :             for( int iLayer = 0; 
    1929                 :                  iLayer < nLayerCount; 
    1930                 :                  iLayer++ )
    1931                 :             {
    1932             106 :                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
    1933                 : 
    1934             106 :                 if( poLayer == NULL )
    1935                 :                 {
    1936                 :                     fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
    1937               0 :                             iLayer );
    1938               0 :                     exit( 1 );
    1939                 :                 }
    1940                 : 
    1941             106 :                 papoLayers[iLayer] = poLayer;
    1942                 :             }
    1943                 :         }
    1944                 : /* -------------------------------------------------------------------- */
    1945                 : /*      Process specified data source layers.                           */
    1946                 : /* -------------------------------------------------------------------- */
    1947                 :         else
    1948                 :         {
    1949               5 :             nLayerCount = CSLCount(papszLayers);
    1950               5 :             papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
    1951                 : 
    1952              20 :             for( int iLayer = 0; 
    1953              10 :                 papszLayers[iLayer] != NULL; 
    1954                 :                 iLayer++ )
    1955                 :             {
    1956               5 :                 OGRLayer        *poLayer = poDS->GetLayerByName(papszLayers[iLayer]);
    1957                 : 
    1958               5 :                 if( poLayer == NULL )
    1959                 :                 {
    1960                 :                     fprintf( stderr, "FAILURE: Couldn't fetch requested layer '%s'!\n",
    1961               0 :                              papszLayers[iLayer] );
    1962               0 :                     if (!bSkipFailures)
    1963               0 :                         exit( 1 );
    1964                 :                 }
    1965                 : 
    1966               5 :                 papoLayers[iLayer] = poLayer;
    1967                 :             }
    1968                 :         }
    1969                 : 
    1970                 : /* -------------------------------------------------------------------- */
    1971                 : /*      Special case to improve user experience when translating into   */
    1972                 : /*      single file shapefile and source has only one layer, and that   */
    1973                 : /*      the layer name isn't specified                                  */
    1974                 : /* -------------------------------------------------------------------- */
    1975                 :         VSIStatBufL  sStat;
    1976              79 :         if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
    1977                 :             nLayerCount == 1 && pszNewLayerName == NULL &&
    1978                 :             VSIStatL(pszDestDataSource, &sStat) == 0 && VSI_ISREG(sStat.st_mode))
    1979                 :         {
    1980               3 :             pszNewLayerName = CPLStrdup(CPLGetBasename(pszDestDataSource));
    1981                 :         }
    1982                 : 
    1983              79 :         long* panLayerCountFeatures = (long*) CPLCalloc(sizeof(long), nLayerCount);
    1984              79 :         long nCountLayersFeatures = 0;
    1985              79 :         long nAccCountFeatures = 0;
    1986                 :         int iLayer;
    1987                 : 
    1988                 :         /* First pass to apply filters and count all features if necessary */
    1989             190 :         for( iLayer = 0; 
    1990                 :             iLayer < nLayerCount; 
    1991                 :             iLayer++ )
    1992                 :         {
    1993             111 :             OGRLayer        *poLayer = papoLayers[iLayer];
    1994             111 :             if (poLayer == NULL)
    1995               0 :                 continue;
    1996                 : 
    1997             111 :             if( pszWHERE != NULL )
    1998                 :             {
    1999               3 :                 if( poLayer->SetAttributeFilter( pszWHERE ) != OGRERR_NONE )
    2000                 :                 {
    2001                 :                     fprintf( stderr, "FAILURE: SetAttributeFilter(%s) on layer '%s' failed.\n",
    2002               0 :                              pszWHERE, poLayer->GetName() );
    2003               0 :                     if (!bSkipFailures)
    2004               0 :                         exit( 1 );
    2005                 :                 }
    2006                 :             }
    2007                 : 
    2008             111 :             if( poSpatialFilter != NULL )
    2009               2 :                 poLayer->SetSpatialFilter( poSpatialFilter );
    2010                 : 
    2011             111 :             if (bDisplayProgress && !bSrcIsOSM)
    2012                 :             {
    2013               1 :                 if (!poLayer->TestCapability(OLCFastFeatureCount))
    2014                 :                 {
    2015               0 :                     fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
    2016               0 :                     bDisplayProgress = FALSE;
    2017                 :                 }
    2018                 :                 else
    2019                 :                 {
    2020               1 :                     panLayerCountFeatures[iLayer] = poLayer->GetFeatureCount();
    2021               1 :                     nCountLayersFeatures += panLayerCountFeatures[iLayer];
    2022                 :                 }
    2023                 :             }
    2024                 :         }
    2025                 : 
    2026                 :         /* Second pass to do the real job */
    2027             190 :         for( iLayer = 0; 
    2028                 :             iLayer < nLayerCount; 
    2029                 :             iLayer++ )
    2030                 :         {
    2031             111 :             OGRLayer        *poLayer = papoLayers[iLayer];
    2032             111 :             if (poLayer == NULL)
    2033               0 :                 continue;
    2034                 : 
    2035                 : 
    2036             111 :             OGRLayer* poPassedLayer = poLayer;
    2037             111 :             if (bSplitListFields)
    2038                 :             {
    2039               1 :                 poPassedLayer = new OGRSplitListFieldLayer(poPassedLayer, nMaxSplitListSubFields);
    2040                 : 
    2041               1 :                 if (bDisplayProgress && nMaxSplitListSubFields != 1)
    2042                 :                 {
    2043               0 :                     pfnProgress = GDALScaledProgress;
    2044                 :                     pProgressArg = 
    2045                 :                         GDALCreateScaledProgress(nAccCountFeatures * 1.0 / nCountLayersFeatures,
    2046               0 :                                                 (nAccCountFeatures + panLayerCountFeatures[iLayer] / 2) * 1.0 / nCountLayersFeatures,
    2047                 :                                                 GDALTermProgress,
    2048               0 :                                                 NULL);
    2049                 :                 }
    2050                 :                 else
    2051                 :                 {
    2052               1 :                     pfnProgress = NULL;
    2053               1 :                     pProgressArg = NULL;
    2054                 :                 }
    2055                 : 
    2056               1 :                 int nRet = ((OGRSplitListFieldLayer*)poPassedLayer)->BuildLayerDefn(pfnProgress, pProgressArg);
    2057               1 :                 if (!nRet)
    2058                 :                 {
    2059               0 :                     delete poPassedLayer;
    2060               0 :                     poPassedLayer = poLayer;
    2061                 :                 }
    2062                 : 
    2063               1 :                 if (bDisplayProgress)
    2064               0 :                     GDALDestroyScaledProgress(pProgressArg);
    2065                 :             }
    2066                 : 
    2067                 : 
    2068             111 :             if (bDisplayProgress)
    2069                 :             {
    2070               1 :                 if ( bSrcIsOSM )
    2071               0 :                     pfnProgress = GDALTermProgress;
    2072                 :                 else
    2073                 :                 {
    2074               1 :                     pfnProgress = GDALScaledProgress;
    2075               1 :                     int nStart = 0;
    2076               1 :                     if (poPassedLayer != poLayer && nMaxSplitListSubFields != 1)
    2077               0 :                         nStart = panLayerCountFeatures[iLayer] / 2;
    2078                 :                     pProgressArg =
    2079                 :                         GDALCreateScaledProgress((nAccCountFeatures + nStart) * 1.0 / nCountLayersFeatures,
    2080               1 :                                                 (nAccCountFeatures + panLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures,
    2081                 :                                                 GDALTermProgress,
    2082               1 :                                                 NULL);
    2083                 :                 }
    2084                 :             }
    2085                 : 
    2086             111 :             nAccCountFeatures += panLayerCountFeatures[iLayer];
    2087                 : 
    2088                 :             TargetLayerInfo* psInfo = SetupTargetLayer( poDS,
    2089                 :                                                 poPassedLayer,
    2090                 :                                                 poODS,
    2091                 :                                                 papszLCO,
    2092                 :                                                 pszNewLayerName,
    2093                 :                                                 poOutputSRS,
    2094                 :                                                 bNullifyOutputSRS,
    2095                 :                                                 papszSelFields,
    2096                 :                                                 bAppend, eGType,
    2097                 :                                                 bPromoteToMulti,
    2098                 :                                                 nCoordDim, bOverwrite,
    2099                 :                                                 papszFieldTypesToString,
    2100                 :                                                 bExplodeCollections,
    2101                 :                                                 pszZField,
    2102                 :                                                 papszFieldMap,
    2103             111 :                                                 pszWHERE );
    2104                 : 
    2105             111 :             poPassedLayer->ResetReading();
    2106                 : 
    2107             111 :             if( (psInfo == NULL ||
    2108                 :                 !TranslateLayer( psInfo, poDS, poPassedLayer, poODS,
    2109                 :                                   bTransform, bWrapDateline, pszDateLineOffset,
    2110                 :                                   poOutputSRS, bNullifyOutputSRS,
    2111                 :                                   poSourceSRS,
    2112                 :                                   poGCPCoordTrans,
    2113                 :                                   eGType, bPromoteToMulti, nCoordDim,
    2114                 :                                   eGeomOp, dfGeomOpParam,
    2115                 :                                   panLayerCountFeatures[iLayer],
    2116                 :                                   poClipSrc, poClipDst,
    2117                 :                                   bExplodeCollections,
    2118                 :                                   nSrcFileSize, NULL,
    2119                 :                                   pfnProgress, pProgressArg ))
    2120                 :                 && !bSkipFailures )
    2121                 :             {
    2122                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
    2123                 :                         "Terminating translation prematurely after failed\n"
    2124                 :                         "translation of layer %s (use -skipfailures to skip errors)\n", 
    2125               0 :                         poLayer->GetName() );
    2126                 : 
    2127               0 :                 exit( 1 );
    2128                 :             }
    2129                 : 
    2130             111 :             FreeTargetLayerInfo(psInfo);
    2131                 : 
    2132             111 :             if (poPassedLayer != poLayer)
    2133               1 :                 delete poPassedLayer;
    2134                 : 
    2135             111 :             if (bDisplayProgress && !bSrcIsOSM)
    2136               1 :                 GDALDestroyScaledProgress(pProgressArg);
    2137                 :         }
    2138                 : 
    2139              79 :         CPLFree(panLayerCountFeatures);
    2140              79 :         CPLFree(papoLayers);
    2141                 :     }
    2142                 : /* -------------------------------------------------------------------- */
    2143                 : /*      Process DS style table                                          */
    2144                 : /* -------------------------------------------------------------------- */
    2145                 : 
    2146              89 :     poODS->SetStyleTable( poDS->GetStyleTable () );
    2147                 :     
    2148                 : /* -------------------------------------------------------------------- */
    2149                 : /*      Close down.                                                     */
    2150                 : /* -------------------------------------------------------------------- */
    2151              89 :     if (bCloseODS)
    2152              88 :         OGRDataSource::DestroyDataSource(poODS);
    2153              89 :     OGRDataSource::DestroyDataSource(poDS);
    2154              89 :     OGRGeometryFactory::destroyGeometry(poSpatialFilter);
    2155              89 :     OGRGeometryFactory::destroyGeometry(poClipSrc);
    2156              89 :     OGRGeometryFactory::destroyGeometry(poClipDst);
    2157                 : 
    2158              89 :     delete poGCPCoordTrans;
    2159              89 :     if( pasGCPs != NULL )
    2160                 :     {
    2161               5 :         GDALDeinitGCPs( nGCPCount, pasGCPs );
    2162               5 :         CPLFree( pasGCPs );
    2163                 :     }
    2164                 : 
    2165                 :     /* Destroy them after the last potential user */
    2166              89 :     OGRSpatialReference::DestroySpatialReference(poOutputSRS);
    2167              89 :     OGRSpatialReference::DestroySpatialReference(poSourceSRS);
    2168                 : 
    2169              89 :     CSLDestroy(papszSelFields);
    2170              89 :     CSLDestroy( papszFieldMap );
    2171              89 :     CSLDestroy( papszArgv );
    2172              89 :     CSLDestroy( papszLayers );
    2173              89 :     CSLDestroy( papszDSCO );
    2174              89 :     CSLDestroy( papszLCO );
    2175              89 :     CSLDestroy( papszFieldTypesToString );
    2176              89 :     CPLFree( pszNewLayerName );
    2177                 : 
    2178              89 :     OGRCleanupAll();
    2179                 : 
    2180                 : #ifdef DBMALLOC
    2181                 :     malloc_dump(1);
    2182                 : #endif
    2183                 :     
    2184              89 :     return nRetCode;
    2185                 : }
    2186                 : 
    2187                 : /************************************************************************/
    2188                 : /*                               Usage()                                */
    2189                 : /************************************************************************/
    2190                 : 
    2191               0 : static void Usage(int bShort)
    2192                 : {
    2193               0 :     Usage(NULL, bShort);
    2194               0 : }
    2195                 : 
    2196               0 : static void Usage(const char* pszAdditionalMsg, int bShort)
    2197                 : 
    2198                 : {
    2199               0 :     OGRSFDriverRegistrar        *poR = OGRSFDriverRegistrar::GetRegistrar();
    2200                 : 
    2201                 : 
    2202                 :     printf( "Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update]\n"
    2203                 :             "               [-select field_list] [-where restricted_where]\n"
    2204                 :             "               [-progress] [-sql <sql statement>] [-dialect dialect]\n"
    2205                 :             "               [-preserve_fid] [-fid FID]\n"
    2206                 :             "               [-spat xmin ymin xmax ymax]\n"
    2207                 :             "               [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n"
    2208                 :             "               [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n"
    2209                 :             "               dst_datasource_name src_datasource_name\n"
    2210                 :             "               [-lco NAME=VALUE] [-nln name] [-nlt type] [-dim 2|3] [layer [layer ...]]\n"
    2211                 :             "\n"
    2212                 :             "Advanced options :\n"
    2213                 :             "               [-gt n]\n"
    2214                 :             "               [-clipsrc [xmin ymin xmax ymax]|WKT|datasource|spat_extent]\n"
    2215                 :             "               [-clipsrcsql sql_statement] [-clipsrclayer layer]\n"
    2216                 :             "               [-clipsrcwhere expression]\n"
    2217                 :             "               [-clipdst [xmin ymin xmax ymax]|WKT|datasource]\n"
    2218                 :             "               [-clipdstsql sql_statement] [-clipdstlayer layer]\n"
    2219                 :             "               [-clipdstwhere expression]\n"
    2220                 :             "               [-wrapdateline][-datelineoffset val]\n"
    2221                 :             "               [[-simplify tolerance] | [-segmentize max_dist]]\n"
    2222                 :             "               [-fieldTypeToString All|(type1[,type2]*)]\n"
    2223                 :             "               [-fieldmap identity | index1[,index2]*]\n"
    2224                 :             "               [-splitlistfields] [-maxsubfields val]\n"
    2225                 :             "               [-explodecollections] [-zfield field_name]\n"
    2226               0 :             "               [-gcp pixel line easting northing [elevation]]* [-order n | -tps]\n");
    2227                 : 
    2228               0 :     if (bShort)
    2229                 :     {
    2230               0 :         printf( "\nNote: ogr2ogr --long-usage for full help.\n");
    2231               0 :         if( pszAdditionalMsg )
    2232               0 :             fprintf(stderr, "\nFAILURE: %s\n", pszAdditionalMsg);
    2233               0 :         exit( 1 );
    2234                 :     }
    2235                 : 
    2236               0 :     printf("\n -f format_name: output file format name, possible values are:\n");
    2237                 : 
    2238               0 :     for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
    2239                 :     {
    2240               0 :         OGRSFDriver *poDriver = poR->GetDriver(iDriver);
    2241                 : 
    2242               0 :         if( poDriver->TestCapability( ODrCCreateDataSource ) )
    2243               0 :             printf( "     -f \"%s\"\n", poDriver->GetName() );
    2244                 :     }
    2245                 : 
    2246                 :     printf( " -append: Append to existing layer instead of creating new if it exists\n"
    2247                 :             " -overwrite: delete the output layer and recreate it empty\n"
    2248                 :             " -update: Open existing output datasource in update mode\n"
    2249                 :             " -progress: Display progress on terminal. Only works if input layers have the \n"
    2250                 :             "                                          \"fast feature count\" capability\n"
    2251                 :             " -select field_list: Comma-delimited list of fields from input layer to\n"
    2252                 :             "                     copy to the new layer (defaults to all)\n" 
    2253                 :             " -where restricted_where: Attribute query (like SQL WHERE)\n" 
    2254                 :             " -wrapdateline: split geometries crossing the dateline meridian\n"
    2255                 :             "                (long. = +/- 180deg)\n" 
    2256                 :             " -datelineoffset: offset from dateline in degrees\n"
    2257                 :             "                (default long. = +/- 10deg,\n"
    2258                 :             "                geometries within 170deg to -170deg will be splited)\n" 
    2259                 :             " -sql statement: Execute given SQL statement and save result.\n"
    2260                 :             " -dialect value: select a dialect, usually OGRSQL to avoid native sql.\n"
    2261                 :             " -skipfailures: skip features or layers that fail to convert\n"
    2262                 :             " -gt n: group n features per transaction (default 200)\n"
    2263                 :             " -spat xmin ymin xmax ymax: spatial query extents\n"
    2264                 :             " -simplify tolerance: distance tolerance for simplification.\n"
    2265                 :             " -segmentize max_dist: maximum distance between 2 nodes.\n"
    2266                 :             "                       Used to create intermediate points\n"
    2267                 :             " -dsco NAME=VALUE: Dataset creation option (format specific)\n"
    2268                 :             " -lco  NAME=VALUE: Layer creation option (format specific)\n"
    2269                 :             " -nln name: Assign an alternate name to the new layer\n"
    2270                 :             " -nlt type: Force a geometry type for new layer.  One of NONE, GEOMETRY,\n"
    2271                 :             "      POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n"
    2272                 :             "      MULTIPOLYGON, or MULTILINESTRING, or PROMOTE_TO_MULTI.  Add \"25D\" for 3D layers.\n"
    2273                 :             "      Default is type of source layer.\n"
    2274                 :             " -dim dimension: Force the coordinate dimension to the specified value.\n"
    2275                 :             " -fieldTypeToString type1,...: Converts fields of specified types to\n"
    2276                 :             "      fields of type string in the new layer. Valid types are : Integer,\n"
    2277                 :             "      Real, String, Date, Time, DateTime, Binary, IntegerList, RealList,\n"
    2278                 :             "      StringList. Special value All will convert all fields to strings.\n"
    2279                 :             " -fieldmap index1,index2,...: Specifies the list of field indexes to be\n"
    2280                 :             "      copied from the source to the destination. The (n)th value specified\n"
    2281                 :             "      in the list is the index of the field in the target layer definition\n"
    2282                 :             "      in which the n(th) field of the source layer must be copied. Index count\n"
    2283                 :             "      starts at zero. There must be exactly as many values in the list as\n"
    2284                 :             "      the count of the fields in the source layer. We can use the 'identity'\n"
    2285                 :             "      setting to specify that the fields should be transferred by using the\n"
    2286               0 :             "      same order. This setting should be used along with the append setting.");
    2287                 : 
    2288                 :     printf(" -a_srs srs_def: Assign an output SRS\n"
    2289                 :            " -t_srs srs_def: Reproject/transform to this SRS on output\n"
    2290                 :            " -s_srs srs_def: Override source SRS\n"
    2291                 :            "\n" 
    2292                 :            " Srs_def can be a full WKT definition (hard to escape properly),\n"
    2293                 :            " or a well known definition (ie. EPSG:4326) or a file with a WKT\n"
    2294               0 :            " definition.\n" );
    2295                 : 
    2296               0 :     if( pszAdditionalMsg )
    2297               0 :         fprintf(stderr, "\nFAILURE: %s\n", pszAdditionalMsg);
    2298                 : 
    2299               0 :     exit( 1 );
    2300                 : }
    2301                 : 
    2302                 : /************************************************************************/
    2303                 : /*                               SetZ()                                 */
    2304                 : /************************************************************************/
    2305              60 : static void SetZ (OGRGeometry* poGeom, double dfZ )
    2306                 : {
    2307              60 :     if (poGeom == NULL)
    2308               0 :         return;
    2309              60 :     switch (wkbFlatten(poGeom->getGeometryType()))
    2310                 :     {
    2311                 :         case wkbPoint:
    2312               0 :             ((OGRPoint*)poGeom)->setZ(dfZ);
    2313               0 :             break;
    2314                 : 
    2315                 :         case wkbLineString:
    2316                 :         case wkbLinearRing:
    2317                 :         {
    2318                 :             int i;
    2319              30 :             OGRLineString* poLS = (OGRLineString*) poGeom;
    2320             765 :             for(i=0;i<poLS->getNumPoints();i++)
    2321             735 :                 poLS->setPoint(i, poLS->getX(i), poLS->getY(i), dfZ);
    2322              30 :             break;
    2323                 :         }
    2324                 : 
    2325                 :         case wkbPolygon:
    2326                 :         {
    2327                 :             int i;
    2328              30 :             OGRPolygon* poPoly = (OGRPolygon*) poGeom;
    2329              30 :             SetZ(poPoly->getExteriorRing(), dfZ);
    2330              30 :             for(i=0;i<poPoly->getNumInteriorRings();i++)
    2331               0 :                 SetZ(poPoly->getInteriorRing(i), dfZ);
    2332              30 :             break;
    2333                 :         }
    2334                 : 
    2335                 :         case wkbMultiPoint:
    2336                 :         case wkbMultiLineString:
    2337                 :         case wkbMultiPolygon:
    2338                 :         case wkbGeometryCollection:
    2339                 :         {
    2340                 :             int i;
    2341               0 :             OGRGeometryCollection* poGeomColl = (OGRGeometryCollection*) poGeom;
    2342               0 :             for(i=0;i<poGeomColl->getNumGeometries();i++)
    2343               0 :                 SetZ(poGeomColl->getGeometryRef(i), dfZ);
    2344                 :             break;
    2345                 :         }
    2346                 : 
    2347                 :         default:
    2348                 :             break;
    2349                 :     }
    2350                 : }
    2351                 : 
    2352                 : /************************************************************************/
    2353                 : /*                         SetupTargetLayer()                           */
    2354                 : /************************************************************************/
    2355                 : 
    2356             130 : static TargetLayerInfo* SetupTargetLayer( OGRDataSource *poSrcDS,
    2357                 :                                                 OGRLayer * poSrcLayer,
    2358                 :                                                 OGRDataSource *poDstDS,
    2359                 :                                                 char **papszLCO,
    2360                 :                                                 const char *pszNewLayerName,
    2361                 :                                                 OGRSpatialReference *poOutputSRS,
    2362                 :                                                 int bNullifyOutputSRS,
    2363                 :                                                 char **papszSelFields,
    2364                 :                                                 int bAppend, int eGType,
    2365                 :                                                 int bPromoteToMulti,
    2366                 :                                                 int nCoordDim, int bOverwrite,
    2367                 :                                                 char** papszFieldTypesToString,
    2368                 :                                                 int bExplodeCollections,
    2369                 :                                                 const char* pszZField,
    2370                 :                                                 char **papszFieldMap,
    2371                 :                                                 const char* pszWHERE )
    2372                 : {
    2373                 :     OGRLayer    *poDstLayer;
    2374                 :     OGRFeatureDefn *poSrcFDefn;
    2375             130 :     OGRFeatureDefn *poDstFDefn = NULL;
    2376                 : 
    2377             130 :     if( pszNewLayerName == NULL )
    2378             114 :         pszNewLayerName = poSrcLayer->GetName();
    2379                 : 
    2380                 : /* -------------------------------------------------------------------- */
    2381                 : /*      Get other info.                                                 */
    2382                 : /* -------------------------------------------------------------------- */
    2383             130 :     poSrcFDefn = poSrcLayer->GetLayerDefn();
    2384                 : 
    2385             130 :     if( poOutputSRS == NULL && !bNullifyOutputSRS )
    2386             123 :         poOutputSRS = poSrcLayer->GetSpatialRef();
    2387                 : 
    2388                 : /* -------------------------------------------------------------------- */
    2389                 : /*      Find the layer.                                                 */
    2390                 : /* -------------------------------------------------------------------- */
    2391                 : 
    2392                 :     /* GetLayerByName() can instanciate layers that would have been */
    2393                 :     /* 'hidden' otherwise, for example, non-spatial tables in a */
    2394                 :     /* Postgis-enabled database, so this apparently useless command is */
    2395                 :     /* not useless... (#4012) */
    2396             130 :     CPLPushErrorHandler(CPLQuietErrorHandler);
    2397             130 :     poDstLayer = poDstDS->GetLayerByName(pszNewLayerName);
    2398             130 :     CPLPopErrorHandler();
    2399             130 :     CPLErrorReset();
    2400                 : 
    2401             130 :     int iLayer = -1;
    2402             130 :     if (poDstLayer != NULL)
    2403                 :     {
    2404              15 :         int nLayerCount = poDstDS->GetLayerCount();
    2405             195 :         for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
    2406                 :         {
    2407             195 :             OGRLayer        *poLayer = poDstDS->GetLayer(iLayer);
    2408             195 :             if (poLayer == poDstLayer)
    2409              15 :                 break;
    2410                 :         }
    2411                 : 
    2412              15 :         if (iLayer == nLayerCount)
    2413                 :             /* shouldn't happen with an ideal driver */
    2414               0 :             poDstLayer = NULL;
    2415                 :     }
    2416                 : 
    2417                 : /* -------------------------------------------------------------------- */
    2418                 : /*      If the user requested overwrite, and we have the layer in       */
    2419                 : /*      question we need to delete it now so it will get recreated      */
    2420                 : /*      (overwritten).                                                  */
    2421                 : /* -------------------------------------------------------------------- */
    2422             130 :     if( poDstLayer != NULL && bOverwrite )
    2423                 :     {
    2424               7 :         if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
    2425                 :         {
    2426                 :             fprintf( stderr,
    2427               0 :                      "DeleteLayer() failed when overwrite requested.\n" );
    2428               0 :             return NULL;
    2429                 :         }
    2430               7 :         poDstLayer = NULL;
    2431                 :     }
    2432                 : 
    2433                 : /* -------------------------------------------------------------------- */
    2434                 : /*      If the layer does not exist, then create it.                    */
    2435                 : /* -------------------------------------------------------------------- */
    2436             130 :     if( poDstLayer == NULL )
    2437                 :     {
    2438             122 :         if( eGType == -2 )
    2439                 :         {
    2440             115 :             eGType = poSrcFDefn->GetGeomType();
    2441                 : 
    2442             115 :             int n25DBit = eGType & wkb25DBit;
    2443             115 :             if ( bPromoteToMulti )
    2444                 :             {
    2445               2 :                 if (wkbFlatten(eGType) == wkbLineString)
    2446               1 :                     eGType = wkbMultiLineString | n25DBit;
    2447               1 :                 else if (wkbFlatten(eGType) == wkbPolygon)
    2448               1 :                     eGType = wkbMultiPolygon | n25DBit;
    2449                 :             }
    2450                 : 
    2451             115 :             if ( bExplodeCollections )
    2452                 :             {
    2453               1 :                 if (wkbFlatten(eGType) == wkbMultiPoint)
    2454                 :                 {
    2455               0 :                     eGType = wkbPoint | n25DBit;
    2456                 :                 }
    2457               1 :                 else if (wkbFlatten(eGType) == wkbMultiLineString)
    2458                 :                 {
    2459               0 :                     eGType = wkbLineString | n25DBit;
    2460                 :                 }
    2461               1 :                 else if (wkbFlatten(eGType) == wkbMultiPolygon)
    2462                 :                 {
    2463               0 :                     eGType = wkbPolygon | n25DBit;
    2464                 :                 }
    2465               1 :                 else if (wkbFlatten(eGType) == wkbGeometryCollection)
    2466                 :                 {
    2467               0 :                     eGType = wkbUnknown | n25DBit;
    2468                 :                 }
    2469                 :             }
    2470                 : 
    2471             115 :             if ( pszZField )
    2472               3 :                 eGType |= wkb25DBit;
    2473                 :         }
    2474                 : 
    2475             122 :         if( nCoordDim == 2 )
    2476               1 :             eGType &= ~wkb25DBit;
    2477             121 :         else if( nCoordDim == 3 )
    2478               1 :             eGType |= wkb25DBit;
    2479                 : 
    2480             122 :         if( !poDstDS->TestCapability( ODsCCreateLayer ) )
    2481                 :         {
    2482                 :             fprintf( stderr,
    2483                 :               "Layer %s not found, and CreateLayer not supported by driver.",
    2484               0 :                      pszNewLayerName );
    2485               0 :             return NULL;
    2486                 :         }
    2487                 : 
    2488             122 :         CPLErrorReset();
    2489                 : 
    2490                 :         poDstLayer = poDstDS->CreateLayer( pszNewLayerName, poOutputSRS,
    2491                 :                                            (OGRwkbGeometryType) eGType,
    2492             122 :                                            papszLCO );
    2493                 : 
    2494             122 :         if( poDstLayer == NULL )
    2495               0 :             return NULL;
    2496                 : 
    2497             122 :         bAppend = FALSE;
    2498                 :     }
    2499                 : 
    2500                 : /* -------------------------------------------------------------------- */
    2501                 : /*      Otherwise we will append to it, if append was requested.        */
    2502                 : /* -------------------------------------------------------------------- */
    2503               8 :     else if( !bAppend )
    2504                 :     {
    2505                 :         fprintf( stderr, "FAILED: Layer %s already exists, and -append not specified.\n"
    2506                 :                 "        Consider using -append, or -overwrite.\n",
    2507               0 :                 pszNewLayerName );
    2508               0 :         return NULL;
    2509                 :     }
    2510                 :     else
    2511                 :     {
    2512               8 :         if( CSLCount(papszLCO) > 0 )
    2513                 :         {
    2514                 :             fprintf( stderr, "WARNING: Layer creation options ignored since an existing layer is\n"
    2515               0 :                     "         being appended to.\n" );
    2516                 :         }
    2517                 :     }
    2518                 : 
    2519                 : /* -------------------------------------------------------------------- */
    2520                 : /*      Process Layer style table                                       */
    2521                 : /* -------------------------------------------------------------------- */
    2522                 : 
    2523             130 :     poDstLayer->SetStyleTable( poSrcLayer->GetStyleTable () );
    2524                 : /* -------------------------------------------------------------------- */
    2525                 : /*      Add fields.  Default to copy all field.                         */
    2526                 : /*      If only a subset of all fields requested, then output only      */
    2527                 : /*      the selected fields, and in the order that they were            */
    2528                 : /*      selected.                                                       */
    2529                 : /* -------------------------------------------------------------------- */
    2530             130 :     int         nSrcFieldCount = poSrcFDefn->GetFieldCount();
    2531                 :     int         iField, *panMap;
    2532                 : 
    2533                 :     // Initialize the index-to-index map to -1's
    2534             130 :     panMap = (int *) VSIMalloc( sizeof(int) * nSrcFieldCount );
    2535             902 :     for( iField=0; iField < nSrcFieldCount; iField++)
    2536             772 :         panMap[iField] = -1;
    2537                 : 
    2538                 :     /* Caution : at the time of writing, the MapInfo driver */
    2539                 :     /* returns NULL until a field has been added */
    2540             130 :     poDstFDefn = poDstLayer->GetLayerDefn();
    2541                 : 
    2542             132 :     if (papszFieldMap && bAppend)
    2543                 :     {
    2544               2 :         int bIdentity = FALSE;
    2545                 : 
    2546               2 :         if (EQUAL(papszFieldMap[0], "identity"))
    2547               1 :             bIdentity = TRUE;
    2548               1 :         else if (CSLCount(papszFieldMap) != nSrcFieldCount)
    2549                 :         {
    2550               0 :             fprintf( stderr, "Field map should contain the value 'identity' or the same number of integer values as the source field count.\n");
    2551               0 :             VSIFree(panMap);
    2552               0 :             return NULL;
    2553                 :         }
    2554                 : 
    2555              32 :         for( iField=0; iField < nSrcFieldCount; iField++)
    2556                 :         {
    2557              30 :             panMap[iField] = bIdentity? iField : atoi(papszFieldMap[iField]);
    2558              30 :             if (panMap[iField] >= poDstFDefn->GetFieldCount())
    2559                 :             {
    2560               0 :                 fprintf( stderr, "Invalid destination field index %d.\n", panMap[iField]);
    2561               0 :                 VSIFree(panMap);
    2562               0 :                 return NULL;
    2563                 :             }
    2564                 :         }
    2565                 :     }
    2566             135 :     else if (papszSelFields && !bAppend )
    2567                 :     {
    2568               7 :         int  nDstFieldCount = 0;
    2569               7 :         if (poDstFDefn)
    2570               6 :             nDstFieldCount = poDstFDefn->GetFieldCount();
    2571              18 :         for( iField=0; papszSelFields[iField] != NULL; iField++)
    2572                 :         {
    2573              11 :             int iSrcField = poSrcFDefn->GetFieldIndex(papszSelFields[iField]);
    2574              11 :             if (iSrcField >= 0)
    2575                 :             {
    2576              11 :                 OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iSrcField);
    2577              11 :                 OGRFieldDefn oFieldDefn( poSrcFieldDefn );
    2578                 : 
    2579              11 :                 if (papszFieldTypesToString != NULL &&
    2580                 :                     (CSLFindString(papszFieldTypesToString, "All") != -1 ||
    2581                 :                      CSLFindString(papszFieldTypesToString,
    2582                 :                                    OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
    2583                 :                 {
    2584               0 :                     oFieldDefn.SetType(OFTString);
    2585                 :                 }
    2586                 : 
    2587                 :                 /* The field may have been already created at layer creation */
    2588              11 :                 int iDstField = -1;
    2589              11 :                 if (poDstFDefn)
    2590              10 :                     iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
    2591              11 :                 if (iDstField >= 0)
    2592                 :                 {
    2593               0 :                     panMap[iSrcField] = iDstField;
    2594                 :                 }
    2595              11 :                 else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
    2596                 :                 {
    2597                 :                     /* now that we've created a field, GetLayerDefn() won't return NULL */
    2598              11 :                     if (poDstFDefn == NULL)
    2599               1 :                         poDstFDefn = poDstLayer->GetLayerDefn();
    2600                 : 
    2601                 :                     /* Sanity check : if it fails, the driver is buggy */
    2602              11 :                     if (poDstFDefn != NULL &&
    2603                 :                         poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
    2604                 :                     {
    2605                 :                         CPLError(CE_Warning, CPLE_AppDefined,
    2606                 :                                  "The output driver has claimed to have added the %s field, but it did not!",
    2607               0 :                                  oFieldDefn.GetNameRef() );
    2608                 :                     }
    2609                 :                     else
    2610                 :                     {
    2611              11 :                         panMap[iSrcField] = nDstFieldCount;
    2612              11 :                         nDstFieldCount ++;
    2613                 :                     }
    2614              11 :                 }
    2615                 :             }
    2616                 :             else
    2617                 :             {
    2618                 :                 fprintf( stderr, "Field '%s' not found in source layer.\n",
    2619               0 :                         papszSelFields[iField] );
    2620               0 :                 if( !bSkipFailures )
    2621                 :                 {
    2622               0 :                     VSIFree(panMap);
    2623               0 :                     return NULL;
    2624                 :                 }
    2625                 :             }
    2626                 :         }
    2627                 : 
    2628                 :         /* -------------------------------------------------------------------- */
    2629                 :         /* Use SetIgnoredFields() on source layer if available                  */
    2630                 :         /* -------------------------------------------------------------------- */
    2631               7 :         if (poSrcLayer->TestCapability(OLCIgnoreFields))
    2632                 :         {
    2633                 :             int iSrcField;
    2634               3 :             char** papszIgnoredFields = NULL;
    2635               3 :             int bUseIgnoredFields = TRUE;
    2636               3 :             char** papszWHEREUsedFields = NULL;
    2637                 : 
    2638               3 :             if (pszWHERE)
    2639                 :             {
    2640                 :                 /* We must not ignore fields used in the -where expression (#4015) */
    2641               2 :                 OGRFeatureQuery oFeatureQuery;
    2642               2 :                 if ( oFeatureQuery.Compile( poSrcLayer->GetLayerDefn(), pszWHERE ) == OGRERR_NONE )
    2643                 :                 {
    2644               2 :                     papszWHEREUsedFields = oFeatureQuery.GetUsedFields();
    2645                 :                 }
    2646                 :                 else
    2647                 :                 {
    2648               0 :                     bUseIgnoredFields = FALSE;
    2649               2 :                 }
    2650                 :             }
    2651                 : 
    2652              12 :             for(iSrcField=0;iSrcField<poSrcFDefn->GetFieldCount();iSrcField++)
    2653                 :             {
    2654                 :                 const char* pszFieldName =
    2655               9 :                     poSrcFDefn->GetFieldDefn(iSrcField)->GetNameRef();
    2656               9 :                 int bFieldRequested = FALSE;
    2657              16 :                 for( iField=0; papszSelFields[iField] != NULL; iField++)
    2658                 :                 {
    2659              11 :                     if (EQUAL(pszFieldName, papszSelFields[iField]))
    2660                 :                     {
    2661               4 :                         bFieldRequested = TRUE;
    2662               4 :                         break;
    2663                 :                     }
    2664                 :                 }
    2665               9 :                 bFieldRequested |= CSLFindString(papszWHEREUsedFields, pszFieldName) >= 0;
    2666               9 :                 bFieldRequested |= (pszZField != NULL && EQUAL(pszFieldName, pszZField));
    2667                 : 
    2668                 :                 /* If source field not requested, add it to ignored files list */
    2669               9 :                 if (!bFieldRequested)
    2670               4 :                     papszIgnoredFields = CSLAddString(papszIgnoredFields, pszFieldName);
    2671                 :             }
    2672               3 :             if (bUseIgnoredFields)
    2673               3 :                 poSrcLayer->SetIgnoredFields((const char**)papszIgnoredFields);
    2674               3 :             CSLDestroy(papszIgnoredFields);
    2675               3 :             CSLDestroy(papszWHEREUsedFields);
    2676                 :         }
    2677                 :     }
    2678             121 :     else if( !bAppend )
    2679                 :     {
    2680             115 :         int nDstFieldCount = 0;
    2681             115 :         if (poDstFDefn)
    2682             113 :             nDstFieldCount = poDstFDefn->GetFieldCount();
    2683             821 :         for( iField = 0; iField < nSrcFieldCount; iField++ )
    2684                 :         {
    2685             706 :             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
    2686             706 :             OGRFieldDefn oFieldDefn( poSrcFieldDefn );
    2687                 : 
    2688             706 :             if (papszFieldTypesToString != NULL &&
    2689                 :                 (CSLFindString(papszFieldTypesToString, "All") != -1 ||
    2690                 :                  CSLFindString(papszFieldTypesToString,
    2691                 :                                OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
    2692                 :             {
    2693               0 :                 oFieldDefn.SetType(OFTString);
    2694                 :             }
    2695                 : 
    2696                 :             /* The field may have been already created at layer creation */
    2697             706 :             int iDstField = -1;
    2698             706 :             if (poDstFDefn)
    2699             704 :                  iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
    2700             706 :             if (iDstField >= 0)
    2701                 :             {
    2702             285 :                 panMap[iField] = iDstField;
    2703                 :             }
    2704             421 :             else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
    2705                 :             {
    2706                 :                 /* now that we've created a field, GetLayerDefn() won't return NULL */
    2707             421 :                 if (poDstFDefn == NULL)
    2708               2 :                     poDstFDefn = poDstLayer->GetLayerDefn();
    2709                 : 
    2710                 :                 /* Sanity check : if it fails, the driver is buggy */
    2711             421 :                 if (poDstFDefn != NULL &&
    2712                 :                     poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
    2713                 :                 {
    2714                 :                     CPLError(CE_Warning, CPLE_AppDefined,
    2715                 :                              "The output driver has claimed to have added the %s field, but it did not!",
    2716               0 :                              oFieldDefn.GetNameRef() );
    2717                 :                 }
    2718                 :                 else
    2719                 :                 {
    2720             421 :                     panMap[iField] = nDstFieldCount;
    2721             421 :                     nDstFieldCount ++;
    2722                 :                 }
    2723                 :             }
    2724                 :         }
    2725                 :     }
    2726                 :     else
    2727                 :     {
    2728                 :         /* For an existing layer, build the map by fetching the index in the destination */
    2729                 :         /* layer for each source field */
    2730               6 :         if (poDstFDefn == NULL)
    2731                 :         {
    2732               0 :             fprintf( stderr, "poDstFDefn == NULL.\n" );
    2733               0 :             VSIFree(panMap);
    2734               0 :             return NULL;
    2735                 :         }
    2736                 : 
    2737              24 :         for( iField = 0; iField < nSrcFieldCount; iField++ )
    2738                 :         {
    2739              18 :             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
    2740              18 :             int iDstField = poDstFDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
    2741              18 :             if (iDstField >= 0)
    2742              18 :                 panMap[iField] = iDstField;
    2743                 :             else
    2744                 :                 CPLDebug("OGR2OGR", "Skipping field '%s' not found in destination layer '%s'.",
    2745               0 :                          poSrcFieldDefn->GetNameRef(), poDstLayer->GetName() );
    2746                 :         }
    2747                 :     }
    2748                 : 
    2749             130 :     int iSrcZField = -1;
    2750             130 :     if (pszZField != NULL)
    2751                 :     {
    2752               3 :         iSrcZField = poSrcFDefn->GetFieldIndex(pszZField);
    2753                 :     }
    2754                 : 
    2755                 :     TargetLayerInfo* psInfo = (TargetLayerInfo*)
    2756             130 :                                             CPLMalloc(sizeof(TargetLayerInfo));
    2757             130 :     psInfo->nFeaturesRead = 0;
    2758             130 :     psInfo->bPerFeatureCT = FALSE;
    2759             130 :     psInfo->poDstLayer = poDstLayer;
    2760             130 :     psInfo->poCT = NULL;
    2761             130 :     psInfo->papszTransformOptions = NULL;
    2762             130 :     psInfo->panMap = panMap;
    2763             130 :     psInfo->iSrcZField = iSrcZField;
    2764                 : 
    2765             130 :     return psInfo;
    2766                 : }
    2767                 : 
    2768                 : /************************************************************************/
    2769                 : /*                         FreeTargetLayerInfo()                        */
    2770                 : /************************************************************************/
    2771                 : 
    2772             130 : static void FreeTargetLayerInfo(TargetLayerInfo* psInfo)
    2773                 : {
    2774             130 :     if( psInfo == NULL )
    2775               0 :         return;
    2776             130 :     delete psInfo->poCT;
    2777             130 :     CSLDestroy(psInfo->papszTransformOptions);
    2778             130 :     CPLFree(psInfo->panMap);
    2779             130 :     CPLFree(psInfo);
    2780                 : }
    2781                 : 
    2782                 : /************************************************************************/
    2783                 : /*                           TranslateLayer()                           */
    2784                 : /************************************************************************/
    2785                 : 
    2786             142 : static int TranslateLayer( TargetLayerInfo* psInfo,
    2787                 :                            OGRDataSource *poSrcDS,
    2788                 :                            OGRLayer * poSrcLayer,
    2789                 :                            OGRDataSource *poDstDS,
    2790                 :                            int bTransform,
    2791                 :                            int bWrapDateline,
    2792                 :                            const char* pszDateLineOffset,
    2793                 :                            OGRSpatialReference *poOutputSRS,
    2794                 :                            int bNullifyOutputSRS,
    2795                 :                            OGRSpatialReference *poUserSourceSRS,
    2796                 :                            OGRCoordinateTransformation *poGCPCoordTrans,
    2797                 :                            int eGType,
    2798                 :                            int bPromoteToMulti,
    2799                 :                            int nCoordDim,
    2800                 :                            GeomOperation eGeomOp,
    2801                 :                            double dfGeomOpParam,
    2802                 :                            long nCountLayerFeatures,
    2803                 :                            OGRGeometry* poClipSrc,
    2804                 :                            OGRGeometry *poClipDst,
    2805                 :                            int bExplodeCollections,
    2806                 :                            vsi_l_offset nSrcFileSize,
    2807                 :                            GIntBig* pnReadFeatureCount,
    2808                 :                            GDALProgressFunc pfnProgress,
    2809                 :                            void *pProgressArg )
    2810                 : 
    2811                 : {
    2812                 :     OGRLayer    *poDstLayer;
    2813             142 :     int         bForceToPolygon = FALSE;
    2814             142 :     int         bForceToMultiPolygon = FALSE;
    2815             142 :     int         bForceToMultiLineString = FALSE;
    2816             142 :     char**      papszTransformOptions = NULL;
    2817             142 :     OGRCoordinateTransformation *poCT = NULL;
    2818             142 :     int         *panMap = NULL;
    2819                 :     int         iSrcZField;
    2820                 : 
    2821             142 :     poDstLayer = psInfo->poDstLayer;
    2822             142 :     panMap = psInfo->panMap;
    2823             142 :     iSrcZField = psInfo->iSrcZField;
    2824                 : 
    2825             142 :     if( poOutputSRS == NULL && !bNullifyOutputSRS )
    2826             135 :         poOutputSRS = poSrcLayer->GetSpatialRef();
    2827                 :     
    2828             142 :     if( wkbFlatten(eGType) == wkbPolygon )
    2829               1 :         bForceToPolygon = TRUE;
    2830             141 :     else if( wkbFlatten(eGType) == wkbMultiPolygon )
    2831               2 :         bForceToMultiPolygon = TRUE;
    2832             139 :     else if( wkbFlatten(eGType) == wkbMultiLineString )
    2833               0 :         bForceToMultiLineString = TRUE;
    2834                 : 
    2835                 : /* -------------------------------------------------------------------- */
    2836                 : /*      Transfer features.                                              */
    2837                 : /* -------------------------------------------------------------------- */
    2838                 :     OGRFeature  *poFeature;
    2839             142 :     int         nFeaturesInTransaction = 0;
    2840             142 :     GIntBig      nCount = 0; /* written + failed */
    2841             142 :     GIntBig      nFeaturesWritten = 0;
    2842                 : 
    2843             142 :     if( nGroupTransactions )
    2844             142 :         poDstLayer->StartTransaction();
    2845                 : 
    2846          125925 :     while( TRUE )
    2847                 :     {
    2848          126067 :         OGRFeature      *poDstFeature = NULL;
    2849                 : 
    2850          126067 :         if( nFIDToFetch != OGRNullFID )
    2851                 :         {
    2852                 :             // Only fetch feature on first pass.
    2853               2 :             if( nFeaturesInTransaction == 0 )
    2854               1 :                 poFeature = poSrcLayer->GetFeature(nFIDToFetch);
    2855                 :             else
    2856               1 :                 poFeature = NULL;
    2857                 :         }
    2858                 :         else
    2859          126065 :             poFeature = poSrcLayer->GetNextFeature();
    2860                 : 
    2861          126067 :         if( poFeature == NULL )
    2862                 :             break;
    2863                 : 
    2864          125925 :         if( psInfo->nFeaturesRead == 0 || psInfo->bPerFeatureCT )
    2865                 :         {
    2866                 :         /* -------------------------------------------------------------------- */
    2867                 :         /*      Setup coordinate transformation if we need it.                  */
    2868                 :         /* -------------------------------------------------------------------- */
    2869             129 :             OGRSpatialReference* poSourceSRS = NULL;
    2870                 : 
    2871             129 :             poCT = NULL;
    2872             129 :             papszTransformOptions = NULL;
    2873                 : 
    2874             129 :             if( bTransform )
    2875                 :             {
    2876               5 :                 if( psInfo->nFeaturesRead == 0 )
    2877                 :                 {
    2878               4 :                     poSourceSRS = poUserSourceSRS;
    2879               4 :                     if( poSourceSRS == NULL )
    2880               3 :                         poSourceSRS = poSrcLayer->GetSpatialRef();
    2881                 :                 }
    2882               5 :                 if( poSourceSRS == NULL )
    2883                 :                 {
    2884               2 :                     OGRGeometry* poSrcGeometry = poFeature->GetGeometryRef();
    2885               2 :                     if( poSrcGeometry )
    2886               2 :                         poSourceSRS = poSrcGeometry->getSpatialReference();
    2887               2 :                     psInfo->bPerFeatureCT = TRUE;
    2888                 :                 }
    2889                 : 
    2890               5 :                 if( poSourceSRS == NULL )
    2891                 :                 {
    2892                 :                     fprintf( stderr, "Can't transform coordinates, source layer has no\n"
    2893               0 :                             "coordinate system.  Use -s_srs to set one.\n" );
    2894               0 :                     OGRFeature::DestroyFeature( poFeature );
    2895               0 :                     return FALSE;
    2896                 :                 }
    2897                 : 
    2898               5 :                 CPLAssert( NULL != poSourceSRS );
    2899               5 :                 CPLAssert( NULL != poOutputSRS );
    2900                 : 
    2901               6 :                 if( psInfo->poCT != NULL &&
    2902               1 :                     psInfo->poCT->GetSourceCS() == poSourceSRS )
    2903                 :                 {
    2904               0 :                     poCT = psInfo->poCT;
    2905                 :                 }
    2906                 :                 else
    2907                 :                 {
    2908               5 :                     poCT = OGRCreateCoordinateTransformation( poSourceSRS, poOutputSRS );
    2909               5 :                     if( poCT == NULL )
    2910                 :                     {
    2911               0 :                         char        *pszWKT = NULL;
    2912                 : 
    2913                 :                         fprintf( stderr, "Failed to create coordinate transformation between the\n"
    2914                 :                             "following coordinate systems.  This may be because they\n"
    2915                 :                             "are not transformable, or because projection services\n"
    2916               0 :                             "(PROJ.4 DLL/.so) could not be loaded.\n" );
    2917                 : 
    2918               0 :                         poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
    2919               0 :                         fprintf( stderr,  "Source:\n%s\n", pszWKT );
    2920               0 :                         CPLFree(pszWKT);
    2921                 : 
    2922               0 :                         poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
    2923               0 :                         fprintf( stderr,  "Target:\n%s\n", pszWKT );
    2924               0 :                         CPLFree(pszWKT);
    2925                 : 
    2926               0 :                         OGRFeature::DestroyFeature( poFeature );
    2927               0 :                         return FALSE;
    2928                 :                     }
    2929               5 :                     if( poGCPCoordTrans != NULL )
    2930               1 :                         poCT = new CompositeCT( poGCPCoordTrans, poCT );
    2931                 :                 }
    2932                 : 
    2933               5 :                 if( poCT != psInfo->poCT )
    2934                 :                 {
    2935               5 :                     delete psInfo->poCT;
    2936               5 :                     psInfo->poCT = poCT;
    2937                 :                 }
    2938                 :             }
    2939                 :             else
    2940                 :             {
    2941             124 :                 poCT = poGCPCoordTrans;
    2942                 :             }
    2943                 : 
    2944             129 :             if (bWrapDateline)
    2945                 :             {
    2946               4 :                 if( poSourceSRS == NULL )
    2947                 :                 {
    2948               3 :                     if( psInfo->nFeaturesRead == 0 )
    2949                 :                     {
    2950               3 :                         poSourceSRS = poUserSourceSRS;
    2951               3 :                         if( poSourceSRS == NULL )
    2952               3 :                             poSourceSRS = poSrcLayer->GetSpatialRef();
    2953                 :                     }
    2954               3 :                     if( poSourceSRS == NULL )
    2955                 :                     {
    2956               0 :                         OGRGeometry* poSrcGeometry = poFeature->GetGeometryRef();
    2957               0 :                         if( poSrcGeometry )
    2958               0 :                             poSourceSRS = poSrcGeometry->getSpatialReference();
    2959               0 :                         psInfo->bPerFeatureCT = TRUE;
    2960                 :                     }
    2961                 :                 }
    2962                 : 
    2963               4 :                 if (bTransform && poCT != NULL && poOutputSRS != NULL && poOutputSRS->IsGeographic())
    2964                 :                 {
    2965                 :                     papszTransformOptions =
    2966               1 :                         CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
    2967               1 :                     CPLString soOffset("DATELINEOFFSET=");
    2968               1 :                     soOffset += pszDateLineOffset;
    2969                 :                     papszTransformOptions =
    2970               1 :                         CSLAddString(papszTransformOptions, soOffset);
    2971                 :                 }
    2972               3 :                 else if (poSourceSRS != NULL && poSourceSRS->IsGeographic())
    2973                 :                 {
    2974                 :                     papszTransformOptions =
    2975               3 :                         CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
    2976               3 :                     CPLString soOffset("DATELINEOFFSET=");
    2977               3 :                     soOffset += pszDateLineOffset;
    2978                 :                     papszTransformOptions =
    2979               3 :                         CSLAddString(papszTransformOptions, soOffset);
    2980                 :                 }
    2981                 :                 else
    2982                 :                 {
    2983                 :                     static int bHasWarned = FALSE;
    2984               0 :                     if( !bHasWarned )
    2985               0 :                         fprintf(stderr, "-wrapdateline option only works when reprojecting to a geographic SRS\n");
    2986               0 :                     bHasWarned = TRUE;
    2987                 :                 }
    2988                 : 
    2989               4 :                 CSLDestroy(psInfo->papszTransformOptions);
    2990               4 :                 psInfo->papszTransformOptions = papszTransformOptions;
    2991                 :             }
    2992                 : 
    2993                 :         }
    2994                 : 
    2995          125925 :         psInfo->nFeaturesRead ++;
    2996                 : 
    2997          125925 :         int nParts = 0;
    2998          125925 :         int nIters = 1;
    2999          125925 :         if (bExplodeCollections)
    3000                 :         {
    3001               2 :             OGRGeometry* poSrcGeometry = poFeature->GetGeometryRef();
    3002               2 :             if (poSrcGeometry)
    3003                 :             {
    3004               2 :                 switch (wkbFlatten(poSrcGeometry->getGeometryType()))
    3005                 :                 {
    3006                 :                     case wkbMultiPoint:
    3007                 :                     case wkbMultiLineString:
    3008                 :                     case wkbMultiPolygon:
    3009                 :                     case wkbGeometryCollection:
    3010               1 :                         nParts = ((OGRGeometryCollection*)poSrcGeometry)->getNumGeometries();
    3011               1 :                         nIters = nParts;
    3012               1 :                         if (nIters == 0)
    3013               0 :                             nIters = 1;
    3014                 :                     default:
    3015                 :                         break;
    3016                 :                 }
    3017                 :             }
    3018                 :         }
    3019                 : 
    3020          251851 :         for(int iPart = 0; iPart < nIters; iPart++)
    3021                 :         {
    3022          125926 :             if( ++nFeaturesInTransaction == nGroupTransactions )
    3023                 :             {
    3024             630 :                 poDstLayer->CommitTransaction();
    3025             630 :                 poDstLayer->StartTransaction();
    3026             630 :                 nFeaturesInTransaction = 0;
    3027                 :             }
    3028                 : 
    3029          125926 :             CPLErrorReset();
    3030          125926 :             poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
    3031                 : 
    3032                 :             /* Optimization to avoid duplicating the source geometry in the */
    3033                 :             /* target feature : we steal it from the source feature for now... */
    3034          125926 :             OGRGeometry* poStealedGeometry = NULL;
    3035          125926 :             if( !bExplodeCollections )
    3036          125923 :                 poStealedGeometry = poFeature->StealGeometry();
    3037                 : 
    3038          125926 :             if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
    3039                 :             {
    3040               0 :                 if( nGroupTransactions )
    3041               0 :                     poDstLayer->CommitTransaction();
    3042                 : 
    3043                 :                 CPLError( CE_Failure, CPLE_AppDefined,
    3044                 :                         "Unable to translate feature %ld from layer %s.\n",
    3045               0 :                         poFeature->GetFID(), poSrcLayer->GetName() );
    3046                 : 
    3047               0 :                 OGRFeature::DestroyFeature( poFeature );
    3048               0 :                 OGRFeature::DestroyFeature( poDstFeature );
    3049               0 :                 OGRGeometryFactory::destroyGeometry( poStealedGeometry );
    3050               0 :                 return FALSE;
    3051                 :             }
    3052                 : 
    3053                 :             /* ... and now we can attach the stealed geometry */
    3054          125926 :             if( poStealedGeometry )
    3055           24406 :                 poDstFeature->SetGeometryDirectly(poStealedGeometry);
    3056                 : 
    3057          125926 :             if( bPreserveFID )
    3058               0 :                 poDstFeature->SetFID( poFeature->GetFID() );
    3059                 : 
    3060          125926 :             OGRGeometry* poDstGeometry = poDstFeature->GetGeometryRef();
    3061          125926 :             if (poDstGeometry != NULL)
    3062                 :             {
    3063           24409 :                 if (nParts > 0)
    3064                 :                 {
    3065                 :                     /* For -explodecollections, extract the iPart(th) of the geometry */
    3066               2 :                     OGRGeometry* poPart = ((OGRGeometryCollection*)poDstGeometry)->getGeometryRef(iPart);
    3067               2 :                     ((OGRGeometryCollection*)poDstGeometry)->removeGeometry(iPart, FALSE);
    3068               2 :                     poDstFeature->SetGeometryDirectly(poPart);
    3069               2 :                     poDstGeometry = poPart;
    3070                 :                 }
    3071                 : 
    3072           24409 :                 if (iSrcZField != -1)
    3073                 :                 {
    3074              30 :                     SetZ(poDstGeometry, poFeature->GetFieldAsDouble(iSrcZField));
    3075                 :                     /* This will correct the coordinate dimension to 3 */
    3076              30 :                     OGRGeometry* poDupGeometry = poDstGeometry->clone();
    3077              30 :                     poDstFeature->SetGeometryDirectly(poDupGeometry);
    3078              30 :                     poDstGeometry = poDupGeometry;
    3079                 :                 }
    3080                 : 
    3081           24409 :                 if (nCoordDim == 2 || nCoordDim == 3)
    3082              20 :                     poDstGeometry->setCoordinateDimension( nCoordDim );
    3083                 : 
    3084           24409 :                 if (eGeomOp == SEGMENTIZE)
    3085                 :                 {
    3086              10 :                     if (dfGeomOpParam > 0)
    3087              10 :                         poDstGeometry->segmentize(dfGeomOpParam);
    3088                 :                 }
    3089           24399 :                 else if (eGeomOp == SIMPLIFY_PRESERVE_TOPOLOGY)
    3090                 :                 {
    3091               0 :                     if (dfGeomOpParam > 0)
    3092                 :                     {
    3093               0 :                         OGRGeometry* poNewGeom = poDstGeometry->SimplifyPreserveTopology(dfGeomOpParam);
    3094               0 :                         if (poNewGeom)
    3095                 :                         {
    3096               0 :                             poDstFeature->SetGeometryDirectly(poNewGeom);
    3097               0 :                             poDstGeometry = poNewGeom;
    3098                 :                         }
    3099                 :                     }
    3100                 :                 }
    3101                 : 
    3102           24409 :                 if (poClipSrc)
    3103                 :                 {
    3104              24 :                     OGRGeometry* poClipped = poDstGeometry->Intersection(poClipSrc);
    3105              24 :                     if (poClipped == NULL || poClipped->IsEmpty())
    3106                 :                     {
    3107              12 :                         OGRGeometryFactory::destroyGeometry(poClipped);
    3108              12 :                         goto end_loop;
    3109                 :                     }
    3110              12 :                     poDstFeature->SetGeometryDirectly(poClipped);
    3111              12 :                     poDstGeometry = poClipped;
    3112                 :                 }
    3113                 : 
    3114           24423 :                 if( poCT != NULL || papszTransformOptions != NULL)
    3115                 :                 {
    3116                 :                     OGRGeometry* poReprojectedGeom =
    3117              26 :                         OGRGeometryFactory::transformWithOptions(poDstGeometry, poCT, papszTransformOptions);
    3118              26 :                     if( poReprojectedGeom == NULL )
    3119                 :                     {
    3120               0 :                         if( nGroupTransactions )
    3121               0 :                             poDstLayer->CommitTransaction();
    3122                 : 
    3123                 :                         fprintf( stderr, "Failed to reproject feature %d (geometry probably out of source or destination SRS).\n",
    3124               0 :                                 (int) poFeature->GetFID() );
    3125               0 :                         if( !bSkipFailures )
    3126                 :                         {
    3127               0 :                             OGRFeature::DestroyFeature( poFeature );
    3128               0 :                             OGRFeature::DestroyFeature( poDstFeature );
    3129               0 :                             return FALSE;
    3130                 :                         }
    3131                 :                     }
    3132                 : 
    3133              26 :                     poDstFeature->SetGeometryDirectly(poReprojectedGeom);
    3134              26 :                     poDstGeometry = poReprojectedGeom;
    3135                 :                 }
    3136           24371 :                 else if (poOutputSRS != NULL)
    3137                 :                 {
    3138           24313 :                     poDstGeometry->assignSpatialReference(poOutputSRS);
    3139                 :                 }
    3140                 : 
    3141           24397 :                 if (poClipDst)
    3142                 :                 {
    3143              20 :                     OGRGeometry* poClipped = poDstGeometry->Intersection(poClipDst);
    3144              20 :                     if (poClipped == NULL || poClipped->IsEmpty())
    3145                 :                     {
    3146              12 :                         OGRGeometryFactory::destroyGeometry(poClipped);
    3147              12 :                         goto end_loop;
    3148                 :                     }
    3149                 : 
    3150               8 :                     poDstFeature->SetGeometryDirectly(poClipped);
    3151               8 :                     poDstGeometry = poClipped;
    3152                 :                 }
    3153                 : 
    3154           24385 :                 if( bForceToPolygon )
    3155                 :                 {
    3156                 :                     poDstFeature->SetGeometryDirectly(
    3157                 :                         OGRGeometryFactory::forceToPolygon(
    3158              10 :                             poDstFeature->StealGeometry() ) );
    3159                 :                 }
    3160           24379 :                 else if( bForceToMultiPolygon ||
    3161               4 :                         (bPromoteToMulti && wkbFlatten(poDstGeometry->getGeometryType()) == wkbPolygon) )
    3162                 :                 {
    3163                 :                     poDstFeature->SetGeometryDirectly(
    3164                 :                         OGRGeometryFactory::forceToMultiPolygon(
    3165              15 :                             poDstFeature->StealGeometry() ) );
    3166                 :                 }
    3167           24363 :                 else if ( bForceToMultiLineString ||
    3168               3 :                         (bPromoteToMulti && wkbFlatten(poDstGeometry->getGeometryType()) == wkbLineString) )
    3169                 :                 {
    3170                 :                     poDstFeature->SetGeometryDirectly(
    3171                 :                         OGRGeometryFactory::forceToMultiLineString(
    3172               1 :                             poDstFeature->StealGeometry() ) );
    3173                 :                 }
    3174                 :             }
    3175                 : 
    3176          125902 :             CPLErrorReset();
    3177          125902 :             if( poDstLayer->CreateFeature( poDstFeature ) == OGRERR_NONE )
    3178                 :             {
    3179          125902 :                 nFeaturesWritten ++;
    3180                 :             }
    3181               0 :             else if( !bSkipFailures )
    3182                 :             {
    3183               0 :                 if( nGroupTransactions )
    3184               0 :                     poDstLayer->RollbackTransaction();
    3185                 : 
    3186               0 :                 OGRFeature::DestroyFeature( poFeature );
    3187               0 :                 OGRFeature::DestroyFeature( poDstFeature );
    3188               0 :                 return FALSE;
    3189                 :             }
    3190                 : 
    3191                 : end_loop:
    3192          125926 :             OGRFeature::DestroyFeature( poDstFeature );
    3193                 :         }
    3194                 : 
    3195          125925 :         OGRFeature::DestroyFeature( poFeature );
    3196                 : 
    3197                 :         /* Report progress */
    3198          125925 :         nCount ++;
    3199          125925 :         if (pfnProgress)
    3200                 :         {
    3201              34 :             if (nSrcFileSize != 0)
    3202                 :             {
    3203              24 :                 if ((nCount % 1000) == 0)
    3204                 :                 {
    3205               0 :                     OGRLayer* poFCLayer = poSrcDS->ExecuteSQL("GetBytesRead()", NULL, NULL);
    3206               0 :                     if( poFCLayer != NULL )
    3207                 :                     {
    3208               0 :                         OGRFeature* poFeat = poFCLayer->GetNextFeature();
    3209               0 :                         if( poFeat )
    3210                 :                         {
    3211               0 :                             const char* pszReadSize = poFeat->GetFieldAsString(0);
    3212               0 :                             GUIntBig nReadSize = CPLScanUIntBig( pszReadSize, 32 );
    3213               0 :                             pfnProgress(nReadSize * 1.0 / nSrcFileSize, "", pProgressArg);
    3214               0 :                             OGRFeature::DestroyFeature( poFeat );
    3215                 :                         }
    3216                 :                     }
    3217               0 :                     poSrcDS->ReleaseResultSet(poFCLayer);
    3218                 :                 }
    3219                 :             }
    3220                 :             else
    3221                 :             {
    3222              10 :                 pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg);
    3223                 :             }
    3224                 :         }
    3225                 : 
    3226          125925 :         if (pnReadFeatureCount)
    3227              21 :             *pnReadFeatureCount = nCount;
    3228                 :     }
    3229                 : 
    3230             142 :     if( nGroupTransactions )
    3231             142 :         poDstLayer->CommitTransaction();
    3232                 : 
    3233                 :     CPLDebug("OGR2OGR", CPL_FRMT_GIB " features written in layer '%s'",
    3234             142 :              nFeaturesWritten, poDstLayer->GetName());
    3235                 : 
    3236             142 :     return TRUE;
    3237                 : }
    3238                 : 

Generated by: LCOV version 1.7