LTP GCOV extension - code coverage report
Current view: directory - apps - ogr2ogr.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 655
Code covered: 67.6 % Executed lines: 443

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

Generated by: LTP GCOV extension version 1.5