LCOV - code coverage report
Current view: directory - apps - ogr2ogr.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 631 370 58.6 %
Date: 2010-01-09 Functions: 5 3 60.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr2ogr.cpp 18249 2009-12-10 18:56:45Z warmerdam $
       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                 : 
      37                 : CPL_CVSID("$Id: ogr2ogr.cpp 18249 2009-12-10 18:56:45Z warmerdam $");
      38                 : 
      39                 : static void Usage();
      40                 : 
      41               1 : static int IsNumber(const char* pszStr)
      42                 : {
      43               1 :     if (*pszStr == '-' || *pszStr == '+')
      44               0 :         pszStr ++;
      45               1 :     if (*pszStr == '.')
      46               0 :         pszStr ++;
      47               1 :     return (*pszStr >= '0' && *pszStr <= '9');
      48                 : }
      49                 : 
      50               0 : static OGRGeometry* LoadGeometry( const char* pszDS,
      51                 :                                   const char* pszSQL,
      52                 :                                   const char* pszLyr,
      53                 :                                   const char* pszWhere)
      54                 : {
      55                 :     OGRDataSource       *poDS;
      56                 :     OGRLayer            *poLyr;
      57                 :     OGRFeature          *poFeat;
      58               0 :     OGRGeometry         *poGeom = NULL;
      59                 :         
      60               0 :     poDS = OGRSFDriverRegistrar::Open( pszDS, FALSE );
      61               0 :     if (poDS == NULL)
      62               0 :         return NULL;
      63                 : 
      64               0 :     if (pszSQL != NULL)
      65               0 :         poLyr = poDS->ExecuteSQL( pszSQL, NULL, NULL ); 
      66               0 :     else if (pszLyr != NULL)
      67               0 :         poLyr = poDS->GetLayerByName(pszLyr);
      68                 :     else
      69               0 :         poLyr = poDS->GetLayer(0);
      70                 :         
      71               0 :     if (poLyr == NULL)
      72                 :     {
      73               0 :         fprintf( stderr, "Failed to identify source layer from datasource.\n" );
      74               0 :         OGRDataSource::DestroyDataSource(poDS);
      75               0 :         return NULL;
      76                 :     }
      77                 :     
      78               0 :     if (pszWhere)
      79               0 :         poLyr->SetAttributeFilter(pszWhere);
      80                 :         
      81               0 :     while ((poFeat = poLyr->GetNextFeature()) != NULL)
      82                 :     {
      83               0 :         OGRGeometry* poSrcGeom = poFeat->GetGeometryRef();
      84               0 :         if (poSrcGeom)
      85                 :         {
      86               0 :             OGRwkbGeometryType eType = wkbFlatten( poSrcGeom->getGeometryType() );
      87                 :             
      88               0 :             if (poGeom == NULL)
      89               0 :                 poGeom = OGRGeometryFactory::createGeometry( wkbMultiPolygon );
      90                 : 
      91               0 :             if( eType == wkbPolygon )
      92               0 :                 ((OGRGeometryCollection*)poGeom)->addGeometry( poSrcGeom );
      93               0 :             else if( eType == wkbMultiPolygon )
      94                 :             {
      95                 :                 int iGeom;
      96               0 :                 int nGeomCount = OGR_G_GetGeometryCount( (OGRGeometryH)poSrcGeom );
      97                 : 
      98               0 :                 for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
      99                 :                 {
     100                 :                     ((OGRGeometryCollection*)poGeom)->addGeometry(
     101               0 :                                 ((OGRGeometryCollection*)poSrcGeom)->getGeometryRef(iGeom) );
     102                 :                 }
     103                 :             }
     104                 :             else
     105                 :             {
     106               0 :                 fprintf( stderr, "ERROR: Geometry not of polygon type.\n" );
     107               0 :                 OGRGeometryFactory::destroyGeometry(poGeom);
     108               0 :                 OGRFeature::DestroyFeature(poFeat);
     109               0 :                 if( pszSQL != NULL )
     110               0 :                     poDS->ReleaseResultSet( poLyr );
     111               0 :                 OGRDataSource::DestroyDataSource(poDS);
     112               0 :                 return NULL;
     113                 :             }
     114                 :         }
     115                 :     
     116               0 :         OGRFeature::DestroyFeature(poFeat);
     117                 :     }
     118                 :     
     119               0 :     if( pszSQL != NULL )
     120               0 :         poDS->ReleaseResultSet( poLyr );
     121               0 :     OGRDataSource::DestroyDataSource(poDS);
     122                 :     
     123               0 :     return poGeom;
     124                 : }
     125                 : 
     126                 : static int TranslateLayer( OGRDataSource *poSrcDS, 
     127                 :                            OGRLayer * poSrcLayer,
     128                 :                            OGRDataSource *poDstDS,
     129                 :                            char ** papszLSCO,
     130                 :                            const char *pszNewLayerName,
     131                 :                            int bTransform, 
     132                 :                            OGRSpatialReference *poOutputSRS,
     133                 :                            OGRSpatialReference *poSourceSRS,
     134                 :                            char **papszSelFields,
     135                 :                            int bAppend, int eGType,
     136                 :                            int bOverwrite,
     137                 :                            double dfMaxSegmentLength,
     138                 :                            char** papszFieldTypesToString,
     139                 :                            long nCountLayerFeatures,
     140                 :                            int bWrapDateline,
     141                 :                            OGRGeometry* poClipSrc,
     142                 :                            OGRGeometry *poClipDst,
     143                 :                            GDALProgressFunc pfnProgress,
     144                 :                            void *pProgressArg);
     145                 : 
     146                 : static int bSkipFailures = FALSE;
     147                 : static int nGroupTransactions = 200;
     148                 : static int bPreserveFID = FALSE;
     149                 : static int nFIDToFetch = OGRNullFID;
     150                 : 
     151                 : /************************************************************************/
     152                 : /*                                main()                                */
     153                 : /************************************************************************/
     154                 : 
     155              25 : int main( int nArgc, char ** papszArgv )
     156                 : 
     157                 : {
     158              25 :     const char  *pszFormat = "ESRI Shapefile";
     159              25 :     const char  *pszDataSource = NULL;
     160              25 :     const char  *pszDestDataSource = NULL;
     161              25 :     char        **papszLayers = NULL;
     162              25 :     char        **papszDSCO = NULL, **papszLCO = NULL;
     163              25 :     int         bTransform = FALSE;
     164              25 :     int         bAppend = FALSE, bUpdate = FALSE, bOverwrite = FALSE;
     165              25 :     const char  *pszOutputSRSDef = NULL;
     166              25 :     const char  *pszSourceSRSDef = NULL;
     167              25 :     OGRSpatialReference *poOutputSRS = NULL;
     168              25 :     OGRSpatialReference *poSourceSRS = NULL;
     169              25 :     const char  *pszNewLayerName = NULL;
     170              25 :     const char  *pszWHERE = NULL;
     171              25 :     OGRGeometry *poSpatialFilter = NULL;
     172                 :     const char  *pszSelect;
     173              25 :     char        **papszSelFields = NULL;
     174              25 :     const char  *pszSQLStatement = NULL;
     175              25 :     const char  *pszDialect = NULL;
     176              25 :     int         eGType = -2;
     177              25 :     double       dfMaxSegmentLength = 0;
     178              25 :     char        **papszFieldTypesToString = NULL;
     179              25 :     int          bDisplayProgress = FALSE;
     180              25 :     GDALProgressFunc pfnProgress = NULL;
     181              25 :     void        *pProgressArg = NULL;
     182              25 :     int          bWrapDateline = FALSE;
     183              25 :     int          bClipSrc = FALSE;
     184              25 :     OGRGeometry* poClipSrc = NULL;
     185              25 :     const char  *pszClipSrcDS = NULL;
     186              25 :     const char  *pszClipSrcSQL = NULL;
     187              25 :     const char  *pszClipSrcLayer = NULL;
     188              25 :     const char  *pszClipSrcWhere = NULL;
     189              25 :     OGRGeometry *poClipDst = NULL;
     190              25 :     const char  *pszClipDstDS = NULL;
     191              25 :     const char  *pszClipDstSQL = NULL;
     192              25 :     const char  *pszClipDstLayer = NULL;
     193              25 :     const char  *pszClipDstWhere = NULL;
     194                 : 
     195                 :     /* Check strict compilation and runtime library version as we use C++ API */
     196              25 :     if (! GDAL_CHECK_VERSION(papszArgv[0]))
     197               0 :         exit(1);
     198                 : /* -------------------------------------------------------------------- */
     199                 : /*      Register format(s).                                             */
     200                 : /* -------------------------------------------------------------------- */
     201              25 :     OGRRegisterAll();
     202                 : 
     203                 : /* -------------------------------------------------------------------- */
     204                 : /*      Processing command line arguments.                              */
     205                 : /* -------------------------------------------------------------------- */
     206              25 :     nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
     207                 :     
     208              25 :     if( nArgc < 1 )
     209               0 :         exit( -nArgc );
     210                 : 
     211             105 :     for( int iArg = 1; iArg < nArgc; iArg++ )
     212                 :     {
     213              81 :         if( EQUAL(papszArgv[iArg], "--utility_version") )
     214                 :         {
     215                 :             printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
     216               1 :                    papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
     217               1 :             return 0;
     218                 :         }
     219              84 :         else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 )
     220                 :         {
     221               4 :             pszFormat = papszArgv[++iArg];
     222                 :         }
     223              76 :         else if( EQUAL(papszArgv[iArg],"-dsco") && iArg < nArgc-1 )
     224                 :         {
     225               0 :             papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg] );
     226                 :         }
     227              77 :         else if( EQUAL(papszArgv[iArg],"-lco") && iArg < nArgc-1 )
     228                 :         {
     229               1 :             papszLCO = CSLAddString(papszLCO, papszArgv[++iArg] );
     230                 :         }
     231              75 :         else if( EQUAL(papszArgv[iArg],"-preserve_fid") )
     232                 :         {
     233               0 :             bPreserveFID = TRUE;
     234                 :         }
     235              75 :         else if( EQUALN(papszArgv[iArg],"-skip",5) )
     236                 :         {
     237               0 :             bSkipFailures = TRUE;
     238               0 :             nGroupTransactions = 1; /* #2409 */
     239                 :         }
     240              75 :         else if( EQUAL(papszArgv[iArg],"-append") )
     241                 :         {
     242               1 :             bAppend = TRUE;
     243               1 :             bUpdate = TRUE;
     244                 :         }
     245              74 :         else if( EQUAL(papszArgv[iArg],"-overwrite") )
     246                 :         {
     247               2 :             bOverwrite = TRUE;
     248               2 :             bUpdate = TRUE;
     249                 :         }
     250              72 :         else if( EQUAL(papszArgv[iArg],"-update") )
     251                 :         {
     252               2 :             bUpdate = TRUE;
     253                 :         }
     254              71 :         else if( EQUAL(papszArgv[iArg],"-fid") && papszArgv[iArg+1] != NULL )
     255                 :         {
     256               1 :             nFIDToFetch = atoi(papszArgv[++iArg]);
     257                 :         }
     258              71 :         else if( EQUAL(papszArgv[iArg],"-sql") && papszArgv[iArg+1] != NULL )
     259                 :         {
     260               2 :             pszSQLStatement = papszArgv[++iArg];
     261                 :         }
     262              67 :         else if( EQUAL(papszArgv[iArg],"-dialect") && papszArgv[iArg+1] != NULL )
     263                 :         {
     264               0 :             pszDialect = papszArgv[++iArg];
     265                 :         }
     266              70 :         else if( EQUAL(papszArgv[iArg],"-nln") && iArg < nArgc-1 )
     267                 :         {
     268               3 :             pszNewLayerName = papszArgv[++iArg];
     269                 :         }
     270              66 :         else if( EQUAL(papszArgv[iArg],"-nlt") && iArg < nArgc-1 )
     271                 :         {
     272               2 :             if( EQUAL(papszArgv[iArg+1],"NONE") )
     273               0 :                 eGType = wkbNone;
     274               2 :             else if( EQUAL(papszArgv[iArg+1],"GEOMETRY") )
     275               0 :                 eGType = wkbUnknown;
     276               2 :             else if( EQUAL(papszArgv[iArg+1],"POINT") )
     277               1 :                 eGType = wkbPoint;
     278               1 :             else if( EQUAL(papszArgv[iArg+1],"LINESTRING") )
     279               0 :                 eGType = wkbLineString;
     280               1 :             else if( EQUAL(papszArgv[iArg+1],"POLYGON") )
     281               0 :                 eGType = wkbPolygon;
     282               1 :             else if( EQUAL(papszArgv[iArg+1],"GEOMETRYCOLLECTION") )
     283               0 :                 eGType = wkbGeometryCollection;
     284               1 :             else if( EQUAL(papszArgv[iArg+1],"MULTIPOINT") )
     285               0 :                 eGType = wkbMultiPoint;
     286               1 :             else if( EQUAL(papszArgv[iArg+1],"MULTILINESTRING") )
     287               0 :                 eGType = wkbMultiLineString;
     288               1 :             else if( EQUAL(papszArgv[iArg+1],"MULTIPOLYGON") )
     289               0 :                 eGType = wkbMultiPolygon;
     290               1 :             else if( EQUAL(papszArgv[iArg+1],"GEOMETRY25D") )
     291               0 :                 eGType = wkbUnknown | wkb25DBit;
     292               1 :             else if( EQUAL(papszArgv[iArg+1],"POINT25D") )
     293               0 :                 eGType = wkbPoint25D;
     294               1 :             else if( EQUAL(papszArgv[iArg+1],"LINESTRING25D") )
     295               0 :                 eGType = wkbLineString25D;
     296               1 :             else if( EQUAL(papszArgv[iArg+1],"POLYGON25D") )
     297               1 :                 eGType = wkbPolygon25D;
     298               0 :             else if( EQUAL(papszArgv[iArg+1],"GEOMETRYCOLLECTION25D") )
     299               0 :                 eGType = wkbGeometryCollection25D;
     300               0 :             else if( EQUAL(papszArgv[iArg+1],"MULTIPOINT25D") )
     301               0 :                 eGType = wkbMultiPoint25D;
     302               0 :             else if( EQUAL(papszArgv[iArg+1],"MULTILINESTRING25D") )
     303               0 :                 eGType = wkbMultiLineString25D;
     304               0 :             else if( EQUAL(papszArgv[iArg+1],"MULTIPOLYGON25D") )
     305               0 :                 eGType = wkbMultiPolygon25D;
     306                 :             else
     307                 :             {
     308                 :                 fprintf( stderr, "-nlt %s: type not recognised.\n", 
     309               0 :                          papszArgv[iArg+1] );
     310               0 :                 exit( 1 );
     311                 :             }
     312               2 :             iArg++;
     313                 :         }
     314             125 :         else if( (EQUAL(papszArgv[iArg],"-tg") ||
     315              62 :                   EQUAL(papszArgv[iArg],"-gt")) && iArg < nArgc-1 )
     316                 :         {
     317               1 :             nGroupTransactions = atoi(papszArgv[++iArg]);
     318                 :         }
     319              61 :         else if( EQUAL(papszArgv[iArg],"-s_srs") && iArg < nArgc-1 )
     320                 :         {
     321               0 :             pszSourceSRSDef = papszArgv[++iArg];
     322                 :         }
     323              62 :         else if( EQUAL(papszArgv[iArg],"-a_srs") && iArg < nArgc-1 )
     324                 :         {
     325               1 :             pszOutputSRSDef = papszArgv[++iArg];
     326                 :         }
     327              62 :         else if( EQUAL(papszArgv[iArg],"-t_srs") && iArg < nArgc-1 )
     328                 :         {
     329               2 :             pszOutputSRSDef = papszArgv[++iArg];
     330               2 :             bTransform = TRUE;
     331                 :         }
     332              68 :         else if( EQUAL(papszArgv[iArg],"-spat") 
     333               2 :                  && papszArgv[iArg+1] != NULL 
     334               2 :                  && papszArgv[iArg+2] != NULL 
     335               2 :                  && papszArgv[iArg+3] != NULL 
     336               2 :                  && papszArgv[iArg+4] != NULL )
     337                 :         {
     338               2 :             OGRLinearRing  oRing;
     339                 : 
     340               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     341               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
     342               2 :             oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
     343               2 :             oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
     344               2 :             oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     345                 : 
     346               2 :             poSpatialFilter = new OGRPolygon();
     347               2 :             ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
     348               2 :             iArg += 4;
     349                 :         }
     350              57 :         else if( EQUAL(papszArgv[iArg],"-where") && papszArgv[iArg+1] != NULL )
     351                 :         {
     352               1 :             pszWHERE = papszArgv[++iArg];
     353                 :         }
     354              56 :         else if( EQUAL(papszArgv[iArg],"-select") && papszArgv[iArg+1] != NULL)
     355                 :         {
     356               1 :             pszSelect = papszArgv[++iArg];
     357                 :             papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,", 
     358               1 :                                                       FALSE, FALSE );
     359                 :         }
     360              55 :         else if( EQUAL(papszArgv[iArg],"-segmentize") && iArg < nArgc-1 )
     361                 :         {
     362               1 :             dfMaxSegmentLength = atof(papszArgv[++iArg]);
     363                 :         }
     364              53 :         else if( EQUAL(papszArgv[iArg],"-fieldTypeToString") && iArg < nArgc-1 )
     365                 :         {
     366                 :             papszFieldTypesToString =
     367               0 :                     CSLTokenizeStringComplex(papszArgv[++iArg], " ,", 
     368               0 :                                              FALSE, FALSE );
     369               0 :             char** iter = papszFieldTypesToString;
     370               0 :             while(*iter)
     371                 :             {
     372               0 :                 if (EQUAL(*iter, "Integer") ||
     373                 :                     EQUAL(*iter, "Real") ||
     374                 :                     EQUAL(*iter, "String") ||
     375                 :                     EQUAL(*iter, "Date") ||
     376                 :                     EQUAL(*iter, "Time") ||
     377                 :                     EQUAL(*iter, "DateTime") ||
     378                 :                     EQUAL(*iter, "Binary") ||
     379                 :                     EQUAL(*iter, "IntegerList") ||
     380                 :                     EQUAL(*iter, "RealList") ||
     381                 :                     EQUAL(*iter, "StringList"))
     382                 :                 {
     383                 :                     /* Do nothing */
     384                 :                 }
     385               0 :                 else if (EQUAL(*iter, "All"))
     386                 :                 {
     387               0 :                     CSLDestroy(papszFieldTypesToString);
     388               0 :                     papszFieldTypesToString = NULL;
     389               0 :                     papszFieldTypesToString = CSLAddString(papszFieldTypesToString, "All");
     390               0 :                     break;
     391                 :                 }
     392                 :                 else
     393                 :                 {
     394                 :                     fprintf(stderr, "Unhandled type for fieldtypeasstring option : %s\n",
     395               0 :                             *iter);
     396               0 :                     Usage();
     397                 :                 }
     398               0 :                 iter ++;
     399                 :             }
     400                 :         }
     401              53 :         else if( EQUAL(papszArgv[iArg],"-progress") )
     402                 :         {
     403               1 :             bDisplayProgress = TRUE;
     404                 :         }
     405              52 :         else if( EQUAL(papszArgv[iArg],"-wrapdateline") )
     406                 :         {
     407               1 :             bWrapDateline = TRUE;
     408                 :         }
     409              52 :         else if( EQUAL(papszArgv[iArg],"-clipsrc") && iArg < nArgc-1 )
     410                 :         {
     411               1 :             bClipSrc = TRUE;
     412               1 :             if ( IsNumber(papszArgv[iArg+1])
     413               0 :                  && papszArgv[iArg+2] != NULL 
     414               0 :                  && papszArgv[iArg+3] != NULL 
     415               0 :                  && papszArgv[iArg+4] != NULL)
     416                 :             {
     417               0 :                 OGRLinearRing  oRing;
     418                 : 
     419               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     420               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
     421               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
     422               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
     423               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     424                 : 
     425               0 :                 poClipSrc = new OGRPolygon();
     426               0 :                 ((OGRPolygon *) poClipSrc)->addRing( &oRing );
     427               0 :                 iArg += 4;
     428                 :             }
     429               2 :             else if (EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
     430               1 :                      EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12))
     431                 :             {
     432               0 :                 OGRGeometryFactory::createFromWkt(&papszArgv[iArg+1], NULL, &poClipSrc);
     433               0 :                 if (poClipSrc == NULL)
     434                 :                 {
     435               0 :                     fprintf( stderr, "FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n\n");
     436               0 :                     Usage();
     437                 :                 }
     438               0 :                 iArg ++;
     439                 :             }
     440               1 :             else if (EQUAL(papszArgv[iArg+1], "spat_extent") )
     441                 :             {
     442               1 :                 iArg ++;
     443                 :             }
     444                 :             else
     445                 :             {
     446               0 :                 pszClipSrcDS = papszArgv[iArg+1];
     447               0 :                 iArg ++;
     448                 :             }
     449                 :         }
     450              50 :         else if( EQUAL(papszArgv[iArg],"-clipsrcsql") && iArg < nArgc-1 )
     451                 :         {
     452               0 :             pszClipSrcSQL = papszArgv[iArg+1];
     453               0 :             iArg ++;
     454                 :         }
     455              50 :         else if( EQUAL(papszArgv[iArg],"-clipsrclayer") && iArg < nArgc-1 )
     456                 :         {
     457               0 :             pszClipSrcLayer = papszArgv[iArg+1];
     458               0 :             iArg ++;
     459                 :         }
     460              50 :         else if( EQUAL(papszArgv[iArg],"-clipsrcwhere") && iArg < nArgc-1 )
     461                 :         {
     462               0 :             pszClipSrcWhere = papszArgv[iArg+1];
     463               0 :             iArg ++;
     464                 :         }
     465              50 :         else if( EQUAL(papszArgv[iArg],"-clipdst") && iArg < nArgc-1 )
     466                 :         {
     467               0 :             if ( IsNumber(papszArgv[iArg+1])
     468               0 :                  && papszArgv[iArg+2] != NULL 
     469               0 :                  && papszArgv[iArg+3] != NULL 
     470               0 :                  && papszArgv[iArg+4] != NULL)
     471                 :             {
     472               0 :                 OGRLinearRing  oRing;
     473                 : 
     474               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     475               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
     476               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
     477               0 :                 oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
     478               0 :                 oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
     479                 : 
     480               0 :                 poClipDst = new OGRPolygon();
     481               0 :                 ((OGRPolygon *) poClipDst)->addRing( &oRing );
     482               0 :                 iArg += 4;
     483                 :             }
     484               0 :             else if (EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
     485               0 :                      EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12))
     486                 :             {
     487               0 :                 OGRGeometryFactory::createFromWkt(&papszArgv[iArg+1], NULL, &poClipDst);
     488               0 :                 if (poClipDst == NULL)
     489                 :                 {
     490               0 :                     fprintf( stderr, "FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n\n");
     491               0 :                     Usage();
     492                 :                 }
     493               0 :                 iArg ++;
     494                 :             }
     495                 :             else
     496                 :             {
     497               0 :                 pszClipDstDS = papszArgv[iArg+1];
     498               0 :                 iArg ++;
     499                 :             }
     500                 :         }
     501              50 :         else if( EQUAL(papszArgv[iArg],"-clipdstsql") && iArg < nArgc-1 )
     502                 :         {
     503               0 :             pszClipDstSQL = papszArgv[iArg+1];
     504               0 :             iArg ++;
     505                 :         }
     506              50 :         else if( EQUAL(papszArgv[iArg],"-clipdstlayer") && iArg < nArgc-1 )
     507                 :         {
     508               0 :             pszClipDstLayer = papszArgv[iArg+1];
     509               0 :             iArg ++;
     510                 :         }
     511              50 :         else if( EQUAL(papszArgv[iArg],"-clipdstwhere") && iArg < nArgc-1 )
     512                 :         {
     513               0 :             pszClipDstWhere = papszArgv[iArg+1];
     514               0 :             iArg ++;
     515                 :         }
     516              50 :         else if( papszArgv[iArg][0] == '-' )
     517                 :         {
     518               0 :             Usage();
     519                 :         }
     520              50 :         else if( pszDestDataSource == NULL )
     521              24 :             pszDestDataSource = papszArgv[iArg];
     522              26 :         else if( pszDataSource == NULL )
     523              24 :             pszDataSource = papszArgv[iArg];
     524                 :         else
     525               2 :             papszLayers = CSLAddString( papszLayers, papszArgv[iArg] );
     526                 :     }
     527                 : 
     528              24 :     if( pszDataSource == NULL )
     529               0 :         Usage();
     530                 :         
     531              24 :     if( bClipSrc && pszClipSrcDS != NULL)
     532                 :     {
     533               0 :         poClipSrc = LoadGeometry(pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere);
     534               0 :         if (poClipSrc == NULL)
     535                 :         {
     536               0 :             fprintf( stderr, "FAILURE: cannot load source clip geometry\n\n" );
     537               0 :             Usage();
     538                 :         }
     539                 :     }
     540              24 :     else if( bClipSrc && poClipSrc == NULL )
     541                 :     {
     542               1 :         if (poSpatialFilter)
     543               1 :             poClipSrc = poSpatialFilter->clone();
     544               1 :         if (poClipSrc == NULL)
     545                 :         {
     546                 :             fprintf( stderr, "FAILURE: -clipsrc must be used with -spat option or a\n"
     547               0 :                              "bounding box, WKT string or datasource must be specified\n\n");
     548               0 :             Usage();
     549                 :         }
     550                 :     }
     551                 :     
     552              24 :     if( pszClipDstDS != NULL)
     553                 :     {
     554               0 :         poClipDst = LoadGeometry(pszClipDstDS, pszClipDstSQL, pszClipDstLayer, pszClipDstWhere);
     555               0 :         if (poClipDst == NULL)
     556                 :         {
     557               0 :             fprintf( stderr, "FAILURE: cannot load dest clip geometry\n\n" );
     558               0 :             Usage();
     559                 :         }
     560                 :     }
     561                 :     
     562                 : /* -------------------------------------------------------------------- */
     563                 : /*      Open data source.                                               */
     564                 : /* -------------------------------------------------------------------- */
     565                 :     OGRDataSource       *poDS;
     566                 :         
     567              24 :     poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
     568                 : 
     569                 : /* -------------------------------------------------------------------- */
     570                 : /*      Report failure                                                  */
     571                 : /* -------------------------------------------------------------------- */
     572              24 :     if( poDS == NULL )
     573                 :     {
     574               0 :         OGRSFDriverRegistrar    *poR = OGRSFDriverRegistrar::GetRegistrar();
     575                 :         
     576                 :         fprintf( stderr, "FAILURE:\n"
     577                 :                 "Unable to open datasource `%s' with the following drivers.\n",
     578               0 :                 pszDataSource );
     579                 : 
     580               0 :         for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
     581                 :         {
     582               0 :             fprintf( stderr, "  -> %s\n", poR->GetDriver(iDriver)->GetName() );
     583                 :         }
     584                 : 
     585               0 :         exit( 1 );
     586                 :     }
     587                 : 
     588                 : /* -------------------------------------------------------------------- */
     589                 : /*      Try opening the output datasource as an existing, writable      */
     590                 : /* -------------------------------------------------------------------- */
     591                 :     OGRDataSource       *poODS;
     592                 :     
     593              24 :     if( bUpdate )
     594                 :     {
     595               3 :         poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, TRUE );
     596               3 :         if( poODS == NULL )
     597                 :         {
     598                 :             fprintf( stderr, "FAILURE:\n"
     599                 :                     "Unable to open existing output datasource `%s'.\n",
     600               0 :                     pszDestDataSource );
     601               0 :             exit( 1 );
     602                 :         }
     603                 : 
     604               3 :         if( CSLCount(papszDSCO) > 0 )
     605                 :         {
     606                 :             fprintf( stderr, "WARNING: Datasource creation options ignored since an existing datasource\n"
     607               0 :                     "         being updated.\n" );
     608                 :         }
     609                 :     }
     610                 : 
     611                 : /* -------------------------------------------------------------------- */
     612                 : /*      Find the output driver.                                         */
     613                 : /* -------------------------------------------------------------------- */
     614                 :     else
     615                 :     {
     616              21 :         OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
     617              21 :         OGRSFDriver          *poDriver = NULL;
     618                 :         int                  iDriver;
     619                 : 
     620             108 :         for( iDriver = 0;
     621                 :              iDriver < poR->GetDriverCount() && poDriver == NULL;
     622                 :              iDriver++ )
     623                 :         {
     624              87 :             if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) )
     625                 :             {
     626              21 :                 poDriver = poR->GetDriver(iDriver);
     627                 :             }
     628                 :         }
     629                 : 
     630              21 :         if( poDriver == NULL )
     631                 :         {
     632               0 :             fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
     633               0 :             fprintf( stderr,  "The following drivers are available:\n" );
     634                 :         
     635               0 :             for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
     636                 :             {
     637               0 :                 fprintf( stderr,  "  -> `%s'\n", poR->GetDriver(iDriver)->GetName() );
     638                 :             }
     639               0 :             exit( 1 );
     640                 :         }
     641                 : 
     642              21 :         if( !poDriver->TestCapability( ODrCCreateDataSource ) )
     643                 :         {
     644                 :             fprintf( stderr,  "%s driver does not support data source creation.\n",
     645               0 :                     pszFormat );
     646               0 :             exit( 1 );
     647                 :         }
     648                 : 
     649                 : /* -------------------------------------------------------------------- */
     650                 : /*      Create the output data source.                                  */
     651                 : /* -------------------------------------------------------------------- */
     652              21 :         poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
     653              21 :         if( poODS == NULL )
     654                 :         {
     655                 :             fprintf( stderr,  "%s driver failed to create %s\n", 
     656               0 :                     pszFormat, pszDestDataSource );
     657               0 :             exit( 1 );
     658                 :         }
     659                 :     }
     660                 : 
     661                 : /* -------------------------------------------------------------------- */
     662                 : /*      Parse the output SRS definition if possible.                    */
     663                 : /* -------------------------------------------------------------------- */
     664              24 :     if( pszOutputSRSDef != NULL )
     665                 :     {
     666               3 :         poOutputSRS = new OGRSpatialReference();
     667               3 :         if( poOutputSRS->SetFromUserInput( pszOutputSRSDef ) != OGRERR_NONE )
     668                 :         {
     669                 :             fprintf( stderr,  "Failed to process SRS definition: %s\n", 
     670               0 :                     pszOutputSRSDef );
     671               0 :             exit( 1 );
     672                 :         }
     673                 :     }
     674                 : 
     675                 : /* -------------------------------------------------------------------- */
     676                 : /*      Parse the source SRS definition if possible.                    */
     677                 : /* -------------------------------------------------------------------- */
     678              24 :     if( pszSourceSRSDef != NULL )
     679                 :     {
     680               0 :         poSourceSRS = new OGRSpatialReference();
     681               0 :         if( poSourceSRS->SetFromUserInput( pszSourceSRSDef ) != OGRERR_NONE )
     682                 :         {
     683                 :             fprintf( stderr,  "Failed to process SRS definition: %s\n", 
     684               0 :                     pszSourceSRSDef );
     685               0 :             exit( 1 );
     686                 :         }
     687                 :     }
     688                 : 
     689                 : /* -------------------------------------------------------------------- */
     690                 : /*      Special case for -sql clause.  No source layers required.       */
     691                 : /* -------------------------------------------------------------------- */
     692              24 :     if( pszSQLStatement != NULL )
     693                 :     {
     694                 :         OGRLayer *poResultSet;
     695                 : 
     696               2 :         if( pszWHERE != NULL )
     697               0 :             fprintf( stderr,  "-where clause ignored in combination with -sql.\n" );
     698               2 :         if( CSLCount(papszLayers) > 0 )
     699               0 :             fprintf( stderr,  "layer names ignored in combination with -sql.\n" );
     700                 :         
     701                 :         poResultSet = poDS->ExecuteSQL( pszSQLStatement, poSpatialFilter, 
     702               2 :                                         pszDialect );
     703                 : 
     704               2 :         if( poResultSet != NULL )
     705                 :         {
     706               2 :             long nCountLayerFeatures = 0;
     707               2 :             if (bDisplayProgress)
     708                 :             {
     709               0 :                 if (!poResultSet->TestCapability(OLCFastFeatureCount))
     710                 :                 {
     711               0 :                     fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
     712               0 :                     bDisplayProgress = FALSE;
     713                 :                 }
     714                 :                 else
     715                 :                 {
     716               0 :                     nCountLayerFeatures = poResultSet->GetFeatureCount();
     717               0 :                     pfnProgress = GDALTermProgress;
     718                 :                 }
     719                 :             }
     720                 : 
     721               2 :             if( !TranslateLayer( poDS, poResultSet, poODS, papszLCO, 
     722                 :                                  pszNewLayerName, bTransform, poOutputSRS,
     723                 :                                  poSourceSRS, papszSelFields, bAppend, eGType,
     724                 :                                  bOverwrite, dfMaxSegmentLength, papszFieldTypesToString,
     725                 :                                  nCountLayerFeatures, bWrapDateline, poClipSrc, poClipDst, pfnProgress, pProgressArg))
     726                 :             {
     727                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     728                 :                           "Terminating translation prematurely after failed\n"
     729               0 :                           "translation from sql statement." );
     730                 : 
     731               0 :                 exit( 1 );
     732                 :             }
     733               2 :             poDS->ReleaseResultSet( poResultSet );
     734                 :         }
     735                 :     }
     736                 : 
     737                 :     else
     738                 :     {
     739              22 :         int nLayerCount = 0;
     740              22 :         OGRLayer** papoLayers = NULL;
     741                 : 
     742                 : /* -------------------------------------------------------------------- */
     743                 : /*      Process each data source layer.                                 */
     744                 : /* -------------------------------------------------------------------- */
     745              22 :         if ( CSLCount(papszLayers) == 0)
     746                 :         {
     747              20 :             nLayerCount = poDS->GetLayerCount();
     748              20 :             papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
     749                 : 
     750              40 :             for( int iLayer = 0; 
     751                 :                  iLayer < nLayerCount; 
     752                 :                  iLayer++ )
     753                 :             {
     754              20 :                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
     755                 : 
     756              20 :                 if( poLayer == NULL )
     757                 :                 {
     758                 :                     fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
     759               0 :                             iLayer );
     760               0 :                     exit( 1 );
     761                 :                 }
     762                 : 
     763              20 :                 papoLayers[iLayer] = poLayer;
     764                 :             }
     765                 :         }
     766                 : /* -------------------------------------------------------------------- */
     767                 : /*      Process specified data source layers.                           */
     768                 : /* -------------------------------------------------------------------- */
     769                 :         else
     770                 :         {
     771               2 :             nLayerCount = CSLCount(papszLayers);
     772               2 :             papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
     773                 : 
     774               8 :             for( int iLayer = 0; 
     775               4 :                 papszLayers[iLayer] != NULL; 
     776                 :                 iLayer++ )
     777                 :             {
     778               2 :                 OGRLayer        *poLayer = poDS->GetLayerByName(papszLayers[iLayer]);
     779                 : 
     780               2 :                 if( poLayer == NULL )
     781                 :                 {
     782                 :                     fprintf( stderr, "FAILURE: Couldn't fetch requested layer '%s'!\n",
     783               0 :                              papszLayers[iLayer] );
     784               0 :                     if (!bSkipFailures)
     785               0 :                         exit( 1 );
     786                 :                 }
     787                 : 
     788               2 :                 papoLayers[iLayer] = poLayer;
     789                 :             }
     790                 :         }
     791                 : 
     792              22 :         long* panLayerCountFeatures = (long*) CPLMalloc(sizeof(long) * nLayerCount);
     793              22 :         long nCountLayersFeatures = 0;
     794              22 :         long nAccCountFeatures = 0;
     795                 :         int iLayer;
     796                 : 
     797                 :         /* First pass to apply filters and count all features if necessary */
     798              44 :         for( iLayer = 0; 
     799                 :             iLayer < nLayerCount; 
     800                 :             iLayer++ )
     801                 :         {
     802              22 :             OGRLayer        *poLayer = papoLayers[iLayer];
     803              22 :             if (poLayer == NULL)
     804               0 :                 continue;
     805                 : 
     806              22 :             if( pszWHERE != NULL )
     807               1 :                 poLayer->SetAttributeFilter( pszWHERE );
     808                 : 
     809              22 :             if( poSpatialFilter != NULL )
     810               2 :                 poLayer->SetSpatialFilter( poSpatialFilter );
     811                 : 
     812              22 :             if (bDisplayProgress)
     813                 :             {
     814               1 :                 if (!poLayer->TestCapability(OLCFastFeatureCount))
     815                 :                 {
     816               0 :                     fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
     817               0 :                     bDisplayProgress = FALSE;
     818                 :                 }
     819                 :                 else
     820                 :                 {
     821               1 :                     panLayerCountFeatures[iLayer] = poLayer->GetFeatureCount();
     822               1 :                     nCountLayersFeatures += panLayerCountFeatures[iLayer];
     823                 :                 }
     824                 :             }
     825                 :         }
     826                 : 
     827                 :         /* Second pass to do the real job */
     828              44 :         for( iLayer = 0; 
     829                 :             iLayer < nLayerCount; 
     830                 :             iLayer++ )
     831                 :         {
     832              22 :             OGRLayer        *poLayer = papoLayers[iLayer];
     833              22 :             if (poLayer == NULL)
     834               0 :                 continue;
     835                 : 
     836              22 :             if (bDisplayProgress)
     837                 :             {
     838               1 :                 pfnProgress = GDALScaledProgress;
     839                 :                 pProgressArg = 
     840                 :                     GDALCreateScaledProgress(nAccCountFeatures * 1.0 / nCountLayersFeatures,
     841               1 :                                             (nAccCountFeatures + panLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures,
     842                 :                                             GDALTermProgress,
     843               1 :                                             NULL);
     844                 :             }
     845                 : 
     846              22 :             nAccCountFeatures += panLayerCountFeatures[iLayer];
     847                 : 
     848              22 :             if( !TranslateLayer( poDS, poLayer, poODS, papszLCO, 
     849                 :                                 pszNewLayerName, bTransform, poOutputSRS,
     850                 :                                 poSourceSRS, papszSelFields, bAppend, eGType,
     851                 :                                 bOverwrite, dfMaxSegmentLength, papszFieldTypesToString,
     852                 :                                 panLayerCountFeatures[iLayer], bWrapDateline, poClipSrc, poClipDst, pfnProgress, pProgressArg) 
     853                 :                 && !bSkipFailures )
     854                 :             {
     855                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     856                 :                         "Terminating translation prematurely after failed\n"
     857                 :                         "translation of layer %s (use -skipfailures to skip errors)\n", 
     858               0 :                         poLayer->GetLayerDefn()->GetName() );
     859                 : 
     860               0 :                 exit( 1 );
     861                 :             }
     862                 : 
     863              22 :             if (bDisplayProgress)
     864               1 :                 GDALDestroyScaledProgress(pProgressArg);
     865                 :         }
     866                 : 
     867              22 :         CPLFree(panLayerCountFeatures);
     868              22 :         CPLFree(papoLayers);
     869                 :     }
     870                 : 
     871                 : /* -------------------------------------------------------------------- */
     872                 : /*      Close down.                                                     */
     873                 : /* -------------------------------------------------------------------- */
     874              24 :     OGRSpatialReference::DestroySpatialReference(poOutputSRS);
     875              24 :     OGRSpatialReference::DestroySpatialReference(poSourceSRS);
     876              24 :     OGRDataSource::DestroyDataSource(poODS);
     877              24 :     OGRDataSource::DestroyDataSource(poDS);
     878              24 :     OGRGeometryFactory::destroyGeometry(poSpatialFilter);
     879              24 :     OGRGeometryFactory::destroyGeometry(poClipSrc);
     880              24 :     OGRGeometryFactory::destroyGeometry(poClipDst);
     881                 : 
     882              24 :     CSLDestroy(papszSelFields);
     883              24 :     CSLDestroy( papszArgv );
     884              24 :     CSLDestroy( papszLayers );
     885              24 :     CSLDestroy( papszDSCO );
     886              24 :     CSLDestroy( papszLCO );
     887              24 :     CSLDestroy( papszFieldTypesToString );
     888                 : 
     889              24 :     OGRCleanupAll();
     890                 : 
     891                 : #ifdef DBMALLOC
     892                 :     malloc_dump(1);
     893                 : #endif
     894                 :     
     895              24 :     return 0;
     896                 : }
     897                 : 
     898                 : /************************************************************************/
     899                 : /*                               Usage()                                */
     900                 : /************************************************************************/
     901                 : 
     902               0 : static void Usage()
     903                 : 
     904                 : {
     905               0 :     OGRSFDriverRegistrar        *poR = OGRSFDriverRegistrar::GetRegistrar();
     906                 : 
     907                 :     printf( "Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update] [-gt n]\n"
     908                 :             "               [-select field_list] [-where restricted_where] \n"
     909                 :             "               [-progress] [-sql <sql statement>] [-dialect dialect]\n" 
     910                 :             "               [-preserve_fid] [-fid FID]\n"
     911                 :             "               [-spat xmin ymin xmax ymax] [-wrapdateline]\n"
     912                 :             "               [-clipsrc [xmin ymin xmax ymax]|WKT|datasource|spat_extent] \n"
     913                 :             "               [-clipsrcsql sql_statement] [-clipsrclayer layer] \n"
     914                 :             "               [-clipsrcwhere expression]\n"
     915                 :             "               [-clipdst [xmin ymin xmax ymax]|WKT|datasource]\n"
     916                 :             "               [-clipdstsql sql_statement] [-clipdstlayer layer] \n"
     917                 :             "               [-clipdstwhere expression]\n"
     918                 :             "               [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n"
     919                 :             "               [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n"
     920                 :             "               [-segmentize max_dist] [-fieldTypeToString All|(type1[,type2]*)]\n"
     921                 :             "               dst_datasource_name src_datasource_name\n"
     922                 :             "               [-lco NAME=VALUE] [-nln name] [-nlt type] [layer [layer ...]]\n"
     923                 :             "\n"
     924               0 :             " -f format_name: output file format name, possible values are:\n");
     925                 :     
     926               0 :     for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
     927                 :     {
     928               0 :         OGRSFDriver *poDriver = poR->GetDriver(iDriver);
     929                 : 
     930               0 :         if( poDriver->TestCapability( ODrCCreateDataSource ) )
     931               0 :             printf( "     -f \"%s\"\n", poDriver->GetName() );
     932                 :     }
     933                 : 
     934                 :     printf( " -append: Append to existing layer instead of creating new if it exists\n"
     935                 :             " -overwrite: delete the output layer and recreate it empty\n"
     936                 :             " -update: Open existing output datasource in update mode\n"
     937                 :             " -progress: Display progress on terminal. Only works if input layers have the \n"
     938                 :             "                                          \"fast feature count\" capability\n"
     939                 :             " -select field_list: Comma-delimited list of fields from input layer to\n"
     940                 :             "                     copy to the new layer (defaults to all)\n" 
     941                 :             " -where restricted_where: Attribute query (like SQL WHERE)\n" 
     942                 :             " -wrapdateline: split geometries crossing the dateline meridian\n"
     943                 :             "                (long. = +/- 180deg)\n" 
     944                 :             " -sql statement: Execute given SQL statement and save result.\n"
     945                 :             " -dialect value: select a dialect, usually OGRSQL to avoid native sql.\n"
     946                 :             " -skipfailures: skip features or layers that fail to convert\n"
     947                 :             " -gt n: group n features per transaction (default 200)\n"
     948                 :             " -spat xmin ymin xmax ymax: spatial query extents\n"
     949                 :             " -segmentize max_dist: maximum distance between 2 nodes.\n"
     950                 :             "                       Used to create intermediate points\n"
     951                 :             " -dsco NAME=VALUE: Dataset creation option (format specific)\n"
     952                 :             " -lco  NAME=VALUE: Layer creation option (format specific)\n"
     953                 :             " -nln name: Assign an alternate name to the new layer\n"
     954                 :             " -nlt type: Force a geometry type for new layer.  One of NONE, GEOMETRY,\n"
     955                 :             "      POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n"
     956                 :             "      MULTIPOLYGON, or MULTILINESTRING.  Add \"25D\" for 3D layers.\n"
     957                 :             "      Default is type of source layer.\n"
     958                 :             " -fieldTypeToString type1,...: Converts fields of specified types to\n"
     959                 :             "      fields of type string in the new layer. Valid types are : Integer,\n"
     960                 :             "      Real, String, Date, Time, DateTime, Binary, IntegerList, RealList,\n"
     961               0 :             "      StringList. Special value All will convert all fields to strings.\n");
     962                 : 
     963                 :     printf(" -a_srs srs_def: Assign an output SRS\n"
     964                 :            " -t_srs srs_def: Reproject/transform to this SRS on output\n"
     965                 :            " -s_srs srs_def: Override source SRS\n"
     966                 :            "\n" 
     967                 :            " Srs_def can be a full WKT definition (hard to escape properly),\n"
     968                 :            " or a well known definition (ie. EPSG:4326) or a file with a WKT\n"
     969               0 :            " definition.\n" );
     970                 : 
     971               0 :     exit( 1 );
     972                 : }
     973                 : 
     974                 : /************************************************************************/
     975                 : /*                           TranslateLayer()                           */
     976                 : /************************************************************************/
     977                 : 
     978              24 : static int TranslateLayer( OGRDataSource *poSrcDS, 
     979                 :                            OGRLayer * poSrcLayer,
     980                 :                            OGRDataSource *poDstDS,
     981                 :                            char **papszLCO,
     982                 :                            const char *pszNewLayerName,
     983                 :                            int bTransform, 
     984                 :                            OGRSpatialReference *poOutputSRS,
     985                 :                            OGRSpatialReference *poSourceSRS,
     986                 :                            char **papszSelFields,
     987                 :                            int bAppend, int eGType, int bOverwrite,
     988                 :                            double dfMaxSegmentLength,
     989                 :                            char** papszFieldTypesToString,
     990                 :                            long nCountLayerFeatures,
     991                 :                            int bWrapDateline,
     992                 :                            OGRGeometry* poClipSrc,
     993                 :                            OGRGeometry *poClipDst,
     994                 :                            GDALProgressFunc pfnProgress,
     995                 :                            void *pProgressArg)
     996                 : 
     997                 : {
     998                 :     OGRLayer    *poDstLayer;
     999                 :     OGRFeatureDefn *poSrcFDefn;
    1000              24 :     OGRFeatureDefn *poDstFDefn = NULL;
    1001              24 :     int         bForceToPolygon = FALSE;
    1002              24 :     int         bForceToMultiPolygon = FALSE;
    1003                 :     
    1004              24 :     char**      papszTransformOptions = NULL;
    1005                 : 
    1006              24 :     if( pszNewLayerName == NULL )
    1007              21 :         pszNewLayerName = poSrcLayer->GetLayerDefn()->GetName();
    1008                 : 
    1009              24 :     if( wkbFlatten(eGType) == wkbPolygon )
    1010               1 :         bForceToPolygon = TRUE;
    1011              23 :     else if( wkbFlatten(eGType) == wkbMultiPolygon )
    1012               0 :         bForceToMultiPolygon = TRUE;
    1013                 : 
    1014                 : /* -------------------------------------------------------------------- */
    1015                 : /*      Setup coordinate transformation if we need it.                  */
    1016                 : /* -------------------------------------------------------------------- */
    1017              24 :     OGRCoordinateTransformation *poCT = NULL;
    1018                 : 
    1019              24 :     if( bTransform )
    1020                 :     {
    1021               2 :         if( poSourceSRS == NULL )
    1022               2 :             poSourceSRS = poSrcLayer->GetSpatialRef();
    1023                 : 
    1024               2 :         if( poSourceSRS == NULL )
    1025                 :         {
    1026                 :             fprintf( stderr, "Can't transform coordinates, source layer has no\n"
    1027               0 :                     "coordinate system.  Use -s_srs to set one.\n" );
    1028               0 :             exit( 1 );
    1029                 :         }
    1030                 : 
    1031                 :         CPLAssert( NULL != poSourceSRS );
    1032                 :         CPLAssert( NULL != poOutputSRS );
    1033                 : 
    1034               2 :         poCT = OGRCreateCoordinateTransformation( poSourceSRS, poOutputSRS );
    1035               2 :         if( poCT == NULL )
    1036                 :         {
    1037               0 :             char        *pszWKT = NULL;
    1038                 : 
    1039                 :             fprintf( stderr, "Failed to create coordinate transformation between the\n"
    1040                 :                    "following coordinate systems.  This may be because they\n"
    1041                 :                    "are not transformable, or because projection services\n"
    1042               0 :                    "(PROJ.4 DLL/.so) could not be loaded.\n" );
    1043                 :             
    1044               0 :             poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
    1045               0 :             fprintf( stderr,  "Source:\n%s\n", pszWKT );
    1046                 :             
    1047               0 :             poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
    1048               0 :             fprintf( stderr,  "Target:\n%s\n", pszWKT );
    1049               0 :             exit( 1 );
    1050                 :         }
    1051                 :     }
    1052                 :     
    1053              24 :     if (bWrapDateline)
    1054                 :     {
    1055               1 :         if (poCT != NULL && poOutputSRS->IsGeographic())
    1056                 :         {
    1057                 :             papszTransformOptions =
    1058               1 :                 CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
    1059                 :         }
    1060                 :         else
    1061                 :         {
    1062               0 :             fprintf(stderr, "-wrapdateline option only works when reprojecting to a geographic SRS\n");
    1063                 :         }
    1064                 :     }
    1065                 :     
    1066                 : /* -------------------------------------------------------------------- */
    1067                 : /*      Get other info.                                                 */
    1068                 : /* -------------------------------------------------------------------- */
    1069              24 :     poSrcFDefn = poSrcLayer->GetLayerDefn();
    1070                 :     
    1071              24 :     if( poOutputSRS == NULL )
    1072              21 :         poOutputSRS = poSrcLayer->GetSpatialRef();
    1073                 : 
    1074                 : /* -------------------------------------------------------------------- */
    1075                 : /*      Find the layer.                                                 */
    1076                 : /* -------------------------------------------------------------------- */
    1077              24 :     int iLayer = -1;
    1078              24 :     poDstLayer = NULL;
    1079                 : 
    1080              24 :     for( iLayer = 0; iLayer < poDstDS->GetLayerCount(); iLayer++ )
    1081                 :     {
    1082               3 :         OGRLayer        *poLayer = poDstDS->GetLayer(iLayer);
    1083                 : 
    1084               6 :         if( poLayer != NULL 
    1085               3 :             && EQUAL(poLayer->GetLayerDefn()->GetName(),pszNewLayerName) )
    1086                 :         {
    1087               3 :             poDstLayer = poLayer;
    1088               3 :             break;
    1089                 :         }
    1090                 :     }
    1091                 :     
    1092                 : /* -------------------------------------------------------------------- */
    1093                 : /*      If the user requested overwrite, and we have the layer in       */
    1094                 : /*      question we need to delete it now so it will get recreated      */
    1095                 : /*      (overwritten).                                                  */
    1096                 : /* -------------------------------------------------------------------- */
    1097              24 :     if( poDstLayer != NULL && bOverwrite )
    1098                 :     {
    1099               2 :         if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
    1100                 :         {
    1101                 :             fprintf( stderr, 
    1102               0 :                      "DeleteLayer() failed when overwrite requested.\n" );
    1103               0 :             return FALSE;
    1104                 :         }
    1105               2 :         poDstLayer = NULL;
    1106                 :     }
    1107                 : 
    1108                 : /* -------------------------------------------------------------------- */
    1109                 : /*      If the layer does not exist, then create it.                    */
    1110                 : /* -------------------------------------------------------------------- */
    1111              24 :     if( poDstLayer == NULL )
    1112                 :     {
    1113              23 :         if( eGType == -2 )
    1114              21 :             eGType = poSrcFDefn->GetGeomType();
    1115                 : 
    1116              23 :         if( !poDstDS->TestCapability( ODsCCreateLayer ) )
    1117                 :         {
    1118                 :             fprintf( stderr, 
    1119                 :               "Layer %s not found, and CreateLayer not supported by driver.", 
    1120               0 :                      pszNewLayerName );
    1121               0 :             return FALSE;
    1122                 :         }
    1123                 : 
    1124              23 :         CPLErrorReset();
    1125                 : 
    1126                 :         poDstLayer = poDstDS->CreateLayer( pszNewLayerName, poOutputSRS,
    1127                 :                                            (OGRwkbGeometryType) eGType, 
    1128              23 :                                            papszLCO );
    1129                 : 
    1130              23 :         if( poDstLayer == NULL )
    1131               0 :             return FALSE;
    1132                 : 
    1133              23 :         bAppend = FALSE;
    1134                 :     }
    1135                 : 
    1136                 : /* -------------------------------------------------------------------- */
    1137                 : /*      Otherwise we will append to it, if append was requested.        */
    1138                 : /* -------------------------------------------------------------------- */
    1139               1 :     else if( !bAppend )
    1140                 :     {
    1141                 :         fprintf( stderr, "FAILED: Layer %s already exists, and -append not specified.\n"
    1142                 :                 "        Consider using -append, or -overwrite.\n",
    1143               0 :                 pszNewLayerName );
    1144               0 :         return FALSE;
    1145                 :     }
    1146                 :     else
    1147                 :     {
    1148               1 :         if( CSLCount(papszLCO) > 0 )
    1149                 :         {
    1150                 :             fprintf( stderr, "WARNING: Layer creation options ignored since an existing layer is\n"
    1151               0 :                     "         being appended to.\n" );
    1152                 :         }
    1153                 :     }
    1154                 : 
    1155                 : /* -------------------------------------------------------------------- */
    1156                 : /*      Add fields.  Default to copy all field.                         */
    1157                 : /*      If only a subset of all fields requested, then output only      */
    1158                 : /*      the selected fields, and in the order that they were            */
    1159                 : /*      selected.                                                       */
    1160                 : /* -------------------------------------------------------------------- */
    1161              24 :     int         nSrcFieldCount = poSrcFDefn->GetFieldCount();
    1162                 :     int         iField, *panMap;
    1163                 : 
    1164                 :     // Initialize the index-to-index map to -1's
    1165              24 :     panMap = (int *) VSIMalloc( sizeof(int) * nSrcFieldCount );
    1166             105 :     for( iField=0; iField < nSrcFieldCount; iField++)
    1167              81 :         panMap[iField] = -1;
    1168                 :         
    1169              24 :     poDstFDefn = poDstLayer->GetLayerDefn();
    1170                 : 
    1171              25 :     if (papszSelFields && !bAppend )
    1172                 :     {
    1173               1 :         int         nDstFieldCount = poDstFDefn->GetFieldCount();
    1174               2 :         for( iField=0; papszSelFields[iField] != NULL; iField++)
    1175                 :         {
    1176               1 :             int iSrcField = poSrcFDefn->GetFieldIndex(papszSelFields[iField]);
    1177               1 :             if (iSrcField >= 0)
    1178                 :             {
    1179               1 :                 OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iSrcField);
    1180               1 :                 OGRFieldDefn oFieldDefn( poSrcFieldDefn );
    1181                 : 
    1182               1 :                 if (papszFieldTypesToString != NULL &&
    1183                 :                     (CSLFindString(papszFieldTypesToString, "All") != -1 ||
    1184                 :                      CSLFindString(papszFieldTypesToString,
    1185                 :                                    OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
    1186                 :                 {
    1187               0 :                     oFieldDefn.SetType(OFTString);
    1188                 :                 }
    1189                 :                 
    1190                 :                 /* The field may have been already created at layer creation */
    1191               1 :                 int iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
    1192               1 :                 if (iDstField >= 0)
    1193                 :                 {
    1194               0 :                     panMap[iSrcField] = iDstField;
    1195                 :                 }
    1196               1 :                 else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
    1197                 :                 {
    1198                 :                     /* Sanity check : if it fails, the driver is buggy */
    1199               1 :                     if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
    1200                 :                     {
    1201                 :                         CPLError(CE_Warning, CPLE_AppDefined,
    1202                 :                                  "The output driver has claimed to have added the %s field, but it did not!",
    1203               0 :                                  oFieldDefn.GetNameRef() );
    1204                 :                     }
    1205                 :                     else
    1206                 :                     {
    1207               1 :                         panMap[iSrcField] = nDstFieldCount;
    1208               1 :                         nDstFieldCount ++;
    1209                 :                     }
    1210               1 :                 }
    1211                 :             }
    1212                 :             else
    1213                 :             {
    1214                 :                 fprintf( stderr, "Field '%s' not found in source layer.\n", 
    1215               0 :                         papszSelFields[iField] );
    1216               0 :                 if( !bSkipFailures )
    1217                 :                 {
    1218               0 :                     VSIFree(panMap);
    1219               0 :                     return FALSE;
    1220                 :                 }
    1221                 :             }
    1222                 :         }
    1223                 :     }
    1224              23 :     else if( !bAppend )
    1225                 :     {
    1226              22 :         int         nDstFieldCount = poDstFDefn->GetFieldCount();
    1227              97 :         for( iField = 0; iField < nSrcFieldCount; iField++ )
    1228                 :         {
    1229              75 :             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
    1230              75 :             OGRFieldDefn oFieldDefn( poSrcFieldDefn );
    1231                 : 
    1232              75 :             if (papszFieldTypesToString != NULL &&
    1233                 :                 (CSLFindString(papszFieldTypesToString, "All") != -1 ||
    1234                 :                  CSLFindString(papszFieldTypesToString,
    1235                 :                                OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
    1236                 :             {
    1237               0 :                 oFieldDefn.SetType(OFTString);
    1238                 :             }
    1239                 : 
    1240                 :             /* The field may have been already created at layer creation */
    1241              75 :             int iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
    1242              75 :             if (iDstField >= 0)
    1243                 :             {
    1244               2 :                 panMap[iField] = iDstField;
    1245                 :             }
    1246              73 :             else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
    1247                 :             {
    1248                 :                 /* Sanity check : if it fails, the driver is buggy */
    1249              73 :                 if (poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
    1250                 :                 {
    1251                 :                     CPLError(CE_Warning, CPLE_AppDefined,
    1252                 :                              "The output driver has claimed to have added the %s field, but it did not!",
    1253               0 :                              oFieldDefn.GetNameRef() );
    1254                 :                 }
    1255                 :                 else
    1256                 :                 {
    1257              73 :                     panMap[iField] = nDstFieldCount;
    1258              73 :                     nDstFieldCount ++;
    1259                 :                 }
    1260                 :             }
    1261                 :         }
    1262                 :     }
    1263                 :     else
    1264                 :     {
    1265                 :         /* For an existing layer, build the map by fetching the index in the destination */
    1266                 :         /* layer for each source field */
    1267               4 :         for( iField = 0; iField < nSrcFieldCount; iField++ )
    1268                 :         {
    1269               3 :             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
    1270               3 :             int iDstField = poDstFDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
    1271               3 :             if (iDstField >= 0)
    1272               3 :                 panMap[iField] = iDstField;
    1273                 :         }
    1274                 :     }
    1275                 :     
    1276                 : /* -------------------------------------------------------------------- */
    1277                 : /*      Transfer features.                                              */
    1278                 : /* -------------------------------------------------------------------- */
    1279                 :     OGRFeature  *poFeature;
    1280              24 :     int         nFeaturesInTransaction = 0;
    1281              24 :     long        nCount = 0;
    1282                 :     
    1283              24 :     poSrcLayer->ResetReading();
    1284                 : 
    1285              24 :     if( nGroupTransactions )
    1286              24 :         poDstLayer->StartTransaction();
    1287                 : 
    1288             183 :     while( TRUE )
    1289                 :     {
    1290             207 :         OGRFeature      *poDstFeature = NULL;
    1291                 : 
    1292             207 :         if( nFIDToFetch != OGRNullFID )
    1293                 :         {
    1294                 :             // Only fetch feature on first pass.
    1295               2 :             if( nFeaturesInTransaction == 0 )
    1296               1 :                 poFeature = poSrcLayer->GetFeature(nFIDToFetch);
    1297                 :             else
    1298               1 :                 poFeature = NULL;
    1299                 :         }
    1300                 :         else
    1301             205 :             poFeature = poSrcLayer->GetNextFeature();
    1302                 :         
    1303             207 :         if( poFeature == NULL )
    1304                 :             break;
    1305                 : 
    1306             183 :         if( ++nFeaturesInTransaction == nGroupTransactions )
    1307                 :         {
    1308              10 :             poDstLayer->CommitTransaction();
    1309              10 :             poDstLayer->StartTransaction();
    1310              10 :             nFeaturesInTransaction = 0;
    1311                 :         }
    1312                 : 
    1313             183 :         CPLErrorReset();
    1314             183 :         poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
    1315                 : 
    1316             183 :         if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
    1317                 :         {
    1318               0 :             if( nGroupTransactions )
    1319               0 :                 poDstLayer->CommitTransaction();
    1320                 :             
    1321                 :             CPLError( CE_Failure, CPLE_AppDefined,
    1322                 :                       "Unable to translate feature %ld from layer %s.\n",
    1323               0 :                       poFeature->GetFID(), poSrcFDefn->GetName() );
    1324                 :             
    1325               0 :             OGRFeature::DestroyFeature( poFeature );
    1326               0 :             OGRFeature::DestroyFeature( poDstFeature );
    1327               0 :             VSIFree(panMap);
    1328               0 :             return FALSE;
    1329                 :         }
    1330                 : 
    1331             183 :         if( bPreserveFID )
    1332               0 :             poDstFeature->SetFID( poFeature->GetFID() );
    1333                 : 
    1334             183 :         OGRGeometry* poDstGeometry = poDstFeature->GetGeometryRef();
    1335             183 :         if (poDstGeometry != NULL)
    1336                 :         {
    1337             182 :             if (dfMaxSegmentLength > 0)
    1338              10 :                 poDstGeometry->segmentize(dfMaxSegmentLength);
    1339                 :                 
    1340             182 :             if (poClipSrc)
    1341                 :             {
    1342               4 :                 OGRGeometry* poClipped = poDstGeometry->Intersection(poClipSrc);
    1343               4 :                 if (poClipped == NULL || poClipped->IsEmpty())
    1344                 :                 {
    1345               0 :                     OGRGeometryFactory::destroyGeometry(poClipped);
    1346               0 :                     goto end_loop;
    1347                 :                 }
    1348               4 :                 poDstFeature->SetGeometryDirectly(poClipped);
    1349               4 :                 poDstGeometry = poClipped;
    1350                 :             }
    1351                 : 
    1352             182 :             if( poCT )
    1353                 :             {
    1354                 :                 OGRGeometry* poReprojectedGeom =
    1355              11 :                     OGRGeometryFactory::transformWithOptions(poDstGeometry, poCT, papszTransformOptions);
    1356              11 :                 if( poReprojectedGeom == NULL )
    1357                 :                 {
    1358               0 :                     if( nGroupTransactions )
    1359               0 :                         poDstLayer->CommitTransaction();
    1360                 : 
    1361                 :                     fprintf( stderr, "Failed to reproject feature %d (geometry probably out of source or destination SRS).\n", 
    1362               0 :                             (int) poFeature->GetFID() );
    1363               0 :                     if( !bSkipFailures )
    1364                 :                     {
    1365               0 :                         OGRFeature::DestroyFeature( poFeature );
    1366               0 :                         OGRFeature::DestroyFeature( poDstFeature );
    1367               0 :                         VSIFree(panMap);
    1368               0 :                         return FALSE;
    1369                 :                     }
    1370                 :                 }
    1371                 :                 
    1372              11 :                 poDstFeature->SetGeometryDirectly(poReprojectedGeom);
    1373              11 :                 poDstGeometry = poReprojectedGeom;
    1374                 :             }
    1375             171 :             else if (poOutputSRS != NULL)
    1376                 :             {
    1377             170 :                 poDstGeometry->assignSpatialReference(poOutputSRS);
    1378                 :             }
    1379                 :             
    1380             182 :             if (poClipDst)
    1381                 :             {
    1382               0 :                 OGRGeometry* poClipped = poDstGeometry->Intersection(poClipDst);
    1383               0 :                 if (poClipped == NULL || poClipped->IsEmpty())
    1384                 :                 {
    1385               0 :                     OGRGeometryFactory::destroyGeometry(poClipped);
    1386               0 :                     goto end_loop;
    1387                 :                 }
    1388                 :                 
    1389               0 :                 poDstFeature->SetGeometryDirectly(poClipped);
    1390               0 :                 poDstGeometry = poClipped;
    1391                 :             }
    1392                 : 
    1393             182 :             if( bForceToPolygon )
    1394                 :             {
    1395                 :                 poDstFeature->SetGeometryDirectly( 
    1396                 :                     OGRGeometryFactory::forceToPolygon(
    1397              10 :                         poDstFeature->StealGeometry() ) );
    1398                 :             }
    1399                 : 
    1400             182 :             if( bForceToMultiPolygon )
    1401                 :             {
    1402                 :                 poDstFeature->SetGeometryDirectly( 
    1403                 :                     OGRGeometryFactory::forceToMultiPolygon(
    1404               0 :                         poDstFeature->StealGeometry() ) );
    1405                 :             }
    1406                 :         }
    1407                 : 
    1408             183 :         CPLErrorReset();
    1409             183 :         if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE 
    1410                 :             && !bSkipFailures )
    1411                 :         {
    1412               0 :             if( nGroupTransactions )
    1413               0 :                 poDstLayer->RollbackTransaction();
    1414                 : 
    1415               0 :             OGRFeature::DestroyFeature( poFeature );
    1416               0 :             OGRFeature::DestroyFeature( poDstFeature );
    1417               0 :             VSIFree(panMap);
    1418               0 :             return FALSE;
    1419                 :         }
    1420                 : 
    1421                 : end_loop:
    1422             183 :         OGRFeature::DestroyFeature( poFeature );
    1423             183 :         OGRFeature::DestroyFeature( poDstFeature );
    1424                 : 
    1425                 :         /* Report progress */
    1426             183 :         nCount ++;
    1427             183 :         if (pfnProgress)
    1428              10 :             pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg);
    1429                 :     }
    1430                 : 
    1431              24 :     if( nGroupTransactions )
    1432              24 :         poDstLayer->CommitTransaction();
    1433                 : 
    1434                 : /* -------------------------------------------------------------------- */
    1435                 : /*      Cleaning                                                        */
    1436                 : /* -------------------------------------------------------------------- */
    1437              24 :     OGRCoordinateTransformation::DestroyCT(poCT);
    1438                 :     
    1439              24 :     VSIFree(panMap);
    1440                 : 
    1441              24 :     return TRUE;
    1442                 : }
    1443                 : 

Generated by: LCOV version 1.7