LCOV - code coverage report
Current view: directory - apps - ogr2ogr.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 1291 940 72.8 %
Date: 2012-12-26 Functions: 43 27 62.8 %

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

Generated by: LCOV version 1.7