1 : /******************************************************************************
2 : * $Id: ogr2ogr.cpp 24202 2012-04-06 19:10:22Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Simple client for translating between formats.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 1999, Frank Warmerdam
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogrsf_frmts.h"
31 : #include "ogr_p.h"
32 : #include "cpl_conv.h"
33 : #include "cpl_string.h"
34 : #include "ogr_api.h"
35 : #include "gdal.h"
36 :
37 : CPL_CVSID("$Id: ogr2ogr.cpp 24202 2012-04-06 19:10:22Z rouault $");
38 :
39 : static int bSkipFailures = FALSE;
40 : static int nGroupTransactions = 200;
41 : static int bPreserveFID = FALSE;
42 : static int nFIDToFetch = OGRNullFID;
43 :
44 : static void Usage(int bShort = TRUE);
45 :
46 : typedef enum
47 : {
48 : NONE,
49 : SEGMENTIZE,
50 : SIMPLIFY_PRESERVE_TOPOLOGY,
51 : } GeomOperation;
52 :
53 : static int TranslateLayer( OGRDataSource *poSrcDS,
54 : OGRLayer * poSrcLayer,
55 : OGRDataSource *poDstDS,
56 : char ** papszLSCO,
57 : const char *pszNewLayerName,
58 : int bTransform,
59 : OGRSpatialReference *poOutputSRS,
60 : int bNullifyOutputSRS,
61 : OGRSpatialReference *poSourceSRS,
62 : char **papszSelFields,
63 : int bAppend, int eGType,
64 : int bOverwrite,
65 : GeomOperation eGeomOp,
66 : double dfGeomOpParam,
67 : char** papszFieldTypesToString,
68 : long nCountLayerFeatures,
69 : int bWrapDateline,
70 : OGRGeometry* poClipSrc,
71 : OGRGeometry *poClipDst,
72 : int bExplodeCollections,
73 : const char* pszZField,
74 : const char* pszWHERE,
75 : GDALProgressFunc pfnProgress,
76 : void *pProgressArg);
77 :
78 :
79 : /* -------------------------------------------------------------------- */
80 : /* CheckDestDataSourceNameConsistency() */
81 : /* -------------------------------------------------------------------- */
82 :
83 : static
84 72 : void CheckDestDataSourceNameConsistency(const char* pszDestFilename,
85 : const char* pszDriverName)
86 : {
87 : int i;
88 72 : char* pszDestExtension = CPLStrdup(CPLGetExtension(pszDestFilename));
89 :
90 : /* TODO: Would be good to have driver metadata like for GDAL drivers ! */
91 : static const char* apszExtensions[][2] = { { "shp" , "ESRI Shapefile" },
92 : { "dbf" , "ESRI Shapefile" },
93 : { "sqlite" , "SQLite" },
94 : { "db" , "SQLite" },
95 : { "mif" , "MapInfo File" },
96 : { "tab" , "MapInfo File" },
97 : { "s57" , "S57" },
98 : { "bna" , "BNA" },
99 : { "csv" , "CSV" },
100 : { "gml" , "GML" },
101 : { "kml" , "KML/LIBKML" },
102 : { "kmz" , "LIBKML" },
103 : { "json" , "GeoJSON" },
104 : { "geojson", "GeoJSON" },
105 : { "dxf" , "DXF" },
106 : { "gdb" , "FileGDB" },
107 : { "pix" , "PCIDSK" },
108 : { "sql" , "PGDump" },
109 : { "gtm" , "GPSTrackMaker" },
110 : { "gmt" , "GMT" },
111 : { NULL, NULL }
112 : };
113 : static const char* apszBeginName[][2] = { { "PG:" , "PG" },
114 : { "MySQL:" , "MySQL" },
115 : { "CouchDB:" , "CouchDB" },
116 : { "GFT:" , "GFT" },
117 : { "MSSQL:" , "MSSQLSpatial" },
118 : { "ODBC:" , "ODBC" },
119 : { "OCI:" , "OCI" },
120 : { "SDE:" , "SDE" },
121 : { "WFS:" , "WFS" },
122 : { NULL, NULL }
123 : };
124 :
125 1512 : for(i=0; apszExtensions[i][0] != NULL; i++)
126 : {
127 1440 : if (EQUAL(pszDestExtension, apszExtensions[i][0]) && !EQUAL(pszDriverName, apszExtensions[i][1]))
128 : {
129 : fprintf(stderr,
130 : "Warning: The target file has a '%s' extension, which is normally used by the %s driver,\n"
131 : "but the requested output driver is %s. Is it really what you want ?\n",
132 : pszDestExtension,
133 : apszExtensions[i][1],
134 0 : pszDriverName);
135 0 : break;
136 : }
137 : }
138 :
139 720 : for(i=0; apszBeginName[i][0] != NULL; i++)
140 : {
141 648 : if (EQUALN(pszDestFilename, apszBeginName[i][0], strlen(apszBeginName[i][0])) &&
142 : !EQUAL(pszDriverName, apszBeginName[i][1]))
143 : {
144 : fprintf(stderr,
145 : "Warning: The target file has a name which is normally recognized by the %s driver,\n"
146 : "but the requested output driver is %s. Is it really what you want ?\n",
147 : apszBeginName[i][1],
148 0 : pszDriverName);
149 0 : break;
150 : }
151 : }
152 :
153 72 : CPLFree(pszDestExtension);
154 72 : }
155 :
156 : /************************************************************************/
157 : /* IsNumber() */
158 : /************************************************************************/
159 :
160 10 : static int IsNumber(const char* pszStr)
161 : {
162 10 : if (*pszStr == '-' || *pszStr == '+')
163 0 : pszStr ++;
164 10 : if (*pszStr == '.')
165 0 : pszStr ++;
166 10 : return (*pszStr >= '0' && *pszStr <= '9');
167 : }
168 :
169 : /************************************************************************/
170 : /* LoadGeometry() */
171 : /************************************************************************/
172 :
173 4 : static OGRGeometry* LoadGeometry( const char* pszDS,
174 : const char* pszSQL,
175 : const char* pszLyr,
176 : const char* pszWhere)
177 : {
178 : OGRDataSource *poDS;
179 : OGRLayer *poLyr;
180 : OGRFeature *poFeat;
181 4 : OGRGeometry *poGeom = NULL;
182 :
183 4 : poDS = OGRSFDriverRegistrar::Open( pszDS, FALSE );
184 4 : if (poDS == NULL)
185 0 : return NULL;
186 :
187 4 : if (pszSQL != NULL)
188 2 : poLyr = poDS->ExecuteSQL( pszSQL, NULL, NULL );
189 2 : else if (pszLyr != NULL)
190 0 : poLyr = poDS->GetLayerByName(pszLyr);
191 : else
192 2 : poLyr = poDS->GetLayer(0);
193 :
194 4 : if (poLyr == NULL)
195 : {
196 0 : fprintf( stderr, "Failed to identify source layer from datasource.\n" );
197 0 : OGRDataSource::DestroyDataSource(poDS);
198 0 : return NULL;
199 : }
200 :
201 4 : if (pszWhere)
202 2 : poLyr->SetAttributeFilter(pszWhere);
203 :
204 12 : while ((poFeat = poLyr->GetNextFeature()) != NULL)
205 : {
206 4 : OGRGeometry* poSrcGeom = poFeat->GetGeometryRef();
207 4 : if (poSrcGeom)
208 : {
209 4 : OGRwkbGeometryType eType = wkbFlatten( poSrcGeom->getGeometryType() );
210 :
211 4 : if (poGeom == NULL)
212 4 : poGeom = OGRGeometryFactory::createGeometry( wkbMultiPolygon );
213 :
214 4 : if( eType == wkbPolygon )
215 4 : ((OGRGeometryCollection*)poGeom)->addGeometry( poSrcGeom );
216 0 : else if( eType == wkbMultiPolygon )
217 : {
218 : int iGeom;
219 0 : int nGeomCount = OGR_G_GetGeometryCount( (OGRGeometryH)poSrcGeom );
220 :
221 0 : for( iGeom = 0; iGeom < nGeomCount; iGeom++ )
222 : {
223 : ((OGRGeometryCollection*)poGeom)->addGeometry(
224 0 : ((OGRGeometryCollection*)poSrcGeom)->getGeometryRef(iGeom) );
225 : }
226 : }
227 : else
228 : {
229 0 : fprintf( stderr, "ERROR: Geometry not of polygon type.\n" );
230 0 : OGRGeometryFactory::destroyGeometry(poGeom);
231 0 : OGRFeature::DestroyFeature(poFeat);
232 0 : if( pszSQL != NULL )
233 0 : poDS->ReleaseResultSet( poLyr );
234 0 : OGRDataSource::DestroyDataSource(poDS);
235 0 : return NULL;
236 : }
237 : }
238 :
239 4 : OGRFeature::DestroyFeature(poFeat);
240 : }
241 :
242 4 : if( pszSQL != NULL )
243 2 : poDS->ReleaseResultSet( poLyr );
244 4 : OGRDataSource::DestroyDataSource(poDS);
245 :
246 4 : return poGeom;
247 : }
248 :
249 :
250 : /************************************************************************/
251 : /* OGRSplitListFieldLayer */
252 : /************************************************************************/
253 :
254 : typedef struct
255 : {
256 : int iSrcIndex;
257 : OGRFieldType eType;
258 : int nMaxOccurences;
259 : int nWidth;
260 : } ListFieldDesc;
261 :
262 : class OGRSplitListFieldLayer : public OGRLayer
263 : {
264 : OGRLayer *poSrcLayer;
265 : OGRFeatureDefn *poFeatureDefn;
266 : ListFieldDesc *pasListFields;
267 : int nListFieldCount;
268 : int nMaxSplitListSubFields;
269 :
270 : OGRFeature *TranslateFeature(OGRFeature* poSrcFeature);
271 :
272 : public:
273 : OGRSplitListFieldLayer(OGRLayer* poSrcLayer,
274 : int nMaxSplitListSubFields);
275 : ~OGRSplitListFieldLayer();
276 :
277 : int BuildLayerDefn(GDALProgressFunc pfnProgress,
278 : void *pProgressArg);
279 :
280 : virtual OGRFeature *GetNextFeature();
281 : virtual OGRFeature *GetFeature(long nFID);
282 : virtual OGRFeatureDefn *GetLayerDefn();
283 :
284 2 : virtual void ResetReading() { poSrcLayer->ResetReading(); }
285 0 : virtual int TestCapability(const char*) { return FALSE; }
286 :
287 0 : virtual int GetFeatureCount( int bForce = TRUE )
288 : {
289 0 : return poSrcLayer->GetFeatureCount(bForce);
290 : }
291 :
292 2 : virtual OGRSpatialReference *GetSpatialRef()
293 : {
294 2 : return poSrcLayer->GetSpatialRef();
295 : }
296 :
297 0 : virtual OGRGeometry *GetSpatialFilter()
298 : {
299 0 : return poSrcLayer->GetSpatialFilter();
300 : }
301 :
302 2 : virtual OGRStyleTable *GetStyleTable()
303 : {
304 2 : return poSrcLayer->GetStyleTable();
305 : }
306 :
307 0 : virtual void SetSpatialFilter( OGRGeometry *poGeom )
308 : {
309 0 : poSrcLayer->SetSpatialFilter(poGeom);
310 0 : }
311 :
312 0 : virtual void SetSpatialFilterRect( double dfMinX, double dfMinY,
313 : double dfMaxX, double dfMaxY )
314 : {
315 0 : poSrcLayer->SetSpatialFilterRect(dfMinX, dfMinY, dfMaxX, dfMaxY);
316 0 : }
317 :
318 0 : virtual OGRErr SetAttributeFilter( const char *pszFilter )
319 : {
320 0 : return poSrcLayer->SetAttributeFilter(pszFilter);
321 : }
322 : };
323 :
324 : /************************************************************************/
325 : /* OGRSplitListFieldLayer() */
326 : /************************************************************************/
327 :
328 2 : OGRSplitListFieldLayer::OGRSplitListFieldLayer(OGRLayer* poSrcLayer,
329 2 : int nMaxSplitListSubFields)
330 : {
331 2 : this->poSrcLayer = poSrcLayer;
332 2 : if (nMaxSplitListSubFields < 0)
333 2 : nMaxSplitListSubFields = INT_MAX;
334 2 : this->nMaxSplitListSubFields = nMaxSplitListSubFields;
335 2 : poFeatureDefn = NULL;
336 2 : pasListFields = NULL;
337 2 : nListFieldCount = 0;
338 2 : }
339 :
340 : /************************************************************************/
341 : /* ~OGRSplitListFieldLayer() */
342 : /************************************************************************/
343 :
344 2 : OGRSplitListFieldLayer::~OGRSplitListFieldLayer()
345 : {
346 2 : if( poFeatureDefn )
347 2 : poFeatureDefn->Release();
348 :
349 2 : CPLFree(pasListFields);
350 2 : }
351 :
352 : /************************************************************************/
353 : /* BuildLayerDefn() */
354 : /************************************************************************/
355 :
356 2 : int OGRSplitListFieldLayer::BuildLayerDefn(GDALProgressFunc pfnProgress,
357 : void *pProgressArg)
358 : {
359 2 : CPLAssert(poFeatureDefn == NULL);
360 :
361 2 : OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
362 :
363 2 : int nSrcFields = poSrcFieldDefn->GetFieldCount();
364 : pasListFields =
365 2 : (ListFieldDesc*)CPLCalloc(sizeof(ListFieldDesc), nSrcFields);
366 2 : nListFieldCount = 0;
367 : int i;
368 :
369 : /* Establish the list of fields of list type */
370 12 : for(i=0;i<nSrcFields;i++)
371 : {
372 10 : OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
373 10 : if (eType == OFTIntegerList ||
374 : eType == OFTRealList ||
375 : eType == OFTStringList)
376 : {
377 6 : pasListFields[nListFieldCount].iSrcIndex = i;
378 6 : pasListFields[nListFieldCount].eType = eType;
379 6 : if (nMaxSplitListSubFields == 1)
380 0 : pasListFields[nListFieldCount].nMaxOccurences = 1;
381 6 : nListFieldCount++;
382 : }
383 : }
384 :
385 2 : if (nListFieldCount == 0)
386 0 : return FALSE;
387 :
388 : /* No need for full scan if the limit is 1. We just to have to create */
389 : /* one and a single one field */
390 2 : if (nMaxSplitListSubFields != 1)
391 : {
392 2 : poSrcLayer->ResetReading();
393 : OGRFeature* poSrcFeature;
394 :
395 2 : int nFeatureCount = 0;
396 2 : if (poSrcLayer->TestCapability(OLCFastFeatureCount))
397 2 : nFeatureCount = poSrcLayer->GetFeatureCount();
398 2 : int nFeatureIndex = 0;
399 :
400 : /* Scan the whole layer to compute the maximum number of */
401 : /* items for each field of list type */
402 6 : while( (poSrcFeature = poSrcLayer->GetNextFeature()) != NULL )
403 : {
404 8 : for(i=0;i<nListFieldCount;i++)
405 : {
406 6 : int nCount = 0;
407 : OGRField* psField =
408 6 : poSrcFeature->GetRawFieldRef(pasListFields[i].iSrcIndex);
409 6 : switch(pasListFields[i].eType)
410 : {
411 : case OFTIntegerList:
412 2 : nCount = psField->IntegerList.nCount;
413 2 : break;
414 : case OFTRealList:
415 2 : nCount = psField->RealList.nCount;
416 2 : break;
417 : case OFTStringList:
418 : {
419 2 : nCount = psField->StringList.nCount;
420 2 : char** paList = psField->StringList.paList;
421 : int j;
422 6 : for(j=0;j<nCount;j++)
423 : {
424 4 : int nWidth = strlen(paList[j]);
425 4 : if (nWidth > pasListFields[i].nWidth)
426 2 : pasListFields[i].nWidth = nWidth;
427 : }
428 2 : break;
429 : }
430 : default:
431 0 : CPLAssert(0);
432 : break;
433 : }
434 6 : if (nCount > pasListFields[i].nMaxOccurences)
435 : {
436 6 : if (nCount > nMaxSplitListSubFields)
437 0 : nCount = nMaxSplitListSubFields;
438 6 : pasListFields[i].nMaxOccurences = nCount;
439 : }
440 : }
441 2 : OGRFeature::DestroyFeature(poSrcFeature);
442 :
443 2 : nFeatureIndex ++;
444 2 : if (pfnProgress != NULL && nFeatureCount != 0)
445 0 : pfnProgress(nFeatureIndex * 1.0 / nFeatureCount, "", pProgressArg);
446 : }
447 : }
448 :
449 : /* Now let's build the target feature definition */
450 :
451 : poFeatureDefn =
452 2 : OGRFeatureDefn::CreateFeatureDefn( poSrcFieldDefn->GetName() );
453 2 : poFeatureDefn->Reference();
454 2 : poFeatureDefn->SetGeomType( poSrcFieldDefn->GetGeomType() );
455 :
456 2 : int iListField = 0;
457 12 : for(i=0;i<nSrcFields;i++)
458 : {
459 10 : OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(i)->GetType();
460 16 : if (eType == OFTIntegerList ||
461 : eType == OFTRealList ||
462 : eType == OFTStringList)
463 : {
464 6 : int nMaxOccurences = pasListFields[iListField].nMaxOccurences;
465 6 : int nWidth = pasListFields[iListField].nWidth;
466 6 : iListField ++;
467 : int j;
468 6 : if (nMaxOccurences == 1)
469 : {
470 : OGRFieldDefn oFieldDefn(poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(),
471 : (eType == OFTIntegerList) ? OFTInteger :
472 : (eType == OFTRealList) ? OFTReal :
473 0 : OFTString);
474 0 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
475 : }
476 : else
477 : {
478 18 : for(j=0;j<nMaxOccurences;j++)
479 : {
480 12 : CPLString osFieldName;
481 : osFieldName.Printf("%s%d",
482 12 : poSrcFieldDefn->GetFieldDefn(i)->GetNameRef(), j+1);
483 : OGRFieldDefn oFieldDefn(osFieldName.c_str(),
484 : (eType == OFTIntegerList) ? OFTInteger :
485 : (eType == OFTRealList) ? OFTReal :
486 12 : OFTString);
487 12 : oFieldDefn.SetWidth(nWidth);
488 12 : poFeatureDefn->AddFieldDefn(&oFieldDefn);
489 : }
490 : }
491 : }
492 : else
493 : {
494 4 : poFeatureDefn->AddFieldDefn(poSrcFieldDefn->GetFieldDefn(i));
495 : }
496 : }
497 :
498 2 : return TRUE;
499 : }
500 :
501 :
502 : /************************************************************************/
503 : /* TranslateFeature() */
504 : /************************************************************************/
505 :
506 4 : OGRFeature *OGRSplitListFieldLayer::TranslateFeature(OGRFeature* poSrcFeature)
507 : {
508 4 : if (poSrcFeature == NULL)
509 2 : return NULL;
510 2 : if (poFeatureDefn == NULL)
511 0 : return poSrcFeature;
512 :
513 2 : OGRFeature* poFeature = OGRFeature::CreateFeature(poFeatureDefn);
514 2 : poFeature->SetFID(poSrcFeature->GetFID());
515 2 : poFeature->SetGeometryDirectly(poSrcFeature->StealGeometry());
516 2 : poFeature->SetStyleString(poFeature->GetStyleString());
517 :
518 2 : OGRFeatureDefn* poSrcFieldDefn = poSrcLayer->GetLayerDefn();
519 2 : int nSrcFields = poSrcFeature->GetFieldCount();
520 : int iSrcField;
521 2 : int iDstField = 0;
522 2 : int iListField = 0;
523 : int j;
524 12 : for(iSrcField=0;iSrcField<nSrcFields;iSrcField++)
525 : {
526 10 : OGRFieldType eType = poSrcFieldDefn->GetFieldDefn(iSrcField)->GetType();
527 10 : OGRField* psField = poSrcFeature->GetRawFieldRef(iSrcField);
528 10 : switch(eType)
529 : {
530 : case OFTIntegerList:
531 : {
532 2 : int nCount = psField->IntegerList.nCount;
533 2 : if (nCount > nMaxSplitListSubFields)
534 0 : nCount = nMaxSplitListSubFields;
535 2 : int* paList = psField->IntegerList.paList;
536 6 : for(j=0;j<nCount;j++)
537 4 : poFeature->SetField(iDstField + j, paList[j]);
538 2 : iDstField += pasListFields[iListField].nMaxOccurences;
539 2 : iListField++;
540 2 : break;
541 : }
542 : case OFTRealList:
543 : {
544 2 : int nCount = psField->RealList.nCount;
545 2 : if (nCount > nMaxSplitListSubFields)
546 0 : nCount = nMaxSplitListSubFields;
547 2 : double* paList = psField->RealList.paList;
548 6 : for(j=0;j<nCount;j++)
549 4 : poFeature->SetField(iDstField + j, paList[j]);
550 2 : iDstField += pasListFields[iListField].nMaxOccurences;
551 2 : iListField++;
552 2 : break;
553 : }
554 : case OFTStringList:
555 : {
556 2 : int nCount = psField->StringList.nCount;
557 2 : if (nCount > nMaxSplitListSubFields)
558 0 : nCount = nMaxSplitListSubFields;
559 2 : char** paList = psField->StringList.paList;
560 6 : for(j=0;j<nCount;j++)
561 4 : poFeature->SetField(iDstField + j, paList[j]);
562 2 : iDstField += pasListFields[iListField].nMaxOccurences;
563 2 : iListField++;
564 2 : break;
565 : }
566 : default:
567 4 : poFeature->SetField(iDstField, psField);
568 4 : iDstField ++;
569 : break;
570 : }
571 : }
572 :
573 2 : OGRFeature::DestroyFeature(poSrcFeature);
574 :
575 2 : return poFeature;
576 : }
577 :
578 : /************************************************************************/
579 : /* GetNextFeature() */
580 : /************************************************************************/
581 :
582 4 : OGRFeature *OGRSplitListFieldLayer::GetNextFeature()
583 : {
584 4 : return TranslateFeature(poSrcLayer->GetNextFeature());
585 : }
586 :
587 : /************************************************************************/
588 : /* GetFeature() */
589 : /************************************************************************/
590 :
591 0 : OGRFeature *OGRSplitListFieldLayer::GetFeature(long nFID)
592 : {
593 0 : return TranslateFeature(poSrcLayer->GetFeature(nFID));
594 : }
595 :
596 : /************************************************************************/
597 : /* GetLayerDefn() */
598 : /************************************************************************/
599 :
600 4 : OGRFeatureDefn* OGRSplitListFieldLayer::GetLayerDefn()
601 : {
602 4 : if (poFeatureDefn == NULL)
603 0 : return poSrcLayer->GetLayerDefn();
604 4 : return poFeatureDefn;
605 : }
606 :
607 : /************************************************************************/
608 : /* main() */
609 : /************************************************************************/
610 :
611 144 : int main( int nArgc, char ** papszArgv )
612 :
613 : {
614 144 : int bQuiet = FALSE;
615 144 : int bFormatExplicitelySet = FALSE;
616 144 : const char *pszFormat = "ESRI Shapefile";
617 144 : const char *pszDataSource = NULL;
618 144 : const char *pszDestDataSource = NULL;
619 144 : char **papszLayers = NULL;
620 144 : char **papszDSCO = NULL, **papszLCO = NULL;
621 144 : int bTransform = FALSE;
622 144 : int bAppend = FALSE, bUpdate = FALSE, bOverwrite = FALSE;
623 144 : const char *pszOutputSRSDef = NULL;
624 144 : const char *pszSourceSRSDef = NULL;
625 144 : OGRSpatialReference *poOutputSRS = NULL;
626 144 : int bNullifyOutputSRS = FALSE;
627 144 : OGRSpatialReference *poSourceSRS = NULL;
628 144 : char *pszNewLayerName = NULL;
629 144 : const char *pszWHERE = NULL;
630 144 : OGRGeometry *poSpatialFilter = NULL;
631 : const char *pszSelect;
632 144 : char **papszSelFields = NULL;
633 144 : const char *pszSQLStatement = NULL;
634 144 : const char *pszDialect = NULL;
635 144 : int eGType = -2;
636 144 : GeomOperation eGeomOp = NONE;
637 144 : double dfGeomOpParam = 0;
638 144 : char **papszFieldTypesToString = NULL;
639 144 : int bDisplayProgress = FALSE;
640 144 : GDALProgressFunc pfnProgress = NULL;
641 144 : void *pProgressArg = NULL;
642 144 : int bWrapDateline = FALSE;
643 144 : int bClipSrc = FALSE;
644 144 : OGRGeometry* poClipSrc = NULL;
645 144 : const char *pszClipSrcDS = NULL;
646 144 : const char *pszClipSrcSQL = NULL;
647 144 : const char *pszClipSrcLayer = NULL;
648 144 : const char *pszClipSrcWhere = NULL;
649 144 : OGRGeometry *poClipDst = NULL;
650 144 : const char *pszClipDstDS = NULL;
651 144 : const char *pszClipDstSQL = NULL;
652 144 : const char *pszClipDstLayer = NULL;
653 144 : const char *pszClipDstWhere = NULL;
654 144 : int bSplitListFields = FALSE;
655 144 : int nMaxSplitListSubFields = -1;
656 144 : int bExplodeCollections = FALSE;
657 144 : const char *pszZField = NULL;
658 :
659 : /* Check strict compilation and runtime library version as we use C++ API */
660 144 : if (! GDAL_CHECK_VERSION(papszArgv[0]))
661 0 : exit(1);
662 : /* -------------------------------------------------------------------- */
663 : /* Register format(s). */
664 : /* -------------------------------------------------------------------- */
665 144 : OGRRegisterAll();
666 :
667 : /* -------------------------------------------------------------------- */
668 : /* Processing command line arguments. */
669 : /* -------------------------------------------------------------------- */
670 144 : nArgc = OGRGeneralCmdLineProcessor( nArgc, &papszArgv, 0 );
671 :
672 144 : if( nArgc < 1 )
673 0 : exit( -nArgc );
674 :
675 662 : for( int iArg = 1; iArg < nArgc; iArg++ )
676 : {
677 520 : if( EQUAL(papszArgv[iArg], "--utility_version") )
678 : {
679 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
680 2 : papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
681 2 : return 0;
682 : }
683 518 : else if ( EQUAL(papszArgv[iArg], "--long-usage") )
684 : {
685 0 : Usage(FALSE);
686 : }
687 :
688 518 : else if( EQUAL(papszArgv[iArg],"-q") || EQUAL(papszArgv[iArg],"-quiet") )
689 : {
690 0 : bQuiet = TRUE;
691 : }
692 568 : else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 )
693 : {
694 50 : bFormatExplicitelySet = TRUE;
695 50 : pszFormat = papszArgv[++iArg];
696 : }
697 474 : else if( EQUAL(papszArgv[iArg],"-dsco") && iArg < nArgc-1 )
698 : {
699 6 : papszDSCO = CSLAddString(papszDSCO, papszArgv[++iArg] );
700 : }
701 464 : else if( EQUAL(papszArgv[iArg],"-lco") && iArg < nArgc-1 )
702 : {
703 2 : papszLCO = CSLAddString(papszLCO, papszArgv[++iArg] );
704 : }
705 460 : else if( EQUAL(papszArgv[iArg],"-preserve_fid") )
706 : {
707 0 : bPreserveFID = TRUE;
708 : }
709 460 : else if( EQUALN(papszArgv[iArg],"-skip",5) )
710 : {
711 0 : bSkipFailures = TRUE;
712 0 : nGroupTransactions = 1; /* #2409 */
713 : }
714 460 : else if( EQUAL(papszArgv[iArg],"-append") )
715 : {
716 12 : bAppend = TRUE;
717 12 : bUpdate = TRUE;
718 : }
719 448 : else if( EQUAL(papszArgv[iArg],"-overwrite") )
720 : {
721 22 : bOverwrite = TRUE;
722 22 : bUpdate = TRUE;
723 : }
724 426 : else if( EQUAL(papszArgv[iArg],"-update") )
725 : {
726 8 : bUpdate = TRUE;
727 : }
728 420 : else if( EQUAL(papszArgv[iArg],"-fid") && papszArgv[iArg+1] != NULL )
729 : {
730 2 : nFIDToFetch = atoi(papszArgv[++iArg]);
731 : }
732 428 : else if( EQUAL(papszArgv[iArg],"-sql") && papszArgv[iArg+1] != NULL )
733 : {
734 12 : pszSQLStatement = papszArgv[++iArg];
735 : }
736 404 : else if( EQUAL(papszArgv[iArg],"-dialect") && papszArgv[iArg+1] != NULL )
737 : {
738 0 : pszDialect = papszArgv[++iArg];
739 : }
740 430 : else if( EQUAL(papszArgv[iArg],"-nln") && iArg < nArgc-1 )
741 : {
742 26 : pszNewLayerName = CPLStrdup(papszArgv[++iArg]);
743 : }
744 392 : else if( EQUAL(papszArgv[iArg],"-nlt") && iArg < nArgc-1 )
745 : {
746 14 : int bIs3D = FALSE;
747 14 : CPLString osGeomName = papszArgv[iArg+1];
748 42 : if (strlen(papszArgv[iArg+1]) > 3 &&
749 28 : EQUALN(papszArgv[iArg+1] + strlen(papszArgv[iArg+1]) - 3, "25D", 3))
750 : {
751 2 : bIs3D = TRUE;
752 2 : osGeomName.resize(osGeomName.size() - 3);
753 : }
754 14 : if( EQUAL(osGeomName,"NONE") )
755 0 : eGType = wkbNone;
756 14 : else if( EQUAL(osGeomName,"GEOMETRY") )
757 0 : eGType = wkbUnknown;
758 : else
759 : {
760 14 : eGType = OGRFromOGCGeomType(osGeomName);
761 14 : if (eGType == wkbUnknown)
762 : {
763 : fprintf( stderr, "-nlt %s: type not recognised.\n",
764 0 : papszArgv[iArg+1] );
765 0 : exit( 1 );
766 : }
767 : }
768 14 : if (eGType != wkbNone && bIs3D)
769 2 : eGType |= wkb25DBit;
770 :
771 14 : iArg++;
772 : }
773 730 : else if( (EQUAL(papszArgv[iArg],"-tg") ||
774 364 : EQUAL(papszArgv[iArg],"-gt")) && iArg < nArgc-1 )
775 : {
776 2 : nGroupTransactions = atoi(papszArgv[++iArg]);
777 : }
778 362 : else if( EQUAL(papszArgv[iArg],"-s_srs") && iArg < nArgc-1 )
779 : {
780 0 : pszSourceSRSDef = papszArgv[++iArg];
781 : }
782 366 : else if( EQUAL(papszArgv[iArg],"-a_srs") && iArg < nArgc-1 )
783 : {
784 4 : pszOutputSRSDef = papszArgv[++iArg];
785 4 : if (EQUAL(pszOutputSRSDef, "NULL") ||
786 : EQUAL(pszOutputSRSDef, "NONE"))
787 : {
788 2 : pszOutputSRSDef = NULL;
789 2 : bNullifyOutputSRS = TRUE;
790 : }
791 : }
792 362 : else if( EQUAL(papszArgv[iArg],"-t_srs") && iArg < nArgc-1 )
793 : {
794 4 : pszOutputSRSDef = papszArgv[++iArg];
795 4 : bTransform = TRUE;
796 : }
797 374 : else if( EQUAL(papszArgv[iArg],"-spat")
798 4 : && papszArgv[iArg+1] != NULL
799 4 : && papszArgv[iArg+2] != NULL
800 4 : && papszArgv[iArg+3] != NULL
801 4 : && papszArgv[iArg+4] != NULL )
802 : {
803 4 : OGRLinearRing oRing;
804 :
805 4 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
806 4 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
807 4 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
808 4 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
809 4 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
810 :
811 4 : poSpatialFilter = OGRGeometryFactory::createGeometry(wkbPolygon);
812 4 : ((OGRPolygon *) poSpatialFilter)->addRing( &oRing );
813 4 : iArg += 4;
814 : }
815 356 : else if( EQUAL(papszArgv[iArg],"-where") && papszArgv[iArg+1] != NULL )
816 : {
817 6 : pszWHERE = papszArgv[++iArg];
818 : }
819 358 : else if( EQUAL(papszArgv[iArg],"-select") && papszArgv[iArg+1] != NULL)
820 : {
821 14 : pszSelect = papszArgv[++iArg];
822 : papszSelFields = CSLTokenizeStringComplex(pszSelect, " ,",
823 14 : FALSE, FALSE );
824 : }
825 332 : else if( EQUAL(papszArgv[iArg],"-segmentize") && iArg < nArgc-1 )
826 : {
827 2 : eGeomOp = SEGMENTIZE;
828 2 : dfGeomOpParam = atof(papszArgv[++iArg]);
829 : }
830 328 : else if( EQUAL(papszArgv[iArg],"-simplify") && iArg < nArgc-1 )
831 : {
832 0 : eGeomOp = SIMPLIFY_PRESERVE_TOPOLOGY;
833 0 : dfGeomOpParam = atof(papszArgv[++iArg]);
834 : }
835 328 : else if( EQUAL(papszArgv[iArg],"-fieldTypeToString") && iArg < nArgc-1 )
836 : {
837 : papszFieldTypesToString =
838 0 : CSLTokenizeStringComplex(papszArgv[++iArg], " ,",
839 0 : FALSE, FALSE );
840 0 : char** iter = papszFieldTypesToString;
841 0 : while(*iter)
842 : {
843 0 : if (EQUAL(*iter, "Integer") ||
844 : EQUAL(*iter, "Real") ||
845 : EQUAL(*iter, "String") ||
846 : EQUAL(*iter, "Date") ||
847 : EQUAL(*iter, "Time") ||
848 : EQUAL(*iter, "DateTime") ||
849 : EQUAL(*iter, "Binary") ||
850 : EQUAL(*iter, "IntegerList") ||
851 : EQUAL(*iter, "RealList") ||
852 : EQUAL(*iter, "StringList"))
853 : {
854 : /* Do nothing */
855 : }
856 0 : else if (EQUAL(*iter, "All"))
857 : {
858 0 : CSLDestroy(papszFieldTypesToString);
859 0 : papszFieldTypesToString = NULL;
860 0 : papszFieldTypesToString = CSLAddString(papszFieldTypesToString, "All");
861 0 : break;
862 : }
863 : else
864 : {
865 : fprintf(stderr, "Unhandled type for fieldtypeasstring option : %s\n",
866 0 : *iter);
867 0 : Usage();
868 : }
869 0 : iter ++;
870 : }
871 : }
872 328 : else if( EQUAL(papszArgv[iArg],"-progress") )
873 : {
874 2 : bDisplayProgress = TRUE;
875 : }
876 326 : else if( EQUAL(papszArgv[iArg],"-wrapdateline") )
877 : {
878 8 : bWrapDateline = TRUE;
879 : }
880 324 : else if( EQUAL(papszArgv[iArg],"-clipsrc") && iArg < nArgc-1 )
881 : {
882 : VSIStatBufL sStat;
883 6 : bClipSrc = TRUE;
884 6 : if ( IsNumber(papszArgv[iArg+1])
885 0 : && papszArgv[iArg+2] != NULL
886 0 : && papszArgv[iArg+3] != NULL
887 0 : && papszArgv[iArg+4] != NULL)
888 : {
889 0 : OGRLinearRing oRing;
890 :
891 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
892 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
893 0 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
894 0 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
895 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
896 :
897 0 : poClipSrc = OGRGeometryFactory::createGeometry(wkbPolygon);
898 0 : ((OGRPolygon *) poClipSrc)->addRing( &oRing );
899 0 : iArg += 4;
900 : }
901 12 : else if ((EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
902 4 : EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12)) &&
903 2 : VSIStatL(papszArgv[iArg+1], &sStat) != 0)
904 : {
905 2 : char* pszTmp = (char*) papszArgv[iArg+1];
906 2 : OGRGeometryFactory::createFromWkt(&pszTmp, NULL, &poClipSrc);
907 2 : if (poClipSrc == NULL)
908 : {
909 0 : fprintf( stderr, "FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n\n");
910 0 : Usage();
911 : }
912 2 : iArg ++;
913 : }
914 4 : else if (EQUAL(papszArgv[iArg+1], "spat_extent") )
915 : {
916 2 : iArg ++;
917 : }
918 : else
919 : {
920 2 : pszClipSrcDS = papszArgv[iArg+1];
921 2 : iArg ++;
922 : }
923 : }
924 312 : else if( EQUAL(papszArgv[iArg],"-clipsrcsql") && iArg < nArgc-1 )
925 : {
926 0 : pszClipSrcSQL = papszArgv[iArg+1];
927 0 : iArg ++;
928 : }
929 312 : else if( EQUAL(papszArgv[iArg],"-clipsrclayer") && iArg < nArgc-1 )
930 : {
931 0 : pszClipSrcLayer = papszArgv[iArg+1];
932 0 : iArg ++;
933 : }
934 314 : else if( EQUAL(papszArgv[iArg],"-clipsrcwhere") && iArg < nArgc-1 )
935 : {
936 2 : pszClipSrcWhere = papszArgv[iArg+1];
937 2 : iArg ++;
938 : }
939 314 : else if( EQUAL(papszArgv[iArg],"-clipdst") && iArg < nArgc-1 )
940 : {
941 : VSIStatBufL sStat;
942 4 : if ( IsNumber(papszArgv[iArg+1])
943 0 : && papszArgv[iArg+2] != NULL
944 0 : && papszArgv[iArg+3] != NULL
945 0 : && papszArgv[iArg+4] != NULL)
946 : {
947 0 : OGRLinearRing oRing;
948 :
949 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
950 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+4]) );
951 0 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+4]) );
952 0 : oRing.addPoint( atof(papszArgv[iArg+3]), atof(papszArgv[iArg+2]) );
953 0 : oRing.addPoint( atof(papszArgv[iArg+1]), atof(papszArgv[iArg+2]) );
954 :
955 0 : poClipDst = OGRGeometryFactory::createGeometry(wkbPolygon);
956 0 : ((OGRPolygon *) poClipDst)->addRing( &oRing );
957 0 : iArg += 4;
958 : }
959 8 : else if ((EQUALN(papszArgv[iArg+1], "POLYGON", 7) ||
960 2 : EQUALN(papszArgv[iArg+1], "MULTIPOLYGON", 12)) &&
961 2 : VSIStatL(papszArgv[iArg+1], &sStat) != 0)
962 : {
963 2 : char* pszTmp = (char*) papszArgv[iArg+1];
964 2 : OGRGeometryFactory::createFromWkt(&pszTmp, NULL, &poClipDst);
965 2 : if (poClipDst == NULL)
966 : {
967 0 : fprintf( stderr, "FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n\n");
968 0 : Usage();
969 : }
970 2 : iArg ++;
971 : }
972 : else
973 : {
974 2 : pszClipDstDS = papszArgv[iArg+1];
975 2 : iArg ++;
976 : }
977 : }
978 308 : else if( EQUAL(papszArgv[iArg],"-clipdstsql") && iArg < nArgc-1 )
979 : {
980 2 : pszClipDstSQL = papszArgv[iArg+1];
981 2 : iArg ++;
982 : }
983 304 : else if( EQUAL(papszArgv[iArg],"-clipdstlayer") && iArg < nArgc-1 )
984 : {
985 0 : pszClipDstLayer = papszArgv[iArg+1];
986 0 : iArg ++;
987 : }
988 304 : else if( EQUAL(papszArgv[iArg],"-clipdstwhere") && iArg < nArgc-1 )
989 : {
990 0 : pszClipDstWhere = papszArgv[iArg+1];
991 0 : iArg ++;
992 : }
993 304 : else if( EQUAL(papszArgv[iArg],"-splitlistfields") )
994 : {
995 2 : bSplitListFields = TRUE;
996 : }
997 302 : else if ( EQUAL(papszArgv[iArg],"-maxsubfields") && iArg < nArgc-1 )
998 : {
999 0 : if (IsNumber(papszArgv[iArg+1]))
1000 : {
1001 0 : int nTemp = atoi(papszArgv[iArg+1]);
1002 0 : if (nTemp > 0)
1003 : {
1004 0 : nMaxSplitListSubFields = nTemp;
1005 0 : iArg ++;
1006 : }
1007 : }
1008 : }
1009 302 : else if( EQUAL(papszArgv[iArg],"-explodecollections") )
1010 : {
1011 2 : bExplodeCollections = TRUE;
1012 : }
1013 306 : else if( EQUAL(papszArgv[iArg],"-zfield") && iArg < nArgc-1 )
1014 : {
1015 6 : pszZField = papszArgv[iArg+1];
1016 6 : iArg ++;
1017 : }
1018 294 : else if( papszArgv[iArg][0] == '-' )
1019 : {
1020 0 : Usage();
1021 : }
1022 294 : else if( pszDestDataSource == NULL )
1023 142 : pszDestDataSource = papszArgv[iArg];
1024 152 : else if( pszDataSource == NULL )
1025 142 : pszDataSource = papszArgv[iArg];
1026 : else
1027 10 : papszLayers = CSLAddString( papszLayers, papszArgv[iArg] );
1028 : }
1029 :
1030 142 : if( pszDataSource == NULL )
1031 0 : Usage();
1032 :
1033 142 : if( bPreserveFID && bExplodeCollections )
1034 : {
1035 0 : fprintf( stderr, "FAILURE: cannot use -preserve_fid and -explodecollections at the same time\n\n" );
1036 0 : Usage();
1037 : }
1038 :
1039 144 : if( bClipSrc && pszClipSrcDS != NULL)
1040 : {
1041 2 : poClipSrc = LoadGeometry(pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere);
1042 2 : if (poClipSrc == NULL)
1043 : {
1044 0 : fprintf( stderr, "FAILURE: cannot load source clip geometry\n\n" );
1045 0 : Usage();
1046 : }
1047 : }
1048 140 : else if( bClipSrc && poClipSrc == NULL )
1049 : {
1050 2 : if (poSpatialFilter)
1051 2 : poClipSrc = poSpatialFilter->clone();
1052 2 : if (poClipSrc == NULL)
1053 : {
1054 : fprintf( stderr, "FAILURE: -clipsrc must be used with -spat option or a\n"
1055 0 : "bounding box, WKT string or datasource must be specified\n\n");
1056 0 : Usage();
1057 : }
1058 : }
1059 :
1060 142 : if( pszClipDstDS != NULL)
1061 : {
1062 2 : poClipDst = LoadGeometry(pszClipDstDS, pszClipDstSQL, pszClipDstLayer, pszClipDstWhere);
1063 2 : if (poClipDst == NULL)
1064 : {
1065 0 : fprintf( stderr, "FAILURE: cannot load dest clip geometry\n\n" );
1066 0 : Usage();
1067 : }
1068 : }
1069 :
1070 : /* -------------------------------------------------------------------- */
1071 : /* Open data source. */
1072 : /* -------------------------------------------------------------------- */
1073 : OGRDataSource *poDS;
1074 142 : OGRDataSource *poODS = NULL;
1075 142 : OGRSFDriver *poDriver = NULL;
1076 142 : int bCloseODS = TRUE;
1077 :
1078 : /* Avoid opening twice the same datasource if it is both the input and output */
1079 : /* Known to cause problems with at least FGdb and SQlite drivers. See #4270 */
1080 148 : if (bUpdate && strcmp(pszDestDataSource, pszDataSource) == 0)
1081 : {
1082 6 : poODS = poDS = OGRSFDriverRegistrar::Open( pszDataSource, TRUE, &poDriver );
1083 : /* Restrict to those 2 drivers. For example it is known to break with */
1084 : /* the PG driver due to the way it manages transactions... */
1085 12 : if (poDS && !(EQUAL(poDriver->GetName(), "FileGDB") ||
1086 6 : EQUAL(poDriver->GetName(), "SQLite")))
1087 : {
1088 4 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
1089 : }
1090 : else
1091 2 : bCloseODS = FALSE;
1092 6 : if (poDS)
1093 : {
1094 6 : if (bOverwrite || bAppend)
1095 : {
1096 : /* Various tests to avoid overwriting the source layer(s) */
1097 : /* or to avoid appending a layer to itself */
1098 2 : int bError = FALSE;
1099 2 : if (pszNewLayerName == NULL)
1100 0 : bError = TRUE;
1101 2 : else if (CSLCount(papszLayers) == 1)
1102 2 : bError = strcmp(pszNewLayerName, papszLayers[0]) == 0;
1103 0 : else if (pszSQLStatement == NULL)
1104 0 : bError = TRUE;
1105 2 : if (bError)
1106 : {
1107 : fprintf( stderr,
1108 : "ERROR: -nln name must be specified combined with "
1109 : "a single source layer name,\nor a -sql statement, and "
1110 0 : "name must be different from an existing layer.\n");
1111 0 : exit(1);
1112 : }
1113 : }
1114 : }
1115 : }
1116 : else
1117 136 : poDS = OGRSFDriverRegistrar::Open( pszDataSource, FALSE );
1118 :
1119 : /* -------------------------------------------------------------------- */
1120 : /* Report failure */
1121 : /* -------------------------------------------------------------------- */
1122 142 : if( poDS == NULL )
1123 : {
1124 0 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
1125 :
1126 : fprintf( stderr, "FAILURE:\n"
1127 : "Unable to open datasource `%s' with the following drivers.\n",
1128 0 : pszDataSource );
1129 :
1130 0 : for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
1131 : {
1132 0 : fprintf( stderr, " -> %s\n", poR->GetDriver(iDriver)->GetName() );
1133 : }
1134 :
1135 0 : exit( 1 );
1136 : }
1137 :
1138 : /* -------------------------------------------------------------------- */
1139 : /* Try opening the output datasource as an existing, writable */
1140 : /* -------------------------------------------------------------------- */
1141 :
1142 142 : if( bUpdate && poODS == NULL )
1143 : {
1144 32 : poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, TRUE, &poDriver );
1145 :
1146 32 : if( poODS == NULL )
1147 : {
1148 2 : if (bOverwrite || bAppend)
1149 : {
1150 2 : poODS = OGRSFDriverRegistrar::Open( pszDestDataSource, FALSE, &poDriver );
1151 2 : if (poODS == NULL)
1152 : {
1153 : /* ok the datasource doesn't exist at all */
1154 2 : bUpdate = FALSE;
1155 : }
1156 : else
1157 : {
1158 0 : OGRDataSource::DestroyDataSource(poODS);
1159 0 : poODS = NULL;
1160 : }
1161 : }
1162 :
1163 2 : if (bUpdate)
1164 : {
1165 : fprintf( stderr, "FAILURE:\n"
1166 : "Unable to open existing output datasource `%s'.\n",
1167 0 : pszDestDataSource );
1168 0 : exit( 1 );
1169 : }
1170 : }
1171 30 : else if( CSLCount(papszDSCO) > 0 )
1172 : {
1173 : fprintf( stderr, "WARNING: Datasource creation options ignored since an existing datasource\n"
1174 0 : " being updated.\n" );
1175 : }
1176 : }
1177 :
1178 : /* -------------------------------------------------------------------- */
1179 : /* Find the output driver. */
1180 : /* -------------------------------------------------------------------- */
1181 142 : if( !bUpdate )
1182 : {
1183 106 : if (!bQuiet && !bFormatExplicitelySet)
1184 72 : CheckDestDataSourceNameConsistency(pszDestDataSource, pszFormat);
1185 :
1186 106 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
1187 : int iDriver;
1188 :
1189 106 : poDriver = poR->GetDriverByName(pszFormat);
1190 106 : if( poDriver == NULL )
1191 : {
1192 0 : fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat );
1193 0 : fprintf( stderr, "The following drivers are available:\n" );
1194 :
1195 0 : for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
1196 : {
1197 0 : fprintf( stderr, " -> `%s'\n", poR->GetDriver(iDriver)->GetName() );
1198 : }
1199 0 : exit( 1 );
1200 : }
1201 :
1202 106 : if( !poDriver->TestCapability( ODrCCreateDataSource ) )
1203 : {
1204 : fprintf( stderr, "%s driver does not support data source creation.\n",
1205 0 : pszFormat );
1206 0 : exit( 1 );
1207 : }
1208 :
1209 : /* -------------------------------------------------------------------- */
1210 : /* Special case to improve user experience when translating */
1211 : /* a datasource with multiple layers into a shapefile. If the */
1212 : /* user gives a target datasource with .shp and it does not exist, */
1213 : /* the shapefile driver will try to create a file, but this is not */
1214 : /* appropriate because here we have several layers, so create */
1215 : /* a directory instead. */
1216 : /* -------------------------------------------------------------------- */
1217 : VSIStatBufL sStat;
1218 170 : if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
1219 : pszSQLStatement == NULL &&
1220 : (CSLCount(papszLayers) > 1 ||
1221 64 : (CSLCount(papszLayers) == 0 && poDS->GetLayerCount() > 1)) &&
1222 : pszNewLayerName == NULL &&
1223 : EQUAL(CPLGetExtension(pszDestDataSource), "SHP") &&
1224 : VSIStatL(pszDestDataSource, &sStat) != 0)
1225 : {
1226 2 : if (VSIMkdir(pszDestDataSource, 0755) != 0)
1227 : {
1228 : CPLError( CE_Failure, CPLE_AppDefined,
1229 : "Failed to create directory %s\n"
1230 : "for shapefile datastore.\n",
1231 0 : pszDestDataSource );
1232 0 : exit(1);
1233 : }
1234 : }
1235 :
1236 : /* -------------------------------------------------------------------- */
1237 : /* Create the output data source. */
1238 : /* -------------------------------------------------------------------- */
1239 106 : poODS = poDriver->CreateDataSource( pszDestDataSource, papszDSCO );
1240 106 : if( poODS == NULL )
1241 : {
1242 : fprintf( stderr, "%s driver failed to create %s\n",
1243 0 : pszFormat, pszDestDataSource );
1244 0 : exit( 1 );
1245 : }
1246 : }
1247 :
1248 : /* -------------------------------------------------------------------- */
1249 : /* Parse the output SRS definition if possible. */
1250 : /* -------------------------------------------------------------------- */
1251 142 : if( pszOutputSRSDef != NULL )
1252 : {
1253 6 : poOutputSRS = (OGRSpatialReference*)OSRNewSpatialReference(NULL);
1254 6 : if( poOutputSRS->SetFromUserInput( pszOutputSRSDef ) != OGRERR_NONE )
1255 : {
1256 : fprintf( stderr, "Failed to process SRS definition: %s\n",
1257 0 : pszOutputSRSDef );
1258 0 : exit( 1 );
1259 : }
1260 : }
1261 :
1262 : /* -------------------------------------------------------------------- */
1263 : /* Parse the source SRS definition if possible. */
1264 : /* -------------------------------------------------------------------- */
1265 142 : if( pszSourceSRSDef != NULL )
1266 : {
1267 0 : poSourceSRS = (OGRSpatialReference*)OSRNewSpatialReference(NULL);
1268 0 : if( poSourceSRS->SetFromUserInput( pszSourceSRSDef ) != OGRERR_NONE )
1269 : {
1270 : fprintf( stderr, "Failed to process SRS definition: %s\n",
1271 0 : pszSourceSRSDef );
1272 0 : exit( 1 );
1273 : }
1274 : }
1275 :
1276 : /* -------------------------------------------------------------------- */
1277 : /* Special case for -sql clause. No source layers required. */
1278 : /* -------------------------------------------------------------------- */
1279 142 : if( pszSQLStatement != NULL )
1280 : {
1281 : OGRLayer *poResultSet;
1282 :
1283 12 : if( pszWHERE != NULL )
1284 0 : fprintf( stderr, "-where clause ignored in combination with -sql.\n" );
1285 12 : if( CSLCount(papszLayers) > 0 )
1286 0 : fprintf( stderr, "layer names ignored in combination with -sql.\n" );
1287 :
1288 : poResultSet = poDS->ExecuteSQL( pszSQLStatement, poSpatialFilter,
1289 12 : pszDialect );
1290 :
1291 12 : if( poResultSet != NULL )
1292 : {
1293 12 : long nCountLayerFeatures = 0;
1294 12 : if (bDisplayProgress)
1295 : {
1296 0 : if (!poResultSet->TestCapability(OLCFastFeatureCount))
1297 : {
1298 0 : fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
1299 0 : bDisplayProgress = FALSE;
1300 : }
1301 : else
1302 : {
1303 0 : nCountLayerFeatures = poResultSet->GetFeatureCount();
1304 0 : pfnProgress = GDALTermProgress;
1305 : }
1306 : }
1307 :
1308 12 : OGRLayer* poPassedLayer = poResultSet;
1309 12 : if (bSplitListFields)
1310 : {
1311 0 : poPassedLayer = new OGRSplitListFieldLayer(poPassedLayer, nMaxSplitListSubFields);
1312 0 : int nRet = ((OGRSplitListFieldLayer*)poPassedLayer)->BuildLayerDefn(NULL, NULL);
1313 0 : if (!nRet)
1314 : {
1315 0 : delete poPassedLayer;
1316 0 : poPassedLayer = poResultSet;
1317 : }
1318 : }
1319 :
1320 : /* -------------------------------------------------------------------- */
1321 : /* Special case to improve user experience when translating into */
1322 : /* single file shapefile and source has only one layer, and that */
1323 : /* the layer name isn't specified */
1324 : /* -------------------------------------------------------------------- */
1325 : VSIStatBufL sStat;
1326 12 : if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
1327 : pszNewLayerName == NULL &&
1328 : VSIStatL(pszDestDataSource, &sStat) == 0 && VSI_ISREG(sStat.st_mode))
1329 : {
1330 0 : pszNewLayerName = CPLStrdup(CPLGetBasename(pszDestDataSource));
1331 : }
1332 :
1333 12 : if( !TranslateLayer( poDS, poPassedLayer, poODS, papszLCO,
1334 : pszNewLayerName, bTransform, poOutputSRS, bNullifyOutputSRS,
1335 : poSourceSRS, papszSelFields, bAppend, eGType,
1336 : bOverwrite, eGeomOp, dfGeomOpParam, papszFieldTypesToString,
1337 : nCountLayerFeatures, bWrapDateline, poClipSrc, poClipDst,
1338 : bExplodeCollections, pszZField, pszWHERE, pfnProgress, pProgressArg))
1339 : {
1340 : CPLError( CE_Failure, CPLE_AppDefined,
1341 : "Terminating translation prematurely after failed\n"
1342 0 : "translation from sql statement." );
1343 :
1344 0 : exit( 1 );
1345 : }
1346 :
1347 12 : if (poPassedLayer != poResultSet)
1348 0 : delete poPassedLayer;
1349 :
1350 12 : poDS->ReleaseResultSet( poResultSet );
1351 : }
1352 : }
1353 :
1354 : else
1355 : {
1356 130 : int nLayerCount = 0;
1357 130 : OGRLayer** papoLayers = NULL;
1358 :
1359 : /* -------------------------------------------------------------------- */
1360 : /* Process each data source layer. */
1361 : /* -------------------------------------------------------------------- */
1362 130 : if ( CSLCount(papszLayers) == 0)
1363 : {
1364 120 : nLayerCount = poDS->GetLayerCount();
1365 120 : papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
1366 :
1367 304 : for( int iLayer = 0;
1368 : iLayer < nLayerCount;
1369 : iLayer++ )
1370 : {
1371 184 : OGRLayer *poLayer = poDS->GetLayer(iLayer);
1372 :
1373 184 : if( poLayer == NULL )
1374 : {
1375 : fprintf( stderr, "FAILURE: Couldn't fetch advertised layer %d!\n",
1376 0 : iLayer );
1377 0 : exit( 1 );
1378 : }
1379 :
1380 184 : papoLayers[iLayer] = poLayer;
1381 : }
1382 : }
1383 : /* -------------------------------------------------------------------- */
1384 : /* Process specified data source layers. */
1385 : /* -------------------------------------------------------------------- */
1386 : else
1387 : {
1388 10 : nLayerCount = CSLCount(papszLayers);
1389 10 : papoLayers = (OGRLayer**)CPLMalloc(sizeof(OGRLayer*) * nLayerCount);
1390 :
1391 40 : for( int iLayer = 0;
1392 20 : papszLayers[iLayer] != NULL;
1393 : iLayer++ )
1394 : {
1395 10 : OGRLayer *poLayer = poDS->GetLayerByName(papszLayers[iLayer]);
1396 :
1397 10 : if( poLayer == NULL )
1398 : {
1399 : fprintf( stderr, "FAILURE: Couldn't fetch requested layer '%s'!\n",
1400 0 : papszLayers[iLayer] );
1401 0 : if (!bSkipFailures)
1402 0 : exit( 1 );
1403 : }
1404 :
1405 10 : papoLayers[iLayer] = poLayer;
1406 : }
1407 : }
1408 :
1409 : /* -------------------------------------------------------------------- */
1410 : /* Special case to improve user experience when translating into */
1411 : /* single file shapefile and source has only one layer, and that */
1412 : /* the layer name isn't specified */
1413 : /* -------------------------------------------------------------------- */
1414 : VSIStatBufL sStat;
1415 130 : if (EQUAL(poDriver->GetName(), "ESRI Shapefile") &&
1416 : nLayerCount == 1 && pszNewLayerName == NULL &&
1417 : VSIStatL(pszDestDataSource, &sStat) == 0 && VSI_ISREG(sStat.st_mode))
1418 : {
1419 6 : pszNewLayerName = CPLStrdup(CPLGetBasename(pszDestDataSource));
1420 : }
1421 :
1422 130 : long* panLayerCountFeatures = (long*) CPLMalloc(sizeof(long) * nLayerCount);
1423 130 : long nCountLayersFeatures = 0;
1424 130 : long nAccCountFeatures = 0;
1425 : int iLayer;
1426 :
1427 : /* First pass to apply filters and count all features if necessary */
1428 324 : for( iLayer = 0;
1429 : iLayer < nLayerCount;
1430 : iLayer++ )
1431 : {
1432 194 : OGRLayer *poLayer = papoLayers[iLayer];
1433 194 : if (poLayer == NULL)
1434 0 : continue;
1435 :
1436 194 : if( pszWHERE != NULL )
1437 : {
1438 6 : if( poLayer->SetAttributeFilter( pszWHERE ) != OGRERR_NONE )
1439 : {
1440 0 : fprintf( stderr, "FAILURE: SetAttributeFilter(%s) failed.\n", pszWHERE );
1441 0 : if (!bSkipFailures)
1442 0 : exit( 1 );
1443 : }
1444 : }
1445 :
1446 194 : if( poSpatialFilter != NULL )
1447 4 : poLayer->SetSpatialFilter( poSpatialFilter );
1448 :
1449 194 : if (bDisplayProgress)
1450 : {
1451 2 : if (!poLayer->TestCapability(OLCFastFeatureCount))
1452 : {
1453 0 : fprintf( stderr, "Progress turned off as fast feature count is not available.\n");
1454 0 : bDisplayProgress = FALSE;
1455 : }
1456 : else
1457 : {
1458 2 : panLayerCountFeatures[iLayer] = poLayer->GetFeatureCount();
1459 2 : nCountLayersFeatures += panLayerCountFeatures[iLayer];
1460 : }
1461 : }
1462 : }
1463 :
1464 : /* Second pass to do the real job */
1465 324 : for( iLayer = 0;
1466 : iLayer < nLayerCount;
1467 : iLayer++ )
1468 : {
1469 194 : OGRLayer *poLayer = papoLayers[iLayer];
1470 194 : if (poLayer == NULL)
1471 0 : continue;
1472 :
1473 :
1474 194 : OGRLayer* poPassedLayer = poLayer;
1475 194 : if (bSplitListFields)
1476 : {
1477 2 : poPassedLayer = new OGRSplitListFieldLayer(poPassedLayer, nMaxSplitListSubFields);
1478 :
1479 2 : if (bDisplayProgress && nMaxSplitListSubFields != 1)
1480 : {
1481 0 : pfnProgress = GDALScaledProgress;
1482 : pProgressArg =
1483 : GDALCreateScaledProgress(nAccCountFeatures * 1.0 / nCountLayersFeatures,
1484 0 : (nAccCountFeatures + panLayerCountFeatures[iLayer] / 2) * 1.0 / nCountLayersFeatures,
1485 : GDALTermProgress,
1486 0 : NULL);
1487 : }
1488 : else
1489 : {
1490 2 : pfnProgress = NULL;
1491 2 : pProgressArg = NULL;
1492 : }
1493 :
1494 2 : int nRet = ((OGRSplitListFieldLayer*)poPassedLayer)->BuildLayerDefn(pfnProgress, pProgressArg);
1495 2 : if (!nRet)
1496 : {
1497 0 : delete poPassedLayer;
1498 0 : poPassedLayer = poLayer;
1499 : }
1500 :
1501 2 : if (bDisplayProgress)
1502 0 : GDALDestroyScaledProgress(pProgressArg);
1503 : }
1504 :
1505 :
1506 194 : if (bDisplayProgress)
1507 : {
1508 2 : pfnProgress = GDALScaledProgress;
1509 2 : int nStart = 0;
1510 2 : if (poPassedLayer != poLayer && nMaxSplitListSubFields != 1)
1511 0 : nStart = panLayerCountFeatures[iLayer] / 2;
1512 : pProgressArg =
1513 : GDALCreateScaledProgress((nAccCountFeatures + nStart) * 1.0 / nCountLayersFeatures,
1514 2 : (nAccCountFeatures + panLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures,
1515 : GDALTermProgress,
1516 2 : NULL);
1517 : }
1518 :
1519 194 : nAccCountFeatures += panLayerCountFeatures[iLayer];
1520 :
1521 194 : if( !TranslateLayer( poDS, poPassedLayer, poODS, papszLCO,
1522 : pszNewLayerName, bTransform, poOutputSRS, bNullifyOutputSRS,
1523 : poSourceSRS, papszSelFields, bAppend, eGType,
1524 : bOverwrite, eGeomOp, dfGeomOpParam, papszFieldTypesToString,
1525 : panLayerCountFeatures[iLayer], bWrapDateline, poClipSrc, poClipDst,
1526 : bExplodeCollections, pszZField, pszWHERE, pfnProgress, pProgressArg)
1527 : && !bSkipFailures )
1528 : {
1529 : CPLError( CE_Failure, CPLE_AppDefined,
1530 : "Terminating translation prematurely after failed\n"
1531 : "translation of layer %s (use -skipfailures to skip errors)\n",
1532 0 : poLayer->GetName() );
1533 :
1534 0 : exit( 1 );
1535 : }
1536 :
1537 194 : if (poPassedLayer != poLayer)
1538 2 : delete poPassedLayer;
1539 :
1540 194 : if (bDisplayProgress)
1541 2 : GDALDestroyScaledProgress(pProgressArg);
1542 : }
1543 :
1544 130 : CPLFree(panLayerCountFeatures);
1545 130 : CPLFree(papoLayers);
1546 : }
1547 : /* -------------------------------------------------------------------- */
1548 : /* Process DS style table */
1549 : /* -------------------------------------------------------------------- */
1550 :
1551 142 : poODS->SetStyleTable( poDS->GetStyleTable () );
1552 :
1553 : /* -------------------------------------------------------------------- */
1554 : /* Close down. */
1555 : /* -------------------------------------------------------------------- */
1556 142 : OGRSpatialReference::DestroySpatialReference(poOutputSRS);
1557 142 : OGRSpatialReference::DestroySpatialReference(poSourceSRS);
1558 142 : if (bCloseODS)
1559 140 : OGRDataSource::DestroyDataSource(poODS);
1560 142 : OGRDataSource::DestroyDataSource(poDS);
1561 142 : OGRGeometryFactory::destroyGeometry(poSpatialFilter);
1562 142 : OGRGeometryFactory::destroyGeometry(poClipSrc);
1563 142 : OGRGeometryFactory::destroyGeometry(poClipDst);
1564 :
1565 142 : CSLDestroy(papszSelFields);
1566 142 : CSLDestroy( papszArgv );
1567 142 : CSLDestroy( papszLayers );
1568 142 : CSLDestroy( papszDSCO );
1569 142 : CSLDestroy( papszLCO );
1570 142 : CSLDestroy( papszFieldTypesToString );
1571 142 : CPLFree( pszNewLayerName );
1572 :
1573 142 : OGRCleanupAll();
1574 :
1575 : #ifdef DBMALLOC
1576 : malloc_dump(1);
1577 : #endif
1578 :
1579 142 : return 0;
1580 : }
1581 :
1582 : /************************************************************************/
1583 : /* Usage() */
1584 : /************************************************************************/
1585 :
1586 0 : static void Usage(int bShort)
1587 :
1588 : {
1589 0 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
1590 :
1591 :
1592 : printf( "Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update]\n"
1593 : " [-select field_list] [-where restricted_where]\n"
1594 : " [-progress] [-sql <sql statement>] [-dialect dialect]\n"
1595 : " [-preserve_fid] [-fid FID]\n"
1596 : " [-spat xmin ymin xmax ymax]\n"
1597 : " [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n"
1598 : " [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n"
1599 : " dst_datasource_name src_datasource_name\n"
1600 : " [-lco NAME=VALUE] [-nln name] [-nlt type] [layer [layer ...]]\n"
1601 : "\n"
1602 : "Advanced options :\n"
1603 : " [-gt n]\n"
1604 : " [-clipsrc [xmin ymin xmax ymax]|WKT|datasource|spat_extent]\n"
1605 : " [-clipsrcsql sql_statement] [-clipsrclayer layer]\n"
1606 : " [-clipsrcwhere expression]\n"
1607 : " [-clipdst [xmin ymin xmax ymax]|WKT|datasource]\n"
1608 : " [-clipdstsql sql_statement] [-clipdstlayer layer]\n"
1609 : " [-clipdstwhere expression]\n"
1610 : " [-wrapdateline]\n"
1611 : " [[-simplify tolerance] | [-segmentize max_dist]]\n"
1612 : " [-fieldTypeToString All|(type1[,type2]*)]\n"
1613 : " [-splitlistfields] [-maxsubfields val]\n"
1614 0 : " [-explodecollections] [-zfield field_name]\n");
1615 :
1616 0 : if (bShort)
1617 : {
1618 0 : printf( "\nNote: ogr2ogr --long-usage for full help.\n");
1619 0 : exit( 1 );
1620 : }
1621 :
1622 0 : printf("\n -f format_name: output file format name, possible values are:\n");
1623 :
1624 0 : for( int iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ )
1625 : {
1626 0 : OGRSFDriver *poDriver = poR->GetDriver(iDriver);
1627 :
1628 0 : if( poDriver->TestCapability( ODrCCreateDataSource ) )
1629 0 : printf( " -f \"%s\"\n", poDriver->GetName() );
1630 : }
1631 :
1632 : printf( " -append: Append to existing layer instead of creating new if it exists\n"
1633 : " -overwrite: delete the output layer and recreate it empty\n"
1634 : " -update: Open existing output datasource in update mode\n"
1635 : " -progress: Display progress on terminal. Only works if input layers have the \n"
1636 : " \"fast feature count\" capability\n"
1637 : " -select field_list: Comma-delimited list of fields from input layer to\n"
1638 : " copy to the new layer (defaults to all)\n"
1639 : " -where restricted_where: Attribute query (like SQL WHERE)\n"
1640 : " -wrapdateline: split geometries crossing the dateline meridian\n"
1641 : " (long. = +/- 180deg)\n"
1642 : " -sql statement: Execute given SQL statement and save result.\n"
1643 : " -dialect value: select a dialect, usually OGRSQL to avoid native sql.\n"
1644 : " -skipfailures: skip features or layers that fail to convert\n"
1645 : " -gt n: group n features per transaction (default 200)\n"
1646 : " -spat xmin ymin xmax ymax: spatial query extents\n"
1647 : " -simplify tolerance: distance tolerance for simplification.\n"
1648 : " -segmentize max_dist: maximum distance between 2 nodes.\n"
1649 : " Used to create intermediate points\n"
1650 : " -dsco NAME=VALUE: Dataset creation option (format specific)\n"
1651 : " -lco NAME=VALUE: Layer creation option (format specific)\n"
1652 : " -nln name: Assign an alternate name to the new layer\n"
1653 : " -nlt type: Force a geometry type for new layer. One of NONE, GEOMETRY,\n"
1654 : " POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n"
1655 : " MULTIPOLYGON, or MULTILINESTRING. Add \"25D\" for 3D layers.\n"
1656 : " Default is type of source layer.\n"
1657 : " -fieldTypeToString type1,...: Converts fields of specified types to\n"
1658 : " fields of type string in the new layer. Valid types are : Integer,\n"
1659 : " Real, String, Date, Time, DateTime, Binary, IntegerList, RealList,\n"
1660 0 : " StringList. Special value All will convert all fields to strings.\n");
1661 :
1662 : printf(" -a_srs srs_def: Assign an output SRS\n"
1663 : " -t_srs srs_def: Reproject/transform to this SRS on output\n"
1664 : " -s_srs srs_def: Override source SRS\n"
1665 : "\n"
1666 : " Srs_def can be a full WKT definition (hard to escape properly),\n"
1667 : " or a well known definition (ie. EPSG:4326) or a file with a WKT\n"
1668 0 : " definition.\n" );
1669 :
1670 0 : exit( 1 );
1671 : }
1672 :
1673 : /************************************************************************/
1674 : /* SetZ() */
1675 : /************************************************************************/
1676 120 : static void SetZ (OGRGeometry* poGeom, double dfZ )
1677 : {
1678 120 : if (poGeom == NULL)
1679 0 : return;
1680 120 : switch (wkbFlatten(poGeom->getGeometryType()))
1681 : {
1682 : case wkbPoint:
1683 0 : ((OGRPoint*)poGeom)->setZ(dfZ);
1684 0 : break;
1685 :
1686 : case wkbLineString:
1687 : case wkbLinearRing:
1688 : {
1689 : int i;
1690 60 : OGRLineString* poLS = (OGRLineString*) poGeom;
1691 1530 : for(i=0;i<poLS->getNumPoints();i++)
1692 1470 : poLS->setPoint(i, poLS->getX(i), poLS->getY(i), dfZ);
1693 60 : break;
1694 : }
1695 :
1696 : case wkbPolygon:
1697 : {
1698 : int i;
1699 60 : OGRPolygon* poPoly = (OGRPolygon*) poGeom;
1700 60 : SetZ(poPoly->getExteriorRing(), dfZ);
1701 60 : for(i=0;i<poPoly->getNumInteriorRings();i++)
1702 0 : SetZ(poPoly->getInteriorRing(i), dfZ);
1703 60 : break;
1704 : }
1705 :
1706 : case wkbMultiPoint:
1707 : case wkbMultiLineString:
1708 : case wkbMultiPolygon:
1709 : case wkbGeometryCollection:
1710 : {
1711 : int i;
1712 0 : OGRGeometryCollection* poGeomColl = (OGRGeometryCollection*) poGeom;
1713 0 : for(i=0;i<poGeomColl->getNumGeometries();i++)
1714 0 : SetZ(poGeomColl->getGeometryRef(i), dfZ);
1715 : break;
1716 : }
1717 :
1718 : default:
1719 : break;
1720 : }
1721 : }
1722 :
1723 :
1724 : /************************************************************************/
1725 : /* TranslateLayer() */
1726 : /************************************************************************/
1727 :
1728 206 : static int TranslateLayer( OGRDataSource *poSrcDS,
1729 : OGRLayer * poSrcLayer,
1730 : OGRDataSource *poDstDS,
1731 : char **papszLCO,
1732 : const char *pszNewLayerName,
1733 : int bTransform,
1734 : OGRSpatialReference *poOutputSRS,
1735 : int bNullifyOutputSRS,
1736 : OGRSpatialReference *poSourceSRS,
1737 : char **papszSelFields,
1738 : int bAppend, int eGType, int bOverwrite,
1739 : GeomOperation eGeomOp,
1740 : double dfGeomOpParam,
1741 : char** papszFieldTypesToString,
1742 : long nCountLayerFeatures,
1743 : int bWrapDateline,
1744 : OGRGeometry* poClipSrc,
1745 : OGRGeometry *poClipDst,
1746 : int bExplodeCollections,
1747 : const char* pszZField,
1748 : const char* pszWHERE,
1749 : GDALProgressFunc pfnProgress,
1750 : void *pProgressArg)
1751 :
1752 : {
1753 : OGRLayer *poDstLayer;
1754 : OGRFeatureDefn *poSrcFDefn;
1755 206 : OGRFeatureDefn *poDstFDefn = NULL;
1756 206 : int bForceToPolygon = FALSE;
1757 206 : int bForceToMultiPolygon = FALSE;
1758 206 : int bForceToMultiLineString = FALSE;
1759 :
1760 206 : char** papszTransformOptions = NULL;
1761 :
1762 206 : if( pszNewLayerName == NULL )
1763 174 : pszNewLayerName = poSrcLayer->GetName();
1764 :
1765 206 : if( wkbFlatten(eGType) == wkbPolygon )
1766 2 : bForceToPolygon = TRUE;
1767 204 : else if( wkbFlatten(eGType) == wkbMultiPolygon )
1768 4 : bForceToMultiPolygon = TRUE;
1769 200 : else if( wkbFlatten(eGType) == wkbMultiLineString )
1770 0 : bForceToMultiLineString = TRUE;
1771 :
1772 : /* -------------------------------------------------------------------- */
1773 : /* Setup coordinate transformation if we need it. */
1774 : /* -------------------------------------------------------------------- */
1775 206 : OGRCoordinateTransformation *poCT = NULL;
1776 :
1777 206 : if( bTransform )
1778 : {
1779 4 : if( poSourceSRS == NULL )
1780 4 : poSourceSRS = poSrcLayer->GetSpatialRef();
1781 :
1782 4 : if( poSourceSRS == NULL )
1783 : {
1784 : fprintf( stderr, "Can't transform coordinates, source layer has no\n"
1785 0 : "coordinate system. Use -s_srs to set one.\n" );
1786 0 : exit( 1 );
1787 : }
1788 :
1789 4 : CPLAssert( NULL != poSourceSRS );
1790 4 : CPLAssert( NULL != poOutputSRS );
1791 :
1792 4 : poCT = OGRCreateCoordinateTransformation( poSourceSRS, poOutputSRS );
1793 4 : if( poCT == NULL )
1794 : {
1795 0 : char *pszWKT = NULL;
1796 :
1797 : fprintf( stderr, "Failed to create coordinate transformation between the\n"
1798 : "following coordinate systems. This may be because they\n"
1799 : "are not transformable, or because projection services\n"
1800 0 : "(PROJ.4 DLL/.so) could not be loaded.\n" );
1801 :
1802 0 : poSourceSRS->exportToPrettyWkt( &pszWKT, FALSE );
1803 0 : fprintf( stderr, "Source:\n%s\n", pszWKT );
1804 :
1805 0 : poOutputSRS->exportToPrettyWkt( &pszWKT, FALSE );
1806 0 : fprintf( stderr, "Target:\n%s\n", pszWKT );
1807 0 : exit( 1 );
1808 : }
1809 : }
1810 :
1811 206 : if (bWrapDateline)
1812 : {
1813 8 : if( poSourceSRS == NULL )
1814 6 : poSourceSRS = poSrcLayer->GetSpatialRef();
1815 :
1816 8 : if (poCT != NULL && poOutputSRS->IsGeographic())
1817 : {
1818 : papszTransformOptions =
1819 2 : CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
1820 : }
1821 6 : else if (poSourceSRS != NULL && poOutputSRS == NULL && poSourceSRS->IsGeographic())
1822 : {
1823 : papszTransformOptions =
1824 6 : CSLAddString(papszTransformOptions, "WRAPDATELINE=YES");
1825 : }
1826 : else
1827 : {
1828 0 : fprintf(stderr, "-wrapdateline option only works when reprojecting to a geographic SRS\n");
1829 : }
1830 : }
1831 :
1832 : /* -------------------------------------------------------------------- */
1833 : /* Get other info. */
1834 : /* -------------------------------------------------------------------- */
1835 206 : poSrcFDefn = poSrcLayer->GetLayerDefn();
1836 :
1837 206 : if( poOutputSRS == NULL && !bNullifyOutputSRS )
1838 198 : poOutputSRS = poSrcLayer->GetSpatialRef();
1839 :
1840 : /* -------------------------------------------------------------------- */
1841 : /* Find the layer. */
1842 : /* -------------------------------------------------------------------- */
1843 :
1844 : /* GetLayerByName() can instanciate layers that would have been */
1845 : /* 'hidden' otherwise, for example, non-spatial tables in a */
1846 : /* Postgis-enabled database, so this apparently useless command is */
1847 : /* not useless... (#4012) */
1848 206 : CPLPushErrorHandler(CPLQuietErrorHandler);
1849 206 : poDstLayer = poDstDS->GetLayerByName(pszNewLayerName);
1850 206 : CPLPopErrorHandler();
1851 206 : CPLErrorReset();
1852 :
1853 206 : int iLayer = -1;
1854 206 : if (poDstLayer != NULL)
1855 : {
1856 26 : int nLayerCount = poDstDS->GetLayerCount();
1857 700 : for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
1858 : {
1859 700 : OGRLayer *poLayer = poDstDS->GetLayer(iLayer);
1860 700 : if (poLayer == poDstLayer)
1861 26 : break;
1862 : }
1863 :
1864 26 : if (iLayer == nLayerCount)
1865 : /* shouldn't happen with an ideal driver */
1866 0 : poDstLayer = NULL;
1867 : }
1868 :
1869 : /* -------------------------------------------------------------------- */
1870 : /* If the user requested overwrite, and we have the layer in */
1871 : /* question we need to delete it now so it will get recreated */
1872 : /* (overwritten). */
1873 : /* -------------------------------------------------------------------- */
1874 206 : if( poDstLayer != NULL && bOverwrite )
1875 : {
1876 14 : if( poDstDS->DeleteLayer( iLayer ) != OGRERR_NONE )
1877 : {
1878 : fprintf( stderr,
1879 0 : "DeleteLayer() failed when overwrite requested.\n" );
1880 0 : CSLDestroy(papszTransformOptions);
1881 0 : return FALSE;
1882 : }
1883 14 : poDstLayer = NULL;
1884 : }
1885 :
1886 : /* -------------------------------------------------------------------- */
1887 : /* If the layer does not exist, then create it. */
1888 : /* -------------------------------------------------------------------- */
1889 206 : if( poDstLayer == NULL )
1890 : {
1891 194 : if( eGType == -2 )
1892 : {
1893 180 : eGType = poSrcFDefn->GetGeomType();
1894 :
1895 180 : if ( bExplodeCollections )
1896 : {
1897 2 : int n25DBit = eGType & wkb25DBit;
1898 2 : if (wkbFlatten(eGType) == wkbMultiPoint)
1899 : {
1900 0 : eGType = wkbPoint | n25DBit;
1901 : }
1902 2 : else if (wkbFlatten(eGType) == wkbMultiLineString)
1903 : {
1904 0 : eGType = wkbLineString | n25DBit;
1905 : }
1906 2 : else if (wkbFlatten(eGType) == wkbMultiPolygon)
1907 : {
1908 0 : eGType = wkbPolygon | n25DBit;
1909 : }
1910 2 : else if (wkbFlatten(eGType) == wkbGeometryCollection)
1911 : {
1912 0 : eGType = wkbUnknown | n25DBit;
1913 : }
1914 : }
1915 :
1916 180 : if ( pszZField )
1917 6 : eGType |= wkb25DBit;
1918 : }
1919 :
1920 194 : if( !poDstDS->TestCapability( ODsCCreateLayer ) )
1921 : {
1922 : fprintf( stderr,
1923 : "Layer %s not found, and CreateLayer not supported by driver.",
1924 0 : pszNewLayerName );
1925 0 : return FALSE;
1926 : }
1927 :
1928 194 : CPLErrorReset();
1929 :
1930 : poDstLayer = poDstDS->CreateLayer( pszNewLayerName, poOutputSRS,
1931 : (OGRwkbGeometryType) eGType,
1932 194 : papszLCO );
1933 :
1934 194 : if( poDstLayer == NULL )
1935 : {
1936 0 : CSLDestroy(papszTransformOptions);
1937 0 : return FALSE;
1938 : }
1939 :
1940 194 : bAppend = FALSE;
1941 : }
1942 :
1943 : /* -------------------------------------------------------------------- */
1944 : /* Otherwise we will append to it, if append was requested. */
1945 : /* -------------------------------------------------------------------- */
1946 12 : else if( !bAppend )
1947 : {
1948 : fprintf( stderr, "FAILED: Layer %s already exists, and -append not specified.\n"
1949 : " Consider using -append, or -overwrite.\n",
1950 0 : pszNewLayerName );
1951 0 : return FALSE;
1952 : }
1953 : else
1954 : {
1955 12 : if( CSLCount(papszLCO) > 0 )
1956 : {
1957 : fprintf( stderr, "WARNING: Layer creation options ignored since an existing layer is\n"
1958 0 : " being appended to.\n" );
1959 : }
1960 : }
1961 :
1962 : /* -------------------------------------------------------------------- */
1963 : /* Process Layer style table */
1964 : /* -------------------------------------------------------------------- */
1965 :
1966 206 : poDstLayer->SetStyleTable( poSrcLayer->GetStyleTable () );
1967 : /* -------------------------------------------------------------------- */
1968 : /* Add fields. Default to copy all field. */
1969 : /* If only a subset of all fields requested, then output only */
1970 : /* the selected fields, and in the order that they were */
1971 : /* selected. */
1972 : /* -------------------------------------------------------------------- */
1973 206 : int nSrcFieldCount = poSrcFDefn->GetFieldCount();
1974 : int iField, *panMap;
1975 :
1976 : // Initialize the index-to-index map to -1's
1977 206 : panMap = (int *) VSIMalloc( sizeof(int) * nSrcFieldCount );
1978 1302 : for( iField=0; iField < nSrcFieldCount; iField++)
1979 1096 : panMap[iField] = -1;
1980 :
1981 : /* Caution : at the time of writing, the MapInfo driver */
1982 : /* returns NULL until a field has been added */
1983 206 : poDstFDefn = poDstLayer->GetLayerDefn();
1984 :
1985 220 : if (papszSelFields && !bAppend )
1986 : {
1987 14 : int nDstFieldCount = 0;
1988 14 : if (poDstFDefn)
1989 12 : nDstFieldCount = poDstFDefn->GetFieldCount();
1990 36 : for( iField=0; papszSelFields[iField] != NULL; iField++)
1991 : {
1992 22 : int iSrcField = poSrcFDefn->GetFieldIndex(papszSelFields[iField]);
1993 22 : if (iSrcField >= 0)
1994 : {
1995 22 : OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iSrcField);
1996 22 : OGRFieldDefn oFieldDefn( poSrcFieldDefn );
1997 :
1998 22 : if (papszFieldTypesToString != NULL &&
1999 : (CSLFindString(papszFieldTypesToString, "All") != -1 ||
2000 : CSLFindString(papszFieldTypesToString,
2001 : OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
2002 : {
2003 0 : oFieldDefn.SetType(OFTString);
2004 : }
2005 :
2006 : /* The field may have been already created at layer creation */
2007 22 : int iDstField = -1;
2008 22 : if (poDstFDefn)
2009 20 : iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
2010 22 : if (iDstField >= 0)
2011 : {
2012 0 : panMap[iSrcField] = iDstField;
2013 : }
2014 22 : else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
2015 : {
2016 : /* now that we've created a field, GetLayerDefn() won't return NULL */
2017 22 : if (poDstFDefn == NULL)
2018 2 : poDstFDefn = poDstLayer->GetLayerDefn();
2019 :
2020 : /* Sanity check : if it fails, the driver is buggy */
2021 22 : if (poDstFDefn != NULL &&
2022 : poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
2023 : {
2024 : CPLError(CE_Warning, CPLE_AppDefined,
2025 : "The output driver has claimed to have added the %s field, but it did not!",
2026 0 : oFieldDefn.GetNameRef() );
2027 : }
2028 : else
2029 : {
2030 22 : panMap[iSrcField] = nDstFieldCount;
2031 22 : nDstFieldCount ++;
2032 : }
2033 22 : }
2034 : }
2035 : else
2036 : {
2037 : fprintf( stderr, "Field '%s' not found in source layer.\n",
2038 0 : papszSelFields[iField] );
2039 0 : if( !bSkipFailures )
2040 : {
2041 0 : VSIFree(panMap);
2042 0 : CSLDestroy(papszTransformOptions);
2043 0 : return FALSE;
2044 : }
2045 : }
2046 : }
2047 :
2048 : /* -------------------------------------------------------------------- */
2049 : /* Use SetIgnoredFields() on source layer if available */
2050 : /* -------------------------------------------------------------------- */
2051 14 : if (poSrcLayer->TestCapability(OLCIgnoreFields))
2052 : {
2053 : int iSrcField;
2054 6 : char** papszIgnoredFields = NULL;
2055 6 : int bUseIgnoredFields = TRUE;
2056 6 : char** papszWHEREUsedFields = NULL;
2057 :
2058 6 : if (pszWHERE)
2059 : {
2060 : /* We must not ignore fields used in the -where expression (#4015) */
2061 4 : OGRFeatureQuery oFeatureQuery;
2062 4 : if ( oFeatureQuery.Compile( poSrcLayer->GetLayerDefn(), pszWHERE ) == OGRERR_NONE )
2063 : {
2064 4 : papszWHEREUsedFields = oFeatureQuery.GetUsedFields();
2065 : }
2066 : else
2067 : {
2068 0 : bUseIgnoredFields = FALSE;
2069 4 : }
2070 : }
2071 :
2072 24 : for(iSrcField=0;iSrcField<poSrcFDefn->GetFieldCount();iSrcField++)
2073 : {
2074 : const char* pszFieldName =
2075 18 : poSrcFDefn->GetFieldDefn(iSrcField)->GetNameRef();
2076 18 : int bFieldRequested = FALSE;
2077 32 : for( iField=0; papszSelFields[iField] != NULL; iField++)
2078 : {
2079 22 : if (EQUAL(pszFieldName, papszSelFields[iField]))
2080 : {
2081 8 : bFieldRequested = TRUE;
2082 8 : break;
2083 : }
2084 : }
2085 18 : bFieldRequested |= CSLFindString(papszWHEREUsedFields, pszFieldName) >= 0;
2086 18 : bFieldRequested |= (pszZField != NULL && EQUAL(pszFieldName, pszZField));
2087 :
2088 : /* If source field not requested, add it to ignored files list */
2089 18 : if (!bFieldRequested)
2090 8 : papszIgnoredFields = CSLAddString(papszIgnoredFields, pszFieldName);
2091 : }
2092 6 : if (bUseIgnoredFields)
2093 6 : poSrcLayer->SetIgnoredFields((const char**)papszIgnoredFields);
2094 6 : CSLDestroy(papszIgnoredFields);
2095 6 : CSLDestroy(papszWHEREUsedFields);
2096 : }
2097 : }
2098 192 : else if( !bAppend )
2099 : {
2100 180 : int nDstFieldCount = 0;
2101 180 : if (poDstFDefn)
2102 176 : nDstFieldCount = poDstFDefn->GetFieldCount();
2103 1204 : for( iField = 0; iField < nSrcFieldCount; iField++ )
2104 : {
2105 1024 : OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
2106 1024 : OGRFieldDefn oFieldDefn( poSrcFieldDefn );
2107 :
2108 1024 : if (papszFieldTypesToString != NULL &&
2109 : (CSLFindString(papszFieldTypesToString, "All") != -1 ||
2110 : CSLFindString(papszFieldTypesToString,
2111 : OGRFieldDefn::GetFieldTypeName(poSrcFieldDefn->GetType())) != -1))
2112 : {
2113 0 : oFieldDefn.SetType(OFTString);
2114 : }
2115 :
2116 : /* The field may have been already created at layer creation */
2117 1024 : int iDstField = -1;
2118 1024 : if (poDstFDefn)
2119 1020 : iDstField = poDstFDefn->GetFieldIndex(oFieldDefn.GetNameRef());
2120 1024 : if (iDstField >= 0)
2121 : {
2122 570 : panMap[iField] = iDstField;
2123 : }
2124 454 : else if (poDstLayer->CreateField( &oFieldDefn ) == OGRERR_NONE)
2125 : {
2126 : /* now that we've created a field, GetLayerDefn() won't return NULL */
2127 454 : if (poDstFDefn == NULL)
2128 4 : poDstFDefn = poDstLayer->GetLayerDefn();
2129 :
2130 : /* Sanity check : if it fails, the driver is buggy */
2131 454 : if (poDstFDefn != NULL &&
2132 : poDstFDefn->GetFieldCount() != nDstFieldCount + 1)
2133 : {
2134 : CPLError(CE_Warning, CPLE_AppDefined,
2135 : "The output driver has claimed to have added the %s field, but it did not!",
2136 0 : oFieldDefn.GetNameRef() );
2137 : }
2138 : else
2139 : {
2140 454 : panMap[iField] = nDstFieldCount;
2141 454 : nDstFieldCount ++;
2142 : }
2143 : }
2144 : }
2145 : }
2146 : else
2147 : {
2148 : /* For an existing layer, build the map by fetching the index in the destination */
2149 : /* layer for each source field */
2150 12 : if (poDstFDefn == NULL)
2151 : {
2152 0 : fprintf( stderr, "poDstFDefn == NULL.\n" );
2153 0 : VSIFree(panMap);
2154 0 : CSLDestroy(papszTransformOptions);
2155 0 : return FALSE;
2156 : }
2157 :
2158 48 : for( iField = 0; iField < nSrcFieldCount; iField++ )
2159 : {
2160 36 : OGRFieldDefn* poSrcFieldDefn = poSrcFDefn->GetFieldDefn(iField);
2161 36 : int iDstField = poDstFDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
2162 36 : if (iDstField >= 0)
2163 36 : panMap[iField] = iDstField;
2164 : }
2165 : }
2166 :
2167 : /* -------------------------------------------------------------------- */
2168 : /* Transfer features. */
2169 : /* -------------------------------------------------------------------- */
2170 : OGRFeature *poFeature;
2171 206 : int nFeaturesInTransaction = 0;
2172 206 : GIntBig nCount = 0; /* written + failed */
2173 206 : GIntBig nFeaturesWritten = 0;
2174 :
2175 206 : int iSrcZField = -1;
2176 206 : if (pszZField != NULL)
2177 : {
2178 6 : iSrcZField = poSrcFDefn->GetFieldIndex(pszZField);
2179 : }
2180 :
2181 206 : poSrcLayer->ResetReading();
2182 :
2183 206 : if( nGroupTransactions )
2184 206 : poDstLayer->StartTransaction();
2185 :
2186 251704 : while( TRUE )
2187 : {
2188 251910 : OGRFeature *poDstFeature = NULL;
2189 :
2190 251910 : if( nFIDToFetch != OGRNullFID )
2191 : {
2192 : // Only fetch feature on first pass.
2193 4 : if( nFeaturesInTransaction == 0 )
2194 2 : poFeature = poSrcLayer->GetFeature(nFIDToFetch);
2195 : else
2196 2 : poFeature = NULL;
2197 : }
2198 : else
2199 251906 : poFeature = poSrcLayer->GetNextFeature();
2200 :
2201 251910 : if( poFeature == NULL )
2202 : break;
2203 :
2204 251704 : int nParts = 0;
2205 251704 : int nIters = 1;
2206 251704 : if (bExplodeCollections)
2207 : {
2208 4 : OGRGeometry* poSrcGeometry = poFeature->GetGeometryRef();
2209 4 : if (poSrcGeometry)
2210 : {
2211 4 : switch (wkbFlatten(poSrcGeometry->getGeometryType()))
2212 : {
2213 : case wkbMultiPoint:
2214 : case wkbMultiLineString:
2215 : case wkbMultiPolygon:
2216 : case wkbGeometryCollection:
2217 2 : nParts = ((OGRGeometryCollection*)poSrcGeometry)->getNumGeometries();
2218 2 : nIters = nParts;
2219 2 : if (nIters == 0)
2220 0 : nIters = 1;
2221 : default:
2222 : break;
2223 : }
2224 : }
2225 : }
2226 :
2227 503410 : for(int iPart = 0; iPart < nIters; iPart++)
2228 : {
2229 251706 : if( ++nFeaturesInTransaction == nGroupTransactions )
2230 : {
2231 1260 : poDstLayer->CommitTransaction();
2232 1260 : poDstLayer->StartTransaction();
2233 1260 : nFeaturesInTransaction = 0;
2234 : }
2235 :
2236 251706 : CPLErrorReset();
2237 251706 : poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() );
2238 :
2239 251706 : if( poDstFeature->SetFrom( poFeature, panMap, TRUE ) != OGRERR_NONE )
2240 : {
2241 0 : if( nGroupTransactions )
2242 0 : poDstLayer->CommitTransaction();
2243 :
2244 : CPLError( CE_Failure, CPLE_AppDefined,
2245 : "Unable to translate feature %ld from layer %s.\n",
2246 0 : poFeature->GetFID(), poSrcFDefn->GetName() );
2247 :
2248 0 : OGRFeature::DestroyFeature( poFeature );
2249 0 : OGRFeature::DestroyFeature( poDstFeature );
2250 0 : VSIFree(panMap);
2251 0 : CSLDestroy(papszTransformOptions);
2252 0 : return FALSE;
2253 : }
2254 :
2255 251706 : if( bPreserveFID )
2256 0 : poDstFeature->SetFID( poFeature->GetFID() );
2257 :
2258 251706 : OGRGeometry* poDstGeometry = poDstFeature->GetGeometryRef();
2259 251706 : if (poDstGeometry != NULL)
2260 : {
2261 48678 : if (nParts > 0)
2262 : {
2263 : /* For -explodecollections, extract the iPart(th) of the geometry */
2264 4 : OGRGeometry* poPart = ((OGRGeometryCollection*)poDstGeometry)->getGeometryRef(iPart);
2265 4 : ((OGRGeometryCollection*)poDstGeometry)->removeGeometry(iPart, FALSE);
2266 4 : poDstFeature->SetGeometryDirectly(poPart);
2267 4 : poDstGeometry = poPart;
2268 : }
2269 :
2270 48678 : if (iSrcZField != -1)
2271 : {
2272 60 : SetZ(poDstGeometry, poFeature->GetFieldAsDouble(iSrcZField));
2273 : /* This will correct the coordinate dimension to 3 */
2274 60 : OGRGeometry* poDupGeometry = poDstGeometry->clone();
2275 60 : poDstFeature->SetGeometryDirectly(poDupGeometry);
2276 60 : poDstGeometry = poDupGeometry;
2277 : }
2278 :
2279 48678 : if (eGeomOp == SEGMENTIZE)
2280 : {
2281 20 : if (dfGeomOpParam > 0)
2282 20 : poDstGeometry->segmentize(dfGeomOpParam);
2283 : }
2284 48658 : else if (eGeomOp == SIMPLIFY_PRESERVE_TOPOLOGY)
2285 : {
2286 0 : if (dfGeomOpParam > 0)
2287 : {
2288 0 : OGRGeometry* poNewGeom = poDstGeometry->SimplifyPreserveTopology(dfGeomOpParam);
2289 0 : if (poNewGeom)
2290 : {
2291 0 : poDstFeature->SetGeometryDirectly(poNewGeom);
2292 0 : poDstGeometry = poNewGeom;
2293 : }
2294 : }
2295 : }
2296 :
2297 48678 : if (poClipSrc)
2298 : {
2299 48 : OGRGeometry* poClipped = poDstGeometry->Intersection(poClipSrc);
2300 48 : if (poClipped == NULL || poClipped->IsEmpty())
2301 : {
2302 24 : OGRGeometryFactory::destroyGeometry(poClipped);
2303 24 : goto end_loop;
2304 : }
2305 24 : poDstFeature->SetGeometryDirectly(poClipped);
2306 24 : poDstGeometry = poClipped;
2307 : }
2308 :
2309 48682 : if( poCT != NULL || papszTransformOptions != NULL)
2310 : {
2311 : OGRGeometry* poReprojectedGeom =
2312 28 : OGRGeometryFactory::transformWithOptions(poDstGeometry, poCT, papszTransformOptions);
2313 28 : if( poReprojectedGeom == NULL )
2314 : {
2315 0 : if( nGroupTransactions )
2316 0 : poDstLayer->CommitTransaction();
2317 :
2318 : fprintf( stderr, "Failed to reproject feature %d (geometry probably out of source or destination SRS).\n",
2319 0 : (int) poFeature->GetFID() );
2320 0 : if( !bSkipFailures )
2321 : {
2322 0 : OGRFeature::DestroyFeature( poFeature );
2323 0 : OGRFeature::DestroyFeature( poDstFeature );
2324 0 : VSIFree(panMap);
2325 0 : CSLDestroy(papszTransformOptions);
2326 0 : return FALSE;
2327 : }
2328 : }
2329 :
2330 28 : poDstFeature->SetGeometryDirectly(poReprojectedGeom);
2331 28 : poDstGeometry = poReprojectedGeom;
2332 : }
2333 48626 : else if (poOutputSRS != NULL)
2334 : {
2335 48518 : poDstGeometry->assignSpatialReference(poOutputSRS);
2336 : }
2337 :
2338 48654 : if (poClipDst)
2339 : {
2340 40 : OGRGeometry* poClipped = poDstGeometry->Intersection(poClipDst);
2341 40 : if (poClipped == NULL || poClipped->IsEmpty())
2342 : {
2343 24 : OGRGeometryFactory::destroyGeometry(poClipped);
2344 24 : goto end_loop;
2345 : }
2346 :
2347 16 : poDstFeature->SetGeometryDirectly(poClipped);
2348 16 : poDstGeometry = poClipped;
2349 : }
2350 :
2351 48630 : if( bForceToPolygon )
2352 : {
2353 : poDstFeature->SetGeometryDirectly(
2354 : OGRGeometryFactory::forceToPolygon(
2355 20 : poDstFeature->StealGeometry() ) );
2356 : }
2357 48610 : else if( bForceToMultiPolygon )
2358 : {
2359 : poDstFeature->SetGeometryDirectly(
2360 : OGRGeometryFactory::forceToMultiPolygon(
2361 28 : poDstFeature->StealGeometry() ) );
2362 : }
2363 48582 : else if ( bForceToMultiLineString )
2364 : {
2365 : poDstFeature->SetGeometryDirectly(
2366 : OGRGeometryFactory::forceToMultiLineString(
2367 0 : poDstFeature->StealGeometry() ) );
2368 : }
2369 : }
2370 :
2371 251658 : CPLErrorReset();
2372 251658 : if( poDstLayer->CreateFeature( poDstFeature ) == OGRERR_NONE )
2373 : {
2374 251658 : nFeaturesWritten ++;
2375 : }
2376 0 : else if( !bSkipFailures )
2377 : {
2378 0 : if( nGroupTransactions )
2379 0 : poDstLayer->RollbackTransaction();
2380 :
2381 0 : OGRFeature::DestroyFeature( poFeature );
2382 0 : OGRFeature::DestroyFeature( poDstFeature );
2383 0 : VSIFree(panMap);
2384 0 : CSLDestroy(papszTransformOptions);
2385 0 : return FALSE;
2386 : }
2387 :
2388 : end_loop:
2389 251706 : OGRFeature::DestroyFeature( poDstFeature );
2390 : }
2391 :
2392 251704 : OGRFeature::DestroyFeature( poFeature );
2393 :
2394 : /* Report progress */
2395 251704 : nCount ++;
2396 251704 : if (pfnProgress)
2397 20 : pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg);
2398 : }
2399 :
2400 206 : if( nGroupTransactions )
2401 206 : poDstLayer->CommitTransaction();
2402 :
2403 : CPLDebug("OGR2OGR", CPL_FRMT_GIB " features written in layer '%s'",
2404 206 : nFeaturesWritten, pszNewLayerName);
2405 :
2406 : /* -------------------------------------------------------------------- */
2407 : /* Cleaning */
2408 : /* -------------------------------------------------------------------- */
2409 206 : OGRCoordinateTransformation::DestroyCT(poCT);
2410 :
2411 206 : VSIFree(panMap);
2412 206 : CSLDestroy(papszTransformOptions);
2413 :
2414 206 : return TRUE;
2415 : }
2416 :
|