ogr2ogr.py 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. #*****************************************************************************
  4. # $Id$
  5. #
  6. # Project: OpenGIS Simple Features Reference Implementation
  7. # Purpose: Python port of a simple client for translating between formats.
  8. # Author: Even Rouault, <even dot rouault at mines dash paris dot org>
  9. #
  10. # Port from ogr2ogr.cpp whose author is Frank Warmerdam
  11. #
  12. #*****************************************************************************
  13. # Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
  14. # Copyright (c) 1999, Frank Warmerdam
  15. #
  16. # Permission is hereby granted, free of charge, to any person obtaining a
  17. # copy of this software and associated documentation files (the "Software"),
  18. # to deal in the Software without restriction, including without limitation
  19. # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  20. # and/or sell copies of the Software, and to permit persons to whom the
  21. # Software is furnished to do so, subject to the following conditions:
  22. #
  23. # The above copyright notice and this permission notice shall be included
  24. # in all copies or substantial portions of the Software.
  25. #
  26. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  27. # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  28. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  29. # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  30. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  31. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  32. # DEALINGS IN THE SOFTWARE.
  33. #**************************************************************************
  34. # Note : this is the most direct port of ogr2ogr.cpp possible
  35. # It could be made much more Python'ish !
  36. import sys
  37. import os
  38. import stat
  39. from osgeo import gdal
  40. from osgeo import ogr
  41. from osgeo import osr
  42. ###############################################################################
  43. class ScaledProgressObject:
  44. def __init__(self, min, max, cbk, cbk_data = None):
  45. self.min = min
  46. self.max = max
  47. self.cbk = cbk
  48. self.cbk_data = cbk_data
  49. ###############################################################################
  50. def ScaledProgressFunc(pct, msg, data):
  51. if data.cbk is None:
  52. return True
  53. return data.cbk(data.min + pct * (data.max - data.min), msg, data.cbk_data)
  54. ###############################################################################
  55. def EQUAL(a, b):
  56. return a.lower() == b.lower()
  57. ###############################################################################
  58. # Redefinition of GDALTermProgress, so that autotest/pyscripts/test_ogr2ogr_py.py
  59. # can check that the progress bar is displayed
  60. nLastTick = -1
  61. def TermProgress( dfComplete, pszMessage, pProgressArg ):
  62. global nLastTick
  63. nThisTick = (int) (dfComplete * 40.0)
  64. if nThisTick < 0:
  65. nThisTick = 0
  66. if nThisTick > 40:
  67. nThisTick = 40
  68. # Have we started a new progress run?
  69. if nThisTick < nLastTick and nLastTick >= 39:
  70. nLastTick = -1
  71. if nThisTick <= nLastTick:
  72. return True
  73. while nThisTick > nLastTick:
  74. nLastTick = nLastTick + 1
  75. if (nLastTick % 4) == 0:
  76. sys.stdout.write('%d' % ((nLastTick / 4) * 10))
  77. else:
  78. sys.stdout.write('.')
  79. if nThisTick == 40:
  80. print(" - done." )
  81. else:
  82. sys.stdout.flush()
  83. return True
  84. class TargetLayerInfo:
  85. def __init__(self):
  86. self.poDstLayer = None
  87. self.poCT = None
  88. #self.papszTransformOptions = None
  89. self.panMap = None
  90. self.iSrcZField = None
  91. class AssociatedLayers:
  92. def __init__(self):
  93. self.poSrcLayer = None
  94. self.psInfo = None
  95. #**********************************************************************
  96. # main()
  97. #**********************************************************************
  98. bSkipFailures = False
  99. nGroupTransactions = 200
  100. bPreserveFID = False
  101. nFIDToFetch = ogr.NullFID
  102. class Enum(set):
  103. def __getattr__(self, name):
  104. if name in self:
  105. return name
  106. raise AttributeError
  107. GeomOperation = Enum(["NONE", "SEGMENTIZE", "SIMPLIFY_PRESERVE_TOPOLOGY"])
  108. def main(args = None, progress_func = TermProgress, progress_data = None):
  109. global bSkipFailures
  110. global nGroupTransactions
  111. global bPreserveFID
  112. global nFIDToFetch
  113. pszFormat = "ESRI Shapefile"
  114. pszDataSource = None
  115. pszDestDataSource = None
  116. papszLayers = []
  117. papszDSCO = []
  118. papszLCO = []
  119. bTransform = False
  120. bAppend = False
  121. bUpdate = False
  122. bOverwrite = False
  123. pszOutputSRSDef = None
  124. pszSourceSRSDef = None
  125. poOutputSRS = None
  126. bNullifyOutputSRS = False
  127. poSourceSRS = None
  128. pszNewLayerName = None
  129. pszWHERE = None
  130. poSpatialFilter = None
  131. pszSelect = None
  132. papszSelFields = None
  133. pszSQLStatement = None
  134. eGType = -2
  135. bPromoteToMulti = False
  136. eGeomOp = GeomOperation.NONE
  137. dfGeomOpParam = 0
  138. papszFieldTypesToString = []
  139. bDisplayProgress = False
  140. pfnProgress = None
  141. pProgressArg = None
  142. bClipSrc = False
  143. bWrapDateline = False
  144. poClipSrc = None
  145. pszClipSrcDS = None
  146. pszClipSrcSQL = None
  147. pszClipSrcLayer = None
  148. pszClipSrcWhere = None
  149. poClipDst = None
  150. pszClipDstDS = None
  151. pszClipDstSQL = None
  152. pszClipDstLayer = None
  153. pszClipDstWhere = None
  154. #pszSrcEncoding = None
  155. #pszDstEncoding = None
  156. bWrapDateline = False
  157. bExplodeCollections = False
  158. pszZField = None
  159. nCoordDim = -1
  160. if args is None:
  161. args = sys.argv
  162. args = ogr.GeneralCmdLineProcessor( args )
  163. # --------------------------------------------------------------------
  164. # Processing command line arguments.
  165. # --------------------------------------------------------------------
  166. if args is None:
  167. return False
  168. nArgc = len(args)
  169. iArg = 1
  170. while iArg < nArgc:
  171. if EQUAL(args[iArg],"-f") and iArg < nArgc-1:
  172. iArg = iArg + 1
  173. pszFormat = args[iArg]
  174. elif EQUAL(args[iArg],"-dsco") and iArg < nArgc-1:
  175. iArg = iArg + 1
  176. papszDSCO.append(args[iArg] )
  177. elif EQUAL(args[iArg],"-lco") and iArg < nArgc-1:
  178. iArg = iArg + 1
  179. papszLCO.append(args[iArg] )
  180. elif EQUAL(args[iArg],"-preserve_fid"):
  181. bPreserveFID = True
  182. elif len(args[iArg]) >= 5 and EQUAL(args[iArg][0:5], "-skip"):
  183. bSkipFailures = True
  184. nGroupTransactions = 1 # #2409
  185. elif EQUAL(args[iArg],"-append"):
  186. bAppend = True
  187. bUpdate = True
  188. elif EQUAL(args[iArg],"-overwrite"):
  189. bOverwrite = True
  190. bUpdate = True
  191. elif EQUAL(args[iArg],"-update"):
  192. bUpdate = True
  193. elif EQUAL(args[iArg],"-fid") and iArg < nArgc-1:
  194. iArg = iArg + 1
  195. nFIDToFetch = int(args[iArg])
  196. elif EQUAL(args[iArg],"-sql") and iArg < nArgc-1:
  197. iArg = iArg + 1
  198. pszSQLStatement = args[iArg]
  199. elif EQUAL(args[iArg],"-nln") and iArg < nArgc-1:
  200. iArg = iArg + 1
  201. pszNewLayerName = args[iArg]
  202. elif EQUAL(args[iArg],"-nlt") and iArg < nArgc-1:
  203. if EQUAL(args[iArg+1],"NONE"):
  204. eGType = ogr.wkbNone
  205. elif EQUAL(args[iArg+1],"GEOMETRY"):
  206. eGType = ogr.wkbUnknown
  207. elif EQUAL(args[iArg+1],"PROMOTE_TO_MULTI"):
  208. bPromoteToMulti = True
  209. elif EQUAL(args[iArg+1],"POINT"):
  210. eGType = ogr.wkbPoint
  211. elif EQUAL(args[iArg+1],"LINESTRING"):
  212. eGType = ogr.wkbLineString
  213. elif EQUAL(args[iArg+1],"POLYGON"):
  214. eGType = ogr.wkbPolygon
  215. elif EQUAL(args[iArg+1],"GEOMETRYCOLLECTION"):
  216. eGType = ogr.wkbGeometryCollection
  217. elif EQUAL(args[iArg+1],"MULTIPOINT"):
  218. eGType = ogr.wkbMultiPoint
  219. elif EQUAL(args[iArg+1],"MULTILINESTRING"):
  220. eGType = ogr.wkbMultiLineString
  221. elif EQUAL(args[iArg+1],"MULTIPOLYGON"):
  222. eGType = ogr.wkbMultiPolygon
  223. elif EQUAL(args[iArg+1],"GEOMETRY25D"):
  224. eGType = ogr.wkbUnknown | ogr.wkb25DBit
  225. elif EQUAL(args[iArg+1],"POINT25D"):
  226. eGType = ogr.wkbPoint25D
  227. elif EQUAL(args[iArg+1],"LINESTRING25D"):
  228. eGType = ogr.wkbLineString25D
  229. elif EQUAL(args[iArg+1],"POLYGON25D"):
  230. eGType = ogr.wkbPolygon25D
  231. elif EQUAL(args[iArg+1],"GEOMETRYCOLLECTION25D"):
  232. eGType = ogr.wkbGeometryCollection25D
  233. elif EQUAL(args[iArg+1],"MULTIPOINT25D"):
  234. eGType = ogr.wkbMultiPoint25D
  235. elif EQUAL(args[iArg+1],"MULTILINESTRING25D"):
  236. eGType = ogr.wkbMultiLineString25D
  237. elif EQUAL(args[iArg+1],"MULTIPOLYGON25D"):
  238. eGType = ogr.wkbMultiPolygon25D
  239. else:
  240. print("-nlt %s: type not recognised." % args[iArg+1])
  241. return False
  242. iArg = iArg + 1
  243. elif EQUAL(args[iArg],"-dim") and iArg < nArgc-1:
  244. nCoordDim = int(args[iArg+1])
  245. if nCoordDim != 2 and nCoordDim != 3:
  246. print("-dim %s: value not handled." % args[iArg+1])
  247. return False
  248. iArg = iArg + 1
  249. elif (EQUAL(args[iArg],"-tg") or \
  250. EQUAL(args[iArg],"-gt")) and iArg < nArgc-1:
  251. iArg = iArg + 1
  252. nGroupTransactions = int(args[iArg])
  253. elif EQUAL(args[iArg],"-s_srs") and iArg < nArgc-1:
  254. iArg = iArg + 1
  255. pszSourceSRSDef = args[iArg]
  256. elif EQUAL(args[iArg],"-a_srs") and iArg < nArgc-1:
  257. iArg = iArg + 1
  258. pszOutputSRSDef = args[iArg]
  259. if EQUAL(pszOutputSRSDef, "NULL") or \
  260. EQUAL(pszOutputSRSDef, "NONE"):
  261. pszOutputSRSDef = None
  262. bNullifyOutputSRS = True
  263. elif EQUAL(args[iArg],"-t_srs") and iArg < nArgc-1:
  264. iArg = iArg + 1
  265. pszOutputSRSDef = args[iArg]
  266. bTransform = True
  267. elif EQUAL(args[iArg],"-spat") and iArg + 4 < nArgc:
  268. oRing = ogr.Geometry(ogr.wkbLinearRing)
  269. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  270. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
  271. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
  272. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
  273. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  274. poSpatialFilter = ogr.Geometry(ogr.wkbPolygon)
  275. poSpatialFilter.AddGeometry(oRing)
  276. iArg = iArg + 4
  277. elif EQUAL(args[iArg],"-where") and iArg < nArgc-1:
  278. iArg = iArg + 1
  279. pszWHERE = args[iArg]
  280. elif EQUAL(args[iArg],"-select") and iArg < nArgc-1:
  281. iArg = iArg + 1
  282. pszSelect = args[iArg]
  283. if pszSelect.find(',') != -1:
  284. papszSelFields = pszSelect.split(',')
  285. else:
  286. papszSelFields = pszSelect.split(' ')
  287. if papszSelFields[0] == '':
  288. papszSelFields = []
  289. elif EQUAL(args[iArg],"-simplify") and iArg < nArgc-1:
  290. iArg = iArg + 1
  291. eGeomOp = GeomOperation.SIMPLIFY_PRESERVE_TOPOLOGY
  292. dfGeomOpParam = float(args[iArg])
  293. elif EQUAL(args[iArg],"-segmentize") and iArg < nArgc-1:
  294. iArg = iArg + 1
  295. eGeomOp = GeomOperation.SEGMENTIZE
  296. dfGeomOpParam = float(args[iArg])
  297. elif EQUAL(args[iArg],"-fieldTypeToString") and iArg < nArgc-1:
  298. iArg = iArg + 1
  299. pszFieldTypeToString = args[iArg]
  300. if pszFieldTypeToString.find(',') != -1:
  301. tokens = pszFieldTypeToString.split(',')
  302. else:
  303. tokens = pszFieldTypeToString.split(' ')
  304. for token in tokens:
  305. if EQUAL(token,"Integer") or \
  306. EQUAL(token,"Real") or \
  307. EQUAL(token,"String") or \
  308. EQUAL(token,"Date") or \
  309. EQUAL(token,"Time") or \
  310. EQUAL(token,"DateTime") or \
  311. EQUAL(token,"Binary") or \
  312. EQUAL(token,"IntegerList") or \
  313. EQUAL(token,"RealList") or \
  314. EQUAL(token,"StringList"):
  315. papszFieldTypesToString.append(token)
  316. elif EQUAL(token,"All"):
  317. papszFieldTypesToString = [ 'All' ]
  318. break
  319. else:
  320. print("Unhandled type for fieldtypeasstring option : %s " % token)
  321. return Usage()
  322. elif EQUAL(args[iArg],"-progress"):
  323. bDisplayProgress = True
  324. #elif EQUAL(args[iArg],"-wrapdateline") )
  325. #{
  326. # bWrapDateline = True;
  327. #}
  328. #
  329. elif EQUAL(args[iArg],"-clipsrc") and iArg < nArgc-1:
  330. bClipSrc = True
  331. if IsNumber(args[iArg+1]) and iArg < nArgc - 4:
  332. oRing = ogr.Geometry(ogr.wkbLinearRing)
  333. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  334. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
  335. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
  336. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
  337. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  338. poClipSrc = ogr.Geometry(ogr.wkbPolygon)
  339. poClipSrc.AddGeometry(oRing)
  340. iArg = iArg + 4
  341. elif (len(args[iArg+1]) >= 7 and EQUAL(args[iArg+1][0:7],"POLYGON") ) or \
  342. (len(args[iArg+1]) >= 12 and EQUAL(args[iArg+1][0:12],"MULTIPOLYGON") ) :
  343. poClipSrc = ogr.CreateGeometryFromWkt(args[iArg+1])
  344. if poClipSrc is None:
  345. print("FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n")
  346. return Usage()
  347. iArg = iArg + 1
  348. elif EQUAL(args[iArg+1],"spat_extent"):
  349. iArg = iArg + 1
  350. else:
  351. pszClipSrcDS = args[iArg+1]
  352. iArg = iArg + 1
  353. elif EQUAL(args[iArg],"-clipsrcsql") and iArg < nArgc-1:
  354. pszClipSrcSQL = args[iArg+1]
  355. iArg = iArg + 1
  356. elif EQUAL(args[iArg],"-clipsrclayer") and iArg < nArgc-1:
  357. pszClipSrcLayer = args[iArg+1]
  358. iArg = iArg + 1
  359. elif EQUAL(args[iArg],"-clipsrcwhere") and iArg < nArgc-1:
  360. pszClipSrcWhere = args[iArg+1]
  361. iArg = iArg + 1
  362. elif EQUAL(args[iArg],"-clipdst") and iArg < nArgc-1:
  363. if IsNumber(args[iArg+1]) and iArg < nArgc - 4:
  364. oRing = ogr.Geometry(ogr.wkbLinearRing)
  365. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  366. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
  367. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
  368. oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
  369. oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
  370. poClipDst = ogr.Geometry(ogr.wkbPolygon)
  371. poClipDst.AddGeometry(oRing)
  372. iArg = iArg + 4
  373. elif (len(args[iArg+1]) >= 7 and EQUAL(args[iArg+1][0:7],"POLYGON") ) or \
  374. (len(args[iArg+1]) >= 12 and EQUAL(args[iArg+1][0:12],"MULTIPOLYGON") ) :
  375. poClipDst = ogr.CreateGeometryFromWkt(args[iArg+1])
  376. if poClipDst is None:
  377. print("FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n")
  378. return Usage()
  379. iArg = iArg + 1
  380. elif EQUAL(args[iArg+1],"spat_extent"):
  381. iArg = iArg + 1
  382. else:
  383. pszClipDstDS = args[iArg+1]
  384. iArg = iArg + 1
  385. elif EQUAL(args[iArg],"-clipdstsql") and iArg < nArgc-1:
  386. pszClipDstSQL = args[iArg+1]
  387. iArg = iArg + 1
  388. elif EQUAL(args[iArg],"-clipdstlayer") and iArg < nArgc-1:
  389. pszClipDstLayer = args[iArg+1]
  390. iArg = iArg + 1
  391. elif EQUAL(args[iArg],"-clipdstwhere") and iArg < nArgc-1:
  392. pszClipDstWhere = args[iArg+1]
  393. iArg = iArg + 1
  394. elif EQUAL(args[iArg],"-explodecollections"):
  395. bExplodeCollections = True
  396. elif EQUAL(args[iArg],"-zfield") and iArg < nArgc-1:
  397. pszZField = args[iArg+1]
  398. iArg = iArg + 1
  399. elif args[iArg][0] == '-':
  400. return Usage()
  401. elif pszDestDataSource is None:
  402. pszDestDataSource = args[iArg]
  403. elif pszDataSource is None:
  404. pszDataSource = args[iArg]
  405. else:
  406. papszLayers.append (args[iArg] )
  407. iArg = iArg + 1
  408. if pszDataSource is None:
  409. return Usage()
  410. if bPreserveFID and bExplodeCollections:
  411. print("FAILURE: cannot use -preserve_fid and -explodecollections at the same time\n\n")
  412. return Usage()
  413. if bClipSrc and pszClipSrcDS is not None:
  414. poClipSrc = LoadGeometry(pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere)
  415. if poClipSrc is None:
  416. print("FAILURE: cannot load source clip geometry\n" )
  417. return Usage()
  418. elif bClipSrc and poClipSrc is None:
  419. if poSpatialFilter is not None:
  420. poClipSrc = poSpatialFilter.Clone()
  421. if poClipSrc is None:
  422. print("FAILURE: -clipsrc must be used with -spat option or a\n" + \
  423. "bounding box, WKT string or datasource must be specified\n")
  424. return Usage()
  425. if pszClipDstDS is not None:
  426. poClipDst = LoadGeometry(pszClipDstDS, pszClipDstSQL, pszClipDstLayer, pszClipDstWhere)
  427. if poClipDst is None:
  428. print("FAILURE: cannot load dest clip geometry\n" )
  429. return Usage()
  430. # --------------------------------------------------------------------
  431. # Open data source.
  432. # --------------------------------------------------------------------
  433. poDS = ogr.Open( pszDataSource, False )
  434. # --------------------------------------------------------------------
  435. # Report failure
  436. # --------------------------------------------------------------------
  437. if poDS is None:
  438. print("FAILURE:\n" + \
  439. "Unable to open datasource `%s' with the following drivers." % pszDataSource)
  440. for iDriver in range(ogr.GetDriverCount()):
  441. print(" -> " + ogr.GetDriver(iDriver).GetName() )
  442. return False
  443. # --------------------------------------------------------------------
  444. # Try opening the output datasource as an existing, writable
  445. # --------------------------------------------------------------------
  446. poODS = None
  447. poDriver = None
  448. if bUpdate:
  449. poODS = ogr.Open( pszDestDataSource, True )
  450. if poODS is None:
  451. if bOverwrite or bAppend:
  452. poODS = ogr.Open( pszDestDataSource, False )
  453. if poODS is None:
  454. # the datasource doesn't exist at all
  455. bUpdate = False
  456. else:
  457. poODS.delete()
  458. poODS = None
  459. if bUpdate:
  460. print("FAILURE:\n" +
  461. "Unable to open existing output datasource `%s'." % pszDestDataSource)
  462. return False
  463. elif len(papszDSCO) > 0:
  464. print("WARNING: Datasource creation options ignored since an existing datasource\n" + \
  465. " being updated." )
  466. if poODS is not None:
  467. poDriver = poODS.GetDriver()
  468. # --------------------------------------------------------------------
  469. # Find the output driver.
  470. # --------------------------------------------------------------------
  471. if not bUpdate:
  472. poDriver = ogr.GetDriverByName(pszFormat)
  473. if poDriver is None:
  474. print("Unable to find driver `%s'." % pszFormat)
  475. print( "The following drivers are available:" )
  476. for iDriver in range(ogr.GetDriverCount()):
  477. print(" -> %s" % ogr.GetDriver(iDriver).GetName() )
  478. return False
  479. if poDriver.TestCapability( ogr.ODrCCreateDataSource ) == False:
  480. print( "%s driver does not support data source creation." % pszFormat)
  481. return False
  482. # --------------------------------------------------------------------
  483. # Special case to improve user experience when translating
  484. # a datasource with multiple layers into a shapefile. If the
  485. # user gives a target datasource with .shp and it does not exist,
  486. # the shapefile driver will try to create a file, but this is not
  487. # appropriate because here we have several layers, so create
  488. # a directory instead.
  489. # --------------------------------------------------------------------
  490. if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
  491. pszSQLStatement is None and \
  492. (len(papszLayers) > 1 or \
  493. (len(papszLayers) == 0 and poDS.GetLayerCount() > 1)) and \
  494. pszNewLayerName is None and \
  495. EQUAL(os.path.splitext(pszDestDataSource)[1], ".SHP") :
  496. try:
  497. os.stat(pszDestDataSource)
  498. except:
  499. try:
  500. # decimal 493 = octal 0755. Python 3 needs 0o755, but
  501. # this syntax is only supported by Python >= 2.6
  502. os.mkdir(pszDestDataSource, 493)
  503. except:
  504. print("Failed to create directory %s\n"
  505. "for shapefile datastore.\n" % pszDestDataSource )
  506. return False
  507. # --------------------------------------------------------------------
  508. # Create the output data source.
  509. # --------------------------------------------------------------------
  510. poODS = poDriver.CreateDataSource( pszDestDataSource, options = papszDSCO )
  511. if poODS is None:
  512. print( "%s driver failed to create %s" % (pszFormat, pszDestDataSource ))
  513. return False
  514. # --------------------------------------------------------------------
  515. # Parse the output SRS definition if possible.
  516. # --------------------------------------------------------------------
  517. if pszOutputSRSDef is not None:
  518. poOutputSRS = osr.SpatialReference()
  519. if poOutputSRS.SetFromUserInput( pszOutputSRSDef ) != 0:
  520. print( "Failed to process SRS definition: %s" % pszOutputSRSDef )
  521. return False
  522. # --------------------------------------------------------------------
  523. # Parse the source SRS definition if possible.
  524. # --------------------------------------------------------------------
  525. if pszSourceSRSDef is not None:
  526. poSourceSRS = osr.SpatialReference()
  527. if poSourceSRS.SetFromUserInput( pszSourceSRSDef ) != 0:
  528. print( "Failed to process SRS definition: %s" % pszSourceSRSDef )
  529. return False
  530. # --------------------------------------------------------------------
  531. # For OSM file.
  532. # --------------------------------------------------------------------
  533. bSrcIsOSM = poDS.GetDriver() is not None and \
  534. poDS.GetDriver().GetName() == "OSM"
  535. nSrcFileSize = 0
  536. if bSrcIsOSM and poDS.GetName() != "/vsistdin/":
  537. sStat = gdal.VSIStatL(poDS.GetName())
  538. if sStat is not None:
  539. nSrcFileSize = sStat.size
  540. # --------------------------------------------------------------------
  541. # Special case for -sql clause. No source layers required.
  542. # --------------------------------------------------------------------
  543. if pszSQLStatement is not None:
  544. if pszWHERE is not None:
  545. print( "-where clause ignored in combination with -sql." )
  546. if len(papszLayers) > 0:
  547. print( "layer names ignored in combination with -sql." )
  548. poResultSet = poDS.ExecuteSQL( pszSQLStatement, poSpatialFilter, \
  549. None )
  550. if poResultSet is not None:
  551. nCountLayerFeatures = 0
  552. if bDisplayProgress:
  553. if bSrcIsOSM:
  554. pfnProgress = progress_func
  555. pProgressArg = progress_data
  556. elif not poResultSet.TestCapability(ogr.OLCFastFeatureCount):
  557. print( "Progress turned off as fast feature count is not available.")
  558. bDisplayProgress = False
  559. else:
  560. nCountLayerFeatures = poResultSet.GetFeatureCount()
  561. pfnProgress = progress_func
  562. pProgressArg = progress_data
  563. # --------------------------------------------------------------------
  564. # Special case to improve user experience when translating into
  565. # single file shapefile and source has only one layer, and that
  566. # the layer name isn't specified
  567. # --------------------------------------------------------------------
  568. if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
  569. pszNewLayerName is None:
  570. try:
  571. mode = os.stat(pszDestDataSource).st_mode
  572. if (mode & stat.S_IFDIR) == 0:
  573. pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
  574. except:
  575. pass
  576. psInfo = SetupTargetLayer( poDS, \
  577. poResultSet,
  578. poODS, \
  579. papszLCO, \
  580. pszNewLayerName, \
  581. bTransform, \
  582. poOutputSRS, \
  583. bNullifyOutputSRS, \
  584. poSourceSRS, \
  585. papszSelFields, \
  586. bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
  587. papszFieldTypesToString, \
  588. bWrapDateline, \
  589. bExplodeCollections, \
  590. pszZField, \
  591. pszWHERE )
  592. poResultSet.ResetReading()
  593. if psInfo is None or not TranslateLayer( psInfo, poDS, poResultSet, poODS, \
  594. poOutputSRS, bNullifyOutputSRS, \
  595. eGType, bPromoteToMulti, nCoordDim, \
  596. eGeomOp, dfGeomOpParam, \
  597. nCountLayerFeatures, \
  598. poClipSrc, poClipDst, \
  599. bExplodeCollections, \
  600. nSrcFileSize, None, \
  601. pfnProgress, pProgressArg ):
  602. print(
  603. "Terminating translation prematurely after failed\n" + \
  604. "translation from sql statement." )
  605. return False
  606. poDS.ReleaseResultSet( poResultSet )
  607. # --------------------------------------------------------------------
  608. # Special case for layer interleaving mode.
  609. # --------------------------------------------------------------------
  610. elif bSrcIsOSM and gdal.GetConfigOption("OGR_INTERLEAVED_READING", None) is None:
  611. gdal.SetConfigOption("OGR_INTERLEAVED_READING", "YES")
  612. #if (bSplitListFields)
  613. #{
  614. # fprintf( stderr, "FAILURE: -splitlistfields not supported in this mode\n" );
  615. # exit( 1 );
  616. #}
  617. nSrcLayerCount = poDS.GetLayerCount()
  618. pasAssocLayers = [ AssociatedLayers() for i in range(nSrcLayerCount) ]
  619. # --------------------------------------------------------------------
  620. # Special case to improve user experience when translating into
  621. # single file shapefile and source has only one layer, and that
  622. # the layer name isn't specified
  623. # --------------------------------------------------------------------
  624. if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
  625. (len(papszLayers) == 1 or nSrcLayerCount == 1) and pszNewLayerName is None:
  626. try:
  627. mode = os.stat(pszDestDataSource).st_mode
  628. if (mode & stat.S_IFDIR) == 0:
  629. pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
  630. except:
  631. pass
  632. if bDisplayProgress and bSrcIsOSM:
  633. pfnProgress = progress_func
  634. pProgressArg = progress_data
  635. # --------------------------------------------------------------------
  636. # If no target layer specified, use all source layers.
  637. # --------------------------------------------------------------------
  638. if len(papszLayers) == 0:
  639. papszLayers = [ None for i in range(nSrcLayerCount) ]
  640. for iLayer in range(nSrcLayerCount):
  641. poLayer = poDS.GetLayer(iLayer)
  642. if poLayer is None:
  643. print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
  644. return False
  645. papszLayers[iLayer] = poLayer.GetName()
  646. else:
  647. if bSrcIsOSM:
  648. osInterestLayers = "SET interest_layers ="
  649. for iLayer in range(len(papszLayers)):
  650. if iLayer != 0:
  651. osInterestLayers = osInterestLayers + ","
  652. osInterestLayers = osInterestLayers + papszLayers[iLayer]
  653. poDS.ExecuteSQL(osInterestLayers, None, None)
  654. # --------------------------------------------------------------------
  655. # First pass to set filters and create target layers.
  656. # --------------------------------------------------------------------
  657. for iLayer in range(nSrcLayerCount):
  658. poLayer = poDS.GetLayer(iLayer)
  659. if poLayer is None:
  660. print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
  661. return False
  662. pasAssocLayers[iLayer].poSrcLayer = poLayer
  663. if CSLFindString(papszLayers, poLayer.GetName()) >= 0:
  664. if pszWHERE is not None:
  665. if poLayer.SetAttributeFilter( pszWHERE ) != 0:
  666. print("FAILURE: SetAttributeFilter(%s) on layer '%s' failed.\n" % (pszWHERE, poLayer.GetName()) )
  667. if not bSkipFailures:
  668. return False
  669. if poSpatialFilter is not None:
  670. poLayer.SetSpatialFilter( poSpatialFilter )
  671. psInfo = SetupTargetLayer( poDS, \
  672. poLayer, \
  673. poODS, \
  674. papszLCO, \
  675. pszNewLayerName, \
  676. bTransform, \
  677. poOutputSRS, \
  678. bNullifyOutputSRS, \
  679. poSourceSRS, \
  680. papszSelFields, \
  681. bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
  682. papszFieldTypesToString, \
  683. bWrapDateline, \
  684. bExplodeCollections, \
  685. pszZField, \
  686. pszWHERE )
  687. if psInfo is None and not bSkipFailures:
  688. return False
  689. pasAssocLayers[iLayer].psInfo = psInfo
  690. else:
  691. pasAssocLayers[iLayer].psInfo = None
  692. # --------------------------------------------------------------------
  693. # Second pass to process features in a interleaved layer mode.
  694. # --------------------------------------------------------------------
  695. bHasLayersNonEmpty = True
  696. while bHasLayersNonEmpty:
  697. bHasLayersNonEmpty = False
  698. for iLayer in range(nSrcLayerCount):
  699. poLayer = pasAssocLayers[iLayer].poSrcLayer
  700. psInfo = pasAssocLayers[iLayer].psInfo
  701. anReadFeatureCount = [0]
  702. if psInfo is not None:
  703. if not TranslateLayer(psInfo, poDS, poLayer, poODS, \
  704. poOutputSRS, bNullifyOutputSRS, \
  705. eGType, bPromoteToMulti, nCoordDim, \
  706. eGeomOp, dfGeomOpParam, \
  707. 0, \
  708. poClipSrc, poClipDst, \
  709. bExplodeCollections, \
  710. nSrcFileSize, \
  711. anReadFeatureCount, \
  712. pfnProgress, pProgressArg ) \
  713. and not bSkipFailures:
  714. print(
  715. "Terminating translation prematurely after failed\n" + \
  716. "translation of layer " + poLayer.GetName() + " (use -skipfailures to skip errors)")
  717. return False
  718. else:
  719. # No matching target layer : just consumes the features
  720. poFeature = poLayer.GetNextFeature()
  721. while poFeature is not None:
  722. anReadFeatureCount[0] = anReadFeatureCount[0] + 1
  723. poFeature = poLayer.GetNextFeature()
  724. if anReadFeatureCount[0] != 0:
  725. bHasLayersNonEmpty = True
  726. else:
  727. nLayerCount = 0
  728. papoLayers = []
  729. # --------------------------------------------------------------------
  730. # Process each data source layer.
  731. # --------------------------------------------------------------------
  732. if len(papszLayers) == 0:
  733. nLayerCount = poDS.GetLayerCount()
  734. papoLayers = [None for i in range(nLayerCount)]
  735. iLayer = 0
  736. for iLayer in range(nLayerCount):
  737. poLayer = poDS.GetLayer(iLayer)
  738. if poLayer is None:
  739. print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
  740. return False
  741. papoLayers[iLayer] = poLayer
  742. iLayer = iLayer + 1
  743. # --------------------------------------------------------------------
  744. # Process specified data source layers.
  745. # --------------------------------------------------------------------
  746. else:
  747. nLayerCount = len(papszLayers)
  748. papoLayers = [None for i in range(nLayerCount)]
  749. iLayer = 0
  750. for layername in papszLayers:
  751. poLayer = poDS.GetLayerByName(layername)
  752. if poLayer is None:
  753. print("FAILURE: Couldn't fetch advertised layer %s!" % layername)
  754. return False
  755. papoLayers[iLayer] = poLayer
  756. iLayer = iLayer + 1
  757. panLayerCountFeatures = [0 for i in range(nLayerCount)]
  758. nCountLayersFeatures = 0
  759. nAccCountFeatures = 0
  760. # First pass to apply filters and count all features if necessary
  761. for iLayer in range(nLayerCount):
  762. poLayer = papoLayers[iLayer]
  763. if pszWHERE is not None:
  764. if poLayer.SetAttributeFilter( pszWHERE ) != 0:
  765. print("FAILURE: SetAttributeFilter(%s) failed." % pszWHERE)
  766. if not bSkipFailures:
  767. return False
  768. if poSpatialFilter is not None:
  769. poLayer.SetSpatialFilter( poSpatialFilter )
  770. if bDisplayProgress and not bSrcIsOSM:
  771. if not poLayer.TestCapability(ogr.OLCFastFeatureCount):
  772. print("Progress turned off as fast feature count is not available.")
  773. bDisplayProgress = False
  774. else:
  775. panLayerCountFeatures[iLayer] = poLayer.GetFeatureCount()
  776. nCountLayersFeatures += panLayerCountFeatures[iLayer]
  777. # Second pass to do the real job
  778. for iLayer in range(nLayerCount):
  779. poLayer = papoLayers[iLayer]
  780. if bDisplayProgress:
  781. if bSrcIsOSM:
  782. pfnProgress = progress_func
  783. pProgressArg = progress_data
  784. else:
  785. pfnProgress = ScaledProgressFunc
  786. pProgressArg = ScaledProgressObject( \
  787. nAccCountFeatures * 1.0 / nCountLayersFeatures, \
  788. (nAccCountFeatures + panLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures, \
  789. progress_func, progress_data)
  790. nAccCountFeatures += panLayerCountFeatures[iLayer]
  791. # --------------------------------------------------------------------
  792. # Special case to improve user experience when translating into
  793. # single file shapefile and source has only one layer, and that
  794. # the layer name isn't specified
  795. # --------------------------------------------------------------------
  796. if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
  797. nLayerCount == 1 and pszNewLayerName is None:
  798. try:
  799. mode = os.stat(pszDestDataSource).st_mode
  800. if (mode & stat.S_IFDIR) == 0:
  801. pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
  802. except:
  803. pass
  804. psInfo = SetupTargetLayer( poDS, \
  805. poLayer, \
  806. poODS, \
  807. papszLCO, \
  808. pszNewLayerName, \
  809. bTransform, \
  810. poOutputSRS, \
  811. bNullifyOutputSRS, \
  812. poSourceSRS, \
  813. papszSelFields, \
  814. bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
  815. papszFieldTypesToString, \
  816. bWrapDateline, \
  817. bExplodeCollections, \
  818. pszZField, \
  819. pszWHERE )
  820. poLayer.ResetReading()
  821. if (psInfo is None or \
  822. not TranslateLayer( psInfo, poDS, poLayer, poODS, \
  823. poOutputSRS, bNullifyOutputSRS, \
  824. eGType, bPromoteToMulti, nCoordDim, \
  825. eGeomOp, dfGeomOpParam, \
  826. panLayerCountFeatures[iLayer], \
  827. poClipSrc, poClipDst, \
  828. bExplodeCollections, \
  829. nSrcFileSize, None, \
  830. pfnProgress, pProgressArg )) \
  831. and not bSkipFailures:
  832. print(
  833. "Terminating translation prematurely after failed\n" + \
  834. "translation of layer " + poLayer.GetLayerDefn().GetName() + " (use -skipfailures to skip errors)")
  835. return False
  836. # --------------------------------------------------------------------
  837. # Close down.
  838. # --------------------------------------------------------------------
  839. # We must explicitly destroy the output dataset in order the file
  840. # to be properly closed !
  841. poODS.Destroy()
  842. poDS.Destroy()
  843. return True
  844. #**********************************************************************
  845. # Usage()
  846. #**********************************************************************
  847. def Usage():
  848. print( "Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update] [-gt n]\n" + \
  849. " [-select field_list] [-where restricted_where] \n" + \
  850. " [-progress] [-sql <sql statement>] \n" + \
  851. " [-spat xmin ymin xmax ymax] [-preserve_fid] [-fid FID]\n" + \
  852. " [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n" + \
  853. " [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n" + \
  854. " [-simplify tolerance]\n" + \
  855. #// " [-segmentize max_dist] [-fieldTypeToString All|(type1[,type2]*)]\n" + \
  856. " [-fieldTypeToString All|(type1[,type2]*)] [-explodecollections] \n" + \
  857. " dst_datasource_name src_datasource_name\n" + \
  858. " [-lco NAME=VALUE] [-nln name] [-nlt type] [-dim 2|3] [layer [layer ...]]\n" + \
  859. "\n" + \
  860. " -f format_name: output file format name, possible values are:")
  861. for iDriver in range(ogr.GetDriverCount()):
  862. poDriver = ogr.GetDriver(iDriver)
  863. if poDriver.TestCapability( ogr.ODrCCreateDataSource ):
  864. print( " -f \"" + poDriver.GetName() + "\"" )
  865. print( " -append: Append to existing layer instead of creating new if it exists\n" + \
  866. " -overwrite: delete the output layer and recreate it empty\n" + \
  867. " -update: Open existing output datasource in update mode\n" + \
  868. " -progress: Display progress on terminal. Only works if input layers have the \"fast feature count\" capability\n" + \
  869. " -select field_list: Comma-delimited list of fields from input layer to\n" + \
  870. " copy to the new layer (defaults to all)\n" + \
  871. " -where restricted_where: Attribute query (like SQL WHERE)\n" + \
  872. " -sql statement: Execute given SQL statement and save result.\n" + \
  873. " -skipfailures: skip features or layers that fail to convert\n" + \
  874. " -gt n: group n features per transaction (default 200)\n" + \
  875. " -spat xmin ymin xmax ymax: spatial query extents\n" + \
  876. " -simplify tolerance: distance tolerance for simplification.\n" + \
  877. #//" -segmentize max_dist: maximum distance between 2 nodes.\n" + \
  878. #//" Used to create intermediate points\n" + \
  879. " -dsco NAME=VALUE: Dataset creation option (format specific)\n" + \
  880. " -lco NAME=VALUE: Layer creation option (format specific)\n" + \
  881. " -nln name: Assign an alternate name to the new layer\n" + \
  882. " -nlt type: Force a geometry type for new layer. One of NONE, GEOMETRY,\n" + \
  883. " POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n" + \
  884. " MULTIPOLYGON, or MULTILINESTRING. Add \"25D\" for 3D layers.\n" + \
  885. " Default is type of source layer.\n" + \
  886. " -dim dimension: Force the coordinate dimension to the specified value.\n" + \
  887. " -fieldTypeToString type1,...: Converts fields of specified types to\n" + \
  888. " fields of type string in the new layer. Valid types are : \n" + \
  889. " Integer, Real, String, Date, Time, DateTime, Binary, IntegerList, RealList,\n" + \
  890. " StringList. Special value All can be used to convert all fields to strings.")
  891. print(" -a_srs srs_def: Assign an output SRS\n"
  892. " -t_srs srs_def: Reproject/transform to this SRS on output\n"
  893. " -s_srs srs_def: Override source SRS\n"
  894. "\n"
  895. " Srs_def can be a full WKT definition (hard to escape properly),\n"
  896. " or a well known definition (i.e. EPSG:4326) or a file with a WKT\n"
  897. " definition." )
  898. return False
  899. def CSLFindString(v, mystr):
  900. i = 0
  901. for strIter in v:
  902. if EQUAL(strIter, mystr):
  903. return i
  904. i = i + 1
  905. return -1
  906. def IsNumber( pszStr):
  907. try:
  908. (float)(pszStr)
  909. return True
  910. except:
  911. return False
  912. def LoadGeometry( pszDS, pszSQL, pszLyr, pszWhere):
  913. poGeom = None
  914. poDS = ogr.Open( pszDS, False )
  915. if poDS is None:
  916. return None
  917. if pszSQL is not None:
  918. poLyr = poDS.ExecuteSQL( pszSQL, None, None )
  919. elif pszLyr is not None:
  920. poLyr = poDS.GetLayerByName(pszLyr)
  921. else:
  922. poLyr = poDS.GetLayer(0)
  923. if poLyr is None:
  924. print("Failed to identify source layer from datasource.")
  925. poDS.Destroy()
  926. return None
  927. if pszWhere is not None:
  928. poLyr.SetAttributeFilter(pszWhere)
  929. poFeat = poLyr.GetNextFeature()
  930. while poFeat is not None:
  931. poSrcGeom = poFeat.GetGeometryRef()
  932. if poSrcGeom is not None:
  933. eType = wkbFlatten(poSrcGeom.GetGeometryType())
  934. if poGeom is None:
  935. poGeom = ogr.Geometry( ogr.wkbMultiPolygon )
  936. if eType == ogr.wkbPolygon:
  937. poGeom.AddGeometry( poSrcGeom )
  938. elif eType == ogr.wkbMultiPolygon:
  939. for iGeom in range(poSrcGeom.GetGeometryCount()):
  940. poGeom.AddGeometry(poSrcGeom.GetGeometryRef(iGeom) )
  941. else:
  942. print("ERROR: Geometry not of polygon type." )
  943. if pszSQL is not None:
  944. poDS.ReleaseResultSet( poLyr )
  945. poDS.Destroy()
  946. return None
  947. poFeat = poLyr.GetNextFeature()
  948. if pszSQL is not None:
  949. poDS.ReleaseResultSet( poLyr )
  950. poDS.Destroy()
  951. return poGeom
  952. def wkbFlatten(x):
  953. return x & (~ogr.wkb25DBit)
  954. #**********************************************************************
  955. # SetZ()
  956. #**********************************************************************
  957. def SetZ (poGeom, dfZ ):
  958. if poGeom is None:
  959. return
  960. eGType = wkbFlatten(poGeom.GetGeometryType())
  961. if eGType == ogr.wkbPoint:
  962. poGeom.SetPoint(0, poGeom.GetX(), poGeom.GetY(), dfZ)
  963. elif eGType == ogr.wkbLineString or \
  964. eGType == ogr.wkbLinearRing:
  965. for i in range(poGeom.GetPointCount()):
  966. poGeom.SetPoint(i, poGeom.GetX(i), poGeom.GetY(i), dfZ)
  967. elif eGType == ogr.wkbPolygon or \
  968. eGType == ogr.wkbMultiPoint or \
  969. eGType == ogr.wkbMultiLineString or \
  970. eGType == ogr.wkbMultiPolygon or \
  971. eGType == ogr.wkbGeometryCollection:
  972. for i in range(poGeom.GetGeometryCount()):
  973. SetZ(poGeom.GetGeometryRef(i), dfZ)
  974. #**********************************************************************
  975. # SetupTargetLayer()
  976. #**********************************************************************
  977. def SetupTargetLayer( poSrcDS, poSrcLayer, poDstDS, papszLCO, pszNewLayerName, \
  978. bTransform, poOutputSRS, bNullifyOutputSRS, poSourceSRS, papszSelFields, \
  979. bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
  980. papszFieldTypesToString, bWrapDateline, \
  981. bExplodeCollections, pszZField, pszWHERE) :
  982. if pszNewLayerName is None:
  983. pszNewLayerName = poSrcLayer.GetLayerDefn().GetName()
  984. # --------------------------------------------------------------------
  985. # Setup coordinate transformation if we need it.
  986. # --------------------------------------------------------------------
  987. poCT = None
  988. if bTransform:
  989. if poSourceSRS is None:
  990. poSourceSRS = poSrcLayer.GetSpatialRef()
  991. if poSourceSRS is None:
  992. print("Can't transform coordinates, source layer has no\n" + \
  993. "coordinate system. Use -s_srs to set one." )
  994. return None
  995. poCT = osr.CoordinateTransformation( poSourceSRS, poOutputSRS )
  996. if gdal.GetLastErrorMsg().find( 'Unable to load PROJ.4 library' ) != -1:
  997. poCT = None
  998. if poCT is None:
  999. pszWKT = None
  1000. print("Failed to create coordinate transformation between the\n" + \
  1001. "following coordinate systems. This may be because they\n" + \
  1002. "are not transformable, or because projection services\n" + \
  1003. "(PROJ.4 DLL/.so) could not be loaded." )
  1004. pszWKT = poSourceSRS.ExportToPrettyWkt( 0 )
  1005. print( "Source:\n" + pszWKT )
  1006. pszWKT = poOutputSRS.ExportToPrettyWkt( 0 )
  1007. print( "Target:\n" + pszWKT )
  1008. return None
  1009. # --------------------------------------------------------------------
  1010. # Get other info.
  1011. # --------------------------------------------------------------------
  1012. poSrcFDefn = poSrcLayer.GetLayerDefn()
  1013. if poOutputSRS is None and not bNullifyOutputSRS:
  1014. poOutputSRS = poSrcLayer.GetSpatialRef()
  1015. # --------------------------------------------------------------------
  1016. # Find the layer.
  1017. # --------------------------------------------------------------------
  1018. # GetLayerByName() can instantiate layers that would have been
  1019. # 'hidden' otherwise, for example, non-spatial tables in a
  1020. # PostGIS-enabled database, so this apparently useless command is
  1021. # not useless. (#4012)
  1022. gdal.PushErrorHandler('CPLQuietErrorHandler')
  1023. poDstLayer = poDstDS.GetLayerByName(pszNewLayerName)
  1024. gdal.PopErrorHandler()
  1025. gdal.ErrorReset()
  1026. iLayer = -1
  1027. if poDstLayer is not None:
  1028. nLayerCount = poDstDS.GetLayerCount()
  1029. for iLayer in range(nLayerCount):
  1030. poLayer = poDstDS.GetLayer(iLayer)
  1031. # The .cpp version compares on pointers directly, but we cannot
  1032. # do this with swig object, so just compare the names.
  1033. if poLayer is not None \
  1034. and poLayer.GetName() == poDstLayer.GetName():
  1035. break
  1036. if (iLayer == nLayerCount):
  1037. # Shouldn't happen with an ideal driver
  1038. poDstLayer = None
  1039. # --------------------------------------------------------------------
  1040. # If the user requested overwrite, and we have the layer in
  1041. # question we need to delete it now so it will get recreated
  1042. # (overwritten).
  1043. # --------------------------------------------------------------------
  1044. if poDstLayer is not None and bOverwrite:
  1045. if poDstDS.DeleteLayer( iLayer ) != 0:
  1046. print("DeleteLayer() failed when overwrite requested." )
  1047. return None
  1048. poDstLayer = None
  1049. # --------------------------------------------------------------------
  1050. # If the layer does not exist, then create it.
  1051. # --------------------------------------------------------------------
  1052. if poDstLayer is None:
  1053. if eGType == -2:
  1054. eGType = poSrcFDefn.GetGeomType()
  1055. n25DBit = eGType & ogr.wkb25DBit
  1056. if bPromoteToMulti:
  1057. if wkbFlatten(eGType) == ogr.wkbLineString:
  1058. eGType = ogr.wkbMultiLineString | n25DBit
  1059. elif wkbFlatten(eGType) == ogr.wkbPolygon:
  1060. eGType = ogr.wkbMultiPolygon | n25DBit
  1061. if bExplodeCollections:
  1062. if wkbFlatten(eGType) == ogr.wkbMultiPoint:
  1063. eGType = ogr.wkbPoint | n25DBit
  1064. elif wkbFlatten(eGType) == ogr.wkbMultiLineString:
  1065. eGType = ogr.wkbLineString | n25DBit
  1066. elif wkbFlatten(eGType) == ogr.wkbMultiPolygon:
  1067. eGType = ogr.wkbPolygon | n25DBit
  1068. elif wkbFlatten(eGType) == ogr.wkbGeometryCollection:
  1069. eGType = ogr.wkbUnknown | n25DBit
  1070. if pszZField is not None:
  1071. eGType = eGType | ogr.wkb25DBit
  1072. if nCoordDim == 2:
  1073. eGType = eGType & ~ogr.wkb25DBit
  1074. elif nCoordDim == 3:
  1075. eGType = eGType | ogr.wkb25DBit
  1076. if poDstDS.TestCapability( ogr.ODsCCreateLayer ) == False:
  1077. print("Layer " + pszNewLayerName + "not found, and CreateLayer not supported by driver.")
  1078. return None
  1079. gdal.ErrorReset()
  1080. poDstLayer = poDstDS.CreateLayer( pszNewLayerName, poOutputSRS, \
  1081. eGType, papszLCO )
  1082. if poDstLayer is None:
  1083. return None
  1084. bAppend = False
  1085. # --------------------------------------------------------------------
  1086. # Otherwise we will append to it, if append was requested.
  1087. # --------------------------------------------------------------------
  1088. elif not bAppend:
  1089. print("FAILED: Layer " + pszNewLayerName + "already exists, and -append not specified.\n" + \
  1090. " Consider using -append, or -overwrite.")
  1091. return None
  1092. else:
  1093. if len(papszLCO) > 0:
  1094. print("WARNING: Layer creation options ignored since an existing layer is\n" + \
  1095. " being appended to." )
  1096. # --------------------------------------------------------------------
  1097. # Add fields. Default to copy all field.
  1098. # If only a subset of all fields requested, then output only
  1099. # the selected fields, and in the order that they were
  1100. # selected.
  1101. # --------------------------------------------------------------------
  1102. # Initialize the index-to-index map to -1's
  1103. nSrcFieldCount = poSrcFDefn.GetFieldCount()
  1104. panMap = [ -1 for i in range(nSrcFieldCount) ]
  1105. poDstFDefn = poDstLayer.GetLayerDefn()
  1106. if papszSelFields is not None and not bAppend:
  1107. nDstFieldCount = 0
  1108. if poDstFDefn is not None:
  1109. nDstFieldCount = poDstFDefn.GetFieldCount()
  1110. for iField in range(len(papszSelFields)):
  1111. iSrcField = poSrcFDefn.GetFieldIndex(papszSelFields[iField])
  1112. if iSrcField >= 0:
  1113. poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iSrcField)
  1114. oFieldDefn = ogr.FieldDefn( poSrcFieldDefn.GetNameRef(),
  1115. poSrcFieldDefn.GetType() )
  1116. oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() )
  1117. oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
  1118. if papszFieldTypesToString is not None and \
  1119. (CSLFindString(papszFieldTypesToString, "All") != -1 or \
  1120. CSLFindString(papszFieldTypesToString, \
  1121. ogr.GetFieldTypeName(poSrcFieldDefn.GetType())) != -1):
  1122. oFieldDefn.SetType(ogr.OFTString)
  1123. # The field may have been already created at layer creation
  1124. iDstField = -1
  1125. if poDstFDefn is not None:
  1126. iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef())
  1127. if iDstField >= 0:
  1128. panMap[iSrcField] = iDstField
  1129. elif poDstLayer.CreateField( oFieldDefn ) == 0:
  1130. # now that we've created a field, GetLayerDefn() won't return NULL
  1131. if poDstFDefn is None:
  1132. poDstFDefn = poDstLayer.GetLayerDefn()
  1133. # Sanity check : if it fails, the driver is buggy
  1134. if poDstFDefn is not None and \
  1135. poDstFDefn.GetFieldCount() != nDstFieldCount + 1:
  1136. print("The output driver has claimed to have added the %s field, but it did not!" % oFieldDefn.GetNameRef() )
  1137. else:
  1138. panMap[iSrcField] = nDstFieldCount
  1139. nDstFieldCount = nDstFieldCount + 1
  1140. else:
  1141. print("Field '" + papszSelFields[iField] + "' not found in source layer.")
  1142. if not bSkipFailures:
  1143. return None
  1144. # --------------------------------------------------------------------
  1145. # Use SetIgnoredFields() on source layer if available
  1146. # --------------------------------------------------------------------
  1147. # Here we differ from the ogr2ogr.cpp implementation since the OGRFeatureQuery
  1148. # isn't mapped to swig. So in that case just don't use SetIgnoredFields()
  1149. # to avoid issue raised in #4015
  1150. if poSrcLayer.TestCapability(ogr.OLCIgnoreFields) and pszWHERE is None:
  1151. papszIgnoredFields = []
  1152. for iSrcField in range(nSrcFieldCount):
  1153. pszFieldName = poSrcFDefn.GetFieldDefn(iSrcField).GetNameRef()
  1154. bFieldRequested = False
  1155. for iField in range(len(papszSelFields)):
  1156. if EQUAL(pszFieldName, papszSelFields[iField]):
  1157. bFieldRequested = True
  1158. break
  1159. if pszZField is not None and EQUAL(pszFieldName, pszZField):
  1160. bFieldRequested = True
  1161. # If source field not requested, add it to ignored files list
  1162. if not bFieldRequested:
  1163. papszIgnoredFields.append(pszFieldName)
  1164. poSrcLayer.SetIgnoredFields(papszIgnoredFields)
  1165. elif not bAppend:
  1166. nDstFieldCount = 0
  1167. if poDstFDefn is not None:
  1168. nDstFieldCount = poDstFDefn.GetFieldCount()
  1169. for iField in range(nSrcFieldCount):
  1170. poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField)
  1171. oFieldDefn = ogr.FieldDefn( poSrcFieldDefn.GetNameRef(),
  1172. poSrcFieldDefn.GetType() )
  1173. oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() )
  1174. oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
  1175. if papszFieldTypesToString is not None and \
  1176. (CSLFindString(papszFieldTypesToString, "All") != -1 or \
  1177. CSLFindString(papszFieldTypesToString, \
  1178. ogr.GetFieldTypeName(poSrcFieldDefn.GetType())) != -1):
  1179. oFieldDefn.SetType(ogr.OFTString)
  1180. # The field may have been already created at layer creation
  1181. iDstField = -1
  1182. if poDstFDefn is not None:
  1183. iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef())
  1184. if iDstField >= 0:
  1185. panMap[iField] = iDstField
  1186. elif poDstLayer.CreateField( oFieldDefn ) == 0:
  1187. # now that we've created a field, GetLayerDefn() won't return NULL
  1188. if poDstFDefn is None:
  1189. poDstFDefn = poDstLayer.GetLayerDefn()
  1190. # Sanity check : if it fails, the driver is buggy
  1191. if poDstFDefn is not None and \
  1192. poDstFDefn.GetFieldCount() != nDstFieldCount + 1:
  1193. print("The output driver has claimed to have added the %s field, but it did not!" % oFieldDefn.GetNameRef() )
  1194. else:
  1195. panMap[iField] = nDstFieldCount
  1196. nDstFieldCount = nDstFieldCount + 1
  1197. else:
  1198. # For an existing layer, build the map by fetching the index in the destination
  1199. # layer for each source field
  1200. if poDstFDefn is None:
  1201. print( "poDstFDefn == NULL.\n" )
  1202. return None
  1203. for iField in range(nSrcFieldCount):
  1204. poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField)
  1205. iDstField = poDstFDefn.GetFieldIndex(poSrcFieldDefn.GetNameRef())
  1206. if iDstField >= 0:
  1207. panMap[iField] = iDstField
  1208. iSrcZField = -1
  1209. if pszZField is not None:
  1210. iSrcZField = poSrcFDefn.GetFieldIndex(pszZField)
  1211. psInfo = TargetLayerInfo()
  1212. psInfo.poDstLayer = poDstLayer
  1213. psInfo.poCT = poCT
  1214. #psInfo.papszTransformOptions = papszTransformOptions
  1215. psInfo.panMap = panMap
  1216. psInfo.iSrcZField = iSrcZField
  1217. return psInfo
  1218. #**********************************************************************
  1219. # TranslateLayer()
  1220. #**********************************************************************
  1221. def TranslateLayer( psInfo, poSrcDS, poSrcLayer, poDstDS, \
  1222. poOutputSRS, bNullifyOutputSRS, \
  1223. eGType, bPromoteToMulti, nCoordDim, eGeomOp, dfGeomOpParam, \
  1224. nCountLayerFeatures, \
  1225. poClipSrc, poClipDst, bExplodeCollections, nSrcFileSize, \
  1226. pnReadFeatureCount, pfnProgress, pProgressArg) :
  1227. bForceToPolygon = False
  1228. bForceToMultiPolygon = False
  1229. bForceToMultiLineString = False
  1230. poDstLayer = psInfo.poDstLayer
  1231. #papszTransformOptions = psInfo.papszTransformOptions
  1232. poCT = psInfo.poCT
  1233. panMap = psInfo.panMap
  1234. iSrcZField = psInfo.iSrcZField
  1235. if poOutputSRS is None and not bNullifyOutputSRS:
  1236. poOutputSRS = poSrcLayer.GetSpatialRef()
  1237. if wkbFlatten(eGType) == ogr.wkbPolygon:
  1238. bForceToPolygon = True
  1239. elif wkbFlatten(eGType) == ogr.wkbMultiPolygon:
  1240. bForceToMultiPolygon = True
  1241. elif wkbFlatten(eGType) == ogr.wkbMultiLineString:
  1242. bForceToMultiLineString = True
  1243. # --------------------------------------------------------------------
  1244. # Transfer features.
  1245. # --------------------------------------------------------------------
  1246. nFeaturesInTransaction = 0
  1247. nCount = 0
  1248. if nGroupTransactions > 0:
  1249. poDstLayer.StartTransaction()
  1250. while True:
  1251. poDstFeature = None
  1252. if nFIDToFetch != ogr.NullFID:
  1253. #// Only fetch feature on first pass.
  1254. if nFeaturesInTransaction == 0:
  1255. poFeature = poSrcLayer.GetFeature(nFIDToFetch)
  1256. else:
  1257. poFeature = None
  1258. else:
  1259. poFeature = poSrcLayer.GetNextFeature()
  1260. if poFeature is None:
  1261. break
  1262. nParts = 0
  1263. nIters = 1
  1264. if bExplodeCollections:
  1265. poSrcGeometry = poFeature.GetGeometryRef()
  1266. if poSrcGeometry is not None:
  1267. eSrcType = wkbFlatten(poSrcGeometry.GetGeometryType())
  1268. if eSrcType == ogr.wkbMultiPoint or \
  1269. eSrcType == ogr.wkbMultiLineString or \
  1270. eSrcType == ogr.wkbMultiPolygon or \
  1271. eSrcType == ogr.wkbGeometryCollection:
  1272. nParts = poSrcGeometry.GetGeometryCount()
  1273. nIters = nParts
  1274. if nIters == 0:
  1275. nIters = 1
  1276. for iPart in range(nIters):
  1277. nFeaturesInTransaction = nFeaturesInTransaction + 1
  1278. if nFeaturesInTransaction == nGroupTransactions:
  1279. poDstLayer.CommitTransaction()
  1280. poDstLayer.StartTransaction()
  1281. nFeaturesInTransaction = 0
  1282. gdal.ErrorReset()
  1283. poDstFeature = ogr.Feature( poDstLayer.GetLayerDefn() )
  1284. if poDstFeature.SetFromWithMap( poFeature, 1, panMap ) != 0:
  1285. if nGroupTransactions > 0:
  1286. poDstLayer.CommitTransaction()
  1287. print("Unable to translate feature %d from layer %s" % (poFeature.GetFID() , poSrcLayer.GetName() ))
  1288. return False
  1289. if bPreserveFID:
  1290. poDstFeature.SetFID( poFeature.GetFID() )
  1291. poDstGeometry = poDstFeature.GetGeometryRef()
  1292. if poDstGeometry is not None:
  1293. if nParts > 0:
  1294. # For -explodecollections, extract the iPart(th) of the geometry
  1295. poPart = poDstGeometry.GetGeometryRef(iPart).Clone()
  1296. poDstFeature.SetGeometryDirectly(poPart)
  1297. poDstGeometry = poPart
  1298. if iSrcZField != -1:
  1299. SetZ(poDstGeometry, poFeature.GetFieldAsDouble(iSrcZField))
  1300. # This will correct the coordinate dimension to 3
  1301. poDupGeometry = poDstGeometry.Clone()
  1302. poDstFeature.SetGeometryDirectly(poDupGeometry)
  1303. poDstGeometry = poDupGeometry
  1304. if nCoordDim == 2 or nCoordDim == 3:
  1305. poDstGeometry.SetCoordinateDimension( nCoordDim )
  1306. if eGeomOp == GeomOperation.SEGMENTIZE:
  1307. pass
  1308. #if (poDstFeature.GetGeometryRef() is not None and dfGeomOpParam > 0)
  1309. # poDstFeature.GetGeometryRef().segmentize(dfGeomOpParam);
  1310. elif eGeomOp == GeomOperation.SIMPLIFY_PRESERVE_TOPOLOGY and dfGeomOpParam > 0:
  1311. poNewGeom = poDstGeometry.SimplifyPreserveTopology(dfGeomOpParam)
  1312. if poNewGeom is not None:
  1313. poDstFeature.SetGeometryDirectly(poNewGeom)
  1314. poDstGeometry = poNewGeom
  1315. if poClipSrc is not None:
  1316. poClipped = poDstGeometry.Intersection(poClipSrc)
  1317. if poClipped is None or poClipped.IsEmpty():
  1318. # Report progress
  1319. nCount = nCount +1
  1320. if pfnProgress is not None:
  1321. pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg)
  1322. continue
  1323. poDstFeature.SetGeometryDirectly(poClipped)
  1324. poDstGeometry = poClipped
  1325. if poCT is not None:
  1326. eErr = poDstGeometry.Transform( poCT )
  1327. if eErr != 0:
  1328. if nGroupTransactions > 0:
  1329. poDstLayer.CommitTransaction()
  1330. print("Failed to reproject feature %d (geometry probably out of source or destination SRS)." % poFeature.GetFID())
  1331. if not bSkipFailures:
  1332. return False
  1333. elif poOutputSRS is not None:
  1334. poDstGeometry.AssignSpatialReference(poOutputSRS)
  1335. if poClipDst is not None:
  1336. poClipped = poDstGeometry.Intersection(poClipDst)
  1337. if poClipped is None or poClipped.IsEmpty():
  1338. continue
  1339. poDstFeature.SetGeometryDirectly(poClipped)
  1340. poDstGeometry = poClipped
  1341. if bForceToPolygon:
  1342. poDstFeature.SetGeometryDirectly(ogr.ForceToPolygon(poDstGeometry))
  1343. elif bForceToMultiPolygon or \
  1344. (bPromoteToMulti and wkbFlatten(poDstGeometry.GetGeometryType()) == ogr.wkbPolygon):
  1345. poDstFeature.SetGeometryDirectly(ogr.ForceToMultiPolygon(poDstGeometry))
  1346. elif bForceToMultiLineString or \
  1347. (bPromoteToMulti and wkbFlatten(poDstGeometry.GetGeometryType()) == ogr.wkbLineString):
  1348. poDstFeature.SetGeometryDirectly(ogr.ForceToMultiLineString(poDstGeometry))
  1349. gdal.ErrorReset()
  1350. if poDstLayer.CreateFeature( poDstFeature ) != 0 and not bSkipFailures:
  1351. if nGroupTransactions > 0:
  1352. poDstLayer.RollbackTransaction()
  1353. return False
  1354. # Report progress
  1355. nCount = nCount + 1
  1356. if pfnProgress is not None:
  1357. if nSrcFileSize != 0:
  1358. if (nCount % 1000) == 0:
  1359. poFCLayer = poSrcDS.ExecuteSQL("GetBytesRead()", None, None)
  1360. if poFCLayer is not None:
  1361. poFeat = poFCLayer.GetNextFeature()
  1362. if poFeat is not None:
  1363. pszReadSize = poFeat.GetFieldAsString(0)
  1364. nReadSize = int(pszReadSize)
  1365. pfnProgress(nReadSize * 1.0 / nSrcFileSize, "", pProgressArg)
  1366. poSrcDS.ReleaseResultSet(poFCLayer)
  1367. else:
  1368. pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg)
  1369. if pnReadFeatureCount is not None:
  1370. pnReadFeatureCount[0] = nCount
  1371. if nGroupTransactions > 0:
  1372. poDstLayer.CommitTransaction()
  1373. return True
  1374. if __name__ == '__main__':
  1375. version_num = int(gdal.VersionInfo('VERSION_NUM'))
  1376. if version_num < 1800: # because of ogr.GetFieldTypeName
  1377. print('ERROR: Python bindings of GDAL 1.8.0 or later required')
  1378. sys.exit(1)
  1379. if not main(sys.argv):
  1380. sys.exit(1)
  1381. else:
  1382. sys.exit(0)