1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  Simple client for translating between formats.
5  * Author:   Frank Warmerdam, warmerdam@pobox.com
6  *
7  ******************************************************************************
8  * Copyright (c) 1999, Frank Warmerdam
9  * Copyright (c) 2008-2015, Even Rouault <even dot rouault at spatialys.com>
10  * Copyright (c) 2015, Faza Mahamood
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #include "cpl_port.h"
32 #include "gdal_utils.h"
33 #include "gdal_utils_priv.h"
34 
35 #include <cassert>
36 #include <climits>
37 #include <cstdio>
38 #include <cstdlib>
39 #include <cstring>
40 
41 #include <algorithm>
42 #include <map>
43 #include <memory>
44 #include <set>
45 #include <unordered_set>
46 #include <string>
47 #include <utility>
48 #include <vector>
49 
50 #include "commonutils.h"
51 #include "cpl_conv.h"
52 #include "cpl_error.h"
53 #include "cpl_progress.h"
54 #include "cpl_string.h"
55 #include "cpl_vsi.h"
56 #include "gdal.h"
57 #include "gdal_alg.h"
58 #include "gdal_alg_priv.h"
59 #include "gdal_priv.h"
60 #include "ogr_api.h"
61 #include "ogr_core.h"
62 #include "ogr_feature.h"
63 #include "ogr_featurestyle.h"
64 #include "ogr_geometry.h"
65 #include "ogr_p.h"
66 #include "ogr_spatialref.h"
67 #include "ogrlayerdecorator.h"
68 #include "ogrsf_frmts.h"
69 
70 CPL_CVSID("$Id: ogr2ogr_lib.cpp 28cd152257db832c88c249800e1a8f546404918c 2021-10-13 15:43:32 +0200 Even Rouault $")
71 
72 typedef enum
73 {
74     GEOMOP_NONE,
75     GEOMOP_SEGMENTIZE,
76     GEOMOP_SIMPLIFY_PRESERVE_TOPOLOGY,
77 } GeomOperation;
78 
79 typedef enum
80 {
81     GTC_DEFAULT,
82     GTC_PROMOTE_TO_MULTI,
83     GTC_CONVERT_TO_LINEAR,
84     GTC_CONVERT_TO_CURVE,
85     GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR,
86 } GeomTypeConversion;
87 
88 #define GEOMTYPE_UNCHANGED  -2
89 
90 #define COORD_DIM_UNCHANGED -1
91 #define COORD_DIM_LAYER_DIM -2
92 #define COORD_DIM_XYM -3
93 
94 /************************************************************************/
95 /*                        GDALVectorTranslateOptions                    */
96 /************************************************************************/
97 
98 /** Options for use with GDALVectorTranslate(). GDALVectorTranslateOptions* must be allocated and
99  * freed with GDALVectorTranslateOptionsNew() and GDALVectorTranslateOptionsFree() respectively.
100  */
101 struct GDALVectorTranslateOptions
102 {
103     /*! continue after a failure, skipping the failed feature */
104     bool bSkipFailures;
105 
106     /*! use layer level transaction. If set to FALSE, then it is interpreted as dataset level transaction. */
107     int nLayerTransaction;
108 
109     /*! force the use of particular transaction type based on GDALVectorTranslate::nLayerTransaction */
110     bool bForceTransaction;
111 
112     /*! group nGroupTransactions features per transaction (default 20000). Increase the value for better
113         performance when writing into DBMS drivers that have transaction support. nGroupTransactions can
114         be set to -1 to load the data into a single transaction */
115     int nGroupTransactions;
116 
117     /*! If provided, only the feature with this feature id will be reported. Operates exclusive of
118         the spatial or attribute queries. Note: if you want to select several features based on their
119         feature id, you can also use the fact the 'fid' is a special field recognized by OGR SQL.
120         So GDALVectorTranslateOptions::pszWHERE = "fid in (1,3,5)" would select features 1, 3 and 5. */
121     GIntBig nFIDToFetch;
122 
123     /*! allow or suppress progress monitor and other non-error output */
124     bool bQuiet;
125 
126     /*! output file format name */
127     char *pszFormat;
128 
129     /*! list of layers of the source dataset which needs to be selected */
130     char **papszLayers;
131 
132     /*! dataset creation option (format specific) */
133     char **papszDSCO;
134 
135     /*! layer creation option (format specific) */
136     char **papszLCO;
137 
138     /*! access modes */
139     GDALVectorTranslateAccessMode eAccessMode;
140 
141     /*! It has the effect of adding, to existing target layers, the new fields found in source layers.
142         This option is useful when merging files that have non-strictly identical structures. This might
143         not work for output formats that don't support adding fields to existing non-empty layers. */
144     bool bAddMissingFields;
145 
146     /*! It must be set to true to trigger reprojection, otherwise only SRS assignment is done. */
147     bool bTransform;
148 
149     /*! output SRS. GDALVectorTranslateOptions::bTransform must be set to true to trigger reprojection,
150         otherwise only SRS assignment is done. */
151     char *pszOutputSRSDef;
152 
153     /*! override source SRS */
154     char *pszSourceSRSDef;
155 
156     /*! PROJ pipeline */
157     char *pszCTPipeline;
158 
159     bool bNullifyOutputSRS;
160 
161     /*! If set to false, then field name matching between source and existing target layer is done
162         in a more relaxed way if the target driver has an implementation for it. */
163     bool bExactFieldNameMatch;
164 
165     /*! an alternate name to the new layer */
166     char *pszNewLayerName;
167 
168     /*! attribute query (like SQL WHERE) */
169     char *pszWHERE;
170 
171     /*! name of the geometry field on which the spatial filter operates on. */
172     char *pszGeomField;
173 
174     /*! list of fields from input layer to copy to the new layer. A field is skipped if
175         mentioned previously in the list even if the input layer has duplicate field names.
176         (Defaults to all; any field is skipped if a subsequent field with same name is
177         found.) Geometry fields can also be specified in the list. */
178     char **papszSelFields;
179 
180     /*! SQL statement to execute. The resulting table/layer will be saved to the output. */
181     char *pszSQLStatement;
182 
183     /*! SQL dialect. In some cases can be used to use (unoptimized) OGR SQL instead of the
184         native SQL of an RDBMS by using "OGRSQL". The "SQLITE" dialect can also be used with
185         any datasource. */
186     char *pszDialect;
187 
188     /*! the geometry type for the created layer */
189     int eGType;
190 
191     GeomTypeConversion eGeomTypeConversion;
192 
193     /*! Geometric operation to perform */
194     GeomOperation eGeomOp;
195 
196     /*! the parameter to geometric operation */
197     double dfGeomOpParam;
198 
199     /*! Whether to run MakeValid */
200     bool bMakeValid;
201 
202     /*! list of field types to convert to a field of type string in the destination layer.
203         Valid types are: Integer, Integer64, Real, String, Date, Time, DateTime, Binary,
204         IntegerList, Integer64List, RealList, StringList. Special value "All" can be
205         used to convert all fields to strings. This is an alternate way to using the CAST
206         operator of OGR SQL, that may avoid typing a long SQL query. Note that this does
207         not influence the field types used by the source driver, and is only an afterwards
208         conversion. */
209     char **papszFieldTypesToString;
210 
211     /*! list of field types and the field type after conversion in the destination layer.
212         ("srctype1=dsttype1","srctype2=dsttype2",...).
213         Valid types are : Integer, Integer64, Real, String, Date, Time, DateTime, Binary,
214         IntegerList, Integer64List, RealList, StringList. Types can also include subtype
215         between parenthesis, such as Integer(Boolean), Real(Float32), ... Special value
216         "All" can be used to convert all fields to another type. This is an alternate way to
217         using the CAST operator of OGR SQL, that may avoid typing a long SQL query.
218         This is a generalization of GDALVectorTranslateOptions::papszFieldTypeToString. Note that this does not influence
219         the field types used by the source driver, and is only an afterwards conversion. */
220     char **papszMapFieldType;
221 
222     /*! set field width and precision to 0 */
223     bool bUnsetFieldWidth;
224 
225     /*! display progress on terminal. Only works if input layers have the "fast feature count"
226     capability */
227     bool bDisplayProgress;
228 
229     /*! split geometries crossing the dateline meridian */
230     bool bWrapDateline;
231 
232     /*! offset from dateline in degrees (default long. = +/- 10deg, geometries
233     within 170deg to -170deg will be split) */
234     double dfDateLineOffset;
235 
236     /*! clip geometries when it is set to true */
237     bool bClipSrc;
238 
239     OGRGeometryH hClipSrc;
240 
241     /*! clip datasource */
242     char *pszClipSrcDS;
243 
244     /*! select desired geometries using an SQL query */
245     char *pszClipSrcSQL;
246 
247     /*! selected named layer from the source clip datasource */
248     char *pszClipSrcLayer;
249 
250     /*! restrict desired geometries based on attribute query */
251     char *pszClipSrcWhere;
252 
253     OGRGeometryH hClipDst;
254 
255     /*! destination clip datasource */
256     char *pszClipDstDS;
257 
258     /*! select desired geometries using an SQL query */
259     char *pszClipDstSQL;
260 
261     /*! selected named layer from the destination clip datasource */
262     char *pszClipDstLayer;
263 
264     /*! restrict desired geometries based on attribute query */
265     char *pszClipDstWhere;
266 
267     /*! split fields of type StringList, RealList or IntegerList into as many fields
268         of type String, Real or Integer as necessary. */
269     bool bSplitListFields;
270 
271     /*! limit the number of subfields created for each split field. */
272     int nMaxSplitListSubFields;
273 
274     /*! produce one feature for each geometry in any kind of geometry collection in the
275         source file */
276     bool bExplodeCollections;
277 
278     /*! uses the specified field to fill the Z coordinates of geometries */
279     char *pszZField;
280 
281     /*! the list of field indexes to be copied from the source to the destination. The (n)th value
282         specified in the list is the index of the field in the target layer definition in which the
283         n(th) field of the source layer must be copied. Index count starts at zero. There must be
284         exactly as many values in the list as the count of the fields in the source layer.
285         We can use the "identity" option to specify that the fields should be transferred by using
286         the same order. This option should be used along with the
287         GDALVectorTranslateOptions::eAccessMode = ACCESS_APPEND option. */
288     char **papszFieldMap;
289 
290     /*! force the coordinate dimension to nCoordDim (valid values are 2 or 3). This affects both
291         the layer geometry type, and feature geometries. */
292     int nCoordDim;
293 
294     /*! destination dataset open option (format specific), only valid in update mode */
295     char **papszDestOpenOptions;
296 
297     /*! If set to true, does not propagate not-nullable constraints to target layer if they exist
298         in source layer */
299     bool bForceNullable;
300 
301     /*! If set to true, for each field with a coded field domains, create a field that contains
302         the description of the coded value. */
303     bool bResolveDomains;
304 
305     /*! If set to true, empty string values will be treated as null */
306     bool bEmptyStrAsNull;
307 
308     /*! If set to true, does not propagate default field values to target layer if they exist in
309         source layer */
310     bool bUnsetDefault;
311 
312     /*! to prevent the new default behavior that consists in, if the output driver has a FID layer
313         creation option and we are not in append mode, to preserve the name of the source FID column
314         and source feature IDs */
315     bool bUnsetFid;
316 
317     /*! use the FID of the source features instead of letting the output driver to automatically
318         assign a new one. If not in append mode, this behavior becomes the default if the output
319         driver has a FID layer creation option. In which case the name of the source FID column will
320         be used and source feature IDs will be attempted to be preserved. This behavior can be
321         disabled by option GDALVectorTranslateOptions::bUnsetFid */
322     bool bPreserveFID;
323 
324     /*! set it to false to disable copying of metadata from source dataset and layers into target dataset and
325         layers, when supported by output driver. */
326     bool bCopyMD;
327 
328     /*! list of metadata key and value to set on the output dataset, when supported by output driver.
329         ("META-TAG1=VALUE1","META-TAG2=VALUE2") */
330     char **papszMetadataOptions;
331 
332     /*! override spatial filter SRS */
333     char *pszSpatSRSDef;
334 
335     /*! size of the list GDALVectorTranslateOptions::pasGCPs */
336     int nGCPCount;
337 
338     /*! list of ground control points to be added */
339     GDAL_GCP *pasGCPs;
340 
341     /*! order of polynomial used for warping (1 to 3). The default is to select a polynomial
342         order based on the number of GCPs */
343     int nTransformOrder;
344 
345     /*! spatial query extents, in the SRS of the source layer(s) (or the one specified with
346         GDALVectorTranslateOptions::pszSpatSRSDef). Only features whose geometry intersects the extents
347         will be selected. The geometries will not be clipped unless GDALVectorTranslateOptions::bClipSrc
348         is true. */
349     OGRGeometryH hSpatialFilter;
350 
351     /*! the progress function to use */
352     GDALProgressFunc pfnProgress;
353 
354     /*! pointer to the progress data variable */
355     void *pProgressData;
356 
357     /*! Whether layer and feature native data must be transferred. */
358     bool bNativeData;
359 
360     /*! Maximum number of features, or -1 if no limit. */
361     GIntBig nLimit;
362 };
363 
364 struct TargetLayerInfo
365 {
366     OGRLayer *   m_poSrcLayer = nullptr;
367     GIntBig      m_nFeaturesRead = 0;
368     bool         m_bPerFeatureCT = 0;
369     OGRLayer    *m_poDstLayer = nullptr;
370     std::vector<std::unique_ptr<OGRCoordinateTransformation>> m_apoCT{};
371     std::vector<CPLStringList> m_aosTransformOptions{};
372     std::vector<int> m_anMap{};
373     struct ResolvedInfo
374     {
375         int nSrcField;
376         const OGRFieldDomain* poDomain;
377     };
378     std::map<int, ResolvedInfo> m_oMapResolved{};
379     std::map<const OGRFieldDomain*, std::map<std::string, std::string>> m_oMapDomainToKV{};
380     int          m_iSrcZField = -1;
381     int          m_iSrcFIDField = -1;
382     int          m_iRequestedSrcGeomField = -1;
383     bool         m_bPreserveFID = false;
384     const char  *m_pszCTPipeline = nullptr;
385 };
386 
387 struct AssociatedLayers
388 {
389     OGRLayer         *poSrcLayer = nullptr;
390     std::unique_ptr<TargetLayerInfo> psInfo{};
391 };
392 
393 class SetupTargetLayer
394 {
395 public:
396     GDALDataset          *m_poSrcDS;
397     GDALDataset          *m_poDstDS;
398     char                **m_papszLCO;
399     OGRSpatialReference  *m_poOutputSRS;
400     bool                  m_bNullifyOutputSRS;
401     char                **m_papszSelFields;
402     bool                  m_bAppend;
403     bool                  m_bAddMissingFields;
404     int                   m_eGType;
405     GeomTypeConversion    m_eGeomTypeConversion;
406     int                   m_nCoordDim;
407     bool                  m_bOverwrite;
408     char                **m_papszFieldTypesToString;
409     char                **m_papszMapFieldType;
410     bool                  m_bUnsetFieldWidth;
411     bool                  m_bExplodeCollections;
412     const char           *m_pszZField;
413     char                **m_papszFieldMap;
414     const char           *m_pszWHERE;
415     bool                  m_bExactFieldNameMatch;
416     bool                  m_bQuiet;
417     bool                  m_bForceNullable;
418     bool                  m_bResolveDomains;
419     bool                  m_bUnsetDefault;
420     bool                  m_bUnsetFid;
421     bool                  m_bPreserveFID;
422     bool                  m_bCopyMD;
423     bool                  m_bNativeData;
424     bool                  m_bNewDataSource;
425     const char           *m_pszCTPipeline;
426 
427     std::unique_ptr<TargetLayerInfo> Setup(OGRLayer * poSrcLayer,
428                                       const char *pszNewLayerName,
429                                       GDALVectorTranslateOptions *psOptions,
430                                       GIntBig& nTotalEventsDone);
431 };
432 
433 class LayerTranslator
434 {
435 public:
436     GDALDataset                  *m_poSrcDS;
437     GDALDataset                  *m_poODS;
438     bool                          m_bTransform;
439     bool                          m_bWrapDateline;
440     CPLString                     m_osDateLineOffset;
441     OGRSpatialReference          *m_poOutputSRS;
442     bool                          m_bNullifyOutputSRS;
443     OGRSpatialReference          *m_poUserSourceSRS;
444     OGRCoordinateTransformation  *m_poGCPCoordTrans;
445     int                           m_eGType;
446     GeomTypeConversion            m_eGeomTypeConversion;
447     bool                          m_bMakeValid;
448     int                           m_nCoordDim;
449     GeomOperation                 m_eGeomOp;
450     double                        m_dfGeomOpParam;
451     OGRGeometry                  *m_poClipSrc;
452     OGRGeometry                  *m_poClipDst;
453     bool                          m_bExplodeCollections;
454     bool                          m_bNativeData;
455     GIntBig                       m_nLimit;
456     OGRGeometryFactory::TransformWithOptionsCache m_transformWithOptionsCache;
457 
458     int                 Translate(OGRFeature* poFeatureIn,
459                                   TargetLayerInfo* psInfo,
460                                   GIntBig nCountLayerFeatures,
461                                   GIntBig* pnReadFeatureCount,
462                                   GIntBig& nTotalEventsDone,
463                                   GDALProgressFunc pfnProgress,
464                                   void *pProgressArg,
465                                   GDALVectorTranslateOptions *psOptions);
466 };
467 
468 static OGRLayer* GetLayerAndOverwriteIfNecessary(GDALDataset *poDstDS,
469                                                  const char* pszNewLayerName,
470                                                  bool bOverwrite,
471                                                  bool* pbErrorOccurred,
472                                                  bool* pbOverwriteActuallyDone,
473                                                  bool* pbAddOverwriteLCO);
474 
475 /************************************************************************/
476 /*                           LoadGeometry()                             */
477 /************************************************************************/
478 
LoadGeometry(const char * pszDS,const char * pszSQL,const char * pszLyr,const char * pszWhere)479 static OGRGeometry* LoadGeometry( const char* pszDS,
480                                   const char* pszSQL,
481                                   const char* pszLyr,
482                                   const char* pszWhere)
483 {
484     GDALDataset *poDS =
485         reinterpret_cast<GDALDataset *>(OGROpen(pszDS, FALSE, nullptr));
486     if (poDS == nullptr)
487         return nullptr;
488 
489     OGRLayer *poLyr = nullptr;
490     if (pszSQL != nullptr)
491         poLyr = poDS->ExecuteSQL( pszSQL, nullptr, nullptr );
492     else if (pszLyr != nullptr)
493         poLyr = poDS->GetLayerByName(pszLyr);
494     else
495         poLyr = poDS->GetLayer(0);
496 
497     if (poLyr == nullptr)
498     {
499         CPLError(CE_Failure, CPLE_AppDefined,
500                  "Failed to identify source layer from datasource." );
501         GDALClose(poDS);
502         return nullptr;
503     }
504 
505     if (pszWhere)
506         poLyr->SetAttributeFilter(pszWhere);
507 
508     OGRMultiPolygon *poMP = nullptr;
509     OGRFeature *poFeat = nullptr;
510     while ((poFeat = poLyr->GetNextFeature()) != nullptr)
511     {
512         OGRGeometry* poSrcGeom = poFeat->GetGeometryRef();
513         if (poSrcGeom)
514         {
515             const OGRwkbGeometryType eType =
516                 wkbFlatten(poSrcGeom->getGeometryType());
517 
518             if (poMP == nullptr)
519                 poMP = new OGRMultiPolygon();
520 
521             if( eType == wkbPolygon )
522                 poMP->addGeometry( poSrcGeom );
523             else if( eType == wkbMultiPolygon )
524             {
525                 OGRMultiPolygon* poSrcMP = poSrcGeom->toMultiPolygon();
526                 const int nGeomCount = poSrcMP->getNumGeometries();
527 
528                 for( int iGeom = 0; iGeom < nGeomCount; iGeom++ )
529                 {
530                     poMP->addGeometry(
531                         poSrcMP->getGeometryRef(iGeom) );
532                 }
533             }
534             else
535             {
536                 CPLError( CE_Failure, CPLE_AppDefined, "Geometry not of polygon type." );
537                 OGRGeometryFactory::destroyGeometry(poMP);
538                 OGRFeature::DestroyFeature(poFeat);
539                 if( pszSQL != nullptr )
540                     poDS->ReleaseResultSet( poLyr );
541                 GDALClose(poDS);
542                 return nullptr;
543             }
544         }
545 
546         OGRFeature::DestroyFeature(poFeat);
547     }
548 
549     if( pszSQL != nullptr )
550         poDS->ReleaseResultSet( poLyr );
551     GDALClose(poDS);
552 
553     return poMP;
554 }
555 
556 /************************************************************************/
557 /*                     OGRSplitListFieldLayer                           */
558 /************************************************************************/
559 
560 typedef struct
561 {
562     int          iSrcIndex;
563     OGRFieldType eType;
564     int          nMaxOccurrences;
565     int          nWidth;
566 } ListFieldDesc;
567 
568 class OGRSplitListFieldLayer : public OGRLayer
569 {
570     OGRLayer                    *poSrcLayer;
571     OGRFeatureDefn              *poFeatureDefn;
572     ListFieldDesc               *pasListFields;
573     int                          nListFieldCount;
574     int                          nMaxSplitListSubFields;
575 
576     OGRFeature                  *TranslateFeature(OGRFeature* poSrcFeature);
577 
578   public:
579                                  OGRSplitListFieldLayer(OGRLayer* poSrcLayer,
580                                                         int nMaxSplitListSubFields);
581                         virtual ~OGRSplitListFieldLayer();
582 
583     bool                        BuildLayerDefn(GDALProgressFunc pfnProgress,
584                                                 void *pProgressArg);
585 
586     virtual OGRFeature          *GetNextFeature() override;
587     virtual OGRFeature          *GetFeature(GIntBig nFID) override;
588     virtual OGRFeatureDefn      *GetLayerDefn() override;
589 
ResetReading()590     virtual void                 ResetReading() override { poSrcLayer->ResetReading(); }
TestCapability(const char *)591     virtual int                  TestCapability(const char*) override { return FALSE; }
592 
GetFeatureCount(int bForce=TRUE)593     virtual GIntBig              GetFeatureCount( int bForce = TRUE ) override
594     {
595         return poSrcLayer->GetFeatureCount(bForce);
596     }
597 
GetSpatialRef()598     virtual OGRSpatialReference *GetSpatialRef() override
599     {
600         return poSrcLayer->GetSpatialRef();
601     }
602 
GetSpatialFilter()603     virtual OGRGeometry         *GetSpatialFilter() override
604     {
605         return poSrcLayer->GetSpatialFilter();
606     }
607 
GetStyleTable()608     virtual OGRStyleTable       *GetStyleTable() override
609     {
610         return poSrcLayer->GetStyleTable();
611     }
612 
SetSpatialFilter(OGRGeometry * poGeom)613     virtual void                 SetSpatialFilter( OGRGeometry *poGeom ) override
614     {
615         poSrcLayer->SetSpatialFilter(poGeom);
616     }
617 
SetSpatialFilter(int iGeom,OGRGeometry * poGeom)618     virtual void                 SetSpatialFilter( int iGeom, OGRGeometry *poGeom ) override
619     {
620         poSrcLayer->SetSpatialFilter(iGeom, poGeom);
621     }
622 
SetSpatialFilterRect(double dfMinX,double dfMinY,double dfMaxX,double dfMaxY)623     virtual void                 SetSpatialFilterRect( double dfMinX, double dfMinY,
624                                                        double dfMaxX, double dfMaxY ) override
625     {
626         poSrcLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
627     }
628 
SetSpatialFilterRect(int iGeom,double dfMinX,double dfMinY,double dfMaxX,double dfMaxY)629     virtual void                 SetSpatialFilterRect( int iGeom,
630                                                        double dfMinX, double dfMinY,
631                                                        double dfMaxX, double dfMaxY ) override
632     {
633         poSrcLayer->SetSpatialFilterRect(iGeom, dfMinX, dfMinY, dfMaxX, dfMaxY);
634     }
635 
SetAttributeFilter(const char * pszFilter)636     virtual OGRErr               SetAttributeFilter( const char *pszFilter ) override
637     {
638         return poSrcLayer->SetAttributeFilter(pszFilter);
639     }
640 };
641 
642 /************************************************************************/
643 /*                    OGRSplitListFieldLayer()                          */
644 /************************************************************************/
645 
OGRSplitListFieldLayer(OGRLayer * poSrcLayerIn,int nMaxSplitListSubFieldsIn)646 OGRSplitListFieldLayer::OGRSplitListFieldLayer(OGRLayer* poSrcLayerIn,
647                                                int nMaxSplitListSubFieldsIn) :
648     poSrcLayer(poSrcLayerIn),
649     poFeatureDefn(nullptr),
650     pasListFields(nullptr),
651     nListFieldCount(0),
652     nMaxSplitListSubFields(
653         nMaxSplitListSubFieldsIn < 0 ? INT_MAX : nMaxSplitListSubFieldsIn)
654 {}
655 
656 /************************************************************************/
657 /*                   ~OGRSplitListFieldLayer()                          */
658 /************************************************************************/
659 
~OGRSplitListFieldLayer()660 OGRSplitListFieldLayer::~OGRSplitListFieldLayer()
661 {
662     if( poFeatureDefn )
663         poFeatureDefn->Release();
664 
665     CPLFree(pasListFields);
666 }
667 
668 /************************************************************************/
669 /*                       BuildLayerDefn()                               */
670 /************************************************************************/
671 
BuildLayerDefn(GDALProgressFunc pfnProgress,void * pProgressArg)672 bool OGRSplitListFieldLayer::BuildLayerDefn(GDALProgressFunc pfnProgress,
673                                             void *pProgressArg)
674 {
675     CPLAssert(poFeatureDefn == nullptr);
676 
677     OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
678 
679     int nSrcFields = poSrcFieldDefn->GetFieldCount();
680     pasListFields = static_cast<ListFieldDesc *>(
681         CPLCalloc(sizeof(ListFieldDesc), nSrcFields));
682     nListFieldCount = 0;
683 
684     /* Establish the list of fields of list type */
685     for( int i=0; i<nSrcFields; ++i )
686     {
687         OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
688         if (eType == OFTIntegerList ||
689             eType == OFTInteger64List ||
690             eType == OFTRealList ||
691             eType == OFTStringList)
692         {
693             pasListFields[nListFieldCount].iSrcIndex = i;
694             pasListFields[nListFieldCount].eType = eType;
695             if (nMaxSplitListSubFields == 1)
696                 pasListFields[nListFieldCount].nMaxOccurrences = 1;
697             nListFieldCount++;
698         }
699     }
700 
701     if (nListFieldCount == 0)
702         return false;
703 
704     /* No need for full scan if the limit is 1. We just to have to create */
705     /* one and a single one field */
706     if (nMaxSplitListSubFields != 1)
707     {
708         poSrcLayer->ResetReading();
709 
710         const GIntBig nFeatureCount =
711             poSrcLayer->TestCapability(OLCFastFeatureCount)
712             ? poSrcLayer->GetFeatureCount()
713             : 0;
714         GIntBig nFeatureIndex = 0;
715 
716         /* Scan the whole layer to compute the maximum number of */
717         /* items for each field of list type */
718         OGRFeature* poSrcFeature = nullptr;
719         while( (poSrcFeature = poSrcLayer->GetNextFeature()) != nullptr )
720         {
721             for( int i=0; i<nListFieldCount; ++i )
722             {
723                 int nCount = 0;
724                 OGRField* psField =
725                     poSrcFeature->GetRawFieldRef(pasListFields[i].iSrcIndex);
726                 switch(pasListFields[i].eType)
727                 {
728                     case OFTIntegerList:
729                         nCount = psField->IntegerList.nCount;
730                         break;
731                     case OFTRealList:
732                         nCount = psField->RealList.nCount;
733                         break;
734                     case OFTStringList:
735                     {
736                         nCount = psField->StringList.nCount;
737                         char** paList = psField->StringList.paList;
738                         for(int j=0;j<nCount;j++)
739                         {
740                             int nWidth = static_cast<int>(strlen(paList[j]));
741                             if (nWidth > pasListFields[i].nWidth)
742                                 pasListFields[i].nWidth = nWidth;
743                         }
744                         break;
745                     }
746                     default:
747                         // cppcheck-suppress knownConditionTrueFalse
748                         CPLAssert(false);
749                         break;
750                 }
751                 if (nCount > pasListFields[i].nMaxOccurrences)
752                 {
753                     if (nCount > nMaxSplitListSubFields)
754                         nCount = nMaxSplitListSubFields;
755                     pasListFields[i].nMaxOccurrences = nCount;
756                 }
757             }
758             OGRFeature::DestroyFeature(poSrcFeature);
759 
760             nFeatureIndex ++;
761             if (pfnProgress != nullptr && nFeatureCount != 0)
762                 pfnProgress(nFeatureIndex * 1.0 / nFeatureCount, "", pProgressArg);
763         }
764     }
765 
766     /* Now let's build the target feature definition */
767 
768     poFeatureDefn =
769             OGRFeatureDefn::CreateFeatureDefn( poSrcFieldDefn->GetName() );
770     poFeatureDefn->Reference();
771     poFeatureDefn->SetGeomType( wkbNone );
772 
773     for( int i=0; i < poSrcFieldDefn->GetGeomFieldCount(); ++i )
774     {
775         poFeatureDefn->AddGeomFieldDefn(poSrcFieldDefn->GetGeomFieldDefn(i));
776     }
777 
778     int iListField = 0;
779     for( int i=0;i<nSrcFields; ++i)
780     {
781         const OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
782         if (eType == OFTIntegerList ||
783             eType == OFTInteger64List ||
784             eType == OFTRealList ||
785             eType == OFTStringList)
786         {
787             const int nMaxOccurrences =
788                 pasListFields[iListField].nMaxOccurrences;
789             const int nWidth = pasListFields[iListField].nWidth;
790             iListField ++;
791             if (nMaxOccurrences == 1)
792             {
793                 OGRFieldDefn oFieldDefn(poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(),
794                                             (eType == OFTIntegerList) ? OFTInteger :
795                                             (eType == OFTInteger64List) ? OFTInteger64 :
796                                             (eType == OFTRealList) ?    OFTReal :
797                                                                         OFTString);
798                 poFeatureDefn->AddFieldDefn(&oFieldDefn);
799             }
800             else
801             {
802                 for(int j=0;j<nMaxOccurrences;j++)
803                 {
804                     CPLString osFieldName;
805                     osFieldName.Printf("%s%d",
806                         poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(), j+1);
807                     OGRFieldDefn oFieldDefn(osFieldName.c_str(),
808                                             (eType == OFTIntegerList) ? OFTInteger :
809                                             (eType == OFTInteger64List) ? OFTInteger64 :
810                                             (eType == OFTRealList) ?    OFTReal :
811                                                                         OFTString);
812                     oFieldDefn.SetWidth(nWidth);
813                     poFeatureDefn->AddFieldDefn(&oFieldDefn);
814                 }
815             }
816         }
817         else
818         {
819             poFeatureDefn->AddFieldDefn(poSrcFieldDefn->GetFieldDefn(i));
820         }
821     }
822 
823     return true;
824 }
825 
826 /************************************************************************/
827 /*                       TranslateFeature()                             */
828 /************************************************************************/
829 
TranslateFeature(OGRFeature * poSrcFeature)830 OGRFeature *OGRSplitListFieldLayer::TranslateFeature(OGRFeature* poSrcFeature)
831 {
832     if (poSrcFeature == nullptr)
833         return nullptr;
834     if (poFeatureDefn == nullptr)
835         return poSrcFeature;
836 
837     OGRFeature* poFeature = OGRFeature::CreateFeature(poFeatureDefn);
838     poFeature->SetFID(poSrcFeature->GetFID());
839     for(int i=0;i<poFeature->GetGeomFieldCount();i++)
840     {
841         poFeature->SetGeomFieldDirectly(i, poSrcFeature->StealGeometry(i));
842     }
843     poFeature->SetStyleString(poFeature->GetStyleString());
844 
845     OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
846     int nSrcFields = poSrcFeature->GetFieldCount();
847     int iDstField = 0;
848     int iListField = 0;
849 
850     for( int iSrcField=0; iSrcField < nSrcFields; ++iSrcField)
851     {
852         const OGRFieldType eType =
853             poSrcFieldDefn->GetFieldDefn(iSrcField)->GetType();
854         OGRField* psField = poSrcFeature->GetRawFieldRef(iSrcField);
855         switch(eType)
856         {
857             case OFTIntegerList:
858             {
859                 const int nCount = std::min(nMaxSplitListSubFields,
860                                             psField->IntegerList.nCount);
861                 int* paList = psField->IntegerList.paList;
862                 for( int j=0;j<nCount; ++j)
863                     poFeature->SetField(iDstField + j, paList[j]);
864                 iDstField += pasListFields[iListField].nMaxOccurrences;
865                 iListField++;
866                 break;
867             }
868             case OFTInteger64List:
869             {
870                 const int nCount = std::min(nMaxSplitListSubFields,
871                                             psField->Integer64List.nCount);
872                 GIntBig* paList = psField->Integer64List.paList;
873                 for( int j=0; j < nCount; ++j )
874                     poFeature->SetField(iDstField + j, paList[j]);
875                 iDstField += pasListFields[iListField].nMaxOccurrences;
876                 iListField++;
877                 break;
878             }
879             case OFTRealList:
880             {
881                 const int nCount = std::min(nMaxSplitListSubFields,
882                                             psField->RealList.nCount);
883                 double* paList = psField->RealList.paList;
884                 for( int j=0; j < nCount; ++j )
885                     poFeature->SetField(iDstField + j, paList[j]);
886                 iDstField += pasListFields[iListField].nMaxOccurrences;
887                 iListField++;
888                 break;
889             }
890             case OFTStringList:
891             {
892                 const int nCount = std::min(nMaxSplitListSubFields,
893                                             psField->StringList.nCount);
894                 char** paList = psField->StringList.paList;
895                 for( int j=0; j < nCount; ++j )
896                     poFeature->SetField(iDstField + j, paList[j]);
897                 iDstField += pasListFields[iListField].nMaxOccurrences;
898                 iListField++;
899                 break;
900             }
901             default:
902             {
903                 poFeature->SetField(iDstField, psField);
904                 iDstField ++;
905                 break;
906             }
907         }
908     }
909 
910     OGRFeature::DestroyFeature(poSrcFeature);
911 
912     return poFeature;
913 }
914 
915 /************************************************************************/
916 /*                       GetNextFeature()                               */
917 /************************************************************************/
918 
GetNextFeature()919 OGRFeature *OGRSplitListFieldLayer::GetNextFeature()
920 {
921     return TranslateFeature(poSrcLayer->GetNextFeature());
922 }
923 
924 /************************************************************************/
925 /*                           GetFeature()                               */
926 /************************************************************************/
927 
GetFeature(GIntBig nFID)928 OGRFeature *OGRSplitListFieldLayer::GetFeature(GIntBig nFID)
929 {
930     return TranslateFeature(poSrcLayer->GetFeature(nFID));
931 }
932 
933 /************************************************************************/
934 /*                        GetLayerDefn()                                */
935 /************************************************************************/
936 
GetLayerDefn()937 OGRFeatureDefn* OGRSplitListFieldLayer::GetLayerDefn()
938 {
939     if (poFeatureDefn == nullptr)
940         return poSrcLayer->GetLayerDefn();
941     return poFeatureDefn;
942 }
943 
944 /************************************************************************/
945 /*                            GCPCoordTransformation()                  */
946 /*                                                                      */
947 /*      Apply GCP Transform to points                                   */
948 /************************************************************************/
949 
950 class GCPCoordTransformation : public OGRCoordinateTransformation
951 {
GCPCoordTransformation(const GCPCoordTransformation & other)952     GCPCoordTransformation(const GCPCoordTransformation& other):
953         hTransformArg(GDALCloneTransformer(other.hTransformArg)),
954         bUseTPS(other.bUseTPS),
955         poSRS(other.poSRS)
956     {
957         if( poSRS)
958             poSRS->Reference();
959     }
960 
961     GCPCoordTransformation& operator= (const GCPCoordTransformation&) = delete;
962 
963 public:
964 
965     void               *hTransformArg;
966     bool                 bUseTPS;
967     OGRSpatialReference* poSRS;
968 
GCPCoordTransformation(int nGCPCount,const GDAL_GCP * pasGCPList,int nReqOrder,OGRSpatialReference * poSRSIn)969     GCPCoordTransformation( int nGCPCount,
970                             const GDAL_GCP *pasGCPList,
971                             int  nReqOrder,
972                             OGRSpatialReference* poSRSIn) :
973         hTransformArg(nullptr),
974         bUseTPS(nReqOrder < 0),
975         poSRS(poSRSIn)
976     {
977         if( nReqOrder < 0 )
978         {
979             hTransformArg =
980                 GDALCreateTPSTransformer( nGCPCount, pasGCPList, FALSE );
981         }
982         else
983         {
984             hTransformArg =
985                 GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, FALSE );
986         }
987         if( poSRS)
988             poSRS->Reference();
989     }
990 
Clone() const991     OGRCoordinateTransformation* Clone() const override {
992         return new GCPCoordTransformation(*this);
993     }
994 
IsValid() const995     bool IsValid() const { return hTransformArg != nullptr; }
996 
~GCPCoordTransformation()997     virtual ~GCPCoordTransformation()
998     {
999         if( hTransformArg != nullptr )
1000         {
1001             GDALDestroyTransformer(hTransformArg);
1002         }
1003         if( poSRS)
1004             poSRS->Dereference();
1005     }
1006 
GetSourceCS()1007     virtual OGRSpatialReference *GetSourceCS() override { return poSRS; }
GetTargetCS()1008     virtual OGRSpatialReference *GetTargetCS() override { return poSRS; }
1009 
Transform(int nCount,double * x,double * y,double * z,double *,int * pabSuccess)1010     virtual int Transform( int nCount,
1011                            double *x, double *y, double *z,
1012                            double * /* t */,
1013                            int *pabSuccess ) override
1014     {
1015         if( bUseTPS )
1016             return GDALTPSTransform( hTransformArg, FALSE,
1017                                  nCount, x, y, z, pabSuccess );
1018         else
1019             return GDALGCPTransform( hTransformArg, FALSE,
1020                                  nCount, x, y, z, pabSuccess );
1021     }
1022 
GetInverse() const1023     virtual OGRCoordinateTransformation* GetInverse() const override { return nullptr; }
1024 };
1025 
1026 /************************************************************************/
1027 /*                            CompositeCT                               */
1028 /************************************************************************/
1029 
1030 class CompositeCT : public OGRCoordinateTransformation
1031 {
CompositeCT(const CompositeCT & other)1032     CompositeCT(const CompositeCT& other):
1033         poCT1(other.poCT1 ? other.poCT1->Clone(): nullptr),
1034         bOwnCT1(true),
1035         poCT2(other.poCT2 ? other.poCT2->Clone(): nullptr),
1036         bOwnCT2(true) {}
1037 
1038     CompositeCT& operator= (const CompositeCT&) = delete;
1039 
1040 public:
1041 
1042     OGRCoordinateTransformation* poCT1;
1043     bool bOwnCT1;
1044     OGRCoordinateTransformation* poCT2;
1045     bool bOwnCT2;
1046 
CompositeCT(OGRCoordinateTransformation * poCT1In,bool bOwnCT1In,OGRCoordinateTransformation * poCT2In,bool bOwnCT2In)1047     CompositeCT( OGRCoordinateTransformation* poCT1In, bool bOwnCT1In,
1048                  OGRCoordinateTransformation* poCT2In, bool bOwnCT2In ) :
1049         poCT1(poCT1In),
1050         bOwnCT1(bOwnCT1In),
1051         poCT2(poCT2In),
1052         bOwnCT2(bOwnCT2In)
1053     {}
1054 
~CompositeCT()1055     virtual ~CompositeCT()
1056     {
1057         if( bOwnCT1 )
1058             delete poCT1;
1059         if( bOwnCT2 )
1060             delete poCT2;
1061     }
1062 
Clone() const1063     OGRCoordinateTransformation* Clone() const override {
1064         return new CompositeCT(*this);
1065     }
1066 
GetSourceCS()1067     virtual OGRSpatialReference *GetSourceCS() override
1068     {
1069         return poCT1 ? poCT1->GetSourceCS() :
1070                poCT2 ? poCT2->GetSourceCS() : nullptr;
1071     }
1072 
GetTargetCS()1073     virtual OGRSpatialReference *GetTargetCS() override
1074     {
1075         return poCT2 ? poCT2->GetTargetCS() :
1076                poCT1 ? poCT1->GetTargetCS() : nullptr;
1077     }
1078 
Transform(int nCount,double * x,double * y,double * z,double * t,int * pabSuccess)1079     virtual int Transform( int nCount,
1080                            double *x, double *y, double *z,
1081                            double *t,
1082                            int *pabSuccess ) override
1083     {
1084         int nResult = TRUE;
1085         if( poCT1 )
1086             nResult = poCT1->Transform(nCount, x, y, z, t, pabSuccess);
1087         if( nResult && poCT2 )
1088             nResult = poCT2->Transform(nCount, x, y, z, t, pabSuccess);
1089         return nResult;
1090     }
1091 
GetInverse() const1092     virtual OGRCoordinateTransformation* GetInverse() const override { return nullptr; }
1093 };
1094 
1095 /************************************************************************/
1096 /*                    AxisMappingCoordinateTransformation               */
1097 /************************************************************************/
1098 
1099 class AxisMappingCoordinateTransformation : public OGRCoordinateTransformation
1100 {
1101 public:
1102 
1103     bool bSwapXY = false;
1104 
AxisMappingCoordinateTransformation(const std::vector<int> & mappingIn,const std::vector<int> & mappingOut)1105     AxisMappingCoordinateTransformation( const std::vector<int>& mappingIn,
1106                                          const std::vector<int>& mappingOut )
1107     {
1108         if( mappingIn.size() >= 2 && mappingIn[0] == 1 && mappingIn[1] == 2 &&
1109             mappingOut.size() >= 2 && mappingOut[0] == 2 && mappingOut[1] == 1 )
1110         {
1111             bSwapXY = true;
1112         }
1113         else if( mappingIn.size() >= 2 && mappingIn[0] == 2 && mappingIn[1] == 1 &&
1114                  mappingOut.size() >= 2 && mappingOut[0] == 1 && mappingOut[1] == 2 )
1115         {
1116             bSwapXY = true;
1117         }
1118         else
1119         {
1120             CPLError(CE_Failure, CPLE_NotSupported,
1121                       "Unsupported axis transformation");
1122         }
1123     }
1124 
~AxisMappingCoordinateTransformation()1125     ~AxisMappingCoordinateTransformation() override
1126     {
1127     }
1128 
Clone() const1129     virtual OGRCoordinateTransformation *Clone() const override
1130     {
1131         return new AxisMappingCoordinateTransformation(*this);
1132     }
1133 
GetSourceCS()1134     virtual OGRSpatialReference *GetSourceCS() override
1135     {
1136         return nullptr;
1137     }
1138 
GetTargetCS()1139     virtual OGRSpatialReference *GetTargetCS() override
1140     {
1141         return nullptr;
1142     }
1143 
Transform(int nCount,double * x,double * y,double *,double *,int * pabSuccess)1144     virtual int Transform( int nCount,
1145                            double *x, double *y,
1146                            double * /*z*/,
1147                            double * /*t*/,
1148                            int *pabSuccess ) override
1149     {
1150         for(int i = 0; i < nCount; i++ )
1151         {
1152             if( pabSuccess )
1153                 pabSuccess[i] = true;
1154             if( bSwapXY )
1155                 std::swap(x[i], y[i]);
1156         }
1157         return true;
1158     }
1159 
GetInverse() const1160     virtual OGRCoordinateTransformation* GetInverse() const override { return nullptr; }
1161 };
1162 
1163 /************************************************************************/
1164 /*                        ApplySpatialFilter()                          */
1165 /************************************************************************/
1166 
1167 static
ApplySpatialFilter(OGRLayer * poLayer,OGRGeometry * poSpatialFilter,OGRSpatialReference * poSpatSRS,const char * pszGeomField,OGRSpatialReference * poSourceSRS)1168 void ApplySpatialFilter(OGRLayer* poLayer, OGRGeometry* poSpatialFilter,
1169                         OGRSpatialReference* poSpatSRS,
1170                         const char* pszGeomField,
1171                         OGRSpatialReference* poSourceSRS)
1172 {
1173     if( poSpatialFilter == nullptr )
1174         return;
1175 
1176    OGRGeometry* poSpatialFilterReprojected = nullptr;
1177    if( poSpatSRS )
1178    {
1179        poSpatialFilterReprojected = poSpatialFilter->clone();
1180        poSpatialFilterReprojected->assignSpatialReference(poSpatSRS);
1181        OGRSpatialReference* poSpatialFilterTargetSRS  = poSourceSRS ? poSourceSRS : poLayer->GetSpatialRef();
1182        if( poSpatialFilterTargetSRS )
1183            poSpatialFilterReprojected->transformTo(poSpatialFilterTargetSRS);
1184        else
1185            CPLError(CE_Warning, CPLE_AppDefined, "cannot determine layer SRS for %s.", poLayer->GetDescription());
1186    }
1187 
1188    if( pszGeomField != nullptr )
1189    {
1190        const int iGeomField =
1191            poLayer->GetLayerDefn()->GetGeomFieldIndex(pszGeomField);
1192        if( iGeomField >= 0 )
1193            poLayer->SetSpatialFilter( iGeomField,
1194                poSpatialFilterReprojected ? poSpatialFilterReprojected : poSpatialFilter );
1195        else
1196            CPLError(CE_Warning, CPLE_AppDefined,
1197                     "Cannot find geometry field %s.",
1198                     pszGeomField);
1199    }
1200    else
1201    {
1202        poLayer->SetSpatialFilter( poSpatialFilterReprojected ? poSpatialFilterReprojected : poSpatialFilter );
1203    }
1204 
1205    delete poSpatialFilterReprojected;
1206 }
1207 
1208 /************************************************************************/
1209 /*                            GetFieldType()                            */
1210 /************************************************************************/
1211 
GetFieldType(const char * pszArg,int * pnSubFieldType)1212 static int GetFieldType(const char* pszArg, int* pnSubFieldType)
1213 {
1214     *pnSubFieldType = OFSTNone;
1215     const char* pszOpenParenthesis = strchr(pszArg, '(');
1216     const int nLengthBeforeParenthesis =
1217         pszOpenParenthesis
1218         ? static_cast<int>(pszOpenParenthesis - pszArg)
1219         : static_cast<int>(strlen(pszArg));
1220     for( int iType = 0; iType <= static_cast<int>(OFTMaxType); iType++ )
1221     {
1222          const char* pszFieldTypeName = OGRFieldDefn::GetFieldTypeName(
1223              static_cast<OGRFieldType>(iType));
1224          if( EQUALN(pszArg,pszFieldTypeName,nLengthBeforeParenthesis) &&
1225              pszFieldTypeName[nLengthBeforeParenthesis] == '\0' )
1226          {
1227              if( pszOpenParenthesis != nullptr )
1228              {
1229                  *pnSubFieldType = -1;
1230                  CPLString osArgSubType = pszOpenParenthesis + 1;
1231                  if( !osArgSubType.empty() && osArgSubType.back() == ')' )
1232                      osArgSubType.resize(osArgSubType.size()-1);
1233                  for( int iSubType = 0;
1234                       iSubType <= static_cast<int>(OFSTMaxSubType); iSubType++ )
1235                  {
1236                      const char* pszFieldSubTypeName = OGRFieldDefn::GetFieldSubTypeName(
1237                          static_cast<OGRFieldSubType>(iSubType));
1238                      if( EQUAL( pszFieldSubTypeName, osArgSubType ) )
1239                      {
1240                          *pnSubFieldType = iSubType;
1241                          break;
1242                      }
1243                  }
1244              }
1245              return iType;
1246          }
1247      }
1248      return -1;
1249 }
1250 
1251 /************************************************************************/
1252 /*                            IsNumber()                               */
1253 /************************************************************************/
1254 
IsNumber(const char * pszStr)1255 static bool IsNumber(const char* pszStr)
1256 {
1257     if (*pszStr == '-' || *pszStr == '+')
1258         pszStr ++;
1259     if (*pszStr == '.')
1260         pszStr ++;
1261     return (*pszStr >= '0' && *pszStr <= '9');
1262 }
1263 
1264 /************************************************************************/
1265 /*                           IsFieldType()                              */
1266 /************************************************************************/
1267 
IsFieldType(const char * pszArg)1268 static bool IsFieldType(const char* pszArg)
1269 {
1270     int iSubType;
1271     return GetFieldType(pszArg, &iSubType) >= 0 && iSubType >= 0;
1272 }
1273 
1274 /************************************************************************/
1275 /*                      GDALVectorTranslateOptionsClone()               */
1276 /************************************************************************/
1277 
1278 static
GDALVectorTranslateOptionsClone(const GDALVectorTranslateOptions * psOptionsIn)1279 GDALVectorTranslateOptions* GDALVectorTranslateOptionsClone(const GDALVectorTranslateOptions *psOptionsIn)
1280 {
1281     GDALVectorTranslateOptions* psOptions =
1282         static_cast<GDALVectorTranslateOptions *>(
1283             CPLMalloc(sizeof(GDALVectorTranslateOptions)));
1284     memcpy(psOptions, psOptionsIn, sizeof(GDALVectorTranslateOptions));
1285 
1286     if( psOptionsIn->pszFormat) psOptions->pszFormat = CPLStrdup(psOptionsIn->pszFormat);
1287     if( psOptionsIn->pszOutputSRSDef ) psOptions->pszOutputSRSDef = CPLStrdup(psOptionsIn->pszOutputSRSDef);
1288     if( psOptionsIn->pszCTPipeline ) psOptions->pszCTPipeline = CPLStrdup(psOptionsIn->pszCTPipeline);
1289     if( psOptionsIn->pszSourceSRSDef ) psOptions->pszSourceSRSDef = CPLStrdup(psOptionsIn->pszSourceSRSDef);
1290     if( psOptionsIn->pszNewLayerName ) psOptions->pszNewLayerName = CPLStrdup(psOptionsIn->pszNewLayerName);
1291     if( psOptionsIn->pszWHERE ) psOptions->pszWHERE = CPLStrdup(psOptionsIn->pszWHERE);
1292     if( psOptionsIn->pszGeomField ) psOptions->pszGeomField = CPLStrdup(psOptionsIn->pszGeomField);
1293     if( psOptionsIn->pszSQLStatement ) psOptions->pszSQLStatement = CPLStrdup(psOptionsIn->pszSQLStatement);
1294     if( psOptionsIn->pszDialect ) psOptions->pszDialect = CPLStrdup(psOptionsIn->pszDialect);
1295     if( psOptionsIn->pszClipSrcDS ) psOptions->pszClipSrcDS = CPLStrdup(psOptionsIn->pszClipSrcDS);
1296     if( psOptionsIn->pszClipSrcSQL ) psOptions->pszClipSrcSQL = CPLStrdup(psOptionsIn->pszClipSrcSQL);
1297     if( psOptionsIn->pszClipSrcLayer ) psOptions->pszClipSrcLayer = CPLStrdup(psOptionsIn->pszClipSrcLayer);
1298     if( psOptionsIn->pszClipSrcWhere ) psOptions->pszClipSrcWhere = CPLStrdup(psOptionsIn->pszClipSrcWhere);
1299     if( psOptionsIn->pszClipDstDS ) psOptions->pszClipDstDS = CPLStrdup(psOptionsIn->pszClipDstDS);
1300     if( psOptionsIn->pszClipDstSQL ) psOptions->pszClipDstSQL = CPLStrdup(psOptionsIn->pszClipDstSQL);
1301     if( psOptionsIn->pszClipDstLayer ) psOptions->pszClipDstLayer = CPLStrdup(psOptionsIn->pszClipDstLayer);
1302     if( psOptionsIn->pszClipDstWhere ) psOptions->pszClipDstWhere = CPLStrdup(psOptionsIn->pszClipDstWhere);
1303     if( psOptionsIn->pszZField ) psOptions->pszZField = CPLStrdup(psOptionsIn->pszZField);
1304     if( psOptionsIn->pszSpatSRSDef ) psOptions->pszSpatSRSDef = CPLStrdup(psOptionsIn->pszSpatSRSDef);
1305     psOptions->papszSelFields = CSLDuplicate(psOptionsIn->papszSelFields);
1306     psOptions->papszFieldMap = CSLDuplicate(psOptionsIn->papszFieldMap);
1307     psOptions->papszMapFieldType = CSLDuplicate(psOptionsIn->papszMapFieldType);
1308     psOptions->papszLayers = CSLDuplicate(psOptionsIn->papszLayers);
1309     psOptions->papszDSCO = CSLDuplicate(psOptionsIn->papszDSCO);
1310     psOptions->papszLCO = CSLDuplicate(psOptionsIn->papszLCO);
1311     psOptions->papszDestOpenOptions = CSLDuplicate(psOptionsIn->papszDestOpenOptions);
1312     psOptions->papszFieldTypesToString = CSLDuplicate(psOptionsIn->papszFieldTypesToString);
1313     psOptions->papszMetadataOptions = CSLDuplicate(psOptionsIn->papszMetadataOptions);
1314     if( psOptionsIn->nGCPCount )
1315         psOptions->pasGCPs = GDALDuplicateGCPs( psOptionsIn->nGCPCount, psOptionsIn->pasGCPs );
1316     psOptions->hClipSrc = ( psOptionsIn->hClipSrc != nullptr ) ? OGR_G_Clone(psOptionsIn->hClipSrc) : nullptr;
1317     psOptions->hClipDst = ( psOptionsIn->hClipDst != nullptr ) ? OGR_G_Clone(psOptionsIn->hClipDst) : nullptr;
1318     psOptions->hSpatialFilter = ( psOptionsIn->hSpatialFilter != nullptr ) ? OGR_G_Clone(psOptionsIn->hSpatialFilter) : nullptr;
1319 
1320     return psOptions;
1321 }
1322 
1323 class GDALVectorTranslateWrappedDataset: public GDALDataset
1324 {
1325                 GDALDataset* m_poBase;
1326                 OGRSpatialReference* m_poOutputSRS;
1327                 bool m_bTransform;
1328 
1329                 std::vector<OGRLayer*> m_apoLayers;
1330                 std::vector<OGRLayer*> m_apoHiddenLayers;
1331 
1332                 GDALVectorTranslateWrappedDataset(
1333                                     GDALDataset* poBase,
1334                                     OGRSpatialReference* poOutputSRS,
1335                                     bool bTransform);
1336 public:
1337 
1338        virtual ~GDALVectorTranslateWrappedDataset();
1339 
GetLayerCount()1340        virtual int GetLayerCount() override
1341                         { return static_cast<int>(m_apoLayers.size()); }
1342        virtual OGRLayer* GetLayer(int nIdx) override;
1343        virtual OGRLayer* GetLayerByName(const char* pszName) override;
1344 
1345        virtual OGRLayer *  ExecuteSQL( const char *pszStatement,
1346                                         OGRGeometry *poSpatialFilter,
1347                                         const char *pszDialect ) override;
1348        virtual void        ReleaseResultSet( OGRLayer * poResultsSet ) override;
1349 
1350        static GDALVectorTranslateWrappedDataset* New(
1351                                           GDALDataset* poBase,
1352                                           OGRSpatialReference* poOutputSRS,
1353                                           bool bTransform );
1354 };
1355 
1356 class GDALVectorTranslateWrappedLayer: public OGRLayerDecorator
1357 {
1358     std::vector<OGRCoordinateTransformation*> m_apoCT;
1359     OGRFeatureDefn* m_poFDefn;
1360 
1361             GDALVectorTranslateWrappedLayer(OGRLayer* poBaseLayer,
1362                                             bool bOwnBaseLayer);
1363             OGRFeature* TranslateFeature(OGRFeature* poSrcFeat);
1364 public:
1365 
1366         virtual ~GDALVectorTranslateWrappedLayer();
GetLayerDefn()1367         virtual OGRFeatureDefn* GetLayerDefn() override { return m_poFDefn; }
1368         virtual OGRFeature* GetNextFeature() override;
1369         virtual OGRFeature* GetFeature(GIntBig nFID) override;
1370 
1371         static GDALVectorTranslateWrappedLayer* New(
1372                                         OGRLayer* poBaseLayer,
1373                                         bool bOwnBaseLayer,
1374                                         OGRSpatialReference* poOutputSRS,
1375                                         bool bTransform);
1376 };
1377 
GDALVectorTranslateWrappedLayer(OGRLayer * poBaseLayer,bool bOwnBaseLayer)1378 GDALVectorTranslateWrappedLayer::GDALVectorTranslateWrappedLayer(
1379                     OGRLayer* poBaseLayer, bool bOwnBaseLayer) :
1380         OGRLayerDecorator(poBaseLayer, bOwnBaseLayer),
1381         m_apoCT( poBaseLayer->GetLayerDefn()->GetGeomFieldCount(),
1382                  static_cast<OGRCoordinateTransformation*>(nullptr) ),
1383         m_poFDefn( nullptr )
1384 {
1385 }
1386 
New(OGRLayer * poBaseLayer,bool bOwnBaseLayer,OGRSpatialReference * poOutputSRS,bool bTransform)1387 GDALVectorTranslateWrappedLayer* GDALVectorTranslateWrappedLayer::New(
1388                     OGRLayer* poBaseLayer,
1389                     bool bOwnBaseLayer,
1390                     OGRSpatialReference* poOutputSRS,
1391                     bool bTransform )
1392 {
1393     GDALVectorTranslateWrappedLayer* poNew =
1394                 new GDALVectorTranslateWrappedLayer(poBaseLayer, bOwnBaseLayer);
1395     poNew->m_poFDefn = poBaseLayer->GetLayerDefn()->Clone();
1396     poNew->m_poFDefn->Reference();
1397     if( !poOutputSRS )
1398         return poNew;
1399 
1400     for( int i=0; i < poNew->m_poFDefn->GetGeomFieldCount(); i++ )
1401     {
1402         if( bTransform )
1403         {
1404             OGRSpatialReference* poSourceSRS =
1405                 poBaseLayer->GetLayerDefn()->
1406                                     GetGeomFieldDefn(i)->GetSpatialRef();
1407             if( poSourceSRS == nullptr )
1408             {
1409                 CPLError(CE_Failure, CPLE_AppDefined,
1410                          "Layer %s has no source SRS for geometry field %s",
1411                          poBaseLayer->GetName(),
1412                          poBaseLayer->GetLayerDefn()->
1413                                     GetGeomFieldDefn(i)->GetNameRef());
1414                 delete poNew;
1415                 return nullptr;
1416             }
1417             else
1418             {
1419                 poNew->m_apoCT[i] = OGRCreateCoordinateTransformation(
1420                                                                poSourceSRS,
1421                                                                poOutputSRS);
1422                 if( poNew->m_apoCT[i] == nullptr )
1423                 {
1424                     CPLError( CE_Failure, CPLE_AppDefined,
1425                         "Failed to create coordinate transformation between the\n"
1426                         "following coordinate systems.  This may be because they\n"
1427                         "are not transformable." );
1428 
1429                     char *pszWKT = nullptr;
1430                     poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
1431                     CPLError( CE_Failure, CPLE_AppDefined,
1432                               "Source:\n%s", pszWKT );
1433                     CPLFree(pszWKT);
1434 
1435                     poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
1436                     CPLError( CE_Failure, CPLE_AppDefined,
1437                               "Target:\n%s", pszWKT );
1438                     CPLFree(pszWKT);
1439 
1440                     delete poNew;
1441                     return nullptr;
1442                 }
1443             }
1444         }
1445         poNew->m_poFDefn->GetGeomFieldDefn(i)->SetSpatialRef( poOutputSRS );
1446     }
1447 
1448     return poNew;
1449 }
1450 
~GDALVectorTranslateWrappedLayer()1451 GDALVectorTranslateWrappedLayer::~GDALVectorTranslateWrappedLayer()
1452 {
1453     if( m_poFDefn )
1454         m_poFDefn->Release();
1455     for( size_t i = 0; i < m_apoCT.size(); ++i )
1456         delete m_apoCT[i];
1457 }
1458 
GetNextFeature()1459 OGRFeature* GDALVectorTranslateWrappedLayer::GetNextFeature()
1460 {
1461     return TranslateFeature(OGRLayerDecorator::GetNextFeature());
1462 }
1463 
GetFeature(GIntBig nFID)1464 OGRFeature* GDALVectorTranslateWrappedLayer::GetFeature(GIntBig nFID)
1465 {
1466     return TranslateFeature(OGRLayerDecorator::GetFeature(nFID));
1467 }
1468 
TranslateFeature(OGRFeature * poSrcFeat)1469 OGRFeature* GDALVectorTranslateWrappedLayer::TranslateFeature(
1470                                                     OGRFeature* poSrcFeat )
1471 {
1472     if( poSrcFeat == nullptr )
1473         return nullptr;
1474     OGRFeature* poNewFeat = new OGRFeature(m_poFDefn);
1475     poNewFeat->SetFrom(poSrcFeat);
1476     poNewFeat->SetFID(poSrcFeat->GetFID());
1477     for( int i=0; i < poNewFeat->GetGeomFieldCount(); i++ )
1478     {
1479         OGRGeometry* poGeom = poNewFeat->GetGeomFieldRef(i);
1480         if( poGeom )
1481         {
1482             if( m_apoCT[i] )
1483                 poGeom->transform( m_apoCT[i] );
1484             poGeom->assignSpatialReference(
1485                     m_poFDefn->GetGeomFieldDefn(i)->GetSpatialRef() );
1486         }
1487     }
1488     delete poSrcFeat;
1489     return poNewFeat;
1490 }
1491 
1492 
GDALVectorTranslateWrappedDataset(GDALDataset * poBase,OGRSpatialReference * poOutputSRS,bool bTransform)1493 GDALVectorTranslateWrappedDataset::GDALVectorTranslateWrappedDataset(
1494                                     GDALDataset* poBase,
1495                                     OGRSpatialReference* poOutputSRS,
1496                                     bool bTransform):
1497                                                 m_poBase(poBase),
1498                                                 m_poOutputSRS(poOutputSRS),
1499                                                 m_bTransform(bTransform)
1500 {
1501     SetDescription( poBase->GetDescription() );
1502     if( poBase->GetDriver() )
1503     {
1504         poDriver = new GDALDriver();
1505         poDriver->SetDescription( poBase->GetDriver()->GetDescription() );
1506     }
1507 }
1508 
New(GDALDataset * poBase,OGRSpatialReference * poOutputSRS,bool bTransform)1509 GDALVectorTranslateWrappedDataset* GDALVectorTranslateWrappedDataset::New(
1510                         GDALDataset* poBase,
1511                         OGRSpatialReference* poOutputSRS,
1512                         bool bTransform )
1513 {
1514     GDALVectorTranslateWrappedDataset* poNew =
1515                                 new GDALVectorTranslateWrappedDataset(
1516                                                                 poBase,
1517                                                                 poOutputSRS,
1518                                                                 bTransform);
1519     for(int i = 0; i < poBase->GetLayerCount(); i++ )
1520     {
1521         OGRLayer* poLayer = GDALVectorTranslateWrappedLayer::New(
1522                             poBase->GetLayer(i), false, poOutputSRS, bTransform);
1523         if(poLayer == nullptr )
1524         {
1525             delete poNew;
1526             return nullptr;
1527         }
1528         poNew->m_apoLayers.push_back(poLayer);
1529     }
1530     return poNew;
1531 }
1532 
~GDALVectorTranslateWrappedDataset()1533 GDALVectorTranslateWrappedDataset::~GDALVectorTranslateWrappedDataset()
1534 {
1535     delete poDriver;
1536     for(size_t i = 0; i < m_apoLayers.size(); i++ )
1537     {
1538         delete m_apoLayers[i];
1539     }
1540     for(size_t i = 0; i < m_apoHiddenLayers.size(); i++ )
1541     {
1542         delete m_apoHiddenLayers[i];
1543     }
1544 }
1545 
GetLayer(int i)1546 OGRLayer* GDALVectorTranslateWrappedDataset::GetLayer(int i)
1547 {
1548     if( i < 0 || i >= static_cast<int>(m_apoLayers.size()) )
1549         return nullptr;
1550     return m_apoLayers[i];
1551 }
1552 
GetLayerByName(const char * pszName)1553 OGRLayer* GDALVectorTranslateWrappedDataset::GetLayerByName(const char* pszName)
1554 {
1555     for(size_t i = 0; i < m_apoLayers.size(); i++ )
1556     {
1557         if( strcmp(m_apoLayers[i]->GetName(), pszName) == 0 )
1558             return m_apoLayers[i];
1559     }
1560     for(size_t i = 0; i < m_apoHiddenLayers.size(); i++ )
1561     {
1562         if( strcmp(m_apoHiddenLayers[i]->GetName(), pszName) == 0 )
1563             return m_apoHiddenLayers[i];
1564     }
1565     for(size_t i = 0; i < m_apoLayers.size(); i++ )
1566     {
1567         if( EQUAL(m_apoLayers[i]->GetName(), pszName) )
1568             return m_apoLayers[i];
1569     }
1570     for(size_t i = 0; i < m_apoHiddenLayers.size(); i++ )
1571     {
1572         if( EQUAL(m_apoHiddenLayers[i]->GetName(), pszName) )
1573             return m_apoHiddenLayers[i];
1574     }
1575 
1576     OGRLayer* poLayer = m_poBase->GetLayerByName(pszName);
1577     if( poLayer == nullptr )
1578         return nullptr;
1579     poLayer = GDALVectorTranslateWrappedLayer::New(
1580                                 poLayer, false, m_poOutputSRS, m_bTransform);
1581     if( poLayer == nullptr )
1582         return nullptr;
1583 
1584     // Replicate source dataset behavior: if the fact of calling
1585     // GetLayerByName() on a initially hidden layer makes it visible through
1586     // GetLayerCount()/GetLayer(), do the same. Otherwise we are going to
1587     // maintain it hidden as well.
1588     for( int i = 0; i < m_poBase->GetLayerCount(); i++ )
1589     {
1590         if( m_poBase->GetLayer(i) == poLayer )
1591         {
1592             m_apoLayers.push_back(poLayer);
1593             return poLayer;
1594         }
1595     }
1596     m_apoHiddenLayers.push_back(poLayer);
1597     return poLayer;
1598 }
1599 
1600 
ExecuteSQL(const char * pszStatement,OGRGeometry * poSpatialFilter,const char * pszDialect)1601 OGRLayer *  GDALVectorTranslateWrappedDataset::ExecuteSQL(
1602                                         const char *pszStatement,
1603                                         OGRGeometry *poSpatialFilter,
1604                                         const char *pszDialect )
1605 {
1606     OGRLayer* poLayer = m_poBase->ExecuteSQL(pszStatement,
1607                                                 poSpatialFilter, pszDialect);
1608     if( poLayer == nullptr )
1609         return nullptr;
1610     return GDALVectorTranslateWrappedLayer::New(
1611                                 poLayer, true, m_poOutputSRS, m_bTransform);
1612 }
1613 
ReleaseResultSet(OGRLayer * poResultsSet)1614 void GDALVectorTranslateWrappedDataset:: ReleaseResultSet(
1615                                                     OGRLayer * poResultsSet )
1616 {
1617     delete poResultsSet;
1618 }
1619 
1620 /************************************************************************/
1621 /*                     OGR2OGRSpatialReferenceHolder                    */
1622 /************************************************************************/
1623 
1624 class OGR2OGRSpatialReferenceHolder
1625 {
1626         OGRSpatialReference* m_poSRS;
1627 
1628     public:
OGR2OGRSpatialReferenceHolder()1629         OGR2OGRSpatialReferenceHolder() : m_poSRS(nullptr) {}
~OGR2OGRSpatialReferenceHolder()1630        ~OGR2OGRSpatialReferenceHolder() { if( m_poSRS) m_poSRS->Release(); }
1631 
assignNoRefIncrease(OGRSpatialReference * poSRS)1632        void assignNoRefIncrease(OGRSpatialReference* poSRS) {
1633            CPLAssert(m_poSRS == nullptr);
1634            m_poSRS = poSRS;
1635        }
get()1636        OGRSpatialReference* get() { return m_poSRS; }
1637 };
1638 
1639 /************************************************************************/
1640 /*                     GDALVectorTranslateCreateCopy()                  */
1641 /************************************************************************/
1642 
GDALVectorTranslateCreateCopy(GDALDriver * poDriver,const char * pszDest,GDALDataset * poDS,const GDALVectorTranslateOptions * psOptions)1643 static GDALDataset* GDALVectorTranslateCreateCopy(
1644                                     GDALDriver* poDriver,
1645                                     const char* pszDest,
1646                                     GDALDataset* poDS,
1647                                     const GDALVectorTranslateOptions* psOptions)
1648 {
1649     const char* const szErrorMsg = "%s not supported by this output driver";
1650 
1651     if( psOptions->bSkipFailures )
1652     {
1653         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-skipfailures");
1654         return nullptr;
1655     }
1656     if( psOptions->nLayerTransaction >= 0 )
1657     {
1658         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-lyr_transaction or -ds_transaction");
1659         return nullptr;
1660     }
1661     if( psOptions->nFIDToFetch >= 0 )
1662     {
1663         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-fid");
1664         return nullptr;
1665     }
1666     if( psOptions->papszLCO )
1667     {
1668         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-lco");
1669         return nullptr;
1670     }
1671     if( psOptions->bAddMissingFields )
1672     {
1673         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-addfields");
1674         return nullptr;
1675     }
1676     if( psOptions->pszSourceSRSDef )
1677     {
1678         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-s_srs");
1679         return nullptr;
1680     }
1681     if( !psOptions->bExactFieldNameMatch )
1682     {
1683         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-relaxedFieldNameMatch");
1684         return nullptr;
1685     }
1686     if( psOptions->pszNewLayerName )
1687     {
1688         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-nln");
1689         return nullptr;
1690     }
1691     if( psOptions->papszSelFields )
1692     {
1693         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-select");
1694         return nullptr;
1695     }
1696     if( psOptions->pszSQLStatement )
1697     {
1698         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-sql");
1699         return nullptr;
1700     }
1701     if( psOptions->pszDialect )
1702     {
1703         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-dialect");
1704         return nullptr;
1705     }
1706     if( psOptions->eGType != GEOMTYPE_UNCHANGED ||
1707         psOptions->eGeomTypeConversion != GTC_DEFAULT )
1708     {
1709         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-nlt");
1710         return nullptr;
1711     }
1712     if( psOptions->papszFieldTypesToString )
1713     {
1714         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-fieldTypeToString");
1715         return nullptr;
1716     }
1717     if( psOptions->papszMapFieldType )
1718     {
1719         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-mapFieldType");
1720         return nullptr;
1721     }
1722     if( psOptions->bUnsetFieldWidth )
1723     {
1724         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-unsetFieldWidth");
1725         return nullptr;
1726     }
1727     if( psOptions->bWrapDateline )
1728     {
1729         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-wrapdateline");
1730         return nullptr;
1731     }
1732     if( psOptions->bClipSrc )
1733     {
1734         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipsrc");
1735         return nullptr;
1736     }
1737     if( psOptions->pszClipSrcSQL )
1738     {
1739         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipsrcsql");
1740         return nullptr;
1741     }
1742     if( psOptions->pszClipSrcLayer )
1743     {
1744         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipsrclayer");
1745         return nullptr;
1746     }
1747     if( psOptions->pszClipSrcWhere )
1748     {
1749         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipsrcwhere");
1750         return nullptr;
1751     }
1752     if( psOptions->pszClipDstDS || psOptions->hClipDst )
1753     {
1754         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipdst");
1755         return nullptr;
1756     }
1757     if( psOptions->pszClipDstSQL )
1758     {
1759         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipdstsql");
1760         return nullptr;
1761     }
1762     if( psOptions->pszClipDstLayer )
1763     {
1764         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipdstlayer");
1765         return nullptr;
1766     }
1767     if( psOptions->pszClipDstWhere )
1768     {
1769         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-clipdstwhere");
1770         return nullptr;
1771     }
1772     if( psOptions->bSplitListFields )
1773     {
1774         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-splitlistfields");
1775         return nullptr;
1776     }
1777     if( psOptions->nMaxSplitListSubFields >= 0 )
1778     {
1779         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-maxsubfields");
1780         return nullptr;
1781     }
1782     if( psOptions->bExplodeCollections )
1783     {
1784         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-explodecollections");
1785         return nullptr;
1786     }
1787     if( psOptions->pszZField )
1788     {
1789         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-zfield");
1790         return nullptr;
1791     }
1792     if( psOptions->nGCPCount )
1793     {
1794         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-gcp");
1795         return nullptr;
1796     }
1797     if( psOptions->papszFieldMap )
1798     {
1799         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-fieldmap");
1800         return nullptr;
1801     }
1802     if( psOptions->bForceNullable )
1803     {
1804         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-forceNullable");
1805         return nullptr;
1806     }
1807     if( psOptions->bResolveDomains )
1808     {
1809         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-forceNullable");
1810         return nullptr;
1811     }
1812     if( psOptions->bEmptyStrAsNull )
1813     {
1814         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-emptyStrAsNull");
1815         return nullptr;
1816     }
1817     if( psOptions->bUnsetDefault )
1818     {
1819         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-unsetDefault");
1820         return nullptr;
1821     }
1822     if( psOptions->bUnsetFid )
1823     {
1824         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-unsetFid");
1825         return nullptr;
1826     }
1827     if( !psOptions->bCopyMD )
1828     {
1829         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-nomd");
1830         return nullptr;
1831     }
1832     if( !psOptions->bNativeData )
1833     {
1834         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-noNativeData");
1835         return nullptr;
1836     }
1837     if( psOptions->nLimit >= 0 )
1838     {
1839         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-limit");
1840         return nullptr;
1841     }
1842     if( psOptions->papszMetadataOptions )
1843     {
1844         CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-mo");
1845         return nullptr;
1846     }
1847 
1848     GDALDataset* poWrkSrcDS = poDS;
1849     OGR2OGRSpatialReferenceHolder oOutputSRSHolder;
1850 
1851     if( psOptions->pszOutputSRSDef )
1852     {
1853         oOutputSRSHolder.assignNoRefIncrease(new OGRSpatialReference());
1854         oOutputSRSHolder.get()->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
1855         if( oOutputSRSHolder.get()->
1856                 SetFromUserInput( psOptions->pszOutputSRSDef ) != OGRERR_NONE )
1857         {
1858             CPLError( CE_Failure, CPLE_AppDefined,
1859                       "Failed to process SRS definition: %s",
1860                       psOptions->pszOutputSRSDef );
1861             return nullptr;
1862         }
1863         poWrkSrcDS = GDALVectorTranslateWrappedDataset::New(
1864             poDS, oOutputSRSHolder.get(), psOptions->bTransform);
1865         if( poWrkSrcDS == nullptr )
1866             return nullptr;
1867     }
1868 
1869     if( psOptions->pszWHERE )
1870     {
1871         // Hack for GMLAS driver
1872         if( EQUAL(poDriver->GetDescription(), "GMLAS") )
1873         {
1874             if( psOptions->papszLayers == nullptr )
1875             {
1876                 CPLError(CE_Failure, CPLE_NotSupported,
1877                          "-where not supported by this output driver "
1878                          "without explicit layer name(s)");
1879                 if( poWrkSrcDS != poDS )
1880                     delete poWrkSrcDS;
1881                 return nullptr;
1882             }
1883             else
1884             {
1885                 char** papszIter = psOptions->papszLayers;
1886                 for( ; *papszIter != nullptr; ++papszIter )
1887                 {
1888                     OGRLayer* poSrcLayer = poDS->GetLayerByName(*papszIter);
1889                     if( poSrcLayer != nullptr )
1890                     {
1891                         poSrcLayer->SetAttributeFilter( psOptions->pszWHERE );
1892                     }
1893                 }
1894             }
1895         }
1896         else
1897         {
1898             CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg, "-where");
1899             if( poWrkSrcDS != poDS )
1900                 delete poWrkSrcDS;
1901             return nullptr;
1902         }
1903     }
1904 
1905     if( psOptions->hSpatialFilter )
1906     {
1907         for( int i=0; i<poWrkSrcDS->GetLayerCount();++i)
1908         {
1909             OGRLayer* poSrcLayer = poWrkSrcDS->GetLayer(i);
1910             if( poSrcLayer &&
1911                 poSrcLayer->GetLayerDefn()->GetGeomFieldCount() > 0 &&
1912                 (psOptions->papszLayers == nullptr ||
1913                  CSLFindString(psOptions->papszLayers,
1914                                poSrcLayer->GetName())>=0) )
1915             {
1916                 if( psOptions->pszGeomField != nullptr )
1917                 {
1918                     const int iGeomField = poSrcLayer->GetLayerDefn()->
1919                             GetGeomFieldIndex(psOptions->pszGeomField);
1920                     if( iGeomField >= 0 )
1921                         poSrcLayer->SetSpatialFilter( iGeomField,
1922                             reinterpret_cast<OGRGeometry*>(
1923                                                 psOptions->hSpatialFilter) );
1924                     else
1925                         CPLError( CE_Warning, CPLE_AppDefined,
1926                                   "Cannot find geometry field %s in layer %s. "
1927                                   "Applying to first geometry field",
1928                                   psOptions->pszGeomField,
1929                                   poSrcLayer->GetName() );
1930                 }
1931                 else
1932                 {
1933                     poSrcLayer->SetSpatialFilter(
1934                         reinterpret_cast<OGRGeometry*>(
1935                                             psOptions->hSpatialFilter) );
1936                 }
1937             }
1938         }
1939     }
1940 
1941     char** papszDSCO = CSLDuplicate(psOptions->papszDSCO);
1942     if( psOptions->papszLayers )
1943     {
1944         // Hack for GMLAS driver
1945         if( EQUAL(poDriver->GetDescription(), "GMLAS") )
1946         {
1947             CPLString osLayers;
1948             char** papszIter = psOptions->papszLayers;
1949             for( ; *papszIter != nullptr; ++papszIter )
1950             {
1951                 if( !osLayers.empty() )
1952                     osLayers += ",";
1953                 osLayers += *papszIter;
1954             }
1955             papszDSCO = CSLSetNameValue(papszDSCO, "LAYERS", osLayers);
1956         }
1957         else
1958         {
1959             CPLError(CE_Failure, CPLE_NotSupported, szErrorMsg,
1960                      "Specifying layers");
1961             CSLDestroy(papszDSCO);
1962             if( poWrkSrcDS != poDS )
1963                 delete poWrkSrcDS;
1964             return nullptr;
1965         }
1966     }
1967 
1968     // Hack for GMLAS driver (this speed up deletion by avoiding the GML
1969     // driver to try parsing a pre-existing file). Could be potentially
1970     // removed if the GML driver implemented fast dataset opening (ie
1971     // without parsing) and GetFileList()
1972     if( EQUAL(poDriver->GetDescription(), "GMLAS") )
1973     {
1974         GDALDriverH hIdentifyingDriver = GDALIdentifyDriver(pszDest, nullptr);
1975         if( hIdentifyingDriver != nullptr &&
1976             EQUAL( GDALGetDescription(hIdentifyingDriver), "GML" ) )
1977         {
1978             VSIUnlink( pszDest );
1979             VSIUnlink( CPLResetExtension(pszDest, "gfs") );
1980         }
1981     }
1982 
1983     GDALDataset* poOut = poDriver->CreateCopy(pszDest, poWrkSrcDS, FALSE,
1984                                               papszDSCO,
1985                                               psOptions->pfnProgress,
1986                                               psOptions->pProgressData);
1987     CSLDestroy(papszDSCO);
1988 
1989     if( poWrkSrcDS != poDS )
1990         delete poWrkSrcDS;
1991 
1992     return poOut;
1993 }
1994 
1995 /************************************************************************/
1996 /*                           GDALVectorTranslate()                      */
1997 /************************************************************************/
1998 /**
1999  * Converts vector data between file formats.
2000  *
2001  * This is the equivalent of the <a href="/programs/ogr2ogr.html">ogr2ogr</a> utility.
2002  *
2003  * GDALVectorTranslateOptions* must be allocated and freed with GDALVectorTranslateOptionsNew()
2004  * and GDALVectorTranslateOptionsFree() respectively.
2005  * pszDest and hDstDS cannot be used at the same time.
2006  *
2007  * @param pszDest the destination dataset path or NULL.
2008  * @param hDstDS the destination dataset or NULL.
2009  * @param nSrcCount the number of input datasets (only 1 supported currently)
2010  * @param pahSrcDS the list of input datasets.
2011  * @param psOptionsIn the options struct returned by GDALVectorTranslateOptionsNew() or NULL.
2012  * @param pbUsageError pointer to a integer output variable to store if any usage error has occurred, or NULL.
2013  * @return the output dataset (new dataset that must be closed using GDALClose(), or hDstDS is not NULL) or NULL in case of error.
2014  *
2015  * @since GDAL 2.1
2016  */
2017 
GDALVectorTranslate(const char * pszDest,GDALDatasetH hDstDS,int nSrcCount,GDALDatasetH * pahSrcDS,const GDALVectorTranslateOptions * psOptionsIn,int * pbUsageError)2018 GDALDatasetH GDALVectorTranslate( const char *pszDest, GDALDatasetH hDstDS, int nSrcCount,
2019                                   GDALDatasetH *pahSrcDS,
2020                                   const GDALVectorTranslateOptions *psOptionsIn, int *pbUsageError )
2021 
2022 {
2023     if( pszDest == nullptr && hDstDS == nullptr )
2024     {
2025         CPLError( CE_Failure, CPLE_AppDefined, "pszDest == NULL && hDstDS == NULL");
2026 
2027         if(pbUsageError)
2028             *pbUsageError = TRUE;
2029         return nullptr;
2030     }
2031     if( nSrcCount != 1 )
2032     {
2033         CPLError( CE_Failure, CPLE_AppDefined, "nSrcCount != 1");
2034 
2035         if(pbUsageError)
2036             *pbUsageError = TRUE;
2037         return nullptr;
2038     }
2039 
2040     GDALDatasetH hSrcDS = pahSrcDS[0];
2041     if( hSrcDS == nullptr )
2042     {
2043         CPLError( CE_Failure, CPLE_AppDefined, "hSrcDS == NULL");
2044 
2045         if(pbUsageError)
2046             *pbUsageError = TRUE;
2047         return nullptr;
2048     }
2049 
2050     GDALVectorTranslateOptions* psOptions =
2051         psOptionsIn
2052         ? GDALVectorTranslateOptionsClone(psOptionsIn)
2053         : GDALVectorTranslateOptionsNew(nullptr, nullptr);
2054 
2055     bool bAppend = false;
2056     bool bUpdate = false;
2057     bool bOverwrite = false;
2058 
2059     if( psOptions->eAccessMode == ACCESS_UPDATE )
2060     {
2061         bUpdate = true;
2062     }
2063     else if ( psOptions->eAccessMode == ACCESS_APPEND )
2064     {
2065         bAppend = true;
2066         bUpdate = true;
2067     }
2068     else if ( psOptions->eAccessMode == ACCESS_OVERWRITE )
2069     {
2070         bOverwrite = true;
2071         bUpdate = true;
2072     }
2073     else if( hDstDS != nullptr )
2074     {
2075         bUpdate = true;
2076     }
2077 
2078    const CPLString osDateLineOffset =
2079        CPLOPrintf("%g", psOptions->dfDateLineOffset);
2080 
2081     if( psOptions->bPreserveFID && psOptions->bExplodeCollections )
2082     {
2083         CPLError( CE_Failure, CPLE_IllegalArg, "cannot use -preserve_fid and -explodecollections at the same time.");
2084         if(pbUsageError)
2085             *pbUsageError = TRUE;
2086         GDALVectorTranslateOptionsFree(psOptions);
2087         return nullptr;
2088     }
2089 
2090     if (psOptions->papszFieldMap && !bAppend)
2091     {
2092         CPLError( CE_Failure, CPLE_IllegalArg, "if -fieldmap is specified, -append must also be specified");
2093         if(pbUsageError)
2094             *pbUsageError = TRUE;
2095         GDALVectorTranslateOptionsFree(psOptions);
2096         return nullptr;
2097     }
2098 
2099     if (psOptions->papszFieldMap && psOptions->bAddMissingFields)
2100     {
2101         CPLError( CE_Failure, CPLE_IllegalArg, "if -addfields is specified, -fieldmap cannot be used.");
2102         if(pbUsageError)
2103             *pbUsageError = TRUE;
2104         GDALVectorTranslateOptionsFree(psOptions);
2105         return nullptr;
2106     }
2107 
2108     if (psOptions->papszSelFields && bAppend && !psOptions->bAddMissingFields)
2109     {
2110         CPLError( CE_Failure, CPLE_IllegalArg, "if -append is specified, -select cannot be used "
2111                   "(use -fieldmap or -sql instead)." );
2112         if(pbUsageError)
2113             *pbUsageError = TRUE;
2114         GDALVectorTranslateOptionsFree(psOptions);
2115         return nullptr;
2116     }
2117 
2118     if( psOptions->papszFieldTypesToString && psOptions->papszMapFieldType )
2119     {
2120         CPLError( CE_Failure, CPLE_IllegalArg, "-fieldTypeToString and -mapFieldType are exclusive.");
2121         if(pbUsageError)
2122             *pbUsageError = TRUE;
2123         GDALVectorTranslateOptionsFree(psOptions);
2124         return nullptr;
2125     }
2126 
2127     if( psOptions->pszSourceSRSDef != nullptr && psOptions->pszOutputSRSDef == nullptr && psOptions->pszSpatSRSDef == nullptr )
2128     {
2129         CPLError( CE_Failure, CPLE_IllegalArg, "if -s_srs is specified, -t_srs and/or -spat_srs must also be specified.");
2130         if(pbUsageError)
2131             *pbUsageError = TRUE;
2132         GDALVectorTranslateOptionsFree(psOptions);
2133         return nullptr;
2134     }
2135 
2136     if( psOptions->bClipSrc && psOptions->pszClipSrcDS != nullptr)
2137     {
2138         psOptions->hClipSrc = reinterpret_cast<OGRGeometryH>(LoadGeometry(psOptions->pszClipSrcDS, psOptions->pszClipSrcSQL, psOptions->pszClipSrcLayer, psOptions->pszClipSrcWhere));
2139         if (psOptions->hClipSrc == nullptr)
2140         {
2141             CPLError( CE_Failure,CPLE_IllegalArg, "cannot load source clip geometry");
2142             GDALVectorTranslateOptionsFree(psOptions);
2143             return nullptr;
2144         }
2145     }
2146     else if( psOptions->bClipSrc && psOptions->hClipSrc == nullptr )
2147     {
2148         if (psOptions->hSpatialFilter)
2149             psOptions->hClipSrc = OGR_G_Clone(psOptions->hSpatialFilter);
2150         if (psOptions->hClipSrc == nullptr)
2151         {
2152             CPLError( CE_Failure, CPLE_IllegalArg, "-clipsrc must be used with -spat option or a\n"
2153                              "bounding box, WKT string or datasource must be specified");
2154             if(pbUsageError)
2155                 *pbUsageError = TRUE;
2156             GDALVectorTranslateOptionsFree(psOptions);
2157             return nullptr;
2158         }
2159     }
2160 
2161     if( psOptions->pszClipDstDS != nullptr)
2162     {
2163         psOptions->hClipDst = reinterpret_cast<OGRGeometryH>(LoadGeometry(psOptions->pszClipDstDS, psOptions->pszClipDstSQL, psOptions->pszClipDstLayer, psOptions->pszClipDstWhere));
2164         if (psOptions->hClipDst == nullptr)
2165         {
2166             CPLError( CE_Failure, CPLE_IllegalArg, "cannot load dest clip geometry");
2167             GDALVectorTranslateOptionsFree(psOptions);
2168             return nullptr;
2169         }
2170     }
2171 
2172     GDALDataset *poDS = static_cast<GDALDataset *>(hSrcDS);
2173     GDALDataset *poODS = nullptr;
2174     GDALDriver *poDriver = nullptr;
2175     CPLString osDestFilename;
2176 
2177     if(hDstDS)
2178     {
2179         poODS = static_cast<GDALDataset *>(hDstDS);
2180         osDestFilename = poODS->GetDescription();
2181     }
2182     else
2183     {
2184         osDestFilename = pszDest;
2185     }
2186 
2187     /* Various tests to avoid overwriting the source layer(s) */
2188     /* or to avoid appending a layer to itself */
2189     if( bUpdate && strcmp(osDestFilename, poDS->GetDescription()) == 0 &&
2190         !EQUAL(poDS->GetDriverName(), "Memory") &&
2191         (bOverwrite || bAppend) )
2192     {
2193         bool bError = false;
2194         if (psOptions->pszNewLayerName == nullptr)
2195             bError = true;
2196         else if (CSLCount(psOptions->papszLayers) == 1)
2197             bError = strcmp(psOptions->pszNewLayerName, psOptions->papszLayers[0]) == 0;
2198         else if (psOptions->pszSQLStatement == nullptr)
2199             bError = true;
2200         if (bError)
2201         {
2202             CPLError( CE_Failure, CPLE_IllegalArg,
2203                         "-nln name must be specified combined with "
2204                         "a single source layer name,\nor a -sql statement, and "
2205                         "name must be different from an existing layer.");
2206             GDALVectorTranslateOptionsFree(psOptions);
2207             return nullptr;
2208         }
2209     }
2210     else if( !bUpdate && strcmp(osDestFilename, poDS->GetDescription()) == 0 &&
2211              (psOptions->pszFormat == nullptr || !EQUAL(psOptions->pszFormat, "Memory")) )
2212     {
2213         CPLError( CE_Failure, CPLE_AppDefined,
2214                   "Source and destination datasets must be different "
2215                   "in non-update mode." );
2216         GDALVectorTranslateOptionsFree(psOptions);
2217         return nullptr;
2218     }
2219 
2220 /* -------------------------------------------------------------------- */
2221 /*      Try opening the output datasource as an existing, writable      */
2222 /* -------------------------------------------------------------------- */
2223     std::vector<CPLString> aoDrivers;
2224     if( poODS == nullptr && psOptions->pszFormat == nullptr )
2225     {
2226         aoDrivers = GetOutputDriversFor(pszDest, GDAL_OF_VECTOR);
2227         if( !bUpdate && aoDrivers.size() == 1 )
2228         {
2229             GDALDriverH hDriver = GDALGetDriverByName(aoDrivers[0]);
2230             const char* pszPrefix = GDALGetMetadataItem(hDriver,
2231                     GDAL_DMD_CONNECTION_PREFIX, nullptr);
2232             if( pszPrefix && STARTS_WITH_CI(pszDest, pszPrefix) )
2233             {
2234                 bUpdate = true;
2235             }
2236         }
2237     }
2238 
2239     if( bUpdate && poODS == nullptr )
2240     {
2241         poODS = static_cast<GDALDataset*>(GDALOpenEx( osDestFilename,
2242                 GDAL_OF_UPDATE | GDAL_OF_VECTOR, nullptr, psOptions->papszDestOpenOptions, nullptr ));
2243 
2244         if( poODS == nullptr )
2245         {
2246             if (bOverwrite || bAppend)
2247             {
2248                 poODS = static_cast<GDALDataset*>(GDALOpenEx( osDestFilename,
2249                             GDAL_OF_VECTOR, nullptr, psOptions->papszDestOpenOptions, nullptr ));
2250                 if (poODS == nullptr)
2251                 {
2252                     /* OK the datasource doesn't exist at all */
2253                     bUpdate = false;
2254                 }
2255                 else
2256                 {
2257                     poDriver = poODS->GetDriver();
2258                     GDALClose(poODS);
2259                     poODS = nullptr;
2260                 }
2261             }
2262 
2263             if (bUpdate)
2264             {
2265                 CPLError( CE_Failure, CPLE_AppDefined,
2266                         "Unable to open existing output datasource `%s'.",
2267                         osDestFilename.c_str() );
2268                 GDALVectorTranslateOptionsFree(psOptions);
2269                 return nullptr;
2270             }
2271         }
2272         else if( CSLCount(psOptions->papszDSCO) > 0 )
2273         {
2274             CPLError( CE_Warning, CPLE_AppDefined, "Datasource creation options ignored since an existing datasource\n"
2275                     "         being updated." );
2276         }
2277     }
2278 
2279     if( poODS )
2280         poDriver = poODS->GetDriver();
2281 
2282 /* -------------------------------------------------------------------- */
2283 /*      Find the output driver.                                         */
2284 /* -------------------------------------------------------------------- */
2285     bool bNewDataSource = false;
2286     if( !bUpdate )
2287     {
2288         GDALDriverManager *poDM = GetGDALDriverManager();
2289 
2290         if( psOptions->pszFormat == nullptr )
2291         {
2292             if( aoDrivers.empty() )
2293             {
2294                 if( EQUAL(CPLGetExtension(pszDest), "") )
2295                 {
2296                     psOptions->pszFormat = CPLStrdup("ESRI Shapefile");
2297                 }
2298                 else
2299                 {
2300                     CPLError( CE_Failure, CPLE_AppDefined,
2301                             "Cannot guess driver for %s", pszDest);
2302                     GDALVectorTranslateOptionsFree(psOptions);
2303                     return nullptr;
2304                 }
2305             }
2306             else
2307             {
2308                 if( aoDrivers.size() > 1 )
2309                 {
2310                     CPLError( CE_Warning, CPLE_AppDefined,
2311                             "Several drivers matching %s extension. Using %s",
2312                             CPLGetExtension(pszDest), aoDrivers[0].c_str() );
2313                 }
2314                 psOptions->pszFormat = CPLStrdup(aoDrivers[0]);
2315             }
2316             CPLDebug("GDAL", "Using %s driver",
2317                      psOptions->pszFormat);
2318         }
2319 
2320         CPLString osOGRCompatFormat(psOptions->pszFormat);
2321         // Special processing for non-unified drivers that have the same name
2322         // as GDAL and OGR drivers. GMT should become OGR_GMT.
2323         // Other candidates could be VRT, SDTS and PDS, but they don't
2324         // have write capabilities. But do the substitution to get a sensible
2325         // error message
2326         if( EQUAL(osOGRCompatFormat, "GMT") ||
2327             EQUAL(osOGRCompatFormat, "VRT") ||
2328             EQUAL(osOGRCompatFormat, "SDTS") ||
2329             EQUAL(osOGRCompatFormat, "PDS") )
2330         {
2331             osOGRCompatFormat = "OGR_" + osOGRCompatFormat;
2332         }
2333         poDriver = poDM->GetDriverByName(osOGRCompatFormat);
2334         if( poDriver == nullptr )
2335         {
2336             CPLError( CE_Failure, CPLE_AppDefined,
2337                       "Unable to find driver `%s'.", psOptions->pszFormat );
2338             GDALVectorTranslateOptionsFree(psOptions);
2339             return nullptr;
2340         }
2341 
2342         char** papszDriverMD = poDriver->GetMetadata();
2343         if( !CPLTestBool( CSLFetchNameValueDef(papszDriverMD,
2344                                                GDAL_DCAP_VECTOR, "FALSE") ) )
2345         {
2346             CPLError( CE_Failure, CPLE_AppDefined,
2347                       "%s driver has no vector capabilities.",
2348                       psOptions->pszFormat );
2349             GDALVectorTranslateOptionsFree(psOptions);
2350             return nullptr;
2351         }
2352 
2353         if( !CPLTestBool( CSLFetchNameValueDef(papszDriverMD,
2354                                                GDAL_DCAP_CREATE, "FALSE") ) )
2355         {
2356             if( CPLTestBool( CSLFetchNameValueDef(papszDriverMD,
2357                                             GDAL_DCAP_CREATECOPY, "FALSE") ) )
2358             {
2359                 poODS = GDALVectorTranslateCreateCopy(poDriver, pszDest,
2360                                                       poDS, psOptions);
2361                 GDALVectorTranslateOptionsFree(psOptions);
2362                 return poODS;
2363             }
2364 
2365             CPLError( CE_Failure, CPLE_AppDefined,
2366                       "%s driver does not support data source creation.",
2367                     psOptions->pszFormat );
2368             GDALVectorTranslateOptionsFree(psOptions);
2369             return nullptr;
2370         }
2371 
2372         if( psOptions->papszDestOpenOptions != nullptr )
2373         {
2374             CPLError(CE_Warning, CPLE_AppDefined, "-doo ignored when creating the output datasource.");
2375         }
2376 
2377 /* -------------------------------------------------------------------- */
2378 /*      Special case to improve user experience when translating        */
2379 /*      a datasource with multiple layers into a shapefile. If the      */
2380 /*      user gives a target datasource with .shp and it does not exist, */
2381 /*      the shapefile driver will try to create a file, but this is not */
2382 /*      appropriate because here we have several layers, so create      */
2383 /*      a directory instead.                                            */
2384 /* -------------------------------------------------------------------- */
2385         VSIStatBufL  sStat;
2386         if (EQUAL(poDriver->GetDescription(), "ESRI Shapefile") &&
2387             psOptions->pszSQLStatement == nullptr &&
2388             (CSLCount(psOptions->papszLayers) > 1 ||
2389              (CSLCount(psOptions->papszLayers) == 0 && poDS->GetLayerCount() > 1)) &&
2390             psOptions->pszNewLayerName == nullptr &&
2391             EQUAL(CPLGetExtension(osDestFilename), "SHP") &&
2392             VSIStatL(osDestFilename, &sStat) != 0)
2393         {
2394             if (VSIMkdir(osDestFilename, 0755) != 0)
2395             {
2396                 CPLError( CE_Failure, CPLE_AppDefined,
2397                       "Failed to create directory %s\n"
2398                       "for shapefile datastore.",
2399                       osDestFilename.c_str() );
2400                 GDALVectorTranslateOptionsFree(psOptions);
2401                 return nullptr;
2402             }
2403         }
2404 
2405 /* -------------------------------------------------------------------- */
2406 /*      Create the output data source.                                  */
2407 /* -------------------------------------------------------------------- */
2408         poODS = poDriver->Create( osDestFilename, 0, 0, 0, GDT_Unknown, psOptions->papszDSCO );
2409         if( poODS == nullptr )
2410         {
2411             CPLError( CE_Failure, CPLE_AppDefined, "%s driver failed to create %s",
2412                     psOptions->pszFormat, osDestFilename.c_str() );
2413             GDALVectorTranslateOptionsFree(psOptions);
2414             return nullptr;
2415         }
2416         bNewDataSource = true;
2417 
2418         if( psOptions->bCopyMD )
2419         {
2420             char** papszDomains = poDS->GetMetadataDomainList();
2421             for(char** papszIter = papszDomains; papszIter && *papszIter; ++papszIter )
2422             {
2423                 char** papszMD = poDS->GetMetadata(*papszIter);
2424                 if( papszMD )
2425                     poODS->SetMetadata(papszMD, *papszIter);
2426             }
2427             CSLDestroy(papszDomains);
2428         }
2429         for(char** papszIter = psOptions->papszMetadataOptions; papszIter && *papszIter; ++papszIter )
2430         {
2431             char    *pszKey = nullptr;
2432             const char *pszValue = CPLParseNameValue( *papszIter, &pszKey );
2433             if( pszKey )
2434             {
2435                 poODS->SetMetadataItem(pszKey,pszValue);
2436                 CPLFree( pszKey );
2437             }
2438         }
2439     }
2440 
2441 /* -------------------------------------------------------------------- */
2442 /*      For random reading                                              */
2443 /* -------------------------------------------------------------------- */
2444     const bool bRandomLayerReading = CPL_TO_BOOL(
2445                                     poDS->TestCapability(ODsCRandomLayerRead));
2446     if( bRandomLayerReading &&
2447         !poODS->TestCapability(ODsCRandomLayerWrite) &&
2448         CSLCount(psOptions->papszLayers) != 1 &&
2449         psOptions->pszSQLStatement == nullptr &&
2450         !psOptions->bQuiet )
2451     {
2452         CPLError(CE_Warning, CPLE_AppDefined,
2453                     "Input datasource uses random layer reading, but "
2454                     "output datasource does not support random layer writing");
2455     }
2456 
2457     if( psOptions->nLayerTransaction < 0 )
2458     {
2459         if( bRandomLayerReading )
2460             psOptions->nLayerTransaction = FALSE;
2461         else
2462             psOptions->nLayerTransaction = !poODS->TestCapability(ODsCTransactions);
2463     }
2464     else if( psOptions->nLayerTransaction &&
2465              bRandomLayerReading )
2466     {
2467         psOptions->nLayerTransaction = false;
2468     }
2469 
2470 /* -------------------------------------------------------------------- */
2471 /*      Parse the output SRS definition if possible.                    */
2472 /* -------------------------------------------------------------------- */
2473     OGR2OGRSpatialReferenceHolder oOutputSRSHolder;
2474     if( psOptions->pszOutputSRSDef != nullptr )
2475     {
2476         oOutputSRSHolder.assignNoRefIncrease(new OGRSpatialReference());
2477         oOutputSRSHolder.get()->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
2478         if( oOutputSRSHolder.get()->
2479                 SetFromUserInput( psOptions->pszOutputSRSDef ) != OGRERR_NONE )
2480         {
2481             CPLError( CE_Failure, CPLE_AppDefined, "Failed to process SRS definition: %s",
2482                     psOptions->pszOutputSRSDef );
2483             GDALVectorTranslateOptionsFree(psOptions);
2484             if( hDstDS == nullptr ) GDALClose( poODS );
2485             return nullptr;
2486         }
2487     }
2488 
2489 /* -------------------------------------------------------------------- */
2490 /*      Parse the source SRS definition if possible.                    */
2491 /* -------------------------------------------------------------------- */
2492     OGRSpatialReference oSourceSRS;
2493     OGRSpatialReference *poSourceSRS = nullptr;
2494     if( psOptions->pszSourceSRSDef != nullptr )
2495     {
2496         oSourceSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
2497         if( oSourceSRS.SetFromUserInput( psOptions->pszSourceSRSDef ) != OGRERR_NONE )
2498         {
2499             CPLError( CE_Failure, CPLE_AppDefined, "Failed to process SRS definition: %s",
2500                     psOptions->pszSourceSRSDef );
2501             GDALVectorTranslateOptionsFree(psOptions);
2502             if( hDstDS == nullptr ) GDALClose( poODS );
2503             return nullptr;
2504         }
2505         poSourceSRS = &oSourceSRS;
2506     }
2507 
2508 /* -------------------------------------------------------------------- */
2509 /*      Parse spatial filter SRS if needed.                             */
2510 /* -------------------------------------------------------------------- */
2511     OGRSpatialReference oSpatSRS;
2512     OGRSpatialReference* poSpatSRS = nullptr;
2513     if( psOptions->hSpatialFilter != nullptr && psOptions->pszSpatSRSDef != nullptr )
2514     {
2515         if( psOptions->pszSQLStatement )
2516         {
2517             CPLError( CE_Failure, CPLE_IllegalArg, "-spat_srs not compatible with -sql.");
2518             GDALVectorTranslateOptionsFree(psOptions);
2519             if( hDstDS == nullptr ) GDALClose( poODS );
2520             return nullptr;
2521         }
2522         OGREnvelope sEnvelope;
2523         OGR_G_GetEnvelope(psOptions->hSpatialFilter, &sEnvelope);
2524         oSpatSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
2525         if( oSpatSRS.SetFromUserInput( psOptions->pszSpatSRSDef ) != OGRERR_NONE )
2526         {
2527             CPLError( CE_Failure, CPLE_AppDefined, "Failed to process SRS definition: %s",
2528                     psOptions->pszSpatSRSDef );
2529             GDALVectorTranslateOptionsFree(psOptions);
2530             if( hDstDS == nullptr ) GDALClose( poODS );
2531             return nullptr;
2532         }
2533         poSpatSRS = &oSpatSRS;
2534     }
2535 
2536 /* -------------------------------------------------------------------- */
2537 /*      Create a transformation object from the source to               */
2538 /*      destination coordinate system.                                  */
2539 /* -------------------------------------------------------------------- */
2540     GCPCoordTransformation *poGCPCoordTrans = nullptr;
2541     if( psOptions->nGCPCount > 0 )
2542     {
2543         poGCPCoordTrans = new GCPCoordTransformation( psOptions->nGCPCount, psOptions->pasGCPs,
2544                                                       psOptions->nTransformOrder,
2545                                                       poSourceSRS ? poSourceSRS : oOutputSRSHolder.get() );
2546         if( !(poGCPCoordTrans->IsValid()) )
2547         {
2548             delete poGCPCoordTrans;
2549             poGCPCoordTrans = nullptr;
2550         }
2551     }
2552 
2553 /* -------------------------------------------------------------------- */
2554 /*      Create layer setup and transformer objects.                     */
2555 /* -------------------------------------------------------------------- */
2556     SetupTargetLayer oSetup;
2557     oSetup.m_poSrcDS = poDS;
2558     oSetup.m_poDstDS = poODS;
2559     oSetup.m_papszLCO = psOptions->papszLCO;
2560     oSetup.m_poOutputSRS = oOutputSRSHolder.get();
2561     oSetup.m_bNullifyOutputSRS = psOptions->bNullifyOutputSRS;
2562     oSetup.m_papszSelFields = psOptions->papszSelFields;
2563     oSetup.m_bAppend = bAppend;
2564     oSetup.m_bAddMissingFields = psOptions->bAddMissingFields;
2565     oSetup.m_eGType = psOptions->eGType;
2566     oSetup.m_eGeomTypeConversion = psOptions->eGeomTypeConversion;
2567     oSetup.m_nCoordDim = psOptions->nCoordDim;
2568     oSetup.m_bOverwrite = bOverwrite;
2569     oSetup.m_papszFieldTypesToString = psOptions->papszFieldTypesToString;
2570     oSetup.m_papszMapFieldType = psOptions->papszMapFieldType;
2571     oSetup.m_bUnsetFieldWidth = psOptions->bUnsetFieldWidth;
2572     oSetup.m_bExplodeCollections = psOptions->bExplodeCollections;
2573     oSetup.m_pszZField = psOptions->pszZField;
2574     oSetup.m_papszFieldMap = psOptions->papszFieldMap;
2575     oSetup.m_pszWHERE = psOptions->pszWHERE;
2576     oSetup.m_bExactFieldNameMatch = psOptions->bExactFieldNameMatch;
2577     oSetup.m_bQuiet = psOptions->bQuiet;
2578     oSetup.m_bForceNullable = psOptions->bForceNullable;
2579     oSetup.m_bResolveDomains = psOptions->bResolveDomains;
2580     oSetup.m_bUnsetDefault = psOptions->bUnsetDefault;
2581     oSetup.m_bUnsetFid = psOptions->bUnsetFid;
2582     oSetup.m_bPreserveFID = psOptions->bPreserveFID;
2583     oSetup.m_bCopyMD = psOptions->bCopyMD;
2584     oSetup.m_bNativeData = psOptions->bNativeData;
2585     oSetup.m_bNewDataSource = bNewDataSource;
2586     oSetup.m_pszCTPipeline = psOptions->pszCTPipeline;
2587 
2588     LayerTranslator oTranslator;
2589     oTranslator.m_poSrcDS = poDS;
2590     oTranslator.m_poODS = poODS;
2591     oTranslator.m_bTransform = psOptions->bTransform;
2592     oTranslator.m_bWrapDateline = psOptions->bWrapDateline;
2593     oTranslator.m_osDateLineOffset = osDateLineOffset;
2594     oTranslator.m_poOutputSRS = oOutputSRSHolder.get();
2595     oTranslator.m_bNullifyOutputSRS = psOptions->bNullifyOutputSRS;
2596     oTranslator.m_poUserSourceSRS = poSourceSRS;
2597     oTranslator.m_poGCPCoordTrans = poGCPCoordTrans;
2598     oTranslator.m_eGType = psOptions->eGType;
2599     oTranslator.m_eGeomTypeConversion = psOptions->eGeomTypeConversion;
2600     oTranslator.m_bMakeValid = psOptions->bMakeValid;
2601     oTranslator.m_nCoordDim = psOptions->nCoordDim;
2602     oTranslator.m_eGeomOp = psOptions->eGeomOp;
2603     oTranslator.m_dfGeomOpParam = psOptions->dfGeomOpParam;
2604     oTranslator.m_poClipSrc = reinterpret_cast<OGRGeometry*>(psOptions->hClipSrc);
2605     oTranslator.m_poClipDst = reinterpret_cast<OGRGeometry*>(psOptions->hClipDst);
2606     oTranslator.m_bExplodeCollections = psOptions->bExplodeCollections;
2607     oTranslator.m_bNativeData = psOptions->bNativeData;
2608     oTranslator.m_nLimit = psOptions->nLimit;
2609 
2610     if( psOptions->nGroupTransactions )
2611     {
2612         if( !psOptions->nLayerTransaction )
2613             poODS->StartTransaction(psOptions->bForceTransaction);
2614     }
2615 
2616     GIntBig nTotalEventsDone = 0;
2617 
2618 /* -------------------------------------------------------------------- */
2619 /*      Special case for -sql clause.  No source layers required.       */
2620 /* -------------------------------------------------------------------- */
2621     int nRetCode = 0;
2622 
2623     if( psOptions->pszSQLStatement != nullptr )
2624     {
2625         /* Special case: if output=input, then we must likely destroy the */
2626         /* old table before to avoid transaction issues. */
2627         if( poDS == poODS && psOptions->pszNewLayerName != nullptr && bOverwrite )
2628             GetLayerAndOverwriteIfNecessary(poODS, psOptions->pszNewLayerName, bOverwrite, nullptr, nullptr, nullptr);
2629 
2630         if( psOptions->pszWHERE != nullptr )
2631             CPLError( CE_Warning, CPLE_AppDefined, "-where clause ignored in combination with -sql." );
2632         if( CSLCount(psOptions->papszLayers) > 0 )
2633             CPLError( CE_Warning, CPLE_AppDefined, "layer names ignored in combination with -sql." );
2634 
2635         OGRLayer *poResultSet =
2636             poDS->ExecuteSQL(
2637                 psOptions->pszSQLStatement,
2638                 (psOptions->pszGeomField == nullptr) ? reinterpret_cast<OGRGeometry*>(psOptions->hSpatialFilter) : nullptr,
2639                 psOptions->pszDialect);
2640 
2641         if( poResultSet != nullptr )
2642         {
2643             if( psOptions->hSpatialFilter != nullptr && psOptions->pszGeomField != nullptr )
2644             {
2645                 int iGeomField = poResultSet->GetLayerDefn()->GetGeomFieldIndex(psOptions->pszGeomField);
2646                 if( iGeomField >= 0 )
2647                     poResultSet->SetSpatialFilter( iGeomField, reinterpret_cast<OGRGeometry*>(psOptions->hSpatialFilter) );
2648                 else
2649                     CPLError( CE_Warning, CPLE_AppDefined, "Cannot find geometry field %s.",
2650                            psOptions->pszGeomField);
2651             }
2652 
2653             GIntBig nCountLayerFeatures = 0;
2654             GDALProgressFunc pfnProgress = nullptr;
2655             void *pProgressArg = nullptr;
2656             if (psOptions->bDisplayProgress)
2657             {
2658                 if (bRandomLayerReading)
2659                 {
2660                     pfnProgress = psOptions->pfnProgress;
2661                     pProgressArg = psOptions->pProgressData;
2662                 }
2663                 else if (!poResultSet->TestCapability(OLCFastFeatureCount))
2664                 {
2665                     CPLError( CE_Warning, CPLE_AppDefined, "Progress turned off as fast feature count is not available.");
2666                     psOptions->bDisplayProgress = false;
2667                 }
2668                 else
2669                 {
2670                     nCountLayerFeatures = poResultSet->GetFeatureCount();
2671                     pfnProgress = psOptions->pfnProgress;
2672                     pProgressArg = psOptions->pProgressData;
2673                 }
2674             }
2675 
2676             OGRLayer* poPassedLayer = poResultSet;
2677             if (psOptions->bSplitListFields)
2678             {
2679                 auto poLayer = new OGRSplitListFieldLayer(poPassedLayer, psOptions->nMaxSplitListSubFields);
2680                 poPassedLayer = poLayer;
2681                 int nRet = poLayer->BuildLayerDefn(nullptr, nullptr);
2682                 if (!nRet)
2683                 {
2684                     delete poPassedLayer;
2685                     poPassedLayer = poResultSet;
2686                 }
2687             }
2688 
2689 /* -------------------------------------------------------------------- */
2690 /*      Special case to improve user experience when translating into   */
2691 /*      single file shapefile and source has only one layer, and that   */
2692 /*      the layer name isn't specified                                  */
2693 /* -------------------------------------------------------------------- */
2694             VSIStatBufL sStat;
2695             if (EQUAL(poDriver->GetDescription(), "ESRI Shapefile") &&
2696                 psOptions->pszNewLayerName == nullptr &&
2697                 VSIStatL(osDestFilename, &sStat) == 0 && VSI_ISREG(sStat.st_mode) &&
2698                 (EQUAL(CPLGetExtension(osDestFilename), "shp") ||
2699                  EQUAL(CPLGetExtension(osDestFilename), "shz") ||
2700                  EQUAL(CPLGetExtension(osDestFilename), "dbf")) )
2701             {
2702                 psOptions->pszNewLayerName = CPLStrdup(CPLGetBasename(osDestFilename));
2703             }
2704 
2705             auto psInfo = oSetup.Setup(poPassedLayer,
2706                                                    psOptions->pszNewLayerName,
2707                                                    psOptions,
2708                                                    nTotalEventsDone);
2709 
2710             poPassedLayer->ResetReading();
2711 
2712             if( psInfo == nullptr ||
2713                 !oTranslator.Translate( nullptr, psInfo.get(),
2714                                         nCountLayerFeatures, nullptr,
2715                                         nTotalEventsDone,
2716                                         pfnProgress, pProgressArg, psOptions ))
2717             {
2718                 CPLError( CE_Failure, CPLE_AppDefined,
2719                           "Terminating translation prematurely after failed\n"
2720                           "translation from sql statement." );
2721 
2722                 nRetCode = 1;
2723             }
2724 
2725             if (poPassedLayer != poResultSet)
2726                 delete poPassedLayer;
2727 
2728             poDS->ReleaseResultSet( poResultSet );
2729         }
2730         else
2731         {
2732             if( CPLGetLastErrorNo() != 0 )
2733                 nRetCode = 1;
2734         }
2735     }
2736 
2737 /* -------------------------------------------------------------------- */
2738 /*      Special case for layer interleaving mode.                       */
2739 /* -------------------------------------------------------------------- */
2740     else if( bRandomLayerReading )
2741     {
2742         if (psOptions->bSplitListFields)
2743         {
2744             CPLError( CE_Failure, CPLE_AppDefined, "-splitlistfields not supported in this mode" );
2745             GDALVectorTranslateOptionsFree(psOptions);
2746             if( hDstDS == nullptr ) GDALClose( poODS );
2747             delete poGCPCoordTrans;
2748             return nullptr;
2749         }
2750 
2751         // Make sure to probe all layers in case some are by default invisible
2752         for( char** papszIter = psOptions->papszLayers;
2753                     papszIter && *papszIter; ++papszIter )
2754         {
2755             OGRLayer *poLayer = poDS->GetLayerByName(*papszIter);
2756 
2757             if( poLayer == nullptr )
2758             {
2759                 CPLError( CE_Failure, CPLE_AppDefined, "Couldn't fetch requested layer %s!",
2760                           *papszIter );
2761                 GDALVectorTranslateOptionsFree(psOptions);
2762                 if( hDstDS == nullptr ) GDALClose( poODS );
2763                 delete poGCPCoordTrans;
2764                 return nullptr;
2765             }
2766         }
2767 
2768         const int nSrcLayerCount = poDS->GetLayerCount();
2769         std::vector<AssociatedLayers> pasAssocLayers(nSrcLayerCount);
2770 
2771 /* -------------------------------------------------------------------- */
2772 /*      Special case to improve user experience when translating into   */
2773 /*      single file shapefile and source has only one layer, and that   */
2774 /*      the layer name isn't specified                                  */
2775 /* -------------------------------------------------------------------- */
2776         VSIStatBufL  sStat;
2777         if (EQUAL(poDriver->GetDescription(), "ESRI Shapefile") &&
2778             (CSLCount(psOptions->papszLayers) == 1 || nSrcLayerCount == 1) &&
2779             psOptions->pszNewLayerName == nullptr &&
2780             VSIStatL(osDestFilename, &sStat) == 0 && VSI_ISREG(sStat.st_mode) &&
2781             (EQUAL(CPLGetExtension(osDestFilename), "shp") ||
2782              EQUAL(CPLGetExtension(osDestFilename), "shz") ||
2783              EQUAL(CPLGetExtension(osDestFilename), "dbf")) )
2784         {
2785             psOptions->pszNewLayerName = CPLStrdup(CPLGetBasename(osDestFilename));
2786         }
2787 
2788         GDALProgressFunc pfnProgress = nullptr;
2789         void        *pProgressArg = nullptr;
2790         if ( !psOptions->bQuiet )
2791         {
2792             pfnProgress = psOptions->pfnProgress;
2793             pProgressArg = psOptions->pProgressData;
2794         }
2795 
2796 /* -------------------------------------------------------------------- */
2797 /*      If no target layer specified, use all source layers.            */
2798 /* -------------------------------------------------------------------- */
2799         if ( CSLCount(psOptions->papszLayers) == 0)
2800         {
2801             psOptions->papszLayers = static_cast<char **>(
2802                 CPLCalloc(sizeof(char*), nSrcLayerCount + 1));
2803             for( int iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
2804             {
2805                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
2806 
2807                 if( poLayer == nullptr )
2808                 {
2809                     CPLError( CE_Failure, CPLE_AppDefined, "Couldn't fetch advertised layer %d!",
2810                             iLayer );
2811                     GDALVectorTranslateOptionsFree(psOptions);
2812                     if( hDstDS == nullptr ) GDALClose( poODS );
2813                     delete poGCPCoordTrans;
2814                     return nullptr;
2815                 }
2816 
2817                 psOptions->papszLayers[iLayer] = CPLStrdup(poLayer->GetName());
2818             }
2819         }
2820         else
2821         {
2822             const bool bSrcIsOSM = (strcmp(poDS->GetDriverName(), "OSM") == 0);
2823             if ( bSrcIsOSM )
2824             {
2825                 CPLString osInterestLayers = "SET interest_layers =";
2826                 for( int iLayer = 0; psOptions->papszLayers[iLayer] != nullptr; iLayer++ )
2827                 {
2828                     if( iLayer != 0 ) osInterestLayers += ",";
2829                     osInterestLayers += psOptions->papszLayers[iLayer];
2830                 }
2831 
2832                 poDS->ExecuteSQL(osInterestLayers.c_str(), nullptr, nullptr);
2833             }
2834         }
2835 
2836 /* -------------------------------------------------------------------- */
2837 /*      First pass to set filters.                                      */
2838 /* -------------------------------------------------------------------- */
2839         std::map<OGRLayer*, int> oMapLayerToIdx;
2840 
2841         for( int iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
2842         {
2843             OGRLayer        *poLayer = poDS->GetLayer(iLayer);
2844             if( poLayer == nullptr )
2845             {
2846                 CPLError( CE_Failure, CPLE_AppDefined, "Couldn't fetch advertised layer %d!",
2847                         iLayer );
2848                 GDALVectorTranslateOptionsFree(psOptions);
2849                 if( hDstDS == nullptr ) GDALClose( poODS );
2850                 delete poGCPCoordTrans;
2851                 return nullptr;
2852             }
2853 
2854             pasAssocLayers[iLayer].poSrcLayer = poLayer;
2855 
2856             if( CSLFindString(psOptions->papszLayers, poLayer->GetName()) >= 0 )
2857             {
2858                 if( psOptions->pszWHERE != nullptr )
2859                 {
2860                     if( poLayer->SetAttributeFilter( psOptions->pszWHERE ) != OGRERR_NONE )
2861                     {
2862                         CPLError( CE_Failure,
2863                                   CPLE_AppDefined,
2864                                   "SetAttributeFilter(%s) on layer '%s' failed.",
2865                                   psOptions->pszWHERE, poLayer->GetName() );
2866                         if (!psOptions->bSkipFailures)
2867                         {
2868                             GDALVectorTranslateOptionsFree(psOptions);
2869                             if( hDstDS == nullptr ) GDALClose( poODS );
2870                             delete poGCPCoordTrans;
2871                             return nullptr;
2872                         }
2873                     }
2874                 }
2875 
2876                 ApplySpatialFilter(poLayer,
2877                                    reinterpret_cast<OGRGeometry*>(psOptions->hSpatialFilter),
2878                                    poSpatSRS, psOptions->pszGeomField,
2879                                    poSourceSRS );
2880 
2881                 oMapLayerToIdx[ poLayer ] = iLayer;
2882             }
2883         }
2884 
2885 /* -------------------------------------------------------------------- */
2886 /*      Second pass to process features in a interleaved layer mode.    */
2887 /* -------------------------------------------------------------------- */
2888         bool bTargetLayersHaveBeenCreated = false;
2889         while( true )
2890         {
2891             OGRLayer* poFeatureLayer = nullptr;
2892             OGRFeature* poFeature = poDS->GetNextFeature(&poFeatureLayer,
2893                                                          nullptr,
2894                                                          pfnProgress,
2895                                                          pProgressArg);
2896             if( poFeature == nullptr )
2897                 break;
2898             std::map<OGRLayer*, int>::const_iterator oIter =
2899                 oMapLayerToIdx.find(poFeatureLayer);
2900             if( oIter == oMapLayerToIdx.end() )
2901             {
2902                 // Feature in a layer that is not a layer of interest.
2903                 OGRFeature::DestroyFeature(poFeature);
2904             }
2905             else
2906             {
2907                 if( !bTargetLayersHaveBeenCreated )
2908                 {
2909                     // We defer target layer creation at the first feature
2910                     // retrieved since getting the layer definition can be
2911                     // costly (case of the GMLAS driver) and thus we'd better
2912                     // taking advantage from the progress callback of
2913                     // GetNextFeature.
2914                     bTargetLayersHaveBeenCreated = true;
2915                     for( int iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
2916                     {
2917                         OGRLayer        *poLayer = poDS->GetLayer(iLayer);
2918                         if( CSLFindString(psOptions->papszLayers, poLayer->GetName()) < 0 )
2919                             continue;
2920 
2921                         auto psInfo = oSetup.Setup(poLayer,
2922                                                                psOptions->pszNewLayerName,
2923                                                                psOptions,
2924                                                                nTotalEventsDone);
2925 
2926                         if( psInfo == nullptr && !psOptions->bSkipFailures )
2927                         {
2928                             GDALVectorTranslateOptionsFree(psOptions);
2929                             if( hDstDS == nullptr ) GDALClose( poODS );
2930                             delete poGCPCoordTrans;
2931                             OGRFeature::DestroyFeature(poFeature);
2932                             return nullptr;
2933                         }
2934 
2935                         pasAssocLayers[iLayer].psInfo = std::move(psInfo);
2936                     }
2937                     if( nRetCode )
2938                         break;
2939                 }
2940 
2941                 int iLayer = oIter->second;
2942                 TargetLayerInfo *psInfo = pasAssocLayers[iLayer].psInfo.get();
2943                 if( (psInfo == nullptr ||
2944                      !oTranslator.Translate( poFeature, psInfo,
2945                                             0, nullptr,
2946                                             nTotalEventsDone,
2947                                             nullptr, nullptr, psOptions ))
2948                     && !psOptions->bSkipFailures )
2949                 {
2950                     CPLError( CE_Failure, CPLE_AppDefined,
2951                             "Terminating translation prematurely after failed\n"
2952                             "translation of layer %s (use -skipfailures to skip errors)",
2953                             poFeatureLayer->GetName() );
2954 
2955                     nRetCode = 1;
2956                     break;
2957                 }
2958                 if( psInfo == nullptr )
2959                     OGRFeature::DestroyFeature(poFeature);
2960             }
2961         }  // while true
2962 
2963         if (pfnProgress)
2964         {
2965             pfnProgress(1.0, "", pProgressArg);
2966         }
2967 
2968         if( !bTargetLayersHaveBeenCreated )
2969         {
2970             // bTargetLayersHaveBeenCreated not used after here.
2971             // bTargetLayersHaveBeenCreated = true;
2972             for( int iLayer = 0; iLayer < nSrcLayerCount; iLayer++ )
2973             {
2974                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
2975                 if( CSLFindString(psOptions->papszLayers, poLayer->GetName()) < 0 )
2976                     continue;
2977 
2978                 auto psInfo = oSetup.Setup(poLayer,
2979                                                        psOptions->pszNewLayerName,
2980                                                        psOptions,
2981                                                        nTotalEventsDone);
2982 
2983                 if( psInfo == nullptr && !psOptions->bSkipFailures )
2984                 {
2985                     GDALVectorTranslateOptionsFree(psOptions);
2986                     if( hDstDS == nullptr ) GDALClose( poODS );
2987                     delete poGCPCoordTrans;
2988                     return nullptr;
2989                 }
2990 
2991                 pasAssocLayers[iLayer].psInfo = std::move(psInfo);
2992             }
2993         }
2994     }
2995 
2996     else
2997     {
2998         int nLayerCount = 0;
2999         std::vector<OGRLayer*> apoLayers;
3000 
3001 /* -------------------------------------------------------------------- */
3002 /*      Process each data source layer.                                 */
3003 /* -------------------------------------------------------------------- */
3004         if ( CSLCount(psOptions->papszLayers) == 0)
3005         {
3006             nLayerCount = poDS->GetLayerCount();
3007             apoLayers.resize(nLayerCount);
3008 
3009             for( int iLayer = 0;
3010                  iLayer < nLayerCount;
3011                  iLayer++ )
3012             {
3013                 OGRLayer        *poLayer = poDS->GetLayer(iLayer);
3014 
3015                 if( poLayer == nullptr )
3016                 {
3017                     CPLError( CE_Failure, CPLE_AppDefined, "Couldn't fetch advertised layer %d!",
3018                             iLayer );
3019                     GDALVectorTranslateOptionsFree(psOptions);
3020                     if( hDstDS == nullptr ) GDALClose( poODS );
3021                     delete poGCPCoordTrans;
3022                     return nullptr;
3023                 }
3024 
3025                 apoLayers[iLayer] = poLayer;
3026             }
3027         }
3028 /* -------------------------------------------------------------------- */
3029 /*      Process specified data source layers.                           */
3030 /* -------------------------------------------------------------------- */
3031         else
3032         {
3033             nLayerCount = CSLCount(psOptions->papszLayers);
3034             apoLayers.resize(nLayerCount);
3035 
3036             for( int iLayer = 0;
3037                 psOptions->papszLayers[iLayer] != nullptr;
3038                 iLayer++ )
3039             {
3040                 OGRLayer        *poLayer = poDS->GetLayerByName(psOptions->papszLayers[iLayer]);
3041 
3042                 if( poLayer == nullptr )
3043                 {
3044                     CPLError( CE_Failure, CPLE_AppDefined, "Couldn't fetch requested layer '%s'!",
3045                              psOptions->papszLayers[iLayer] );
3046                     if (!psOptions->bSkipFailures)
3047                     {
3048                         GDALVectorTranslateOptionsFree(psOptions);
3049                         if( hDstDS == nullptr ) GDALClose( poODS );
3050                         delete poGCPCoordTrans;
3051                         return nullptr;
3052                     }
3053                 }
3054 
3055                 apoLayers[iLayer] = poLayer;
3056             }
3057         }
3058 
3059 /* -------------------------------------------------------------------- */
3060 /*      Special case to improve user experience when translating into   */
3061 /*      single file shapefile and source has only one layer, and that   */
3062 /*      the layer name isn't specified                                  */
3063 /* -------------------------------------------------------------------- */
3064         VSIStatBufL  sStat;
3065         if (EQUAL(poDriver->GetDescription(), "ESRI Shapefile") &&
3066             nLayerCount == 1 && psOptions->pszNewLayerName == nullptr &&
3067             VSIStatL(osDestFilename, &sStat) == 0 && VSI_ISREG(sStat.st_mode) &&
3068             (EQUAL(CPLGetExtension(osDestFilename), "shp") ||
3069              EQUAL(CPLGetExtension(osDestFilename), "shz") ||
3070              EQUAL(CPLGetExtension(osDestFilename), "dbf")) )
3071         {
3072             psOptions->pszNewLayerName = CPLStrdup(CPLGetBasename(osDestFilename));
3073         }
3074 
3075         std::vector<GIntBig> anLayerCountFeatures;
3076         anLayerCountFeatures.resize(nLayerCount);
3077         GIntBig nCountLayersFeatures = 0;
3078         GIntBig nAccCountFeatures = 0;
3079 
3080         /* First pass to apply filters and count all features if necessary */
3081         for( int iLayer = 0; iLayer < nLayerCount; iLayer++ )
3082         {
3083             OGRLayer        *poLayer = apoLayers[iLayer];
3084             if (poLayer == nullptr)
3085                 continue;
3086 
3087             if( psOptions->pszWHERE != nullptr )
3088             {
3089                 if( poLayer->SetAttributeFilter( psOptions->pszWHERE ) != OGRERR_NONE )
3090                 {
3091                     CPLError( CE_Failure, CPLE_AppDefined, "SetAttributeFilter(%s) on layer '%s' failed.",
3092                              psOptions->pszWHERE, poLayer->GetName() );
3093                     if (!psOptions->bSkipFailures)
3094                     {
3095                         GDALVectorTranslateOptionsFree(psOptions);
3096                         if( hDstDS == nullptr ) GDALClose( poODS );
3097                         delete poGCPCoordTrans;
3098                         return nullptr;
3099                     }
3100                 }
3101             }
3102 
3103             ApplySpatialFilter(poLayer, reinterpret_cast<OGRGeometry*>(psOptions->hSpatialFilter), poSpatSRS, psOptions->pszGeomField, poSourceSRS);
3104 
3105             if (psOptions->bDisplayProgress)
3106             {
3107                 if (!poLayer->TestCapability(OLCFastFeatureCount))
3108                 {
3109                     CPLError(CE_Warning, CPLE_NotSupported, "Progress turned off as fast feature count is not available.");
3110                     psOptions->bDisplayProgress = false;
3111                 }
3112                 else
3113                 {
3114                     anLayerCountFeatures[iLayer] = poLayer->GetFeatureCount();
3115                     nCountLayersFeatures += anLayerCountFeatures[iLayer];
3116                 }
3117             }
3118         }
3119 
3120         /* Second pass to do the real job */
3121         for( int iLayer = 0; iLayer < nLayerCount && nRetCode == 0; iLayer++ )
3122         {
3123             OGRLayer        *poLayer = apoLayers[iLayer];
3124             if (poLayer == nullptr)
3125                 continue;
3126 
3127             GDALProgressFunc pfnProgress = nullptr;
3128             void        *pProgressArg = nullptr;
3129 
3130             OGRLayer* poPassedLayer = poLayer;
3131             if (psOptions->bSplitListFields)
3132             {
3133                 auto poSLFLayer = new OGRSplitListFieldLayer(poPassedLayer, psOptions->nMaxSplitListSubFields);
3134                 poPassedLayer = poSLFLayer;
3135 
3136                 if (psOptions->bDisplayProgress && psOptions->nMaxSplitListSubFields != 1 &&
3137                     nCountLayersFeatures != 0)
3138                 {
3139                     pfnProgress = GDALScaledProgress;
3140                     pProgressArg =
3141                         GDALCreateScaledProgress(nAccCountFeatures * 1.0 / nCountLayersFeatures,
3142                                                 (nAccCountFeatures + anLayerCountFeatures[iLayer] / 2) * 1.0 / nCountLayersFeatures,
3143                                                 psOptions->pfnProgress,
3144                                                 psOptions->pProgressData);
3145                 }
3146                 else
3147                 {
3148                     pfnProgress = nullptr;
3149                     pProgressArg = nullptr;
3150                 }
3151 
3152                 int nRet = poSLFLayer->BuildLayerDefn(pfnProgress, pProgressArg);
3153                 if (!nRet)
3154                 {
3155                     delete poPassedLayer;
3156                     poPassedLayer = poLayer;
3157                 }
3158 
3159                 if (psOptions->bDisplayProgress)
3160                     GDALDestroyScaledProgress(pProgressArg);
3161                 pfnProgress = nullptr;
3162                 pProgressArg = nullptr;
3163             }
3164 
3165             if (psOptions->bDisplayProgress)
3166             {
3167                 if( nCountLayersFeatures != 0 )
3168                 {
3169                     pfnProgress = GDALScaledProgress;
3170                     GIntBig nStart = 0;
3171                     if (poPassedLayer != poLayer && psOptions->nMaxSplitListSubFields != 1)
3172                         nStart = anLayerCountFeatures[iLayer] / 2;
3173                     pProgressArg =
3174                         GDALCreateScaledProgress((nAccCountFeatures + nStart) * 1.0 / nCountLayersFeatures,
3175                                                 (nAccCountFeatures + anLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures,
3176                                                 psOptions->pfnProgress,
3177                                                 psOptions->pProgressData);
3178                 }
3179             }
3180 
3181             nAccCountFeatures += anLayerCountFeatures[iLayer];
3182 
3183             auto psInfo = oSetup.Setup(poPassedLayer,
3184                                                    psOptions->pszNewLayerName,
3185                                                    psOptions,
3186                                                    nTotalEventsDone);
3187 
3188             poPassedLayer->ResetReading();
3189 
3190             if( (psInfo == nullptr ||
3191                 !oTranslator.Translate( nullptr, psInfo.get(),
3192                                         anLayerCountFeatures[iLayer], nullptr,
3193                                         nTotalEventsDone,
3194                                         pfnProgress, pProgressArg, psOptions ))
3195                 && !psOptions->bSkipFailures )
3196             {
3197                 CPLError( CE_Failure, CPLE_AppDefined,
3198                         "Terminating translation prematurely after failed\n"
3199                         "translation of layer %s (use -skipfailures to skip errors)",
3200                         poLayer->GetName() );
3201 
3202                 nRetCode = 1;
3203             }
3204 
3205             if (poPassedLayer != poLayer)
3206                 delete poPassedLayer;
3207 
3208             if (psOptions->bDisplayProgress)
3209                 GDALDestroyScaledProgress(pProgressArg);
3210         }
3211     }
3212 /* -------------------------------------------------------------------- */
3213 /*      Process DS style table                                          */
3214 /* -------------------------------------------------------------------- */
3215 
3216     poODS->SetStyleTable( poDS->GetStyleTable () );
3217 
3218     if( psOptions->nGroupTransactions )
3219     {
3220         if( !psOptions->nLayerTransaction )
3221         {
3222             if( nRetCode != 0 && !psOptions->bSkipFailures )
3223                 poODS->RollbackTransaction();
3224             else
3225                 poODS->CommitTransaction();
3226         }
3227     }
3228 
3229     delete poGCPCoordTrans;
3230 
3231     GDALVectorTranslateOptionsFree(psOptions);
3232     if(nRetCode == 0)
3233         return static_cast<GDALDatasetH>(poODS);
3234 
3235     if( hDstDS == nullptr ) GDALClose( poODS );
3236     return nullptr;
3237 }
3238 
3239 /************************************************************************/
3240 /*                               SetZ()                                 */
3241 /************************************************************************/
3242 
3243 namespace {
3244 class SetZVisitor: public OGRDefaultGeometryVisitor
3245 {
3246         double m_dfZ;
3247 
3248     public:
SetZVisitor(double dfZ)3249         explicit SetZVisitor(double dfZ): m_dfZ(dfZ) {}
3250 
3251         using OGRDefaultGeometryVisitor::visit;
3252 
visit(OGRPoint * poPoint)3253         void visit(OGRPoint* poPoint) override
3254         {
3255             poPoint->setZ(m_dfZ);
3256         }
3257 };
3258 }
3259 
SetZ(OGRGeometry * poGeom,double dfZ)3260 static void SetZ (OGRGeometry* poGeom, double dfZ )
3261 {
3262     if (poGeom == nullptr)
3263         return;
3264     SetZVisitor visitor(dfZ);
3265     poGeom->set3D(true);
3266     poGeom->accept(&visitor);
3267 }
3268 
3269 /************************************************************************/
3270 /*                       ForceCoordDimension()                          */
3271 /************************************************************************/
3272 
ForceCoordDimension(int eGType,int nCoordDim)3273 static int ForceCoordDimension(int eGType, int nCoordDim)
3274 {
3275     if( nCoordDim == 2 && eGType != wkbNone )
3276         return wkbFlatten(eGType);
3277     else if( nCoordDim == 3 && eGType != wkbNone )
3278         return wkbSetZ(wkbFlatten(eGType));
3279     else if( nCoordDim == COORD_DIM_XYM && eGType != wkbNone )
3280         return wkbSetM(wkbFlatten(eGType));
3281     else if( nCoordDim == 4 && eGType != wkbNone )
3282         return OGR_GT_SetModifier(static_cast<OGRwkbGeometryType>(eGType), TRUE, TRUE);
3283     else
3284         return eGType;
3285 }
3286 
3287 /************************************************************************/
3288 /*                   GetLayerAndOverwriteIfNecessary()                  */
3289 /************************************************************************/
3290 
GetLayerAndOverwriteIfNecessary(GDALDataset * poDstDS,const char * pszNewLayerName,bool bOverwrite,bool * pbErrorOccurred,bool * pbOverwriteActuallyDone,bool * pbAddOverwriteLCO)3291 static OGRLayer* GetLayerAndOverwriteIfNecessary(GDALDataset *poDstDS,
3292                                                  const char* pszNewLayerName,
3293                                                  bool bOverwrite,
3294                                                  bool* pbErrorOccurred,
3295                                                  bool* pbOverwriteActuallyDone,
3296                                                  bool* pbAddOverwriteLCO)
3297 {
3298     if( pbErrorOccurred )
3299         *pbErrorOccurred = false;
3300     if( pbOverwriteActuallyDone )
3301         *pbOverwriteActuallyDone = false;
3302     if( pbAddOverwriteLCO )
3303         *pbAddOverwriteLCO = false;
3304 
3305     /* GetLayerByName() can instantiate layers that would have been */
3306     /* 'hidden' otherwise, for example, non-spatial tables in a */
3307     /* PostGIS-enabled database, so this apparently useless command is */
3308     /* not useless. (#4012) */
3309     CPLPushErrorHandler(CPLQuietErrorHandler);
3310     OGRLayer* poDstLayer = poDstDS->GetLayerByName(pszNewLayerName);
3311     CPLPopErrorHandler();
3312     CPLErrorReset();
3313 
3314     int iLayer = -1;
3315     if (poDstLayer != nullptr)
3316     {
3317         const int nLayerCount = poDstDS->GetLayerCount();
3318         for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
3319         {
3320             OGRLayer        *poLayer = poDstDS->GetLayer(iLayer);
3321             if (poLayer == poDstLayer)
3322                 break;
3323         }
3324 
3325         if (iLayer == nLayerCount)
3326             /* should not happen with an ideal driver */
3327             poDstLayer = nullptr;
3328     }
3329 
3330 /* -------------------------------------------------------------------- */
3331 /*      If the user requested overwrite, and we have the layer in       */
3332 /*      question we need to delete it now so it will get recreated      */
3333 /*      (overwritten).                                                  */
3334 /* -------------------------------------------------------------------- */
3335     if( poDstLayer != nullptr && bOverwrite )
3336     {
3337         /* When using the CARTO driver we don't want to delete the layer if */
3338         /* it's going to be recreated. Instead we mark it to be overwritten */
3339         /* when the new creation is requested */
3340         if ( poDstDS->GetDriver()->GetMetadataItem(
3341                 GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3342              strstr(poDstDS->GetDriver()->GetMetadataItem(
3343                 GDAL_DS_LAYER_CREATIONOPTIONLIST), "CARTODBFY") != nullptr )
3344         {
3345             if ( pbAddOverwriteLCO )
3346                 *pbAddOverwriteLCO = true;
3347             if( pbOverwriteActuallyDone )
3348                 *pbOverwriteActuallyDone = true;
3349 
3350         } else if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
3351         {
3352             CPLError( CE_Failure, CPLE_AppDefined,
3353                      "DeleteLayer() failed when overwrite requested." );
3354             if( pbErrorOccurred )
3355                 *pbErrorOccurred = true;
3356         }
3357         else
3358         {
3359             if( pbOverwriteActuallyDone )
3360                 *pbOverwriteActuallyDone = true;
3361         }
3362         poDstLayer = nullptr;
3363     }
3364 
3365     return poDstLayer;
3366 }
3367 
3368 /************************************************************************/
3369 /*                          ConvertType()                               */
3370 /************************************************************************/
3371 
ConvertType(GeomTypeConversion eGeomTypeConversion,OGRwkbGeometryType eGType)3372 static OGRwkbGeometryType ConvertType(GeomTypeConversion eGeomTypeConversion,
3373                                       OGRwkbGeometryType eGType)
3374 {
3375     OGRwkbGeometryType eRetType = eGType;
3376 
3377     if ( eGeomTypeConversion == GTC_CONVERT_TO_LINEAR ||
3378          eGeomTypeConversion == GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR )
3379     {
3380         eRetType = OGR_GT_GetLinear(eRetType);
3381     }
3382 
3383     if ( eGeomTypeConversion == GTC_PROMOTE_TO_MULTI ||
3384          eGeomTypeConversion == GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR )
3385     {
3386         if( eRetType == wkbTriangle || eRetType == wkbTIN ||
3387             eRetType == wkbPolyhedralSurface )
3388         {
3389             eRetType = wkbMultiPolygon;
3390         }
3391         else if( !OGR_GT_IsSubClassOf(eRetType, wkbGeometryCollection) )
3392         {
3393             eRetType = OGR_GT_GetCollection(eRetType);
3394         }
3395     }
3396 
3397     if ( eGeomTypeConversion == GTC_CONVERT_TO_CURVE )
3398         eRetType = OGR_GT_GetCurve(eRetType);
3399 
3400     return eRetType;
3401 }
3402 
3403 /************************************************************************/
3404 /*                        DoFieldTypeConversion()                       */
3405 /************************************************************************/
3406 
3407 static
DoFieldTypeConversion(GDALDataset * poDstDS,OGRFieldDefn & oFieldDefn,char ** papszFieldTypesToString,char ** papszMapFieldType,bool bUnsetFieldWidth,bool bQuiet,bool bForceNullable,bool bUnsetDefault)3408 void DoFieldTypeConversion(GDALDataset* poDstDS, OGRFieldDefn& oFieldDefn,
3409                            char** papszFieldTypesToString,
3410                            char** papszMapFieldType,
3411                            bool bUnsetFieldWidth,
3412                            bool bQuiet,
3413                            bool bForceNullable,
3414                            bool bUnsetDefault)
3415 {
3416     if (papszFieldTypesToString != nullptr )
3417     {
3418         CPLString osLookupString;
3419         osLookupString.Printf("%s(%s)",
3420                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()),
3421                         OGRFieldDefn::GetFieldSubTypeName(oFieldDefn.GetSubType()));
3422 
3423         int iIdx = CSLFindString(papszFieldTypesToString, osLookupString);
3424         if( iIdx < 0 )
3425             iIdx = CSLFindString(papszFieldTypesToString,
3426                                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()));
3427         if( iIdx < 0 )
3428             iIdx = CSLFindString(papszFieldTypesToString, "All");
3429         if( iIdx >= 0 )
3430         {
3431             oFieldDefn.SetSubType(OFSTNone);
3432             oFieldDefn.SetType(OFTString);
3433         }
3434     }
3435     else if (papszMapFieldType != nullptr)
3436     {
3437         CPLString osLookupString;
3438         osLookupString.Printf("%s(%s)",
3439                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()),
3440                         OGRFieldDefn::GetFieldSubTypeName(oFieldDefn.GetSubType()));
3441 
3442         const char* pszType = CSLFetchNameValue(papszMapFieldType, osLookupString);
3443         if( pszType == nullptr )
3444             pszType = CSLFetchNameValue(papszMapFieldType,
3445                                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()));
3446         if( pszType == nullptr )
3447             pszType = CSLFetchNameValue(papszMapFieldType, "All");
3448         if( pszType != nullptr )
3449         {
3450             int iSubType;
3451             int iType = GetFieldType(pszType, &iSubType);
3452             if( iType >= 0 && iSubType >= 0 )
3453             {
3454                 oFieldDefn.SetSubType(OFSTNone);
3455                 oFieldDefn.SetType(static_cast<OGRFieldType>(iType));
3456                 oFieldDefn.SetSubType(static_cast<OGRFieldSubType>(iSubType));
3457                 if( iType == OFTInteger )
3458                     oFieldDefn.SetWidth(0);
3459             }
3460         }
3461     }
3462     if( bUnsetFieldWidth )
3463     {
3464         oFieldDefn.SetWidth(0);
3465         oFieldDefn.SetPrecision(0);
3466     }
3467     if( bForceNullable )
3468         oFieldDefn.SetNullable(TRUE);
3469     if( bUnsetDefault )
3470         oFieldDefn.SetDefault(nullptr);
3471 
3472     if( poDstDS->GetDriver() != nullptr &&
3473         poDstDS->GetDriver()->GetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES) != nullptr &&
3474         strstr(poDstDS->GetDriver()->GetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES),
3475                 OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType())) == nullptr )
3476     {
3477         if( oFieldDefn.GetType() == OFTInteger64 )
3478         {
3479             if( !bQuiet )
3480             {
3481                 CPLError(CE_Warning, CPLE_AppDefined,
3482                         "The output driver does not seem to natively support %s "
3483                         "type for field %s. Converting it to Real instead. "
3484                         "-mapFieldType can be used to control field type conversion.",
3485                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()),
3486                         oFieldDefn.GetNameRef());
3487             }
3488             oFieldDefn.SetType(OFTReal);
3489         }
3490         else if( !bQuiet )
3491         {
3492             CPLError(CE_Warning, CPLE_AppDefined,
3493                         "The output driver does not natively support %s type for "
3494                         "field %s. Misconversion can happen. "
3495                         "-mapFieldType can be used to control field type conversion.",
3496                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()),
3497                         oFieldDefn.GetNameRef());
3498         }
3499     }
3500     else if( poDstDS->GetDriver() != nullptr &&
3501              poDstDS->GetDriver()->GetMetadataItem(GDAL_DMD_CREATIONFIELDDATATYPES) == nullptr )
3502     {
3503         // All drivers supporting OFTInteger64 should advertise it theoretically
3504         if( oFieldDefn.GetType() == OFTInteger64 )
3505         {
3506             if( !bQuiet )
3507             {
3508                 CPLError(CE_Warning, CPLE_AppDefined,
3509                         "The output driver does not seem to natively support %s type "
3510                         "for field %s. Converting it to Real instead. "
3511                         "-mapFieldType can be used to control field type conversion.",
3512                         OGRFieldDefn::GetFieldTypeName(oFieldDefn.GetType()),
3513                         oFieldDefn.GetNameRef());
3514             }
3515             oFieldDefn.SetType(OFTReal);
3516         }
3517     }
3518 }
3519 
3520 /************************************************************************/
3521 /*                   SetupTargetLayer::Setup()                          */
3522 /************************************************************************/
3523 
Setup(OGRLayer * poSrcLayer,const char * pszNewLayerName,GDALVectorTranslateOptions * psOptions,GIntBig & nTotalEventsDone)3524 std::unique_ptr<TargetLayerInfo> SetupTargetLayer::Setup(OGRLayer* poSrcLayer,
3525                                          const char* pszNewLayerName,
3526                                          GDALVectorTranslateOptions *psOptions,
3527                                          GIntBig& nTotalEventsDone)
3528 {
3529     int eGType = m_eGType;
3530     bool bPreserveFID = m_bPreserveFID;
3531     bool bAppend = m_bAppend;
3532 
3533     if( pszNewLayerName == nullptr )
3534         pszNewLayerName = poSrcLayer->GetName();
3535 
3536 /* -------------------------------------------------------------------- */
3537 /*      Get other info.                                                 */
3538 /* -------------------------------------------------------------------- */
3539     OGRFeatureDefn *poSrcFDefn = poSrcLayer->GetLayerDefn();
3540 
3541 /* -------------------------------------------------------------------- */
3542 /*      Find requested geometry fields.                                 */
3543 /* -------------------------------------------------------------------- */
3544     std::vector<int> anRequestedGeomFields;
3545     const int nSrcGeomFieldCount = poSrcFDefn->GetGeomFieldCount();
3546     if (m_papszSelFields && !bAppend )
3547     {
3548         for( int iField=0; m_papszSelFields[iField] != nullptr; iField++)
3549         {
3550             int iSrcField = poSrcFDefn->GetFieldIndex(m_papszSelFields[iField]);
3551             if (iSrcField >= 0)
3552             {
3553                 /* do nothing */
3554             }
3555             else
3556             {
3557                 iSrcField = poSrcFDefn->GetGeomFieldIndex(m_papszSelFields[iField]);
3558                 if( iSrcField >= 0)
3559                 {
3560                     anRequestedGeomFields.push_back(iSrcField);
3561                 }
3562                 else
3563                 {
3564                     CPLError( CE_Failure, CPLE_AppDefined, "Field '%s' not found in source layer.",
3565                               m_papszSelFields[iField] );
3566                     if( !psOptions->bSkipFailures )
3567                         return nullptr;
3568                 }
3569             }
3570         }
3571 
3572         if( anRequestedGeomFields.size() > 1 &&
3573             !m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) )
3574         {
3575             CPLError( CE_Failure, CPLE_AppDefined, "Several geometry fields requested, but output "
3576                                 "datasource does not support multiple geometry "
3577                                 "fields." );
3578             if( !psOptions->bSkipFailures )
3579                 return nullptr;
3580             else
3581                 anRequestedGeomFields.resize(0);
3582         }
3583     }
3584 
3585     OGRSpatialReference* poOutputSRS = m_poOutputSRS;
3586     if( poOutputSRS == nullptr && !m_bNullifyOutputSRS )
3587     {
3588         if( nSrcGeomFieldCount == 1 || anRequestedGeomFields.empty() )
3589             poOutputSRS = poSrcLayer->GetSpatialRef();
3590         else if( anRequestedGeomFields.size() == 1 )
3591         {
3592             int iSrcGeomField = anRequestedGeomFields[0];
3593             poOutputSRS = poSrcFDefn->GetGeomFieldDefn(iSrcGeomField)->
3594                 GetSpatialRef();
3595         }
3596     }
3597 
3598     int iSrcZField = -1;
3599     if (m_pszZField != nullptr)
3600     {
3601         iSrcZField = poSrcFDefn->GetFieldIndex(m_pszZField);
3602         if( iSrcZField < 0 )
3603         {
3604             CPLError(CE_Warning, CPLE_AppDefined,
3605                      "zfield '%s' does not exist in layer %s",
3606                      m_pszZField, poSrcLayer->GetName());
3607         }
3608     }
3609 
3610 /* -------------------------------------------------------------------- */
3611 /*      Find the layer.                                                 */
3612 /* -------------------------------------------------------------------- */
3613 
3614     bool bErrorOccurred;
3615     bool bOverwriteActuallyDone;
3616     bool bAddOverwriteLCO;
3617     OGRLayer *poDstLayer =
3618         GetLayerAndOverwriteIfNecessary(m_poDstDS,
3619                                         pszNewLayerName,
3620                                         m_bOverwrite,
3621                                         &bErrorOccurred,
3622                                         &bOverwriteActuallyDone,
3623                                         &bAddOverwriteLCO);
3624     if( bErrorOccurred )
3625         return nullptr;
3626 
3627 /* -------------------------------------------------------------------- */
3628 /*      If the layer does not exist, then create it.                    */
3629 /* -------------------------------------------------------------------- */
3630     if( poDstLayer == nullptr )
3631     {
3632         if( !m_poDstDS->TestCapability( ODsCCreateLayer ) )
3633         {
3634             CPLError( CE_Failure, CPLE_AppDefined,
3635                       "Layer '%s' does not already exist in the output dataset, and "
3636                       "cannot be created by the output driver.",
3637                       pszNewLayerName );
3638             return nullptr;
3639         }
3640 
3641         bool bForceGType = ( eGType != GEOMTYPE_UNCHANGED );
3642         if( !bForceGType )
3643         {
3644             if( anRequestedGeomFields.empty() )
3645             {
3646                 eGType = poSrcFDefn->GetGeomType();
3647             }
3648             else if( anRequestedGeomFields.size() == 1  )
3649             {
3650                 int iSrcGeomField = anRequestedGeomFields[0];
3651                 eGType = poSrcFDefn->GetGeomFieldDefn(iSrcGeomField)->GetType();
3652             }
3653             else
3654             {
3655                 eGType = wkbNone;
3656             }
3657 
3658             bool bHasZ = CPL_TO_BOOL(wkbHasZ(static_cast<OGRwkbGeometryType>(eGType)));
3659             eGType = ConvertType(m_eGeomTypeConversion, static_cast<OGRwkbGeometryType>(eGType));
3660 
3661             if ( m_bExplodeCollections )
3662             {
3663                 const OGRwkbGeometryType eFGType = wkbFlatten(eGType);
3664                 if (eFGType == wkbMultiPoint)
3665                 {
3666                     eGType = wkbPoint;
3667                 }
3668                 else if (eFGType == wkbMultiLineString)
3669                 {
3670                     eGType = wkbLineString;
3671                 }
3672                 else if (eFGType == wkbMultiPolygon)
3673                 {
3674                     eGType = wkbPolygon;
3675                 }
3676                 else if (eFGType == wkbGeometryCollection ||
3677                          eFGType == wkbMultiCurve ||
3678                          eFGType == wkbMultiSurface)
3679                 {
3680                     eGType = wkbUnknown;
3681                 }
3682             }
3683 
3684             if ( bHasZ || (iSrcZField >= 0 && eGType != wkbNone) )
3685                 eGType = wkbSetZ(static_cast<OGRwkbGeometryType>(eGType));
3686         }
3687 
3688         eGType = ForceCoordDimension(eGType, m_nCoordDim);
3689 
3690         CPLErrorReset();
3691 
3692         char** papszLCOTemp = CSLDuplicate(m_papszLCO);
3693 
3694         int eGCreateLayerType = eGType;
3695         if( anRequestedGeomFields.empty() &&
3696             nSrcGeomFieldCount > 1 &&
3697             m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) )
3698         {
3699             eGCreateLayerType = wkbNone;
3700         }
3701         // If the source layer has a single geometry column that is not nullable
3702         // and that ODsCCreateGeomFieldAfterCreateLayer is available, use it
3703         // so as to be able to set the not null constraint (if the driver supports it)
3704         // Same if the source geometry column has a non empty name that is not
3705         // overridden
3706         else if( eGType != wkbNone &&
3707                  anRequestedGeomFields.empty() &&
3708                  nSrcGeomFieldCount == 1 &&
3709                  m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) &&
3710                  ((!poSrcFDefn->GetGeomFieldDefn(0)->IsNullable() &&
3711                    CSLFetchNameValue(m_papszLCO, "GEOMETRY_NULLABLE") == nullptr &&
3712                    !m_bForceNullable) ||
3713                   (poSrcLayer->GetGeometryColumn() != nullptr &&
3714                    CSLFetchNameValue(m_papszLCO, "GEOMETRY_NAME") == nullptr &&
3715                    !EQUAL(poSrcLayer->GetGeometryColumn(), "") &&
3716                    poSrcFDefn->GetFieldIndex(poSrcLayer->GetGeometryColumn()) < 0)) )
3717         {
3718             anRequestedGeomFields.push_back(0);
3719             eGCreateLayerType = wkbNone;
3720         }
3721         else if( anRequestedGeomFields.size() == 1 &&
3722                  m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) )
3723         {
3724             eGCreateLayerType = wkbNone;
3725         }
3726 
3727         // If the source feature first geometry column is not nullable
3728         // and that GEOMETRY_NULLABLE creation option is available, use it
3729         // so as to be able to set the not null constraint (if the driver supports it)
3730         if( eGType != wkbNone &&
3731             anRequestedGeomFields.empty() &&
3732             nSrcGeomFieldCount >= 1 &&
3733             !poSrcFDefn->GetGeomFieldDefn(0)->IsNullable() &&
3734             m_poDstDS->GetDriver()->GetMetadataItem(
3735                 GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3736             strstr(m_poDstDS->GetDriver()->GetMetadataItem(
3737                 GDAL_DS_LAYER_CREATIONOPTIONLIST), "GEOMETRY_NULLABLE") != nullptr &&
3738             CSLFetchNameValue(m_papszLCO, "GEOMETRY_NULLABLE") == nullptr &&
3739             !m_bForceNullable )
3740         {
3741             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "GEOMETRY_NULLABLE", "NO");
3742             CPLDebug("GDALVectorTranslate", "Using GEOMETRY_NULLABLE=NO");
3743         }
3744 
3745         // Use source geometry field name as much as possible
3746         if( eGType != wkbNone &&
3747             m_poDstDS->GetDriver()->GetMetadataItem(
3748                 GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3749             strstr(m_poDstDS->GetDriver()->GetMetadataItem(
3750                 GDAL_DS_LAYER_CREATIONOPTIONLIST), "GEOMETRY_NAME") != nullptr &&
3751             CSLFetchNameValue(m_papszLCO, "GEOMETRY_NAME") == nullptr )
3752         {
3753             int iSrcGeomField = -1;
3754             if( anRequestedGeomFields.empty() &&
3755                 (nSrcGeomFieldCount == 1 ||
3756                  (!m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) &&
3757                   nSrcGeomFieldCount > 1) ) )
3758             {
3759                 iSrcGeomField = 0;
3760             }
3761             else if( anRequestedGeomFields.size() == 1 )
3762             {
3763                 iSrcGeomField = anRequestedGeomFields[0];
3764             }
3765 
3766             if( iSrcGeomField >= 0 )
3767             {
3768                 const char* pszGFldName = poSrcFDefn->GetGeomFieldDefn(
3769                                                 iSrcGeomField)->GetNameRef();
3770                 if( pszGFldName != nullptr && !EQUAL(pszGFldName, "") &&
3771                     poSrcFDefn->GetFieldIndex(pszGFldName) < 0 )
3772                 {
3773                     papszLCOTemp = CSLSetNameValue(papszLCOTemp,
3774                                                 "GEOMETRY_NAME", pszGFldName);
3775                 }
3776             }
3777         }
3778 
3779         // Force FID column as 64 bit if the source feature has a 64 bit FID,
3780         // the target driver supports 64 bit FID and the user didn't set it
3781         // manually.
3782         if( poSrcLayer->GetMetadataItem(OLMD_FID64) != nullptr &&
3783             EQUAL(poSrcLayer->GetMetadataItem(OLMD_FID64), "YES") &&
3784             m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3785             strstr(m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST), "FID64") != nullptr &&
3786             CSLFetchNameValue(m_papszLCO, "FID64") == nullptr )
3787         {
3788             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "FID64", "YES");
3789             CPLDebug("GDALVectorTranslate", "Using FID64=YES");
3790         }
3791 
3792         // If output driver supports FID layer creation option, set it with
3793         // the FID column name of the source layer
3794         if( !m_bUnsetFid && !bAppend &&
3795             poSrcLayer->GetFIDColumn() != nullptr &&
3796             !EQUAL(poSrcLayer->GetFIDColumn(), "") &&
3797             m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3798             strstr(m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST), "='FID'") != nullptr &&
3799             CSLFetchNameValue(m_papszLCO, "FID") == nullptr )
3800         {
3801             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "FID", poSrcLayer->GetFIDColumn());
3802             CPLDebug("GDALVectorTranslate", "Using FID=%s and -preserve_fid", poSrcLayer->GetFIDColumn());
3803             bPreserveFID = true;
3804         }
3805 
3806         // If bAddOverwriteLCO is ON (set up when overwriting a CARTO layer),
3807         // set OVERWRITE to YES so the new layer overwrites the old one
3808         if (bAddOverwriteLCO)
3809         {
3810             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "OVERWRITE", "ON");
3811             CPLDebug("GDALVectorTranslate", "Using OVERWRITE=ON");
3812         }
3813 
3814         if( m_bNativeData &&
3815             poSrcLayer->GetMetadataItem("NATIVE_DATA", "NATIVE_DATA") != nullptr &&
3816             poSrcLayer->GetMetadataItem("NATIVE_MEDIA_TYPE", "NATIVE_DATA") != nullptr &&
3817             m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST) != nullptr &&
3818             strstr(m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST), "NATIVE_DATA") != nullptr &&
3819             strstr(m_poDstDS->GetDriver()->GetMetadataItem(GDAL_DS_LAYER_CREATIONOPTIONLIST), "NATIVE_MEDIA_TYPE") != nullptr )
3820         {
3821             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "NATIVE_DATA",
3822                     poSrcLayer->GetMetadataItem("NATIVE_DATA", "NATIVE_DATA"));
3823             papszLCOTemp = CSLSetNameValue(papszLCOTemp, "NATIVE_MEDIA_TYPE",
3824                     poSrcLayer->GetMetadataItem("NATIVE_MEDIA_TYPE", "NATIVE_DATA"));
3825             CPLDebug("GDALVectorTranslate", "Transferring layer NATIVE_DATA");
3826         }
3827 
3828         OGRSpatialReference* poOutputSRSClone = nullptr;
3829         if( poOutputSRS != nullptr )
3830         {
3831             poOutputSRSClone = poOutputSRS->Clone();
3832         }
3833         poDstLayer = m_poDstDS->CreateLayer( pszNewLayerName, poOutputSRSClone,
3834                                            static_cast<OGRwkbGeometryType>(eGCreateLayerType),
3835                                            papszLCOTemp );
3836         CSLDestroy(papszLCOTemp);
3837 
3838         if( poOutputSRSClone != nullptr )
3839         {
3840             poOutputSRSClone->Release();
3841         }
3842 
3843         if( poDstLayer == nullptr )
3844         {
3845             return nullptr;
3846         }
3847 
3848         if( m_bCopyMD )
3849         {
3850             char** papszDomains = poSrcLayer->GetMetadataDomainList();
3851             for(char** papszIter = papszDomains; papszIter && *papszIter; ++papszIter )
3852             {
3853                 if( !EQUAL(*papszIter, "IMAGE_STRUCTURE") &&
3854                     !EQUAL(*papszIter, "SUBDATASETS") )
3855                 {
3856                     char** papszMD = poSrcLayer->GetMetadata(*papszIter);
3857                     if( papszMD )
3858                         poDstLayer->SetMetadata(papszMD, *papszIter);
3859                 }
3860             }
3861             CSLDestroy(papszDomains);
3862         }
3863 
3864         if( anRequestedGeomFields.empty() &&
3865             nSrcGeomFieldCount > 1 &&
3866             m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer) )
3867         {
3868             for(int i = 0; i < nSrcGeomFieldCount; i ++)
3869             {
3870                 anRequestedGeomFields.push_back(i);
3871             }
3872         }
3873 
3874         if( anRequestedGeomFields.size() > 1 ||
3875             (anRequestedGeomFields.size() == 1 &&
3876                  m_poDstDS->TestCapability(ODsCCreateGeomFieldAfterCreateLayer)) )
3877         {
3878           for( int i = 0; i < static_cast<int>(anRequestedGeomFields.size());
3879                i++ )
3880             {
3881                 const int iSrcGeomField = anRequestedGeomFields[i];
3882                 OGRGeomFieldDefn oGFldDefn
3883                     (poSrcFDefn->GetGeomFieldDefn(iSrcGeomField));
3884                 if( m_poOutputSRS != nullptr )
3885                 {
3886                     poOutputSRSClone = m_poOutputSRS->Clone();
3887                     oGFldDefn.SetSpatialRef(poOutputSRSClone);
3888                     poOutputSRSClone->Release();
3889                 }
3890                 if( bForceGType )
3891                 {
3892                     oGFldDefn.SetType(static_cast<OGRwkbGeometryType>(eGType));
3893                 }
3894                 else
3895                 {
3896                     eGType = oGFldDefn.GetType();
3897                     eGType = ConvertType(
3898                         m_eGeomTypeConversion,
3899                         static_cast<OGRwkbGeometryType>(eGType));
3900                     eGType = ForceCoordDimension(eGType, m_nCoordDim);
3901                     oGFldDefn.SetType(static_cast<OGRwkbGeometryType>(eGType));
3902                 }
3903                 if( m_bForceNullable )
3904                     oGFldDefn.SetNullable(TRUE);
3905                 poDstLayer->CreateGeomField(&oGFldDefn);
3906             }
3907         }
3908 
3909         bAppend = false;
3910     }
3911 
3912 /* -------------------------------------------------------------------- */
3913 /*      Otherwise we will append to it, if append was requested.        */
3914 /* -------------------------------------------------------------------- */
3915     else if( !bAppend && !m_bNewDataSource )
3916     {
3917         CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, and -append not specified.\n"
3918                          "        Consider using -append, or -overwrite.",
3919                 pszNewLayerName );
3920         return nullptr;
3921     }
3922     else
3923     {
3924         if( CSLCount(m_papszLCO) > 0 )
3925         {
3926             CPLError( CE_Warning, CPLE_AppDefined, "Layer creation options ignored since an existing layer is\n"
3927                                                   "         being appended to." );
3928         }
3929     }
3930 
3931 /* -------------------------------------------------------------------- */
3932 /*      Process Layer style table                                       */
3933 /* -------------------------------------------------------------------- */
3934 
3935     poDstLayer->SetStyleTable( poSrcLayer->GetStyleTable () );
3936 /* -------------------------------------------------------------------- */
3937 /*      Add fields.  Default to copy all field.                         */
3938 /*      If only a subset of all fields requested, then output only      */
3939 /*      the selected fields, and in the order that they were            */
3940 /*      selected.                                                       */
3941 /* -------------------------------------------------------------------- */
3942     const int nSrcFieldCount = poSrcFDefn->GetFieldCount();
3943     int         iSrcFIDField = -1;
3944 
3945     // Initialize the index-to-index map to -1's
3946     std::vector<int> anMap(nSrcFieldCount, -1);
3947 
3948     std::map<int, TargetLayerInfo::ResolvedInfo> oMapResolved;
3949 
3950     /* Caution : at the time of writing, the MapInfo driver */
3951     /* returns NULL until a field has been added */
3952     OGRFeatureDefn *poDstFDefn = poDstLayer->GetLayerDefn();
3953 
3954     if (m_papszFieldMap && bAppend)
3955     {
3956         bool bIdentity = false;
3957 
3958         if (EQUAL(m_papszFieldMap[0], "identity"))
3959             bIdentity = true;
3960         else if (CSLCount(m_papszFieldMap) != nSrcFieldCount)
3961         {
3962             CPLError( CE_Failure, CPLE_AppDefined, "Field map should contain the value 'identity' or "
3963                     "the same number of integer values as the source field count.");
3964             return nullptr;
3965         }
3966 
3967         for( int iField=0; iField < nSrcFieldCount; iField++)
3968         {
3969             anMap[iField] = bIdentity? iField : atoi(m_papszFieldMap[iField]);
3970             if (anMap[iField] >= poDstFDefn->GetFieldCount())
3971             {
3972                 CPLError( CE_Failure, CPLE_AppDefined, "Invalid destination field index %d.", anMap[iField]);
3973                 return nullptr;
3974             }
3975         }
3976     }
3977     else if (m_papszSelFields && !bAppend )
3978     {
3979         int nDstFieldCount = poDstFDefn ? poDstFDefn->GetFieldCount() : 0;
3980         for( int iField=0; m_papszSelFields[iField] != nullptr; iField++)
3981         {
3982             const int iSrcField =
3983                 poSrcFDefn->GetFieldIndex(m_papszSelFields[iField]);
3984             if (iSrcField >= 0)
3985             {
3986                 OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iSrcField);
3987                 OGRFieldDefn oFieldDefn( poSrcFieldDefn );
3988 
3989                 DoFieldTypeConversion(m_poDstDS, oFieldDefn,
3990                                       m_papszFieldTypesToString,
3991                                       m_papszMapFieldType,
3992                                       m_bUnsetFieldWidth,
3993                                       psOptions->bQuiet,
3994                                       m_bForceNullable,
3995                                       m_bUnsetDefault);
3996 
3997                 /* The field may have been already created at layer creation */
3998                 const int iDstField =
3999                     poDstFDefn
4000                     ? poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef())
4001                     : -1;
4002                 if (iDstField >= 0)
4003                 {
4004                     anMap[iSrcField] = iDstField;
4005                 }
4006                 else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
4007                 {
4008                     /* now that we've created a field, GetLayerDefn() won't return NULL */
4009                     if (poDstFDefn == nullptr)
4010                         poDstFDefn = poDstLayer->GetLayerDefn();
4011 
4012                     /* Sanity check : if it fails, the driver is buggy */
4013                     if (poDstFDefn != nullptr &&
4014                         poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
4015                     {
4016                         CPLError(CE_Warning, CPLE_AppDefined,
4017                                  "The output driver has claimed to have added the %s field, but it did not!",
4018                                  oFieldDefn.GetNameRef() );
4019                     }
4020                     else
4021                     {
4022                         anMap[iSrcField] = nDstFieldCount;
4023                         nDstFieldCount ++;
4024                     }
4025                 }
4026             }
4027         }
4028 
4029         /* -------------------------------------------------------------------- */
4030         /* Use SetIgnoredFields() on source layer if available                  */
4031         /* -------------------------------------------------------------------- */
4032         if (poSrcLayer->TestCapability(OLCIgnoreFields))
4033         {
4034             bool bUseIgnoredFields = true;
4035             char** papszWHEREUsedFields = nullptr;
4036 
4037             if (m_pszWHERE)
4038             {
4039                 /* We must not ignore fields used in the -where expression (#4015) */
4040                 OGRFeatureQuery oFeatureQuery;
4041                 if ( oFeatureQuery.Compile( poSrcLayer->GetLayerDefn(), m_pszWHERE, FALSE, nullptr ) == OGRERR_NONE )
4042                 {
4043                     papszWHEREUsedFields = oFeatureQuery.GetUsedFields();
4044                 }
4045                 else
4046                 {
4047                     bUseIgnoredFields = false;
4048                 }
4049             }
4050 
4051             char** papszIgnoredFields = nullptr;
4052 
4053             for(int iSrcField=0;
4054                 bUseIgnoredFields && iSrcField<poSrcFDefn->GetFieldCount();
4055                 iSrcField++)
4056             {
4057                 const char* pszFieldName =
4058                     poSrcFDefn->GetFieldDefn(iSrcField)->GetNameRef();
4059                 bool bFieldRequested = false;
4060                 for( int iField=0; m_papszSelFields[iField] != nullptr; iField++)
4061                 {
4062                     if (EQUAL(pszFieldName, m_papszSelFields[iField]))
4063                     {
4064                         bFieldRequested = true;
4065                         break;
4066                     }
4067                 }
4068                 bFieldRequested |= CSLFindString(papszWHEREUsedFields, pszFieldName) >= 0;
4069                 bFieldRequested |= (m_pszZField != nullptr && EQUAL(pszFieldName, m_pszZField));
4070 
4071                 /* If source field not requested, add it to ignored files list */
4072                 if (!bFieldRequested)
4073                     papszIgnoredFields = CSLAddString(papszIgnoredFields, pszFieldName);
4074             }
4075             if (bUseIgnoredFields)
4076                 poSrcLayer->SetIgnoredFields(const_cast<const char**>(papszIgnoredFields));
4077             CSLDestroy(papszIgnoredFields);
4078             CSLDestroy(papszWHEREUsedFields);
4079         }
4080     }
4081     else if( !bAppend || m_bAddMissingFields )
4082     {
4083         int nDstFieldCount = poDstFDefn ? poDstFDefn->GetFieldCount() : 0;
4084 
4085         const bool caseInsensitive =
4086             !EQUAL(m_poDstDS->GetDriver()->GetDescription(), "GeoJSON");
4087         auto formatName = [caseInsensitive](const char* name) {
4088             if( caseInsensitive ) {
4089                 return CPLString(name).toupper();
4090             } else {
4091                 return CPLString(name);
4092             }
4093         };
4094 
4095         /* Save the map of existing fields, before creating new ones */
4096         /* This helps when converting a source layer that has duplicated field names */
4097         /* which is a bad idea */
4098         std::map<CPLString, int> oMapPreExistingFields;
4099         std::unordered_set<std::string> oSetDstFieldNames;
4100         for( int iField = 0; iField < nDstFieldCount; iField++ )
4101         {
4102             const char* pszFieldName = poDstFDefn->GetFieldDefn(iField)->GetNameRef();
4103             CPLString osUpperFieldName(formatName(pszFieldName));
4104             oSetDstFieldNames.insert(osUpperFieldName);
4105             if( oMapPreExistingFields.find(osUpperFieldName) ==
4106                                             oMapPreExistingFields.end() )
4107                 oMapPreExistingFields[osUpperFieldName] = iField;
4108             /*else
4109                 CPLError(CE_Warning, CPLE_AppDefined,
4110                          "The target layer has already a duplicated field name '%s' before "
4111                          "adding the fields of the source layer", pszFieldName); */
4112         }
4113 
4114         const char* pszFIDColumn = poDstLayer->GetFIDColumn();
4115 
4116         std::vector<int> anSrcFieldIndices;
4117         if( m_papszSelFields )
4118         {
4119             for( int iField=0; m_papszSelFields[iField] != nullptr; iField++)
4120             {
4121                 const int iSrcField =
4122                     poSrcFDefn->GetFieldIndex(m_papszSelFields[iField]);
4123                 if (iSrcField >= 0)
4124                 {
4125                     anSrcFieldIndices.push_back(iSrcField);
4126                 }
4127             }
4128         }
4129         else
4130         {
4131             for( int iField = 0; iField < nSrcFieldCount; iField++ )
4132             {
4133                 anSrcFieldIndices.push_back(iField);
4134             }
4135         }
4136 
4137         std::unordered_set<std::string> oSetSrcFieldNames;
4138         for( int i = 0; i < poSrcFDefn->GetFieldCount(); i++ )
4139         {
4140             oSetSrcFieldNames.insert(
4141                 formatName(poSrcFDefn->GetFieldDefn(i)->GetNameRef()));
4142         }
4143 
4144         for( size_t i = 0; i < anSrcFieldIndices.size(); i++ )
4145         {
4146             const int iField = anSrcFieldIndices[i];
4147             const OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
4148             OGRFieldDefn oFieldDefn( poSrcFieldDefn );
4149 
4150             // Avoid creating a field with the same name as the FID column
4151             if( pszFIDColumn != nullptr && EQUAL(pszFIDColumn, oFieldDefn.GetNameRef()) &&
4152                 (oFieldDefn.GetType() == OFTInteger || oFieldDefn.GetType() == OFTInteger64) )
4153             {
4154                 iSrcFIDField = iField;
4155                 continue;
4156             }
4157 
4158             DoFieldTypeConversion(m_poDstDS, oFieldDefn,
4159                                   m_papszFieldTypesToString,
4160                                   m_papszMapFieldType,
4161                                   m_bUnsetFieldWidth,
4162                                   psOptions->bQuiet,
4163                                   m_bForceNullable,
4164                                   m_bUnsetDefault);
4165 
4166             /* The field may have been already created at layer creation */
4167             std::map<CPLString, int>::iterator oIter =
4168                 oMapPreExistingFields.find(formatName(oFieldDefn.GetNameRef()));
4169             if( oIter != oMapPreExistingFields.end() )
4170             {
4171                 anMap[iField] = oIter->second;
4172                 continue;
4173             }
4174 
4175             bool bHasRenamed = false;
4176             /* In case the field name already exists in the target layer, */
4177             /* build a unique field name */
4178             if( oSetDstFieldNames.find(
4179                     formatName(oFieldDefn.GetNameRef())) !=
4180                                                     oSetDstFieldNames.end() )
4181             {
4182                 int nTry = 1;
4183                 CPLString osTmpNameRaddixUC(oFieldDefn.GetNameRef());
4184                 osTmpNameRaddixUC = formatName(osTmpNameRaddixUC);
4185                 CPLString osTmpNameUC = osTmpNameRaddixUC;
4186                 osTmpNameUC.reserve(osTmpNameUC.size() + 10);
4187                 while( true )
4188                 {
4189                     ++nTry;
4190                     char szTry[32];
4191                     snprintf(szTry, sizeof(szTry), "%d", nTry);
4192                     osTmpNameUC.replace(osTmpNameRaddixUC.size(), std::string::npos, szTry);
4193 
4194                     /* Check that the proposed name doesn't exist either in the already */
4195                     /* created fields or in the source fields */
4196                     if( oSetDstFieldNames.find(osTmpNameUC) ==
4197                                                     oSetDstFieldNames.end() &&
4198                         oSetSrcFieldNames.find(osTmpNameUC) ==
4199                                                     oSetSrcFieldNames.end() )
4200                     {
4201                         bHasRenamed = true;
4202                         oFieldDefn.SetName((CPLString(oFieldDefn.GetNameRef()) + szTry).c_str());
4203                         break;
4204                     }
4205                 }
4206             }
4207 
4208             // Create field domain in output dataset if not already existing.
4209             const auto osDomainName = oFieldDefn.GetDomainName();
4210             if( !osDomainName.empty() )
4211             {
4212                 if( m_poDstDS->TestCapability(ODsCAddFieldDomain) &&
4213                     m_poDstDS->GetFieldDomain(osDomainName) == nullptr )
4214                 {
4215                     const auto poSrcDomain =
4216                         m_poSrcDS->GetFieldDomain(osDomainName);
4217                     if( poSrcDomain )
4218                     {
4219                         std::string failureReason;
4220                         if( !m_poDstDS->AddFieldDomain(
4221                                 std::unique_ptr<OGRFieldDomain>(poSrcDomain->Clone()),
4222                                 failureReason) )
4223                         {
4224                             oFieldDefn.SetDomainName(std::string());
4225                             CPLDebug("OGR2OGR", "Cannot create domain %s: %s",
4226                                      osDomainName.c_str(), failureReason.c_str());
4227                         }
4228                     }
4229                     else
4230                     {
4231                         CPLDebug("OGR2OGR",
4232                                  "Cannot find domain %s in source dataset",
4233                                  osDomainName.c_str());
4234                     }
4235                 }
4236                 if( m_poDstDS->GetFieldDomain(osDomainName) == nullptr )
4237                 {
4238                     oFieldDefn.SetDomainName(std::string());
4239                 }
4240             }
4241 
4242             if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
4243             {
4244                 /* now that we've created a field, GetLayerDefn() won't return NULL */
4245                 if (poDstFDefn == nullptr)
4246                     poDstFDefn = poDstLayer->GetLayerDefn();
4247 
4248                 /* Sanity check : if it fails, the driver is buggy */
4249                 if (poDstFDefn != nullptr &&
4250                     poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
4251                 {
4252                     CPLError(CE_Warning, CPLE_AppDefined,
4253                              "The output driver has claimed to have added the %s field, but it did not!",
4254                              oFieldDefn.GetNameRef() );
4255                 }
4256                 else
4257                 {
4258                     if( poDstFDefn != nullptr )
4259                     {
4260                         const char* pszNewFieldName =
4261                             poDstFDefn->GetFieldDefn(nDstFieldCount)->GetNameRef();
4262                         if( bHasRenamed )
4263                         {
4264                             CPLError(CE_Warning, CPLE_AppDefined,
4265                                     "Field '%s' already exists. Renaming it as '%s'",
4266                                     poSrcFieldDefn->GetNameRef(), pszNewFieldName);
4267                         }
4268                         oSetDstFieldNames.insert(formatName(pszNewFieldName));
4269                     }
4270 
4271                     anMap[iField] = nDstFieldCount;
4272                     nDstFieldCount ++;
4273                 }
4274             }
4275 
4276             if( m_bResolveDomains && !osDomainName.empty() )
4277             {
4278                 const auto poSrcDomain =
4279                         m_poSrcDS->GetFieldDomain(osDomainName);
4280                 if( poSrcDomain && poSrcDomain->GetDomainType() == OFDT_CODED )
4281                 {
4282                     OGRFieldDefn oResolvedField(
4283                         CPLSPrintf("%s_resolved", oFieldDefn.GetNameRef()),
4284                         OFTString );
4285                     if (poDstLayer->CreateField( &oResolvedField ) == OGRERR_NONE)
4286                     {
4287                         TargetLayerInfo::ResolvedInfo resolvedInfo;
4288                         resolvedInfo.nSrcField = iField;
4289                         resolvedInfo.poDomain = poSrcDomain;
4290                         oMapResolved[nDstFieldCount] = resolvedInfo;
4291                         nDstFieldCount ++;
4292                     }
4293                 }
4294             }
4295         }
4296     }
4297     else
4298     {
4299         /* For an existing layer, build the map by fetching the index in the destination */
4300         /* layer for each source field */
4301         if (poDstFDefn == nullptr)
4302         {
4303             CPLError( CE_Failure, CPLE_AppDefined, "poDstFDefn == NULL." );
4304             return nullptr;
4305         }
4306 
4307         for( int iField = 0; iField < nSrcFieldCount; iField++ )
4308         {
4309             OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
4310             const int iDstField =
4311                 poDstLayer->FindFieldIndex(poSrcFieldDefn->GetNameRef(),
4312                                            m_bExactFieldNameMatch);
4313             if (iDstField >= 0)
4314                 anMap[iField] = iDstField;
4315             else
4316                 CPLDebug("GDALVectorTranslate", "Skipping field '%s' not found in destination layer '%s'.",
4317                          poSrcFieldDefn->GetNameRef(), poDstLayer->GetName() );
4318         }
4319     }
4320 
4321     if( bOverwriteActuallyDone && !bAddOverwriteLCO &&
4322         EQUAL(m_poDstDS->GetDriver()->GetDescription(), "PostgreSQL") &&
4323         !psOptions->nLayerTransaction &&
4324         psOptions->nGroupTransactions >= 0 &&
4325         CPLTestBool(CPLGetConfigOption("PG_COMMIT_WHEN_OVERWRITING", "YES")) )
4326     {
4327         CPLDebug("GDALVectorTranslate",
4328                  "Forcing transaction commit as table overwriting occurred");
4329         // Commit when overwriting as this consumes a lot of PG resources
4330         // and could result in """out of shared memory.
4331         // You might need to increase max_locks_per_transaction."""" errors
4332         if( m_poDstDS->CommitTransaction() == OGRERR_FAILURE ||
4333             m_poDstDS->StartTransaction(psOptions->bForceTransaction) == OGRERR_FAILURE )
4334         {
4335             return nullptr;
4336         }
4337         nTotalEventsDone = 0;
4338     }
4339 
4340     std::unique_ptr<TargetLayerInfo> psInfo(new TargetLayerInfo);
4341     psInfo->m_nFeaturesRead = 0;
4342     psInfo->m_bPerFeatureCT = false;
4343     psInfo->m_poSrcLayer = poSrcLayer;
4344     psInfo->m_poDstLayer = poDstLayer;
4345     psInfo->m_apoCT.resize(poDstLayer->GetLayerDefn()->GetGeomFieldCount());
4346     psInfo->m_aosTransformOptions.resize(poDstLayer->GetLayerDefn()->GetGeomFieldCount());
4347     psInfo->m_anMap = std::move(anMap);
4348     psInfo->m_iSrcZField = iSrcZField;
4349     psInfo->m_iSrcFIDField = iSrcFIDField;
4350     if( anRequestedGeomFields.size() == 1 )
4351         psInfo->m_iRequestedSrcGeomField = anRequestedGeomFields[0];
4352     else
4353         psInfo->m_iRequestedSrcGeomField = -1;
4354     psInfo->m_bPreserveFID = bPreserveFID;
4355     psInfo->m_pszCTPipeline = m_pszCTPipeline;
4356     psInfo->m_oMapResolved = std::move(oMapResolved);
4357     for( const auto& kv: psInfo->m_oMapResolved )
4358     {
4359         const auto poDomain = kv.second.poDomain;
4360         const auto poCodedDomain =
4361             cpl::down_cast<const OGRCodedFieldDomain*>(poDomain);
4362         const auto enumeration = poCodedDomain->GetEnumeration();
4363         std::map<std::string, std::string> oMapCodeValue;
4364         for( int i = 0; enumeration[i].pszCode != nullptr; ++i )
4365         {
4366             oMapCodeValue[enumeration[i].pszCode] =
4367                 enumeration[i].pszValue ? enumeration[i].pszValue : "";
4368         }
4369         psInfo->m_oMapDomainToKV[poDomain] = std::move(oMapCodeValue);
4370     }
4371 
4372     return psInfo;
4373 }
4374 
4375 /************************************************************************/
4376 /*                               SetupCT()                              */
4377 /************************************************************************/
4378 
SetupCT(TargetLayerInfo * psInfo,OGRLayer * poSrcLayer,bool bTransform,bool bWrapDateline,const CPLString & osDateLineOffset,OGRSpatialReference * poUserSourceSRS,OGRFeature * poFeature,OGRSpatialReference * poOutputSRS,OGRCoordinateTransformation * poGCPCoordTrans)4379 static bool SetupCT( TargetLayerInfo* psInfo,
4380                     OGRLayer* poSrcLayer,
4381                     bool bTransform,
4382                     bool bWrapDateline,
4383                     const CPLString& osDateLineOffset,
4384                     OGRSpatialReference* poUserSourceSRS,
4385                     OGRFeature* poFeature,
4386                     OGRSpatialReference* poOutputSRS,
4387                     OGRCoordinateTransformation* poGCPCoordTrans)
4388 {
4389     OGRLayer    *poDstLayer = psInfo->m_poDstLayer;
4390     const int nDstGeomFieldCount =
4391         poDstLayer->GetLayerDefn()->GetGeomFieldCount();
4392     for( int iGeom = 0; iGeom < nDstGeomFieldCount; iGeom ++ )
4393     {
4394 /* -------------------------------------------------------------------- */
4395 /*      Setup coordinate transformation if we need it.                  */
4396 /* -------------------------------------------------------------------- */
4397         OGRSpatialReference* poSourceSRS = nullptr;
4398         OGRCoordinateTransformation* poCT = nullptr;
4399         char** papszTransformOptions = nullptr;
4400 
4401         int iSrcGeomField;
4402         auto poDstGeomFieldDefn = poDstLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom);
4403         if( psInfo->m_iRequestedSrcGeomField >= 0 )
4404         {
4405             iSrcGeomField = psInfo->m_iRequestedSrcGeomField;
4406         }
4407         else
4408         {
4409             iSrcGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(
4410                 poDstGeomFieldDefn->GetNameRef());
4411             if( iSrcGeomField < 0 )
4412             {
4413                 if( nDstGeomFieldCount == 1 &&
4414                     poSrcLayer->GetLayerDefn()->GetGeomFieldCount() > 0 )
4415                 {
4416                     iSrcGeomField = 0;
4417                 }
4418                 else
4419                 {
4420                     continue;
4421                 }
4422             }
4423         }
4424 
4425         if( psInfo->m_nFeaturesRead == 0 )
4426         {
4427             poSourceSRS = poUserSourceSRS;
4428             if( poSourceSRS == nullptr )
4429             {
4430                 if( iSrcGeomField > 0 )
4431                     poSourceSRS = poSrcLayer->GetLayerDefn()->
4432                         GetGeomFieldDefn(iSrcGeomField)->GetSpatialRef();
4433                 else
4434                     poSourceSRS = poSrcLayer->GetSpatialRef();
4435             }
4436         }
4437         if( poSourceSRS == nullptr )
4438         {
4439             OGRGeometry* poSrcGeometry =
4440                 poFeature->GetGeomFieldRef(iSrcGeomField);
4441             if( poSrcGeometry )
4442                 poSourceSRS = poSrcGeometry->getSpatialReference();
4443             psInfo->m_bPerFeatureCT = (bTransform || bWrapDateline);
4444         }
4445 
4446         if( bTransform )
4447         {
4448             if( poSourceSRS == nullptr && psInfo->m_pszCTPipeline == nullptr )
4449             {
4450                 CPLError( CE_Failure, CPLE_AppDefined, "Can't transform coordinates, source layer has no\n"
4451                         "coordinate system.  Use -s_srs to set one." );
4452 
4453                 return false;
4454             }
4455 
4456             if( psInfo->m_pszCTPipeline == nullptr )
4457             {
4458                 CPLAssert( nullptr != poSourceSRS );
4459                 CPLAssert( nullptr != poOutputSRS );
4460             }
4461 
4462             if( psInfo->m_apoCT[iGeom] != nullptr &&
4463                 psInfo->m_apoCT[iGeom]->GetSourceCS() == poSourceSRS )
4464             {
4465                 poCT = psInfo->m_apoCT[iGeom].get();
4466             }
4467             else
4468             {
4469                 OGRCoordinateTransformationOptions options;
4470                 if( psInfo->m_pszCTPipeline )
4471                 {
4472                     options.SetCoordinateOperation( psInfo->m_pszCTPipeline, false );
4473                 }
4474                 poCT = OGRCreateCoordinateTransformation( poSourceSRS, poOutputSRS, options );
4475                 if( poCT == nullptr )
4476                 {
4477                     char        *pszWKT = nullptr;
4478 
4479                     CPLError( CE_Failure, CPLE_AppDefined,
4480                         "Failed to create coordinate transformation between the\n"
4481                         "following coordinate systems.  This may be because they\n"
4482                         "are not transformable." );
4483 
4484                     if( poSourceSRS )
4485                     {
4486                         poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
4487                         CPLError( CE_Failure, CPLE_AppDefined,  "Source:\n%s", pszWKT );
4488                         CPLFree(pszWKT);
4489                     }
4490 
4491                     if( poOutputSRS )
4492                     {
4493                         poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
4494                         CPLError( CE_Failure, CPLE_AppDefined,  "Target:\n%s", pszWKT );
4495                         CPLFree(pszWKT);
4496                     }
4497 
4498                     return false;
4499                 }
4500                 poCT = new CompositeCT( poGCPCoordTrans, false, poCT, true );
4501                 psInfo->m_apoCT[iGeom].reset(poCT);
4502             }
4503         }
4504         else
4505         {
4506             const char* const apszOptions[] = {
4507                 "IGNORE_DATA_AXIS_TO_SRS_AXIS_MAPPING=YES",
4508                 "CRITERION=EQUIVALENT", nullptr };
4509             auto poDstGeomFieldDefnSpatialRef = poDstGeomFieldDefn->GetSpatialRef();
4510             if( poSourceSRS && poDstGeomFieldDefnSpatialRef &&
4511                 poSourceSRS->GetDataAxisToSRSAxisMapping() !=
4512                     poDstGeomFieldDefnSpatialRef->GetDataAxisToSRSAxisMapping() &&
4513                 poSourceSRS->IsSame(poDstGeomFieldDefnSpatialRef, apszOptions) )
4514             {
4515                 psInfo->m_apoCT[iGeom].reset(new CompositeCT(
4516                     new AxisMappingCoordinateTransformation(
4517                         poSourceSRS->GetDataAxisToSRSAxisMapping(),
4518                         poDstGeomFieldDefnSpatialRef->GetDataAxisToSRSAxisMapping()),
4519                     true,
4520                     poGCPCoordTrans,
4521                     false));
4522                 poCT = psInfo->m_apoCT[iGeom].get();
4523             }
4524             else if( poGCPCoordTrans )
4525             {
4526                 psInfo->m_apoCT[iGeom].reset(new CompositeCT(
4527                     poGCPCoordTrans, false, nullptr, false));
4528                 poCT = psInfo->m_apoCT[iGeom].get();
4529             }
4530         }
4531 
4532         if (bWrapDateline)
4533         {
4534             if (bTransform && poCT != nullptr && poOutputSRS != nullptr && poOutputSRS->IsGeographic())
4535             {
4536                 papszTransformOptions =
4537                     CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
4538                 if( !osDateLineOffset.empty() )
4539                 {
4540                     CPLString soOffset("DATELINEOFFSET=");
4541                     soOffset += osDateLineOffset;
4542                     papszTransformOptions =
4543                         CSLAddString(papszTransformOptions, soOffset);
4544                 }
4545             }
4546             else if (poSourceSRS != nullptr && poSourceSRS->IsGeographic())
4547             {
4548                 papszTransformOptions =
4549                     CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
4550                 if( !osDateLineOffset.empty() )
4551                 {
4552                     CPLString soOffset("DATELINEOFFSET=");
4553                     soOffset += osDateLineOffset;
4554                     papszTransformOptions =
4555                         CSLAddString(papszTransformOptions, soOffset);
4556                 }
4557             }
4558             else
4559             {
4560                 static bool bHasWarned = false;
4561                 if( !bHasWarned )
4562                     CPLError( CE_Failure, CPLE_IllegalArg, "-wrapdateline option only works when reprojecting to a geographic SRS");
4563                 bHasWarned = true;
4564             }
4565 
4566             psInfo->m_aosTransformOptions[iGeom].Assign(papszTransformOptions);
4567         }
4568     }
4569     return true;
4570 }
4571 
4572 /************************************************************************/
4573 /*                     LayerTranslator::Translate()                     */
4574 /************************************************************************/
4575 
Translate(OGRFeature * poFeatureIn,TargetLayerInfo * psInfo,GIntBig nCountLayerFeatures,GIntBig * pnReadFeatureCount,GIntBig & nTotalEventsDone,GDALProgressFunc pfnProgress,void * pProgressArg,GDALVectorTranslateOptions * psOptions)4576 int LayerTranslator::Translate( OGRFeature* poFeatureIn,
4577                                 TargetLayerInfo* psInfo,
4578                                 GIntBig nCountLayerFeatures,
4579                                 GIntBig* pnReadFeatureCount,
4580                                 GIntBig& nTotalEventsDone,
4581                                 GDALProgressFunc pfnProgress,
4582                                 void *pProgressArg,
4583                                 GDALVectorTranslateOptions *psOptions )
4584 {
4585     const int eGType = m_eGType;
4586     OGRSpatialReference* poOutputSRS = m_poOutputSRS;
4587 
4588     OGRLayer *poSrcLayer = psInfo->m_poSrcLayer;
4589     OGRLayer *poDstLayer = psInfo->m_poDstLayer;
4590     const int* const panMap = psInfo->m_anMap.data();
4591     const int iSrcZField = psInfo->m_iSrcZField;
4592     const bool bPreserveFID = psInfo->m_bPreserveFID;
4593     const int nSrcGeomFieldCount = poSrcLayer->GetLayerDefn()->GetGeomFieldCount();
4594     const int nDstGeomFieldCount = poDstLayer->GetLayerDefn()->GetGeomFieldCount();
4595     const bool bExplodeCollections = m_bExplodeCollections && nDstGeomFieldCount <= 1;
4596     const int iRequestedSrcGeomField = psInfo->m_iRequestedSrcGeomField;
4597 
4598     if( poOutputSRS == nullptr && !m_bNullifyOutputSRS )
4599     {
4600         if( nSrcGeomFieldCount == 1 )
4601         {
4602             poOutputSRS = poSrcLayer->GetSpatialRef();
4603         }
4604         else if( iRequestedSrcGeomField > 0 )
4605         {
4606             poOutputSRS = poSrcLayer->GetLayerDefn()->GetGeomFieldDefn(
4607                 iRequestedSrcGeomField)->GetSpatialRef();
4608         }
4609     }
4610 
4611 /* -------------------------------------------------------------------- */
4612 /*      Transfer features.                                              */
4613 /* -------------------------------------------------------------------- */
4614     if( psOptions->nGroupTransactions )
4615     {
4616         if( psOptions->nLayerTransaction )
4617         {
4618             if( poDstLayer->StartTransaction() == OGRERR_FAILURE )
4619                 return false;
4620         }
4621     }
4622 
4623     OGRFeature *poFeature = nullptr;
4624     int         nFeaturesInTransaction = 0;
4625     GIntBig      nCount = 0; /* written + failed */
4626     GIntBig      nFeaturesWritten = 0;
4627 
4628     bool bRet = true;
4629     CPLErrorReset();
4630     while( true )
4631     {
4632         if( m_nLimit >= 0 && psInfo->m_nFeaturesRead >= m_nLimit )
4633         {
4634             break;
4635         }
4636 
4637         if( poFeatureIn != nullptr )
4638             poFeature = poFeatureIn;
4639         else if( psOptions->nFIDToFetch != OGRNullFID )
4640             poFeature = poSrcLayer->GetFeature(psOptions->nFIDToFetch);
4641         else
4642             poFeature = poSrcLayer->GetNextFeature();
4643 
4644         if( poFeature == nullptr )
4645         {
4646             if( CPLGetLastErrorType() == CE_Failure )
4647             {
4648                 bRet = false;
4649             }
4650             break;
4651         }
4652 
4653         if( psInfo->m_nFeaturesRead == 0 || psInfo->m_bPerFeatureCT )
4654         {
4655             if( !SetupCT( psInfo, poSrcLayer, m_bTransform, m_bWrapDateline,
4656                           m_osDateLineOffset, m_poUserSourceSRS,
4657                           poFeature, poOutputSRS, m_poGCPCoordTrans) )
4658             {
4659                 OGRFeature::DestroyFeature( poFeature );
4660                 return false;
4661             }
4662         }
4663 
4664         psInfo->m_nFeaturesRead ++;
4665 
4666         int nIters = 1;
4667         std::unique_ptr<OGRGeometryCollection> poCollToExplode;
4668         int iGeomCollToExplode = -1;
4669         if (bExplodeCollections)
4670         {
4671             OGRGeometry* poSrcGeometry;
4672             if( iRequestedSrcGeomField >= 0 )
4673                 poSrcGeometry = poFeature->GetGeomFieldRef(
4674                                         iRequestedSrcGeomField);
4675             else
4676                 poSrcGeometry = poFeature->GetGeometryRef();
4677             if (poSrcGeometry &&
4678                 OGR_GT_IsSubClassOf(poSrcGeometry->getGeometryType(), wkbGeometryCollection) )
4679             {
4680                 const int nParts = poSrcGeometry->toGeometryCollection()->getNumGeometries();
4681                 if( nParts > 0 )
4682                 {
4683                     iGeomCollToExplode = iRequestedSrcGeomField >= 0 ?
4684                         iRequestedSrcGeomField : 0;
4685                     poCollToExplode.reset(
4686                         poFeature->StealGeometry(iGeomCollToExplode)->toGeometryCollection());
4687                     nIters = nParts;
4688                 }
4689             }
4690         }
4691 
4692         OGRFeature *poDstFeature = nullptr;
4693         for(int iPart = 0; iPart < nIters; iPart++)
4694         {
4695             if( psOptions->nLayerTransaction &&
4696                 ++nFeaturesInTransaction == psOptions->nGroupTransactions )
4697             {
4698                 if( poDstLayer->CommitTransaction() == OGRERR_FAILURE ||
4699                     poDstLayer->StartTransaction() == OGRERR_FAILURE )
4700                 {
4701                     OGRFeature::DestroyFeature( poFeature );
4702                     return false;
4703                 }
4704                 nFeaturesInTransaction = 0;
4705             }
4706             else if( !psOptions->nLayerTransaction &&
4707                      psOptions->nGroupTransactions >= 0 &&
4708                      ++nTotalEventsDone >= psOptions->nGroupTransactions )
4709             {
4710                 if( m_poODS->CommitTransaction() == OGRERR_FAILURE ||
4711                         m_poODS->StartTransaction(psOptions->bForceTransaction) == OGRERR_FAILURE )
4712                 {
4713                     OGRFeature::DestroyFeature( poFeature );
4714                     return false;
4715                 }
4716                 nTotalEventsDone = 0;
4717             }
4718 
4719             CPLErrorReset();
4720             poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
4721 
4722             /* Optimization to avoid duplicating the source geometry in the */
4723             /* target feature : we steal it from the source feature for now... */
4724             OGRGeometry* poStolenGeometry = nullptr;
4725             if( !bExplodeCollections && nSrcGeomFieldCount == 1 &&
4726                 (nDstGeomFieldCount == 1 ||
4727                  (nDstGeomFieldCount == 0 && m_poClipSrc)) )
4728             {
4729                 poStolenGeometry = poFeature->StealGeometry();
4730             }
4731             else if( !bExplodeCollections &&
4732                      iRequestedSrcGeomField >= 0 )
4733             {
4734                 poStolenGeometry = poFeature->StealGeometry(
4735                     iRequestedSrcGeomField);
4736             }
4737 
4738             if( nDstGeomFieldCount == 0 && poStolenGeometry && m_poClipSrc )
4739             {
4740                 OGRGeometry* poClipped = poStolenGeometry->Intersection(m_poClipSrc);
4741                 delete poStolenGeometry;
4742                 poStolenGeometry = nullptr;
4743                 if (poClipped == nullptr || poClipped->IsEmpty())
4744                 {
4745                     delete poClipped;
4746                     goto end_loop;
4747                 }
4748                 delete poClipped;
4749             }
4750 
4751             if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
4752             {
4753                 if( psOptions->nGroupTransactions )
4754                 {
4755                     if( psOptions->nLayerTransaction )
4756                     {
4757                         if( poDstLayer->CommitTransaction() != OGRERR_NONE )
4758                         {
4759                             OGRFeature::DestroyFeature( poFeature );
4760                             OGRFeature::DestroyFeature( poDstFeature );
4761                             OGRGeometryFactory::destroyGeometry( poStolenGeometry );
4762                             return false;
4763                         }
4764                     }
4765                 }
4766 
4767                 CPLError( CE_Failure, CPLE_AppDefined,
4768                         "Unable to translate feature " CPL_FRMT_GIB " from layer %s.",
4769                         poFeature->GetFID(), poSrcLayer->GetName() );
4770 
4771                 OGRFeature::DestroyFeature( poFeature );
4772                 OGRFeature::DestroyFeature( poDstFeature );
4773                 OGRGeometryFactory::destroyGeometry( poStolenGeometry );
4774                 return false;
4775             }
4776 
4777             if (psOptions->bEmptyStrAsNull) {
4778                 for( int i=0; i < poDstFeature->GetFieldCount(); i++ )
4779                 {
4780                     if (!poDstFeature->IsFieldSetAndNotNull(i))
4781                         continue;
4782                     auto fieldDef = poDstFeature->GetFieldDefnRef(i);
4783                     if (fieldDef->GetType() != OGRFieldType::OFTString)
4784                         continue;
4785                     auto str = poDstFeature->GetFieldAsString(i);
4786                     if (strcmp(str, "") == 0)
4787                         poDstFeature->SetFieldNull(i);
4788                 }
4789             }
4790 
4791             /* ... and now we can attach the stolen geometry */
4792             if( poStolenGeometry )
4793             {
4794                 poDstFeature->SetGeometryDirectly(poStolenGeometry);
4795             }
4796 
4797             if( bPreserveFID )
4798                 poDstFeature->SetFID( poFeature->GetFID() );
4799             else if( psInfo->m_iSrcFIDField >= 0 &&
4800                      poFeature->IsFieldSetAndNotNull(psInfo->m_iSrcFIDField))
4801                 poDstFeature->SetFID( poFeature->GetFieldAsInteger64(psInfo->m_iSrcFIDField) );
4802 
4803             /* Erase native data if asked explicitly */
4804             if( !m_bNativeData )
4805             {
4806                 poDstFeature->SetNativeData(nullptr);
4807                 poDstFeature->SetNativeMediaType(nullptr);
4808             }
4809 
4810             for( int iGeom = 0; iGeom < nDstGeomFieldCount; iGeom ++ )
4811             {
4812                 OGRGeometry* poDstGeometry;
4813 
4814                 if( poCollToExplode && iGeom == iGeomCollToExplode )
4815                 {
4816                     OGRGeometry* poPart = poCollToExplode->getGeometryRef(0);
4817                     poCollToExplode->removeGeometry(0, FALSE);
4818                     poDstGeometry = poPart;
4819                     assert(poDstGeometry);
4820                 }
4821                 else
4822                 {
4823                     poDstGeometry = poDstFeature->StealGeometry(iGeom);
4824                     if (poDstGeometry == nullptr)
4825                         continue;
4826                 }
4827 
4828                 if (iSrcZField != -1)
4829                 {
4830                     SetZ(poDstGeometry, poFeature->GetFieldAsDouble(iSrcZField));
4831                     /* This will correct the coordinate dimension to 3 */
4832                     OGRGeometry* poDupGeometry = poDstGeometry->clone();
4833                     delete poDstGeometry;
4834                     poDstGeometry = poDupGeometry;
4835                 }
4836 
4837                 if (m_nCoordDim == 2 || m_nCoordDim == 3)
4838                 {
4839                     poDstGeometry->setCoordinateDimension( m_nCoordDim );
4840                 }
4841                 else if (m_nCoordDim == 4)
4842                 {
4843                     poDstGeometry->set3D( TRUE );
4844                     poDstGeometry->setMeasured( TRUE );
4845                 }
4846                 else if (m_nCoordDim == COORD_DIM_XYM)
4847                 {
4848                     poDstGeometry->set3D( FALSE );
4849                     poDstGeometry->setMeasured( TRUE );
4850                 }
4851                 else if ( m_nCoordDim == COORD_DIM_LAYER_DIM )
4852                 {
4853                     const OGRwkbGeometryType eDstLayerGeomType =
4854                       poDstLayer->GetLayerDefn()->GetGeomFieldDefn(iGeom)->GetType();
4855                     poDstGeometry->set3D( wkbHasZ(eDstLayerGeomType) );
4856                     poDstGeometry->setMeasured( wkbHasM(eDstLayerGeomType) );
4857                 }
4858 
4859                 if (m_eGeomOp == GEOMOP_SEGMENTIZE)
4860                 {
4861                     if (m_dfGeomOpParam > 0)
4862                         poDstGeometry->segmentize(m_dfGeomOpParam);
4863                 }
4864                 else if (m_eGeomOp == GEOMOP_SIMPLIFY_PRESERVE_TOPOLOGY)
4865                 {
4866                     if (m_dfGeomOpParam > 0)
4867                     {
4868                         OGRGeometry* poNewGeom = poDstGeometry->SimplifyPreserveTopology(m_dfGeomOpParam);
4869                         if (poNewGeom)
4870                         {
4871                             delete poDstGeometry;
4872                             poDstGeometry = poNewGeom;
4873                         }
4874                     }
4875                 }
4876 
4877                 if (m_poClipSrc)
4878                 {
4879                     OGRGeometry* poClipped = poDstGeometry->Intersection(m_poClipSrc);
4880                     delete poDstGeometry;
4881                     if (poClipped == nullptr || poClipped->IsEmpty())
4882                     {
4883                         delete poClipped;
4884                         goto end_loop;
4885                     }
4886                     poDstGeometry = poClipped;
4887                 }
4888 
4889                 OGRCoordinateTransformation* const poCT = psInfo->m_apoCT[iGeom].get();
4890                 char** const papszTransformOptions = psInfo->m_aosTransformOptions[iGeom].List();
4891 
4892                 if( poCT != nullptr || papszTransformOptions != nullptr)
4893                 {
4894                     OGRGeometry* poReprojectedGeom =
4895                         OGRGeometryFactory::transformWithOptions(
4896                             poDstGeometry, poCT, papszTransformOptions, m_transformWithOptionsCache);
4897                     if( poReprojectedGeom == nullptr )
4898                     {
4899                         if( psOptions->nGroupTransactions )
4900                         {
4901                             if( psOptions->nLayerTransaction )
4902                             {
4903                                 if( poDstLayer->CommitTransaction() != OGRERR_NONE &&
4904                                     !psOptions->bSkipFailures )
4905                                 {
4906                                     OGRFeature::DestroyFeature( poFeature );
4907                                     OGRFeature::DestroyFeature( poDstFeature );
4908                                     delete poDstGeometry;
4909                                     return false;
4910                                 }
4911                             }
4912                         }
4913 
4914                         CPLError( CE_Failure, CPLE_AppDefined, "Failed to reproject feature " CPL_FRMT_GIB " (geometry probably out of source or destination SRS).",
4915                                   poFeature->GetFID() );
4916                         if( !psOptions->bSkipFailures )
4917                         {
4918                             OGRFeature::DestroyFeature( poFeature );
4919                             OGRFeature::DestroyFeature( poDstFeature );
4920                             delete poDstGeometry;
4921                             return false;
4922                         }
4923                     }
4924 
4925                     delete poDstGeometry;
4926                     poDstGeometry = poReprojectedGeom;
4927                 }
4928                 else if (poOutputSRS != nullptr)
4929                 {
4930                     poDstGeometry->assignSpatialReference(poOutputSRS);
4931                 }
4932 
4933                 if( poDstGeometry != nullptr )
4934                 {
4935                     if (m_poClipDst)
4936                     {
4937                         OGRGeometry* poClipped = poDstGeometry->Intersection(m_poClipDst);
4938                         delete poDstGeometry;
4939                         if (poClipped == nullptr || poClipped->IsEmpty())
4940                         {
4941                             delete poClipped;
4942                             goto end_loop;
4943                         }
4944 
4945                         poDstGeometry = poClipped;
4946                     }
4947 
4948                     if( m_bMakeValid )
4949                     {
4950                         OGRGeometry* poValidGeom = poDstGeometry->MakeValid();
4951                         delete poDstGeometry;
4952                         poDstGeometry = poValidGeom;
4953                         if( poDstGeometry == nullptr )
4954                             goto end_loop;
4955                         OGRGeometry* poCleanedGeom =
4956                             OGRGeometryFactory::removeLowerDimensionSubGeoms(poDstGeometry);
4957                         delete poDstGeometry;
4958                         poDstGeometry = poCleanedGeom;
4959                     }
4960 
4961                     if( eGType != GEOMTYPE_UNCHANGED )
4962                     {
4963                         poDstGeometry = OGRGeometryFactory::forceTo(
4964                                 poDstGeometry, static_cast<OGRwkbGeometryType>(eGType));
4965                     }
4966                     else if( m_eGeomTypeConversion == GTC_PROMOTE_TO_MULTI ||
4967                             m_eGeomTypeConversion == GTC_CONVERT_TO_LINEAR ||
4968                             m_eGeomTypeConversion == GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR ||
4969                             m_eGeomTypeConversion == GTC_CONVERT_TO_CURVE )
4970                     {
4971                         OGRwkbGeometryType eTargetType = poDstGeometry->getGeometryType();
4972                         eTargetType = ConvertType(m_eGeomTypeConversion, eTargetType);
4973                         poDstGeometry = OGRGeometryFactory::forceTo(poDstGeometry, eTargetType);
4974                     }
4975                 }
4976 
4977                 poDstFeature->SetGeomFieldDirectly(iGeom, poDstGeometry);
4978             }
4979 
4980             if( !psInfo->m_oMapResolved.empty() )
4981             {
4982                 for( const auto& kv: psInfo->m_oMapResolved )
4983                 {
4984                     const int nDstField = kv.first;
4985                     const int nSrcField = kv.second.nSrcField;
4986                     if( poFeature->IsFieldSetAndNotNull(nSrcField) )
4987                     {
4988                         const auto poDomain = kv.second.poDomain;
4989                         const auto& oMapKV = psInfo->m_oMapDomainToKV[poDomain];
4990                         const auto iter = oMapKV.find(
4991                             poFeature->GetFieldAsString(nSrcField));
4992                         if( iter != oMapKV.end() )
4993                         {
4994                             poDstFeature->SetField(nDstField, iter->second.c_str());
4995                         }
4996                     }
4997                 }
4998             }
4999 
5000             CPLErrorReset();
5001             if( poDstLayer->CreateFeature( poDstFeature ) == OGRERR_NONE )
5002             {
5003                 nFeaturesWritten ++;
5004                 if( (bPreserveFID && poDstFeature->GetFID() != poFeature->GetFID()) ||
5005                     (!bPreserveFID && psInfo->m_iSrcFIDField >= 0 && poFeature->IsFieldSetAndNotNull(psInfo->m_iSrcFIDField) &&
5006                      poDstFeature->GetFID() != poFeature->GetFieldAsInteger64(psInfo->m_iSrcFIDField)) )
5007                 {
5008                     CPLError( CE_Warning, CPLE_AppDefined,
5009                               "Feature id not preserved");
5010                 }
5011             }
5012             else if( !psOptions->bSkipFailures )
5013             {
5014                 if( psOptions->nGroupTransactions )
5015                 {
5016                     if( psOptions->nLayerTransaction )
5017                         poDstLayer->RollbackTransaction();
5018                 }
5019 
5020                 CPLError( CE_Failure, CPLE_AppDefined,
5021                         "Unable to write feature " CPL_FRMT_GIB " from layer %s.",
5022                         poFeature->GetFID(), poSrcLayer->GetName() );
5023 
5024                 OGRFeature::DestroyFeature( poFeature );
5025                 OGRFeature::DestroyFeature( poDstFeature );
5026                 return false;
5027             }
5028             else
5029             {
5030                 CPLDebug( "GDALVectorTranslate", "Unable to write feature " CPL_FRMT_GIB " into layer %s.",
5031                            poFeature->GetFID(), poSrcLayer->GetName() );
5032                 if( psOptions->nGroupTransactions )
5033                 {
5034                     if( psOptions->nLayerTransaction )
5035                     {
5036                         poDstLayer->RollbackTransaction();
5037                         CPL_IGNORE_RET_VAL(poDstLayer->StartTransaction());
5038                     }
5039                     else
5040                     {
5041                         m_poODS->RollbackTransaction();
5042                         m_poODS->StartTransaction(psOptions->bForceTransaction);
5043                     }
5044                 }
5045             }
5046 
5047 end_loop:
5048             OGRFeature::DestroyFeature( poDstFeature );
5049         }
5050 
5051         OGRFeature::DestroyFeature( poFeature );
5052 
5053         /* Report progress */
5054         nCount ++;
5055         bool bGoOn = true;
5056         if (pfnProgress)
5057         {
5058             bGoOn = pfnProgress(nCountLayerFeatures ? nCount * 1.0 / nCountLayerFeatures: 1.0, "", pProgressArg) != FALSE;
5059         }
5060         if( !bGoOn )
5061         {
5062             bRet = false;
5063             break;
5064         }
5065 
5066         if (pnReadFeatureCount)
5067             *pnReadFeatureCount = nCount;
5068 
5069         if( psOptions->nFIDToFetch != OGRNullFID )
5070             break;
5071         if( poFeatureIn != nullptr )
5072             break;
5073     }
5074 
5075     if( psOptions->nGroupTransactions )
5076     {
5077         if( psOptions->nLayerTransaction )
5078         {
5079             if( poDstLayer->CommitTransaction() != OGRERR_NONE )
5080                 bRet = false;
5081         }
5082     }
5083 
5084     if( poFeatureIn == nullptr )
5085     {
5086         CPLDebug("GDALVectorTranslate", CPL_FRMT_GIB " features written in layer '%s'",
5087                 nFeaturesWritten, poDstLayer->GetName());
5088     }
5089 
5090     return bRet;
5091 }
5092 
5093 /************************************************************************/
5094 /*                             RemoveBOM()                              */
5095 /************************************************************************/
5096 
5097 /* Remove potential UTF-8 BOM from data (must be NUL terminated) */
RemoveBOM(GByte * pabyData)5098 static void RemoveBOM(GByte* pabyData)
5099 {
5100     if( pabyData[0] == 0xEF && pabyData[1] == 0xBB && pabyData[2] == 0xBF )
5101     {
5102         memmove(pabyData, pabyData + 3, strlen(reinterpret_cast<char*>(pabyData) + 3) + 1);
5103     }
5104 }
5105 
RemoveSQLComments(char * & pszSQL)5106 static void RemoveSQLComments(char*& pszSQL)
5107 {
5108     char** papszLines = CSLTokenizeStringComplex(pszSQL, "\r\n", FALSE, FALSE);
5109     CPLString osSQL;
5110     for( char** papszIter = papszLines; papszIter && *papszIter; ++papszIter )
5111     {
5112         const char* pszLine = *papszIter;
5113         char chQuote = 0;
5114         int i = 0;
5115         for(; pszLine[i] != '\0'; ++i )
5116         {
5117             if( chQuote )
5118             {
5119                 if( pszLine[i] == chQuote )
5120                 {
5121                     if( pszLine[i+1] == chQuote )
5122                     {
5123                         i++;
5124                     }
5125                     else
5126                     {
5127                         chQuote = 0;
5128                     }
5129                 }
5130             }
5131             else if( pszLine[i] == '\'' || pszLine[i] == '"' )
5132             {
5133                 chQuote = pszLine[i];
5134             }
5135             else if( pszLine[i] == '-' && pszLine[i+1] == '-' )
5136             {
5137                 break;
5138             }
5139         }
5140         if( i > 0 )
5141         {
5142             osSQL.append(pszLine, i);
5143         }
5144         osSQL += ' ';
5145     }
5146     CSLDestroy(papszLines);
5147     CPLFree(pszSQL);
5148     pszSQL = CPLStrdup(osSQL);
5149 }
5150 
5151 /************************************************************************/
5152 /*                       GDALVectorTranslateOptionsNew()                */
5153 /************************************************************************/
5154 
5155 /**
5156  * allocates a GDALVectorTranslateOptions struct.
5157  *
5158  * @param papszArgv NULL terminated list of options (potentially including filename and open options too), or NULL.
5159  *                  The accepted options are the ones of the <a href="/programs/ogr2ogr.html">ogr2ogr</a> utility.
5160  * @param psOptionsForBinary (output) may be NULL (and should generally be NULL),
5161  *                           otherwise (gdal_translate_bin.cpp use case) must be allocated with
5162  *                           GDALVectorTranslateOptionsForBinaryNew() prior to this function. Will be
5163  *                           filled with potentially present filename, open options,...
5164  * @return pointer to the allocated GDALVectorTranslateOptions struct. Must be freed with GDALVectorTranslateOptionsFree().
5165  *
5166  * @since GDAL 2.1
5167  */
GDALVectorTranslateOptionsNew(char ** papszArgv,GDALVectorTranslateOptionsForBinary * psOptionsForBinary)5168 GDALVectorTranslateOptions *GDALVectorTranslateOptionsNew(char** papszArgv,
5169                                                       GDALVectorTranslateOptionsForBinary* psOptionsForBinary)
5170 {
5171     GDALVectorTranslateOptions *psOptions =
5172         static_cast<GDALVectorTranslateOptions *>(
5173             CPLCalloc( 1, sizeof(GDALVectorTranslateOptions)));
5174 
5175     psOptions->eAccessMode = ACCESS_CREATION;
5176     psOptions->bSkipFailures = false;
5177     psOptions->nLayerTransaction = -1;
5178     psOptions->bForceTransaction = false;
5179     psOptions->nGroupTransactions = 100 * 1000;
5180     psOptions->nFIDToFetch = OGRNullFID;
5181     psOptions->bQuiet = false;
5182     psOptions->pszFormat = nullptr;
5183     psOptions->papszLayers = nullptr;
5184     psOptions->papszDSCO = nullptr;
5185     psOptions->papszLCO = nullptr;
5186     psOptions->bTransform = false;
5187     psOptions->bAddMissingFields = false;
5188     psOptions->pszOutputSRSDef = nullptr;
5189     psOptions->pszSourceSRSDef = nullptr;
5190     psOptions->pszCTPipeline = nullptr;
5191     psOptions->bNullifyOutputSRS = false;
5192     psOptions->bExactFieldNameMatch = true;
5193     psOptions->pszNewLayerName = nullptr;
5194     psOptions->pszWHERE = nullptr;
5195     psOptions->pszGeomField = nullptr;
5196     psOptions->papszSelFields = nullptr;
5197     psOptions->pszSQLStatement = nullptr;
5198     psOptions->pszDialect = nullptr;
5199     psOptions->eGType = GEOMTYPE_UNCHANGED;
5200     psOptions->eGeomTypeConversion = GTC_DEFAULT;
5201     psOptions->eGeomOp = GEOMOP_NONE;
5202     psOptions->dfGeomOpParam = 0;
5203     psOptions->bMakeValid = false;
5204     psOptions->papszFieldTypesToString = nullptr;
5205     psOptions->papszMapFieldType = nullptr;
5206     psOptions->bUnsetFieldWidth = false;
5207     psOptions->bDisplayProgress = false;
5208     psOptions->bWrapDateline = false;
5209     psOptions->dfDateLineOffset = 10.0;
5210     psOptions->bClipSrc = false;
5211     psOptions->hClipSrc = nullptr;
5212     psOptions->pszClipSrcDS = nullptr;
5213     psOptions->pszClipSrcSQL = nullptr;
5214     psOptions->pszClipSrcLayer = nullptr;
5215     psOptions->pszClipSrcWhere = nullptr;
5216     psOptions->hClipDst = nullptr;
5217     psOptions->pszClipDstDS = nullptr;
5218     psOptions->pszClipDstSQL = nullptr;
5219     psOptions->pszClipDstLayer = nullptr;
5220     psOptions->pszClipDstWhere = nullptr;
5221     psOptions->bSplitListFields = false;
5222     psOptions->nMaxSplitListSubFields = -1;
5223     psOptions->bExplodeCollections = false;
5224     psOptions->pszZField = nullptr;
5225     psOptions->papszFieldMap = nullptr;
5226     psOptions->nCoordDim = COORD_DIM_UNCHANGED;
5227     psOptions->papszDestOpenOptions = nullptr;
5228     psOptions->bForceNullable = false;
5229     psOptions->bResolveDomains = false;
5230     psOptions->bUnsetDefault = false;
5231     psOptions->bUnsetFid = false;
5232     psOptions->bPreserveFID = false;
5233     psOptions->bCopyMD = true;
5234     psOptions->papszMetadataOptions = nullptr;
5235     psOptions->pszSpatSRSDef = nullptr;
5236     psOptions->nGCPCount = 0;
5237     psOptions->pasGCPs = nullptr;
5238     psOptions->nTransformOrder = 0;  /* Default to 0 for now... let the lib decide */
5239     psOptions->hSpatialFilter = nullptr;
5240     psOptions->bNativeData = true;
5241     psOptions->nLimit = -1;
5242 
5243     int nArgc = CSLCount(papszArgv);
5244     for( int i = 0; papszArgv != nullptr && i < nArgc; i++ )
5245     {
5246         if( EQUAL(papszArgv[i],"-q") || EQUAL(papszArgv[i],"-quiet") )
5247         {
5248             if( psOptionsForBinary )
5249                 psOptionsForBinary->bQuiet = TRUE;
5250         }
5251         else if( i+1 < nArgc && (EQUAL(papszArgv[i],"-f") || EQUAL(papszArgv[i],"-of")) )
5252         {
5253             CPLFree(psOptions->pszFormat);
5254             const char* pszFormatArg = papszArgv[++i];
5255             psOptions->pszFormat = CPLStrdup(pszFormatArg);
5256         }
5257         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-dsco") )
5258         {
5259             psOptions->papszDSCO = CSLAddString(psOptions->papszDSCO, papszArgv[++i] );
5260         }
5261         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-lco") )
5262         {
5263             psOptions->papszLCO = CSLAddString(psOptions->papszLCO, papszArgv[++i] );
5264         }
5265         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-oo") )
5266         {
5267             ++i;
5268             if( psOptionsForBinary )
5269             {
5270                 psOptionsForBinary->papszOpenOptions = CSLAddString(psOptionsForBinary->papszOpenOptions, papszArgv[i] );
5271             }
5272         }
5273         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-doo") )
5274         {
5275             ++i;
5276             psOptions->papszDestOpenOptions = CSLAddString(psOptions->papszDestOpenOptions, papszArgv[i] );
5277         }
5278         else if( EQUAL(papszArgv[i],"-preserve_fid") )
5279         {
5280             psOptions->bPreserveFID = true;
5281         }
5282         else if( STARTS_WITH_CI(papszArgv[i], "-skip") )
5283         {
5284             psOptions->bSkipFailures = true;
5285             psOptions->nGroupTransactions = 1; /* #2409 */
5286         }
5287         else if( EQUAL(papszArgv[i],"-append") )
5288         {
5289             psOptions->eAccessMode = ACCESS_APPEND;
5290         }
5291         else if( EQUAL(papszArgv[i],"-overwrite") )
5292         {
5293             psOptions->eAccessMode = ACCESS_OVERWRITE;
5294         }
5295         else if( EQUAL(papszArgv[i],"-addfields") )
5296         {
5297             psOptions->bAddMissingFields = true;
5298             psOptions->eAccessMode = ACCESS_APPEND;
5299         }
5300         else if( EQUAL(papszArgv[i],"-update") )
5301         {
5302             /* Don't reset -append or -overwrite */
5303             if( psOptions->eAccessMode != ACCESS_APPEND && psOptions->eAccessMode != ACCESS_OVERWRITE )
5304                 psOptions->eAccessMode = ACCESS_UPDATE;
5305         }
5306         else if( EQUAL(papszArgv[i],"-relaxedFieldNameMatch") )
5307         {
5308             psOptions->bExactFieldNameMatch = false;
5309         }
5310         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-fid") )
5311         {
5312             psOptions->nFIDToFetch = CPLAtoGIntBig(papszArgv[++i]);
5313         }
5314         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-sql") )
5315         {
5316             i++;
5317             CPLFree(psOptions->pszSQLStatement);
5318             GByte* pabyRet = nullptr;
5319             if( papszArgv[i][0] == '@' &&
5320                 VSIIngestFile( nullptr, papszArgv[i] + 1, &pabyRet, nullptr, 1024*1024) )
5321             {
5322                 RemoveBOM(pabyRet);
5323                 psOptions->pszSQLStatement = reinterpret_cast<char*>(pabyRet);
5324                 RemoveSQLComments(psOptions->pszSQLStatement);
5325             }
5326             else
5327             {
5328                 psOptions->pszSQLStatement = CPLStrdup(papszArgv[i]);
5329             }
5330         }
5331         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-dialect") )
5332         {
5333             CPLFree(psOptions->pszDialect);
5334             psOptions->pszDialect = CPLStrdup(papszArgv[++i]);
5335         }
5336         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-nln") )
5337         {
5338             CPLFree(psOptions->pszNewLayerName);
5339             psOptions->pszNewLayerName = CPLStrdup(papszArgv[++i]);
5340         }
5341         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-nlt") )
5342         {
5343             bool bIs3D = false;
5344             CPLString osGeomName = papszArgv[i+1];
5345             if (strlen(papszArgv[i+1]) > 3 &&
5346                 STARTS_WITH_CI(papszArgv[i+1] + strlen(papszArgv[i+1]) - 3, "25D"))
5347             {
5348                 bIs3D = true;
5349                 osGeomName.resize(osGeomName.size() - 3);
5350             }
5351             else if (strlen(papszArgv[i+1]) > 1 &&
5352                 STARTS_WITH_CI(papszArgv[i+1] + strlen(papszArgv[i+1]) - 1, "Z"))
5353             {
5354                 bIs3D = true;
5355                 osGeomName.resize(osGeomName.size() - 1);
5356             }
5357             if( EQUAL(osGeomName,"NONE") )
5358                 psOptions->eGType = wkbNone;
5359             else if( EQUAL(osGeomName,"GEOMETRY") )
5360                 psOptions->eGType = wkbUnknown;
5361             else if( EQUAL(osGeomName,"PROMOTE_TO_MULTI") )
5362             {
5363                 if( psOptions->eGeomTypeConversion == GTC_CONVERT_TO_LINEAR )
5364                     psOptions->eGeomTypeConversion = GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR;
5365                 else
5366                     psOptions->eGeomTypeConversion = GTC_PROMOTE_TO_MULTI;
5367             }
5368             else if( EQUAL(osGeomName,"CONVERT_TO_LINEAR") )
5369             {
5370                 if( psOptions->eGeomTypeConversion == GTC_PROMOTE_TO_MULTI )
5371                     psOptions->eGeomTypeConversion = GTC_PROMOTE_TO_MULTI_AND_CONVERT_TO_LINEAR;
5372                 else
5373                     psOptions->eGeomTypeConversion = GTC_CONVERT_TO_LINEAR;
5374             }
5375             else if( EQUAL(osGeomName,"CONVERT_TO_CURVE") )
5376                 psOptions->eGeomTypeConversion = GTC_CONVERT_TO_CURVE;
5377             else
5378             {
5379                 psOptions->eGType = OGRFromOGCGeomType(osGeomName);
5380                 if (psOptions->eGType == wkbUnknown)
5381                 {
5382                     CPLError(CE_Failure, CPLE_IllegalArg,
5383                              "-nlt %s: type not recognised.",
5384                             papszArgv[i+1] );
5385                     GDALVectorTranslateOptionsFree(psOptions);
5386                     return nullptr;
5387                 }
5388             }
5389             if (psOptions->eGType != GEOMTYPE_UNCHANGED && psOptions->eGType != wkbNone && bIs3D)
5390                 psOptions->eGType = wkbSetZ(static_cast<OGRwkbGeometryType>(psOptions->eGType));
5391 
5392             i++;
5393         }
5394         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-dim") )
5395         {
5396             if( EQUAL(papszArgv[i+1], "layer_dim") )
5397                 psOptions->nCoordDim = COORD_DIM_LAYER_DIM;
5398             else if( EQUAL(papszArgv[i+1], "XY") || EQUAL(papszArgv[i+1], "2") )
5399                 psOptions->nCoordDim = 2;
5400             else if( EQUAL(papszArgv[i+1], "XYZ") || EQUAL(papszArgv[i+1], "3") )
5401                 psOptions->nCoordDim = 3;
5402             else if( EQUAL(papszArgv[i+1], "XYM") )
5403                 psOptions->nCoordDim = COORD_DIM_XYM;
5404             else if( EQUAL(papszArgv[i+1], "XYZM") )
5405                 psOptions->nCoordDim = 4;
5406             else
5407             {
5408                 CPLError(CE_Failure, CPLE_IllegalArg,"-dim %s: value not handled.",
5409                          papszArgv[i+1] );
5410                 GDALVectorTranslateOptionsFree(psOptions);
5411                 return nullptr;
5412             }
5413             i++;
5414         }
5415         else if( i+1 < nArgc && (EQUAL(papszArgv[i],"-tg") ||
5416                                  EQUAL(papszArgv[i],"-gt")) )
5417         {
5418             ++i;
5419             /* If skipfailures is already set we should not
5420                modify nGroupTransactions = 1  #2409 */
5421             if ( !psOptions->bSkipFailures )
5422             {
5423                 if( EQUAL(papszArgv[i], "unlimited") )
5424                     psOptions->nGroupTransactions = -1;
5425                 else
5426                     psOptions->nGroupTransactions = atoi(papszArgv[i]);
5427             }
5428         }
5429         else if ( EQUAL(papszArgv[i],"-ds_transaction") )
5430         {
5431             psOptions->nLayerTransaction = FALSE;
5432             psOptions->bForceTransaction = true;
5433         }
5434         /* Undocumented. Just a provision. Default behavior should be OK */
5435         else if ( EQUAL(papszArgv[i],"-lyr_transaction") )
5436         {
5437             psOptions->nLayerTransaction = TRUE;
5438         }
5439         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-s_srs") )
5440         {
5441             CPLFree(psOptions->pszSourceSRSDef);
5442             psOptions->pszSourceSRSDef = CPLStrdup(papszArgv[++i]);
5443         }
5444         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-a_srs") )
5445         {
5446             CPLFree(psOptions->pszOutputSRSDef);
5447             psOptions->pszOutputSRSDef = CPLStrdup(papszArgv[++i]);
5448             if (EQUAL(psOptions->pszOutputSRSDef, "NULL") ||
5449                 EQUAL(psOptions->pszOutputSRSDef, "NONE"))
5450             {
5451                 psOptions->pszOutputSRSDef = nullptr;
5452                 psOptions->bNullifyOutputSRS = true;
5453             }
5454         }
5455         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-t_srs") )
5456         {
5457             CPLFree(psOptions->pszOutputSRSDef);
5458             psOptions->pszOutputSRSDef = CPLStrdup(papszArgv[++i]);
5459             psOptions->bTransform = true;
5460         }
5461         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-ct") )
5462         {
5463             CPLFree(psOptions->pszCTPipeline);
5464             psOptions->pszCTPipeline = CPLStrdup(papszArgv[++i]);
5465             psOptions->bTransform = true;
5466         }
5467         else if( i+4 < nArgc && EQUAL(papszArgv[i],"-spat") )
5468         {
5469             OGRLinearRing  oRing;
5470 
5471             oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5472             oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+4]) );
5473             oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+4]) );
5474             oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+2]) );
5475             oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5476 
5477             OGRPolygon* poSpatialFilter = new OGRPolygon();
5478             poSpatialFilter->addRing( &oRing );
5479             OGR_G_DestroyGeometry(psOptions->hSpatialFilter);
5480             psOptions->hSpatialFilter = reinterpret_cast<OGRGeometryH>(poSpatialFilter);
5481             i += 4;
5482         }
5483         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-spat_srs") )
5484         {
5485             CPLFree(psOptions->pszSpatSRSDef);
5486             psOptions->pszSpatSRSDef = CPLStrdup(papszArgv[++i]);
5487         }
5488         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-geomfield") )
5489         {
5490             CPLFree(psOptions->pszGeomField);
5491             psOptions->pszGeomField = CPLStrdup(papszArgv[++i]);
5492         }
5493         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-where") )
5494         {
5495             i++;
5496             CPLFree(psOptions->pszWHERE);
5497             GByte* pabyRet = nullptr;
5498             if( papszArgv[i][0] == '@' &&
5499                 VSIIngestFile( nullptr, papszArgv[i] + 1, &pabyRet, nullptr, 1024*1024) )
5500             {
5501                 RemoveBOM(pabyRet);
5502                 psOptions->pszWHERE = reinterpret_cast<char*>(pabyRet);
5503             }
5504             else
5505             {
5506                 psOptions->pszWHERE = CPLStrdup(papszArgv[i]);
5507             }
5508         }
5509         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-select") )
5510         {
5511             const char* pszSelect = papszArgv[++i];
5512             CSLDestroy(psOptions->papszSelFields);
5513             psOptions->papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,",
5514                                                       FALSE, FALSE );
5515         }
5516         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-segmentize") )
5517         {
5518             psOptions->eGeomOp = GEOMOP_SEGMENTIZE;
5519             psOptions->dfGeomOpParam = CPLAtof(papszArgv[++i]);
5520         }
5521         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-simplify") )
5522         {
5523             psOptions->eGeomOp = GEOMOP_SIMPLIFY_PRESERVE_TOPOLOGY;
5524             psOptions->dfGeomOpParam = CPLAtof(papszArgv[++i]);
5525         }
5526         else if( EQUAL(papszArgv[i],"-makevalid") )
5527         {
5528             // Check that OGRGeometry::MakeValid() is available
5529             OGRGeometry* poInputGeom = nullptr;
5530             OGRGeometryFactory::createFromWkt(
5531                 "POLYGON((0 0,1 1,1 0,0 1,0 0))", nullptr, &poInputGeom );
5532             CPLAssert(poInputGeom);
5533             OGRGeometry* poValidGeom = poInputGeom->MakeValid();
5534             delete poInputGeom;
5535             if( poValidGeom == nullptr )
5536             {
5537                 CPLError(CE_Failure, CPLE_NotSupported,
5538                         "-makevalid only supported for builds against GEOS 3.8 or later");
5539                 GDALVectorTranslateOptionsFree(psOptions);
5540                 return nullptr;
5541             }
5542             delete poValidGeom;
5543             psOptions->bMakeValid = true;
5544         }
5545         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-fieldTypeToString") )
5546         {
5547             CSLDestroy(psOptions->papszFieldTypesToString);
5548             psOptions->papszFieldTypesToString =
5549                     CSLTokenizeStringComplex(papszArgv[++i], " ,",
5550                                              FALSE, FALSE );
5551             char** iter = psOptions->papszFieldTypesToString;
5552             while(*iter)
5553             {
5554                 if (IsFieldType(*iter))
5555                 {
5556                     /* Do nothing */
5557                 }
5558                 else if (EQUAL(*iter, "All"))
5559                 {
5560                     CSLDestroy(psOptions->papszFieldTypesToString);
5561                     psOptions->papszFieldTypesToString = nullptr;
5562                     psOptions->papszFieldTypesToString = CSLAddString(psOptions->papszFieldTypesToString, "All");
5563                     break;
5564                 }
5565                 else
5566                 {
5567                     CPLError(CE_Failure, CPLE_IllegalArg,
5568                              "Unhandled type for fieldTypeToString option : %s",
5569                             *iter);
5570                     GDALVectorTranslateOptionsFree(psOptions);
5571                     return nullptr;
5572                 }
5573                 iter ++;
5574             }
5575         }
5576         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-mapFieldType") )
5577         {
5578             CSLDestroy(psOptions->papszMapFieldType);
5579             psOptions->papszMapFieldType =
5580                     CSLTokenizeStringComplex(papszArgv[++i], " ,",
5581                                              FALSE, FALSE );
5582             char** iter = psOptions->papszMapFieldType;
5583             while(*iter)
5584             {
5585                 char* pszKey = nullptr;
5586                 const char* pszValue = CPLParseNameValue(*iter, &pszKey);
5587                 if( pszKey && pszValue)
5588                 {
5589                     if( !((IsFieldType(pszKey) || EQUAL(pszKey, "All")) && IsFieldType(pszValue)) )
5590                     {
5591                         CPLError(CE_Failure, CPLE_IllegalArg,
5592                                 "Invalid value for -mapFieldType : %s",
5593                                 *iter);
5594                         CPLFree(pszKey);
5595                         GDALVectorTranslateOptionsFree(psOptions);
5596                         return nullptr;
5597                     }
5598                 }
5599                 CPLFree(pszKey);
5600                 iter ++;
5601             }
5602         }
5603         else if( EQUAL(papszArgv[i],"-unsetFieldWidth") )
5604         {
5605             psOptions->bUnsetFieldWidth = true;
5606         }
5607         else if( EQUAL(papszArgv[i],"-progress") )
5608         {
5609             psOptions->bDisplayProgress = true;
5610         }
5611         else if( EQUAL(papszArgv[i],"-wrapdateline") )
5612         {
5613             psOptions->bWrapDateline = true;
5614         }
5615         else if( i < nArgc-1 && EQUAL(papszArgv[i],"-datelineoffset") )
5616         {
5617             psOptions->dfDateLineOffset = CPLAtof(papszArgv[++i]);
5618         }
5619         else if( EQUAL(papszArgv[i],"-clipsrc") )
5620         {
5621             if (i + 1 >= nArgc)
5622             {
5623                 CPLError(CE_Failure, CPLE_IllegalArg, "%s option requires 1 or 4 arguments", papszArgv[i]);
5624                 GDALVectorTranslateOptionsFree(psOptions);
5625                 return nullptr;
5626             }
5627 
5628             OGR_G_DestroyGeometry(psOptions->hClipSrc);
5629             psOptions->hClipSrc = nullptr;
5630             CPLFree(psOptions->pszClipSrcDS);
5631             psOptions->pszClipSrcDS = nullptr;
5632 
5633             VSIStatBufL  sStat;
5634             psOptions->bClipSrc = true;
5635             if ( IsNumber(papszArgv[i+1])
5636                  && papszArgv[i+2] != nullptr
5637                  && papszArgv[i+3] != nullptr
5638                  && papszArgv[i+4] != nullptr)
5639             {
5640                 OGRLinearRing  oRing;
5641 
5642                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5643                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+4]) );
5644                 oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+4]) );
5645                 oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+2]) );
5646                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5647 
5648                 OGRPolygon* poPoly = new OGRPolygon();
5649                 psOptions->hClipSrc = reinterpret_cast<OGRGeometryH>(poPoly);
5650                 poPoly->addRing( &oRing );
5651                 i += 4;
5652             }
5653             else if ((STARTS_WITH_CI(papszArgv[i+1], "POLYGON") ||
5654                       STARTS_WITH_CI(papszArgv[i+1], "MULTIPOLYGON")) &&
5655                       VSIStatL(papszArgv[i+1], &sStat) != 0)
5656             {
5657                 OGRGeometryFactory::createFromWkt(papszArgv[i+1], nullptr,
5658                         reinterpret_cast<OGRGeometry **>(&psOptions->hClipSrc));
5659                 if (psOptions->hClipSrc == nullptr)
5660                 {
5661                     CPLError(CE_Failure, CPLE_IllegalArg,
5662                              "Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT");
5663                     GDALVectorTranslateOptionsFree(psOptions);
5664                     return nullptr;
5665                 }
5666                 i ++;
5667             }
5668             else if (EQUAL(papszArgv[i+1], "spat_extent") )
5669             {
5670                 i ++;
5671             }
5672             else
5673             {
5674                 psOptions->pszClipSrcDS = CPLStrdup(papszArgv[i+1]);
5675                 i ++;
5676             }
5677         }
5678         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipsrcsql") )
5679         {
5680             CPLFree(psOptions->pszClipSrcSQL);
5681             psOptions->pszClipSrcSQL = CPLStrdup(papszArgv[i+1]);
5682             i ++;
5683         }
5684         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipsrclayer") )
5685         {
5686             CPLFree(psOptions->pszClipSrcLayer);
5687             psOptions->pszClipSrcLayer = CPLStrdup(papszArgv[i+1]);
5688             i ++;
5689         }
5690         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipsrcwhere") )
5691         {
5692             CPLFree(psOptions->pszClipSrcWhere);
5693             psOptions->pszClipSrcWhere = CPLStrdup(papszArgv[i+1]);
5694             i ++;
5695         }
5696         else if( EQUAL(papszArgv[i],"-clipdst") )
5697         {
5698             if (i + 1 >= nArgc)
5699             {
5700                 CPLError(CE_Failure, CPLE_IllegalArg, "%s option requires 1 or 4 arguments", papszArgv[i]);
5701                 GDALVectorTranslateOptionsFree(psOptions);
5702                 return nullptr;
5703             }
5704 
5705             OGR_G_DestroyGeometry(psOptions->hClipDst);
5706             psOptions->hClipDst = nullptr;
5707             CPLFree(psOptions->pszClipDstDS);
5708             psOptions->pszClipDstDS = nullptr;
5709 
5710             VSIStatBufL  sStat;
5711             if ( IsNumber(papszArgv[i+1])
5712                  && papszArgv[i+2] != nullptr
5713                  && papszArgv[i+3] != nullptr
5714                  && papszArgv[i+4] != nullptr)
5715             {
5716                 OGRLinearRing  oRing;
5717 
5718                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5719                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+4]) );
5720                 oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+4]) );
5721                 oRing.addPoint( CPLAtof(papszArgv[i+3]), CPLAtof(papszArgv[i+2]) );
5722                 oRing.addPoint( CPLAtof(papszArgv[i+1]), CPLAtof(papszArgv[i+2]) );
5723 
5724                 OGRPolygon* poPoly = new OGRPolygon();
5725                 psOptions->hClipDst = reinterpret_cast<OGRGeometryH>(poPoly);
5726                 poPoly->addRing( &oRing );
5727                 i += 4;
5728             }
5729             else if ((STARTS_WITH_CI(papszArgv[i+1], "POLYGON") ||
5730                       STARTS_WITH_CI(papszArgv[i+1], "MULTIPOLYGON")) &&
5731                       VSIStatL(papszArgv[i+1], &sStat) != 0)
5732             {
5733                 OGRGeometryFactory::createFromWkt(papszArgv[i+1],
5734                     nullptr, reinterpret_cast<OGRGeometry **>(&psOptions->hClipDst));
5735                 if (psOptions->hClipDst == nullptr)
5736                 {
5737                     CPLError(CE_Failure, CPLE_IllegalArg,
5738                              "Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT");
5739                     GDALVectorTranslateOptionsFree(psOptions);
5740                     return nullptr;
5741                 }
5742                 i ++;
5743             }
5744             else
5745             {
5746                 psOptions->pszClipDstDS = CPLStrdup(papszArgv[i+1]);
5747                 i ++;
5748             }
5749         }
5750         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipdstsql") )
5751         {
5752             CPLFree(psOptions->pszClipDstSQL);
5753             psOptions->pszClipDstSQL = CPLStrdup(papszArgv[i+1]);
5754             i ++;
5755         }
5756         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipdstlayer") )
5757         {
5758             CPLFree(psOptions->pszClipDstLayer);
5759             psOptions->pszClipDstLayer = CPLStrdup(papszArgv[i+1]);
5760             i ++;
5761         }
5762         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-clipdstwhere") )
5763         {
5764             CPLFree(psOptions->pszClipDstWhere);
5765             psOptions->pszClipDstWhere = CPLStrdup(papszArgv[i+1]);
5766             i ++;
5767         }
5768         else if( EQUAL(papszArgv[i],"-splitlistfields") )
5769         {
5770             psOptions->bSplitListFields = true;
5771         }
5772         else if ( i+1 < nArgc && EQUAL(papszArgv[i],"-maxsubfields") )
5773         {
5774             if (IsNumber(papszArgv[i+1]))
5775             {
5776                 int nTemp = atoi(papszArgv[i+1]);
5777                 if (nTemp > 0)
5778                 {
5779                     psOptions->nMaxSplitListSubFields = nTemp;
5780                     i ++;
5781                 }
5782             }
5783         }
5784         else if( EQUAL(papszArgv[i],"-explodecollections") )
5785         {
5786             psOptions->bExplodeCollections = true;
5787         }
5788         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-zfield") )
5789         {
5790             CPLFree(psOptions->pszZField);
5791             psOptions->pszZField = CPLStrdup(papszArgv[i+1]);
5792             i ++;
5793         }
5794         else if( i+4 < nArgc && EQUAL(papszArgv[i],"-gcp") )
5795         {
5796             char* endptr = nullptr;
5797             /* -gcp pixel line easting northing [elev] */
5798 
5799             psOptions->nGCPCount++;
5800             psOptions->pasGCPs = static_cast<GDAL_GCP *>(
5801                 CPLRealloc(psOptions->pasGCPs,
5802                            sizeof(GDAL_GCP) * psOptions->nGCPCount));
5803             GDALInitGCPs( 1, psOptions->pasGCPs + psOptions->nGCPCount - 1 );
5804 
5805             psOptions->pasGCPs[psOptions->nGCPCount-1].dfGCPPixel = CPLAtof(papszArgv[++i]);
5806             psOptions->pasGCPs[psOptions->nGCPCount-1].dfGCPLine = CPLAtof(papszArgv[++i]);
5807             psOptions->pasGCPs[psOptions->nGCPCount-1].dfGCPX = CPLAtof(papszArgv[++i]);
5808             psOptions->pasGCPs[psOptions->nGCPCount-1].dfGCPY = CPLAtof(papszArgv[++i]);
5809             if( papszArgv[i+1] != nullptr
5810                 && (CPLStrtod(papszArgv[i+1], &endptr) != 0.0 || papszArgv[i+1][0] == '0') )
5811             {
5812                 /* Check that last argument is really a number and not a filename */
5813                 /* looking like a number (see ticket #863) */
5814                 if (endptr && *endptr == 0)
5815                     psOptions->pasGCPs[psOptions->nGCPCount-1].dfGCPZ = CPLAtof(papszArgv[++i]);
5816             }
5817 
5818             /* should set id and info? */
5819         }
5820         else if( EQUAL(papszArgv[i],"-tps") )
5821         {
5822             psOptions->nTransformOrder = -1;
5823         }
5824         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-order") )
5825         {
5826             psOptions->nTransformOrder = atoi( papszArgv[++i] );
5827         }
5828         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-fieldmap") )
5829         {
5830             CSLDestroy(psOptions->papszFieldMap);
5831             psOptions->papszFieldMap = CSLTokenizeStringComplex(papszArgv[++i], ",",
5832                                                       FALSE, FALSE );
5833         }
5834         else if( EQUAL(papszArgv[i],"-emptyStrAsNull") )
5835         {
5836             psOptions->bEmptyStrAsNull = true;
5837         }
5838         else if( EQUAL(papszArgv[i],"-forceNullable") )
5839         {
5840             psOptions->bForceNullable = true;
5841         }
5842         else if( EQUAL(papszArgv[i],"-resolveDomains") )
5843         {
5844             psOptions->bResolveDomains = true;
5845         }
5846         else if( EQUAL(papszArgv[i],"-unsetDefault") )
5847         {
5848             psOptions->bUnsetDefault = true;
5849         }
5850         else if( EQUAL(papszArgv[i],"-unsetFid") )
5851         {
5852             psOptions->bUnsetFid = true;
5853         }
5854         else if( EQUAL(papszArgv[i],"-nomd") )
5855         {
5856             psOptions->bCopyMD = false;
5857         }
5858         else if( EQUAL(papszArgv[i],"-noNativeData") )
5859         {
5860             psOptions->bNativeData = false;
5861         }
5862         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-mo") )
5863         {
5864             psOptions->papszMetadataOptions = CSLAddString( psOptions->papszMetadataOptions,
5865                                                  papszArgv[++i] );
5866         }
5867         else if( i+1 < nArgc && EQUAL(papszArgv[i],"-limit") )
5868         {
5869             psOptions->nLimit = CPLAtoGIntBig( papszArgv[++i] );
5870         }
5871         else if( papszArgv[i][0] == '-' )
5872         {
5873             CPLError(CE_Failure, CPLE_NotSupported,
5874                      "Unknown option name '%s'", papszArgv[i]);
5875             GDALVectorTranslateOptionsFree(psOptions);
5876             return nullptr;
5877         }
5878         else if( psOptionsForBinary && psOptionsForBinary->pszDestDataSource == nullptr )
5879             psOptionsForBinary->pszDestDataSource = CPLStrdup(papszArgv[i]);
5880         else if(  psOptionsForBinary && psOptionsForBinary->pszDataSource == nullptr )
5881             psOptionsForBinary->pszDataSource = CPLStrdup(papszArgv[i]);
5882         else
5883             psOptions->papszLayers = CSLAddString( psOptions->papszLayers, papszArgv[i] );
5884     }
5885 
5886     if( psOptionsForBinary )
5887     {
5888         psOptionsForBinary->eAccessMode = psOptions->eAccessMode;
5889         if( psOptions->pszFormat )
5890             psOptionsForBinary->pszFormat = CPLStrdup( psOptions->pszFormat );
5891 
5892         if( !(CPLTestBool(CSLFetchNameValueDef(
5893                 psOptionsForBinary->papszOpenOptions, "NATIVE_DATA",
5894                 CSLFetchNameValueDef(
5895                     psOptionsForBinary->papszOpenOptions, "@NATIVE_DATA", "TRUE")))) )
5896         {
5897             psOptions->bNativeData = false;
5898         }
5899 
5900         if( psOptions->bNativeData &&
5901             CSLFetchNameValue(psOptionsForBinary->papszOpenOptions,
5902                               "NATIVE_DATA") == nullptr &&
5903             CSLFetchNameValue(psOptionsForBinary->papszOpenOptions,
5904                               "@NATIVE_DATA") == nullptr )
5905         {
5906             psOptionsForBinary->papszOpenOptions = CSLAddString(
5907                 psOptionsForBinary->papszOpenOptions, "@NATIVE_DATA=YES" );
5908         }
5909     }
5910 
5911     return psOptions;
5912 }
5913 
5914 /************************************************************************/
5915 /*                      GDALVectorTranslateOptionsFree()                */
5916 /************************************************************************/
5917 
5918 /**
5919  * Frees the GDALVectorTranslateOptions struct.
5920  *
5921  * @param psOptions the options struct for GDALVectorTranslate().
5922  * @since GDAL 2.1
5923  */
5924 
GDALVectorTranslateOptionsFree(GDALVectorTranslateOptions * psOptions)5925 void GDALVectorTranslateOptionsFree( GDALVectorTranslateOptions *psOptions )
5926 {
5927     if( psOptions == nullptr )
5928         return;
5929 
5930     CPLFree( psOptions->pszFormat );
5931     CPLFree( psOptions->pszOutputSRSDef);
5932     CPLFree( psOptions->pszSourceSRSDef);
5933     CPLFree( psOptions->pszCTPipeline );
5934     CPLFree( psOptions->pszNewLayerName);
5935     CPLFree( psOptions->pszWHERE );
5936     CPLFree( psOptions->pszGeomField );
5937     CPLFree( psOptions->pszSQLStatement );
5938     CPLFree( psOptions->pszDialect );
5939     CPLFree( psOptions->pszClipSrcDS );
5940     CPLFree( psOptions->pszClipSrcSQL );
5941     CPLFree( psOptions->pszClipSrcLayer );
5942     CPLFree( psOptions->pszClipSrcWhere );
5943     CPLFree( psOptions->pszClipDstDS );
5944     CPLFree( psOptions->pszClipDstSQL );
5945     CPLFree( psOptions->pszClipDstLayer );
5946     CPLFree( psOptions->pszClipDstWhere );
5947     CPLFree( psOptions->pszZField );
5948     CPLFree( psOptions->pszSpatSRSDef );
5949     CSLDestroy(psOptions->papszSelFields);
5950     CSLDestroy( psOptions->papszFieldMap );
5951     CSLDestroy( psOptions->papszMapFieldType );
5952     CSLDestroy( psOptions->papszLayers );
5953     CSLDestroy( psOptions->papszDSCO );
5954     CSLDestroy( psOptions->papszLCO );
5955     CSLDestroy( psOptions->papszDestOpenOptions );
5956     CSLDestroy( psOptions->papszFieldTypesToString );
5957     CSLDestroy( psOptions->papszMetadataOptions );
5958 
5959     if( psOptions->pasGCPs != nullptr )
5960     {
5961         GDALDeinitGCPs( psOptions->nGCPCount, psOptions->pasGCPs );
5962         CPLFree( psOptions->pasGCPs );
5963     }
5964 
5965     if( psOptions->hClipSrc != nullptr )
5966         OGR_G_DestroyGeometry( psOptions->hClipSrc );
5967     if( psOptions->hClipDst != nullptr )
5968         OGR_G_DestroyGeometry( psOptions->hClipDst );
5969     if( psOptions->hSpatialFilter != nullptr )
5970         OGR_G_DestroyGeometry( psOptions->hSpatialFilter );
5971 
5972     CPLFree(psOptions);
5973 }
5974 
5975 /************************************************************************/
5976 /*                 GDALVectorTranslateOptionsSetProgress()              */
5977 /************************************************************************/
5978 
5979 /**
5980  * Set a progress function.
5981  *
5982  * @param psOptions the options struct for GDALVectorTranslate().
5983  * @param pfnProgress the progress callback.
5984  * @param pProgressData the user data for the progress callback.
5985  *
5986  * @since GDAL 2.1
5987  */
5988 
GDALVectorTranslateOptionsSetProgress(GDALVectorTranslateOptions * psOptions,GDALProgressFunc pfnProgress,void * pProgressData)5989 void GDALVectorTranslateOptionsSetProgress( GDALVectorTranslateOptions *psOptions,
5990                                       GDALProgressFunc pfnProgress, void *pProgressData )
5991 {
5992     psOptions->pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress;
5993     psOptions->pProgressData = pProgressData;
5994     if( pfnProgress == GDALTermProgress )
5995         psOptions->bQuiet = false;
5996 }
5997