| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696 |
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #*****************************************************************************
- # $Id$
- #
- # Project: OpenGIS Simple Features Reference Implementation
- # Purpose: Python port of a simple client for translating between formats.
- # Author: Even Rouault, <even dot rouault at mines dash paris dot org>
- #
- # Port from ogr2ogr.cpp whose author is Frank Warmerdam
- #
- #*****************************************************************************
- # Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
- # Copyright (c) 1999, Frank Warmerdam
- #
- # Permission is hereby granted, free of charge, to any person obtaining a
- # copy of this software and associated documentation files (the "Software"),
- # to deal in the Software without restriction, including without limitation
- # the rights to use, copy, modify, merge, publish, distribute, sublicense,
- # and/or sell copies of the Software, and to permit persons to whom the
- # Software is furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included
- # in all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- # DEALINGS IN THE SOFTWARE.
- #**************************************************************************
- # Note : this is the most direct port of ogr2ogr.cpp possible
- # It could be made much more Python'ish !
- import sys
- import os
- import stat
- from osgeo import gdal
- from osgeo import ogr
- from osgeo import osr
- ###############################################################################
- class ScaledProgressObject:
- def __init__(self, min, max, cbk, cbk_data = None):
- self.min = min
- self.max = max
- self.cbk = cbk
- self.cbk_data = cbk_data
- ###############################################################################
- def ScaledProgressFunc(pct, msg, data):
- if data.cbk is None:
- return True
- return data.cbk(data.min + pct * (data.max - data.min), msg, data.cbk_data)
- ###############################################################################
- def EQUAL(a, b):
- return a.lower() == b.lower()
- ###############################################################################
- # Redefinition of GDALTermProgress, so that autotest/pyscripts/test_ogr2ogr_py.py
- # can check that the progress bar is displayed
- nLastTick = -1
- def TermProgress( dfComplete, pszMessage, pProgressArg ):
- global nLastTick
- nThisTick = (int) (dfComplete * 40.0)
- if nThisTick < 0:
- nThisTick = 0
- if nThisTick > 40:
- nThisTick = 40
- # Have we started a new progress run?
- if nThisTick < nLastTick and nLastTick >= 39:
- nLastTick = -1
- if nThisTick <= nLastTick:
- return True
- while nThisTick > nLastTick:
- nLastTick = nLastTick + 1
- if (nLastTick % 4) == 0:
- sys.stdout.write('%d' % ((nLastTick / 4) * 10))
- else:
- sys.stdout.write('.')
- if nThisTick == 40:
- print(" - done." )
- else:
- sys.stdout.flush()
- return True
- class TargetLayerInfo:
- def __init__(self):
- self.poDstLayer = None
- self.poCT = None
- #self.papszTransformOptions = None
- self.panMap = None
- self.iSrcZField = None
- class AssociatedLayers:
- def __init__(self):
- self.poSrcLayer = None
- self.psInfo = None
- #**********************************************************************
- # main()
- #**********************************************************************
- bSkipFailures = False
- nGroupTransactions = 200
- bPreserveFID = False
- nFIDToFetch = ogr.NullFID
- class Enum(set):
- def __getattr__(self, name):
- if name in self:
- return name
- raise AttributeError
- GeomOperation = Enum(["NONE", "SEGMENTIZE", "SIMPLIFY_PRESERVE_TOPOLOGY"])
- def main(args = None, progress_func = TermProgress, progress_data = None):
- global bSkipFailures
- global nGroupTransactions
- global bPreserveFID
- global nFIDToFetch
- pszFormat = "ESRI Shapefile"
- pszDataSource = None
- pszDestDataSource = None
- papszLayers = []
- papszDSCO = []
- papszLCO = []
- bTransform = False
- bAppend = False
- bUpdate = False
- bOverwrite = False
- pszOutputSRSDef = None
- pszSourceSRSDef = None
- poOutputSRS = None
- bNullifyOutputSRS = False
- poSourceSRS = None
- pszNewLayerName = None
- pszWHERE = None
- poSpatialFilter = None
- pszSelect = None
- papszSelFields = None
- pszSQLStatement = None
- eGType = -2
- bPromoteToMulti = False
- eGeomOp = GeomOperation.NONE
- dfGeomOpParam = 0
- papszFieldTypesToString = []
- bDisplayProgress = False
- pfnProgress = None
- pProgressArg = None
- bClipSrc = False
- bWrapDateline = False
- poClipSrc = None
- pszClipSrcDS = None
- pszClipSrcSQL = None
- pszClipSrcLayer = None
- pszClipSrcWhere = None
- poClipDst = None
- pszClipDstDS = None
- pszClipDstSQL = None
- pszClipDstLayer = None
- pszClipDstWhere = None
- #pszSrcEncoding = None
- #pszDstEncoding = None
- bWrapDateline = False
- bExplodeCollections = False
- pszZField = None
- nCoordDim = -1
- if args is None:
- args = sys.argv
- args = ogr.GeneralCmdLineProcessor( args )
- # --------------------------------------------------------------------
- # Processing command line arguments.
- # --------------------------------------------------------------------
- if args is None:
- return False
- nArgc = len(args)
- iArg = 1
- while iArg < nArgc:
- if EQUAL(args[iArg],"-f") and iArg < nArgc-1:
- iArg = iArg + 1
- pszFormat = args[iArg]
- elif EQUAL(args[iArg],"-dsco") and iArg < nArgc-1:
- iArg = iArg + 1
- papszDSCO.append(args[iArg] )
- elif EQUAL(args[iArg],"-lco") and iArg < nArgc-1:
- iArg = iArg + 1
- papszLCO.append(args[iArg] )
- elif EQUAL(args[iArg],"-preserve_fid"):
- bPreserveFID = True
- elif len(args[iArg]) >= 5 and EQUAL(args[iArg][0:5], "-skip"):
- bSkipFailures = True
- nGroupTransactions = 1 # #2409
- elif EQUAL(args[iArg],"-append"):
- bAppend = True
- bUpdate = True
- elif EQUAL(args[iArg],"-overwrite"):
- bOverwrite = True
- bUpdate = True
- elif EQUAL(args[iArg],"-update"):
- bUpdate = True
- elif EQUAL(args[iArg],"-fid") and iArg < nArgc-1:
- iArg = iArg + 1
- nFIDToFetch = int(args[iArg])
- elif EQUAL(args[iArg],"-sql") and iArg < nArgc-1:
- iArg = iArg + 1
- pszSQLStatement = args[iArg]
- elif EQUAL(args[iArg],"-nln") and iArg < nArgc-1:
- iArg = iArg + 1
- pszNewLayerName = args[iArg]
- elif EQUAL(args[iArg],"-nlt") and iArg < nArgc-1:
- if EQUAL(args[iArg+1],"NONE"):
- eGType = ogr.wkbNone
- elif EQUAL(args[iArg+1],"GEOMETRY"):
- eGType = ogr.wkbUnknown
- elif EQUAL(args[iArg+1],"PROMOTE_TO_MULTI"):
- bPromoteToMulti = True
- elif EQUAL(args[iArg+1],"POINT"):
- eGType = ogr.wkbPoint
- elif EQUAL(args[iArg+1],"LINESTRING"):
- eGType = ogr.wkbLineString
- elif EQUAL(args[iArg+1],"POLYGON"):
- eGType = ogr.wkbPolygon
- elif EQUAL(args[iArg+1],"GEOMETRYCOLLECTION"):
- eGType = ogr.wkbGeometryCollection
- elif EQUAL(args[iArg+1],"MULTIPOINT"):
- eGType = ogr.wkbMultiPoint
- elif EQUAL(args[iArg+1],"MULTILINESTRING"):
- eGType = ogr.wkbMultiLineString
- elif EQUAL(args[iArg+1],"MULTIPOLYGON"):
- eGType = ogr.wkbMultiPolygon
- elif EQUAL(args[iArg+1],"GEOMETRY25D"):
- eGType = ogr.wkbUnknown | ogr.wkb25DBit
- elif EQUAL(args[iArg+1],"POINT25D"):
- eGType = ogr.wkbPoint25D
- elif EQUAL(args[iArg+1],"LINESTRING25D"):
- eGType = ogr.wkbLineString25D
- elif EQUAL(args[iArg+1],"POLYGON25D"):
- eGType = ogr.wkbPolygon25D
- elif EQUAL(args[iArg+1],"GEOMETRYCOLLECTION25D"):
- eGType = ogr.wkbGeometryCollection25D
- elif EQUAL(args[iArg+1],"MULTIPOINT25D"):
- eGType = ogr.wkbMultiPoint25D
- elif EQUAL(args[iArg+1],"MULTILINESTRING25D"):
- eGType = ogr.wkbMultiLineString25D
- elif EQUAL(args[iArg+1],"MULTIPOLYGON25D"):
- eGType = ogr.wkbMultiPolygon25D
- else:
- print("-nlt %s: type not recognised." % args[iArg+1])
- return False
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-dim") and iArg < nArgc-1:
- nCoordDim = int(args[iArg+1])
- if nCoordDim != 2 and nCoordDim != 3:
- print("-dim %s: value not handled." % args[iArg+1])
- return False
- iArg = iArg + 1
- elif (EQUAL(args[iArg],"-tg") or \
- EQUAL(args[iArg],"-gt")) and iArg < nArgc-1:
- iArg = iArg + 1
- nGroupTransactions = int(args[iArg])
- elif EQUAL(args[iArg],"-s_srs") and iArg < nArgc-1:
- iArg = iArg + 1
- pszSourceSRSDef = args[iArg]
- elif EQUAL(args[iArg],"-a_srs") and iArg < nArgc-1:
- iArg = iArg + 1
- pszOutputSRSDef = args[iArg]
- if EQUAL(pszOutputSRSDef, "NULL") or \
- EQUAL(pszOutputSRSDef, "NONE"):
- pszOutputSRSDef = None
- bNullifyOutputSRS = True
- elif EQUAL(args[iArg],"-t_srs") and iArg < nArgc-1:
- iArg = iArg + 1
- pszOutputSRSDef = args[iArg]
- bTransform = True
- elif EQUAL(args[iArg],"-spat") and iArg + 4 < nArgc:
- oRing = ogr.Geometry(ogr.wkbLinearRing)
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- poSpatialFilter = ogr.Geometry(ogr.wkbPolygon)
- poSpatialFilter.AddGeometry(oRing)
- iArg = iArg + 4
- elif EQUAL(args[iArg],"-where") and iArg < nArgc-1:
- iArg = iArg + 1
- pszWHERE = args[iArg]
- elif EQUAL(args[iArg],"-select") and iArg < nArgc-1:
- iArg = iArg + 1
- pszSelect = args[iArg]
- if pszSelect.find(',') != -1:
- papszSelFields = pszSelect.split(',')
- else:
- papszSelFields = pszSelect.split(' ')
- if papszSelFields[0] == '':
- papszSelFields = []
- elif EQUAL(args[iArg],"-simplify") and iArg < nArgc-1:
- iArg = iArg + 1
- eGeomOp = GeomOperation.SIMPLIFY_PRESERVE_TOPOLOGY
- dfGeomOpParam = float(args[iArg])
- elif EQUAL(args[iArg],"-segmentize") and iArg < nArgc-1:
- iArg = iArg + 1
- eGeomOp = GeomOperation.SEGMENTIZE
- dfGeomOpParam = float(args[iArg])
- elif EQUAL(args[iArg],"-fieldTypeToString") and iArg < nArgc-1:
- iArg = iArg + 1
- pszFieldTypeToString = args[iArg]
- if pszFieldTypeToString.find(',') != -1:
- tokens = pszFieldTypeToString.split(',')
- else:
- tokens = pszFieldTypeToString.split(' ')
- for token in tokens:
- if EQUAL(token,"Integer") or \
- EQUAL(token,"Real") or \
- EQUAL(token,"String") or \
- EQUAL(token,"Date") or \
- EQUAL(token,"Time") or \
- EQUAL(token,"DateTime") or \
- EQUAL(token,"Binary") or \
- EQUAL(token,"IntegerList") or \
- EQUAL(token,"RealList") or \
- EQUAL(token,"StringList"):
- papszFieldTypesToString.append(token)
- elif EQUAL(token,"All"):
- papszFieldTypesToString = [ 'All' ]
- break
- else:
- print("Unhandled type for fieldtypeasstring option : %s " % token)
- return Usage()
- elif EQUAL(args[iArg],"-progress"):
- bDisplayProgress = True
- #elif EQUAL(args[iArg],"-wrapdateline") )
- #{
- # bWrapDateline = True;
- #}
- #
- elif EQUAL(args[iArg],"-clipsrc") and iArg < nArgc-1:
- bClipSrc = True
- if IsNumber(args[iArg+1]) and iArg < nArgc - 4:
- oRing = ogr.Geometry(ogr.wkbLinearRing)
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- poClipSrc = ogr.Geometry(ogr.wkbPolygon)
- poClipSrc.AddGeometry(oRing)
- iArg = iArg + 4
- elif (len(args[iArg+1]) >= 7 and EQUAL(args[iArg+1][0:7],"POLYGON") ) or \
- (len(args[iArg+1]) >= 12 and EQUAL(args[iArg+1][0:12],"MULTIPOLYGON") ) :
- poClipSrc = ogr.CreateGeometryFromWkt(args[iArg+1])
- if poClipSrc is None:
- print("FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n")
- return Usage()
- iArg = iArg + 1
- elif EQUAL(args[iArg+1],"spat_extent"):
- iArg = iArg + 1
- else:
- pszClipSrcDS = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipsrcsql") and iArg < nArgc-1:
- pszClipSrcSQL = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipsrclayer") and iArg < nArgc-1:
- pszClipSrcLayer = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipsrcwhere") and iArg < nArgc-1:
- pszClipSrcWhere = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipdst") and iArg < nArgc-1:
- if IsNumber(args[iArg+1]) and iArg < nArgc - 4:
- oRing = ogr.Geometry(ogr.wkbLinearRing)
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+4]) )
- oRing.AddPoint_2D( float(args[iArg+3]), float(args[iArg+2]) )
- oRing.AddPoint_2D( float(args[iArg+1]), float(args[iArg+2]) )
- poClipDst = ogr.Geometry(ogr.wkbPolygon)
- poClipDst.AddGeometry(oRing)
- iArg = iArg + 4
- elif (len(args[iArg+1]) >= 7 and EQUAL(args[iArg+1][0:7],"POLYGON") ) or \
- (len(args[iArg+1]) >= 12 and EQUAL(args[iArg+1][0:12],"MULTIPOLYGON") ) :
- poClipDst = ogr.CreateGeometryFromWkt(args[iArg+1])
- if poClipDst is None:
- print("FAILURE: Invalid geometry. Must be a valid POLYGON or MULTIPOLYGON WKT\n")
- return Usage()
- iArg = iArg + 1
- elif EQUAL(args[iArg+1],"spat_extent"):
- iArg = iArg + 1
- else:
- pszClipDstDS = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipdstsql") and iArg < nArgc-1:
- pszClipDstSQL = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipdstlayer") and iArg < nArgc-1:
- pszClipDstLayer = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-clipdstwhere") and iArg < nArgc-1:
- pszClipDstWhere = args[iArg+1]
- iArg = iArg + 1
- elif EQUAL(args[iArg],"-explodecollections"):
- bExplodeCollections = True
- elif EQUAL(args[iArg],"-zfield") and iArg < nArgc-1:
- pszZField = args[iArg+1]
- iArg = iArg + 1
- elif args[iArg][0] == '-':
- return Usage()
- elif pszDestDataSource is None:
- pszDestDataSource = args[iArg]
- elif pszDataSource is None:
- pszDataSource = args[iArg]
- else:
- papszLayers.append (args[iArg] )
- iArg = iArg + 1
- if pszDataSource is None:
- return Usage()
- if bPreserveFID and bExplodeCollections:
- print("FAILURE: cannot use -preserve_fid and -explodecollections at the same time\n\n")
- return Usage()
- if bClipSrc and pszClipSrcDS is not None:
- poClipSrc = LoadGeometry(pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere)
- if poClipSrc is None:
- print("FAILURE: cannot load source clip geometry\n" )
- return Usage()
- elif bClipSrc and poClipSrc is None:
- if poSpatialFilter is not None:
- poClipSrc = poSpatialFilter.Clone()
- if poClipSrc is None:
- print("FAILURE: -clipsrc must be used with -spat option or a\n" + \
- "bounding box, WKT string or datasource must be specified\n")
- return Usage()
- if pszClipDstDS is not None:
- poClipDst = LoadGeometry(pszClipDstDS, pszClipDstSQL, pszClipDstLayer, pszClipDstWhere)
- if poClipDst is None:
- print("FAILURE: cannot load dest clip geometry\n" )
- return Usage()
- # --------------------------------------------------------------------
- # Open data source.
- # --------------------------------------------------------------------
- poDS = ogr.Open( pszDataSource, False )
- # --------------------------------------------------------------------
- # Report failure
- # --------------------------------------------------------------------
- if poDS is None:
- print("FAILURE:\n" + \
- "Unable to open datasource `%s' with the following drivers." % pszDataSource)
- for iDriver in range(ogr.GetDriverCount()):
- print(" -> " + ogr.GetDriver(iDriver).GetName() )
- return False
- # --------------------------------------------------------------------
- # Try opening the output datasource as an existing, writable
- # --------------------------------------------------------------------
- poODS = None
- poDriver = None
- if bUpdate:
- poODS = ogr.Open( pszDestDataSource, True )
- if poODS is None:
- if bOverwrite or bAppend:
- poODS = ogr.Open( pszDestDataSource, False )
- if poODS is None:
- # the datasource doesn't exist at all
- bUpdate = False
- else:
- poODS.delete()
- poODS = None
- if bUpdate:
- print("FAILURE:\n" +
- "Unable to open existing output datasource `%s'." % pszDestDataSource)
- return False
- elif len(papszDSCO) > 0:
- print("WARNING: Datasource creation options ignored since an existing datasource\n" + \
- " being updated." )
- if poODS is not None:
- poDriver = poODS.GetDriver()
- # --------------------------------------------------------------------
- # Find the output driver.
- # --------------------------------------------------------------------
- if not bUpdate:
- poDriver = ogr.GetDriverByName(pszFormat)
- if poDriver is None:
- print("Unable to find driver `%s'." % pszFormat)
- print( "The following drivers are available:" )
- for iDriver in range(ogr.GetDriverCount()):
- print(" -> %s" % ogr.GetDriver(iDriver).GetName() )
- return False
- if poDriver.TestCapability( ogr.ODrCCreateDataSource ) == False:
- print( "%s driver does not support data source creation." % pszFormat)
- return False
- # --------------------------------------------------------------------
- # Special case to improve user experience when translating
- # a datasource with multiple layers into a shapefile. If the
- # user gives a target datasource with .shp and it does not exist,
- # the shapefile driver will try to create a file, but this is not
- # appropriate because here we have several layers, so create
- # a directory instead.
- # --------------------------------------------------------------------
- if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
- pszSQLStatement is None and \
- (len(papszLayers) > 1 or \
- (len(papszLayers) == 0 and poDS.GetLayerCount() > 1)) and \
- pszNewLayerName is None and \
- EQUAL(os.path.splitext(pszDestDataSource)[1], ".SHP") :
- try:
- os.stat(pszDestDataSource)
- except:
- try:
- # decimal 493 = octal 0755. Python 3 needs 0o755, but
- # this syntax is only supported by Python >= 2.6
- os.mkdir(pszDestDataSource, 493)
- except:
- print("Failed to create directory %s\n"
- "for shapefile datastore.\n" % pszDestDataSource )
- return False
- # --------------------------------------------------------------------
- # Create the output data source.
- # --------------------------------------------------------------------
- poODS = poDriver.CreateDataSource( pszDestDataSource, options = papszDSCO )
- if poODS is None:
- print( "%s driver failed to create %s" % (pszFormat, pszDestDataSource ))
- return False
- # --------------------------------------------------------------------
- # Parse the output SRS definition if possible.
- # --------------------------------------------------------------------
- if pszOutputSRSDef is not None:
- poOutputSRS = osr.SpatialReference()
- if poOutputSRS.SetFromUserInput( pszOutputSRSDef ) != 0:
- print( "Failed to process SRS definition: %s" % pszOutputSRSDef )
- return False
- # --------------------------------------------------------------------
- # Parse the source SRS definition if possible.
- # --------------------------------------------------------------------
- if pszSourceSRSDef is not None:
- poSourceSRS = osr.SpatialReference()
- if poSourceSRS.SetFromUserInput( pszSourceSRSDef ) != 0:
- print( "Failed to process SRS definition: %s" % pszSourceSRSDef )
- return False
- # --------------------------------------------------------------------
- # For OSM file.
- # --------------------------------------------------------------------
- bSrcIsOSM = poDS.GetDriver() is not None and \
- poDS.GetDriver().GetName() == "OSM"
- nSrcFileSize = 0
- if bSrcIsOSM and poDS.GetName() != "/vsistdin/":
- sStat = gdal.VSIStatL(poDS.GetName())
- if sStat is not None:
- nSrcFileSize = sStat.size
- # --------------------------------------------------------------------
- # Special case for -sql clause. No source layers required.
- # --------------------------------------------------------------------
- if pszSQLStatement is not None:
- if pszWHERE is not None:
- print( "-where clause ignored in combination with -sql." )
- if len(papszLayers) > 0:
- print( "layer names ignored in combination with -sql." )
- poResultSet = poDS.ExecuteSQL( pszSQLStatement, poSpatialFilter, \
- None )
- if poResultSet is not None:
- nCountLayerFeatures = 0
- if bDisplayProgress:
- if bSrcIsOSM:
- pfnProgress = progress_func
- pProgressArg = progress_data
- elif not poResultSet.TestCapability(ogr.OLCFastFeatureCount):
- print( "Progress turned off as fast feature count is not available.")
- bDisplayProgress = False
- else:
- nCountLayerFeatures = poResultSet.GetFeatureCount()
- pfnProgress = progress_func
- pProgressArg = progress_data
- # --------------------------------------------------------------------
- # Special case to improve user experience when translating into
- # single file shapefile and source has only one layer, and that
- # the layer name isn't specified
- # --------------------------------------------------------------------
- if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
- pszNewLayerName is None:
- try:
- mode = os.stat(pszDestDataSource).st_mode
- if (mode & stat.S_IFDIR) == 0:
- pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
- except:
- pass
- psInfo = SetupTargetLayer( poDS, \
- poResultSet,
- poODS, \
- papszLCO, \
- pszNewLayerName, \
- bTransform, \
- poOutputSRS, \
- bNullifyOutputSRS, \
- poSourceSRS, \
- papszSelFields, \
- bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
- papszFieldTypesToString, \
- bWrapDateline, \
- bExplodeCollections, \
- pszZField, \
- pszWHERE )
- poResultSet.ResetReading()
- if psInfo is None or not TranslateLayer( psInfo, poDS, poResultSet, poODS, \
- poOutputSRS, bNullifyOutputSRS, \
- eGType, bPromoteToMulti, nCoordDim, \
- eGeomOp, dfGeomOpParam, \
- nCountLayerFeatures, \
- poClipSrc, poClipDst, \
- bExplodeCollections, \
- nSrcFileSize, None, \
- pfnProgress, pProgressArg ):
- print(
- "Terminating translation prematurely after failed\n" + \
- "translation from sql statement." )
- return False
- poDS.ReleaseResultSet( poResultSet )
- # --------------------------------------------------------------------
- # Special case for layer interleaving mode.
- # --------------------------------------------------------------------
- elif bSrcIsOSM and gdal.GetConfigOption("OGR_INTERLEAVED_READING", None) is None:
- gdal.SetConfigOption("OGR_INTERLEAVED_READING", "YES")
- #if (bSplitListFields)
- #{
- # fprintf( stderr, "FAILURE: -splitlistfields not supported in this mode\n" );
- # exit( 1 );
- #}
- nSrcLayerCount = poDS.GetLayerCount()
- pasAssocLayers = [ AssociatedLayers() for i in range(nSrcLayerCount) ]
- # --------------------------------------------------------------------
- # Special case to improve user experience when translating into
- # single file shapefile and source has only one layer, and that
- # the layer name isn't specified
- # --------------------------------------------------------------------
- if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
- (len(papszLayers) == 1 or nSrcLayerCount == 1) and pszNewLayerName is None:
- try:
- mode = os.stat(pszDestDataSource).st_mode
- if (mode & stat.S_IFDIR) == 0:
- pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
- except:
- pass
- if bDisplayProgress and bSrcIsOSM:
- pfnProgress = progress_func
- pProgressArg = progress_data
- # --------------------------------------------------------------------
- # If no target layer specified, use all source layers.
- # --------------------------------------------------------------------
- if len(papszLayers) == 0:
- papszLayers = [ None for i in range(nSrcLayerCount) ]
- for iLayer in range(nSrcLayerCount):
- poLayer = poDS.GetLayer(iLayer)
- if poLayer is None:
- print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
- return False
- papszLayers[iLayer] = poLayer.GetName()
- else:
- if bSrcIsOSM:
- osInterestLayers = "SET interest_layers ="
- for iLayer in range(len(papszLayers)):
- if iLayer != 0:
- osInterestLayers = osInterestLayers + ","
- osInterestLayers = osInterestLayers + papszLayers[iLayer]
- poDS.ExecuteSQL(osInterestLayers, None, None)
- # --------------------------------------------------------------------
- # First pass to set filters and create target layers.
- # --------------------------------------------------------------------
- for iLayer in range(nSrcLayerCount):
- poLayer = poDS.GetLayer(iLayer)
- if poLayer is None:
- print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
- return False
- pasAssocLayers[iLayer].poSrcLayer = poLayer
- if CSLFindString(papszLayers, poLayer.GetName()) >= 0:
- if pszWHERE is not None:
- if poLayer.SetAttributeFilter( pszWHERE ) != 0:
- print("FAILURE: SetAttributeFilter(%s) on layer '%s' failed.\n" % (pszWHERE, poLayer.GetName()) )
- if not bSkipFailures:
- return False
- if poSpatialFilter is not None:
- poLayer.SetSpatialFilter( poSpatialFilter )
- psInfo = SetupTargetLayer( poDS, \
- poLayer, \
- poODS, \
- papszLCO, \
- pszNewLayerName, \
- bTransform, \
- poOutputSRS, \
- bNullifyOutputSRS, \
- poSourceSRS, \
- papszSelFields, \
- bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
- papszFieldTypesToString, \
- bWrapDateline, \
- bExplodeCollections, \
- pszZField, \
- pszWHERE )
- if psInfo is None and not bSkipFailures:
- return False
- pasAssocLayers[iLayer].psInfo = psInfo
- else:
- pasAssocLayers[iLayer].psInfo = None
- # --------------------------------------------------------------------
- # Second pass to process features in a interleaved layer mode.
- # --------------------------------------------------------------------
- bHasLayersNonEmpty = True
- while bHasLayersNonEmpty:
- bHasLayersNonEmpty = False
- for iLayer in range(nSrcLayerCount):
- poLayer = pasAssocLayers[iLayer].poSrcLayer
- psInfo = pasAssocLayers[iLayer].psInfo
- anReadFeatureCount = [0]
- if psInfo is not None:
- if not TranslateLayer(psInfo, poDS, poLayer, poODS, \
- poOutputSRS, bNullifyOutputSRS, \
- eGType, bPromoteToMulti, nCoordDim, \
- eGeomOp, dfGeomOpParam, \
- 0, \
- poClipSrc, poClipDst, \
- bExplodeCollections, \
- nSrcFileSize, \
- anReadFeatureCount, \
- pfnProgress, pProgressArg ) \
- and not bSkipFailures:
- print(
- "Terminating translation prematurely after failed\n" + \
- "translation of layer " + poLayer.GetName() + " (use -skipfailures to skip errors)")
- return False
- else:
- # No matching target layer : just consumes the features
- poFeature = poLayer.GetNextFeature()
- while poFeature is not None:
- anReadFeatureCount[0] = anReadFeatureCount[0] + 1
- poFeature = poLayer.GetNextFeature()
- if anReadFeatureCount[0] != 0:
- bHasLayersNonEmpty = True
- else:
- nLayerCount = 0
- papoLayers = []
- # --------------------------------------------------------------------
- # Process each data source layer.
- # --------------------------------------------------------------------
- if len(papszLayers) == 0:
- nLayerCount = poDS.GetLayerCount()
- papoLayers = [None for i in range(nLayerCount)]
- iLayer = 0
- for iLayer in range(nLayerCount):
- poLayer = poDS.GetLayer(iLayer)
- if poLayer is None:
- print("FAILURE: Couldn't fetch advertised layer %d!" % iLayer)
- return False
- papoLayers[iLayer] = poLayer
- iLayer = iLayer + 1
- # --------------------------------------------------------------------
- # Process specified data source layers.
- # --------------------------------------------------------------------
- else:
- nLayerCount = len(papszLayers)
- papoLayers = [None for i in range(nLayerCount)]
- iLayer = 0
- for layername in papszLayers:
- poLayer = poDS.GetLayerByName(layername)
- if poLayer is None:
- print("FAILURE: Couldn't fetch advertised layer %s!" % layername)
- return False
- papoLayers[iLayer] = poLayer
- iLayer = iLayer + 1
- panLayerCountFeatures = [0 for i in range(nLayerCount)]
- nCountLayersFeatures = 0
- nAccCountFeatures = 0
- # First pass to apply filters and count all features if necessary
- for iLayer in range(nLayerCount):
- poLayer = papoLayers[iLayer]
- if pszWHERE is not None:
- if poLayer.SetAttributeFilter( pszWHERE ) != 0:
- print("FAILURE: SetAttributeFilter(%s) failed." % pszWHERE)
- if not bSkipFailures:
- return False
- if poSpatialFilter is not None:
- poLayer.SetSpatialFilter( poSpatialFilter )
- if bDisplayProgress and not bSrcIsOSM:
- if not poLayer.TestCapability(ogr.OLCFastFeatureCount):
- print("Progress turned off as fast feature count is not available.")
- bDisplayProgress = False
- else:
- panLayerCountFeatures[iLayer] = poLayer.GetFeatureCount()
- nCountLayersFeatures += panLayerCountFeatures[iLayer]
- # Second pass to do the real job
- for iLayer in range(nLayerCount):
- poLayer = papoLayers[iLayer]
- if bDisplayProgress:
- if bSrcIsOSM:
- pfnProgress = progress_func
- pProgressArg = progress_data
- else:
- pfnProgress = ScaledProgressFunc
- pProgressArg = ScaledProgressObject( \
- nAccCountFeatures * 1.0 / nCountLayersFeatures, \
- (nAccCountFeatures + panLayerCountFeatures[iLayer]) * 1.0 / nCountLayersFeatures, \
- progress_func, progress_data)
- nAccCountFeatures += panLayerCountFeatures[iLayer]
- # --------------------------------------------------------------------
- # Special case to improve user experience when translating into
- # single file shapefile and source has only one layer, and that
- # the layer name isn't specified
- # --------------------------------------------------------------------
- if EQUAL(poDriver.GetName(), "ESRI Shapefile") and \
- nLayerCount == 1 and pszNewLayerName is None:
- try:
- mode = os.stat(pszDestDataSource).st_mode
- if (mode & stat.S_IFDIR) == 0:
- pszNewLayerName = os.path.splitext(os.path.basename(pszDestDataSource))[0]
- except:
- pass
- psInfo = SetupTargetLayer( poDS, \
- poLayer, \
- poODS, \
- papszLCO, \
- pszNewLayerName, \
- bTransform, \
- poOutputSRS, \
- bNullifyOutputSRS, \
- poSourceSRS, \
- papszSelFields, \
- bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
- papszFieldTypesToString, \
- bWrapDateline, \
- bExplodeCollections, \
- pszZField, \
- pszWHERE )
- poLayer.ResetReading()
- if (psInfo is None or \
- not TranslateLayer( psInfo, poDS, poLayer, poODS, \
- poOutputSRS, bNullifyOutputSRS, \
- eGType, bPromoteToMulti, nCoordDim, \
- eGeomOp, dfGeomOpParam, \
- panLayerCountFeatures[iLayer], \
- poClipSrc, poClipDst, \
- bExplodeCollections, \
- nSrcFileSize, None, \
- pfnProgress, pProgressArg )) \
- and not bSkipFailures:
- print(
- "Terminating translation prematurely after failed\n" + \
- "translation of layer " + poLayer.GetLayerDefn().GetName() + " (use -skipfailures to skip errors)")
- return False
- # --------------------------------------------------------------------
- # Close down.
- # --------------------------------------------------------------------
- # We must explicitly destroy the output dataset in order the file
- # to be properly closed !
- poODS.Destroy()
- poDS.Destroy()
- return True
- #**********************************************************************
- # Usage()
- #**********************************************************************
- def Usage():
- print( "Usage: ogr2ogr [--help-general] [-skipfailures] [-append] [-update] [-gt n]\n" + \
- " [-select field_list] [-where restricted_where] \n" + \
- " [-progress] [-sql <sql statement>] \n" + \
- " [-spat xmin ymin xmax ymax] [-preserve_fid] [-fid FID]\n" + \
- " [-a_srs srs_def] [-t_srs srs_def] [-s_srs srs_def]\n" + \
- " [-f format_name] [-overwrite] [[-dsco NAME=VALUE] ...]\n" + \
- " [-simplify tolerance]\n" + \
- #// " [-segmentize max_dist] [-fieldTypeToString All|(type1[,type2]*)]\n" + \
- " [-fieldTypeToString All|(type1[,type2]*)] [-explodecollections] \n" + \
- " dst_datasource_name src_datasource_name\n" + \
- " [-lco NAME=VALUE] [-nln name] [-nlt type] [-dim 2|3] [layer [layer ...]]\n" + \
- "\n" + \
- " -f format_name: output file format name, possible values are:")
- for iDriver in range(ogr.GetDriverCount()):
- poDriver = ogr.GetDriver(iDriver)
- if poDriver.TestCapability( ogr.ODrCCreateDataSource ):
- print( " -f \"" + poDriver.GetName() + "\"" )
- print( " -append: Append to existing layer instead of creating new if it exists\n" + \
- " -overwrite: delete the output layer and recreate it empty\n" + \
- " -update: Open existing output datasource in update mode\n" + \
- " -progress: Display progress on terminal. Only works if input layers have the \"fast feature count\" capability\n" + \
- " -select field_list: Comma-delimited list of fields from input layer to\n" + \
- " copy to the new layer (defaults to all)\n" + \
- " -where restricted_where: Attribute query (like SQL WHERE)\n" + \
- " -sql statement: Execute given SQL statement and save result.\n" + \
- " -skipfailures: skip features or layers that fail to convert\n" + \
- " -gt n: group n features per transaction (default 200)\n" + \
- " -spat xmin ymin xmax ymax: spatial query extents\n" + \
- " -simplify tolerance: distance tolerance for simplification.\n" + \
- #//" -segmentize max_dist: maximum distance between 2 nodes.\n" + \
- #//" Used to create intermediate points\n" + \
- " -dsco NAME=VALUE: Dataset creation option (format specific)\n" + \
- " -lco NAME=VALUE: Layer creation option (format specific)\n" + \
- " -nln name: Assign an alternate name to the new layer\n" + \
- " -nlt type: Force a geometry type for new layer. One of NONE, GEOMETRY,\n" + \
- " POINT, LINESTRING, POLYGON, GEOMETRYCOLLECTION, MULTIPOINT,\n" + \
- " MULTIPOLYGON, or MULTILINESTRING. Add \"25D\" for 3D layers.\n" + \
- " Default is type of source layer.\n" + \
- " -dim dimension: Force the coordinate dimension to the specified value.\n" + \
- " -fieldTypeToString type1,...: Converts fields of specified types to\n" + \
- " fields of type string in the new layer. Valid types are : \n" + \
- " Integer, Real, String, Date, Time, DateTime, Binary, IntegerList, RealList,\n" + \
- " StringList. Special value All can be used to convert all fields to strings.")
- print(" -a_srs srs_def: Assign an output SRS\n"
- " -t_srs srs_def: Reproject/transform to this SRS on output\n"
- " -s_srs srs_def: Override source SRS\n"
- "\n"
- " Srs_def can be a full WKT definition (hard to escape properly),\n"
- " or a well known definition (i.e. EPSG:4326) or a file with a WKT\n"
- " definition." )
- return False
- def CSLFindString(v, mystr):
- i = 0
- for strIter in v:
- if EQUAL(strIter, mystr):
- return i
- i = i + 1
- return -1
- def IsNumber( pszStr):
- try:
- (float)(pszStr)
- return True
- except:
- return False
- def LoadGeometry( pszDS, pszSQL, pszLyr, pszWhere):
- poGeom = None
- poDS = ogr.Open( pszDS, False )
- if poDS is None:
- return None
- if pszSQL is not None:
- poLyr = poDS.ExecuteSQL( pszSQL, None, None )
- elif pszLyr is not None:
- poLyr = poDS.GetLayerByName(pszLyr)
- else:
- poLyr = poDS.GetLayer(0)
- if poLyr is None:
- print("Failed to identify source layer from datasource.")
- poDS.Destroy()
- return None
- if pszWhere is not None:
- poLyr.SetAttributeFilter(pszWhere)
- poFeat = poLyr.GetNextFeature()
- while poFeat is not None:
- poSrcGeom = poFeat.GetGeometryRef()
- if poSrcGeom is not None:
- eType = wkbFlatten(poSrcGeom.GetGeometryType())
- if poGeom is None:
- poGeom = ogr.Geometry( ogr.wkbMultiPolygon )
- if eType == ogr.wkbPolygon:
- poGeom.AddGeometry( poSrcGeom )
- elif eType == ogr.wkbMultiPolygon:
- for iGeom in range(poSrcGeom.GetGeometryCount()):
- poGeom.AddGeometry(poSrcGeom.GetGeometryRef(iGeom) )
- else:
- print("ERROR: Geometry not of polygon type." )
- if pszSQL is not None:
- poDS.ReleaseResultSet( poLyr )
- poDS.Destroy()
- return None
- poFeat = poLyr.GetNextFeature()
- if pszSQL is not None:
- poDS.ReleaseResultSet( poLyr )
- poDS.Destroy()
- return poGeom
- def wkbFlatten(x):
- return x & (~ogr.wkb25DBit)
- #**********************************************************************
- # SetZ()
- #**********************************************************************
- def SetZ (poGeom, dfZ ):
- if poGeom is None:
- return
- eGType = wkbFlatten(poGeom.GetGeometryType())
- if eGType == ogr.wkbPoint:
- poGeom.SetPoint(0, poGeom.GetX(), poGeom.GetY(), dfZ)
- elif eGType == ogr.wkbLineString or \
- eGType == ogr.wkbLinearRing:
- for i in range(poGeom.GetPointCount()):
- poGeom.SetPoint(i, poGeom.GetX(i), poGeom.GetY(i), dfZ)
- elif eGType == ogr.wkbPolygon or \
- eGType == ogr.wkbMultiPoint or \
- eGType == ogr.wkbMultiLineString or \
- eGType == ogr.wkbMultiPolygon or \
- eGType == ogr.wkbGeometryCollection:
- for i in range(poGeom.GetGeometryCount()):
- SetZ(poGeom.GetGeometryRef(i), dfZ)
- #**********************************************************************
- # SetupTargetLayer()
- #**********************************************************************
- def SetupTargetLayer( poSrcDS, poSrcLayer, poDstDS, papszLCO, pszNewLayerName, \
- bTransform, poOutputSRS, bNullifyOutputSRS, poSourceSRS, papszSelFields, \
- bAppend, eGType, bPromoteToMulti, nCoordDim, bOverwrite, \
- papszFieldTypesToString, bWrapDateline, \
- bExplodeCollections, pszZField, pszWHERE) :
- if pszNewLayerName is None:
- pszNewLayerName = poSrcLayer.GetLayerDefn().GetName()
- # --------------------------------------------------------------------
- # Setup coordinate transformation if we need it.
- # --------------------------------------------------------------------
- poCT = None
- if bTransform:
- if poSourceSRS is None:
- poSourceSRS = poSrcLayer.GetSpatialRef()
- if poSourceSRS is None:
- print("Can't transform coordinates, source layer has no\n" + \
- "coordinate system. Use -s_srs to set one." )
- return None
- poCT = osr.CoordinateTransformation( poSourceSRS, poOutputSRS )
- if gdal.GetLastErrorMsg().find( 'Unable to load PROJ.4 library' ) != -1:
- poCT = None
- if poCT is None:
- pszWKT = None
- print("Failed to create coordinate transformation between the\n" + \
- "following coordinate systems. This may be because they\n" + \
- "are not transformable, or because projection services\n" + \
- "(PROJ.4 DLL/.so) could not be loaded." )
- pszWKT = poSourceSRS.ExportToPrettyWkt( 0 )
- print( "Source:\n" + pszWKT )
- pszWKT = poOutputSRS.ExportToPrettyWkt( 0 )
- print( "Target:\n" + pszWKT )
- return None
- # --------------------------------------------------------------------
- # Get other info.
- # --------------------------------------------------------------------
- poSrcFDefn = poSrcLayer.GetLayerDefn()
- if poOutputSRS is None and not bNullifyOutputSRS:
- poOutputSRS = poSrcLayer.GetSpatialRef()
- # --------------------------------------------------------------------
- # Find the layer.
- # --------------------------------------------------------------------
- # GetLayerByName() can instantiate layers that would have been
- # 'hidden' otherwise, for example, non-spatial tables in a
- # PostGIS-enabled database, so this apparently useless command is
- # not useless. (#4012)
- gdal.PushErrorHandler('CPLQuietErrorHandler')
- poDstLayer = poDstDS.GetLayerByName(pszNewLayerName)
- gdal.PopErrorHandler()
- gdal.ErrorReset()
- iLayer = -1
- if poDstLayer is not None:
- nLayerCount = poDstDS.GetLayerCount()
- for iLayer in range(nLayerCount):
- poLayer = poDstDS.GetLayer(iLayer)
- # The .cpp version compares on pointers directly, but we cannot
- # do this with swig object, so just compare the names.
- if poLayer is not None \
- and poLayer.GetName() == poDstLayer.GetName():
- break
- if (iLayer == nLayerCount):
- # Shouldn't happen with an ideal driver
- poDstLayer = None
- # --------------------------------------------------------------------
- # If the user requested overwrite, and we have the layer in
- # question we need to delete it now so it will get recreated
- # (overwritten).
- # --------------------------------------------------------------------
- if poDstLayer is not None and bOverwrite:
- if poDstDS.DeleteLayer( iLayer ) != 0:
- print("DeleteLayer() failed when overwrite requested." )
- return None
- poDstLayer = None
- # --------------------------------------------------------------------
- # If the layer does not exist, then create it.
- # --------------------------------------------------------------------
- if poDstLayer is None:
- if eGType == -2:
- eGType = poSrcFDefn.GetGeomType()
- n25DBit = eGType & ogr.wkb25DBit
- if bPromoteToMulti:
- if wkbFlatten(eGType) == ogr.wkbLineString:
- eGType = ogr.wkbMultiLineString | n25DBit
- elif wkbFlatten(eGType) == ogr.wkbPolygon:
- eGType = ogr.wkbMultiPolygon | n25DBit
- if bExplodeCollections:
- if wkbFlatten(eGType) == ogr.wkbMultiPoint:
- eGType = ogr.wkbPoint | n25DBit
- elif wkbFlatten(eGType) == ogr.wkbMultiLineString:
- eGType = ogr.wkbLineString | n25DBit
- elif wkbFlatten(eGType) == ogr.wkbMultiPolygon:
- eGType = ogr.wkbPolygon | n25DBit
- elif wkbFlatten(eGType) == ogr.wkbGeometryCollection:
- eGType = ogr.wkbUnknown | n25DBit
- if pszZField is not None:
- eGType = eGType | ogr.wkb25DBit
- if nCoordDim == 2:
- eGType = eGType & ~ogr.wkb25DBit
- elif nCoordDim == 3:
- eGType = eGType | ogr.wkb25DBit
- if poDstDS.TestCapability( ogr.ODsCCreateLayer ) == False:
- print("Layer " + pszNewLayerName + "not found, and CreateLayer not supported by driver.")
- return None
- gdal.ErrorReset()
- poDstLayer = poDstDS.CreateLayer( pszNewLayerName, poOutputSRS, \
- eGType, papszLCO )
- if poDstLayer is None:
- return None
- bAppend = False
- # --------------------------------------------------------------------
- # Otherwise we will append to it, if append was requested.
- # --------------------------------------------------------------------
- elif not bAppend:
- print("FAILED: Layer " + pszNewLayerName + "already exists, and -append not specified.\n" + \
- " Consider using -append, or -overwrite.")
- return None
- else:
- if len(papszLCO) > 0:
- print("WARNING: Layer creation options ignored since an existing layer is\n" + \
- " being appended to." )
- # --------------------------------------------------------------------
- # Add fields. Default to copy all field.
- # If only a subset of all fields requested, then output only
- # the selected fields, and in the order that they were
- # selected.
- # --------------------------------------------------------------------
- # Initialize the index-to-index map to -1's
- nSrcFieldCount = poSrcFDefn.GetFieldCount()
- panMap = [ -1 for i in range(nSrcFieldCount) ]
- poDstFDefn = poDstLayer.GetLayerDefn()
- if papszSelFields is not None and not bAppend:
- nDstFieldCount = 0
- if poDstFDefn is not None:
- nDstFieldCount = poDstFDefn.GetFieldCount()
- for iField in range(len(papszSelFields)):
- iSrcField = poSrcFDefn.GetFieldIndex(papszSelFields[iField])
- if iSrcField >= 0:
- poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iSrcField)
- oFieldDefn = ogr.FieldDefn( poSrcFieldDefn.GetNameRef(),
- poSrcFieldDefn.GetType() )
- oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() )
- oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
- if papszFieldTypesToString is not None and \
- (CSLFindString(papszFieldTypesToString, "All") != -1 or \
- CSLFindString(papszFieldTypesToString, \
- ogr.GetFieldTypeName(poSrcFieldDefn.GetType())) != -1):
- oFieldDefn.SetType(ogr.OFTString)
- # The field may have been already created at layer creation
- iDstField = -1
- if poDstFDefn is not None:
- iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef())
- if iDstField >= 0:
- panMap[iSrcField] = iDstField
- elif poDstLayer.CreateField( oFieldDefn ) == 0:
- # now that we've created a field, GetLayerDefn() won't return NULL
- if poDstFDefn is None:
- poDstFDefn = poDstLayer.GetLayerDefn()
- # Sanity check : if it fails, the driver is buggy
- if poDstFDefn is not None and \
- poDstFDefn.GetFieldCount() != nDstFieldCount + 1:
- print("The output driver has claimed to have added the %s field, but it did not!" % oFieldDefn.GetNameRef() )
- else:
- panMap[iSrcField] = nDstFieldCount
- nDstFieldCount = nDstFieldCount + 1
- else:
- print("Field '" + papszSelFields[iField] + "' not found in source layer.")
- if not bSkipFailures:
- return None
- # --------------------------------------------------------------------
- # Use SetIgnoredFields() on source layer if available
- # --------------------------------------------------------------------
- # Here we differ from the ogr2ogr.cpp implementation since the OGRFeatureQuery
- # isn't mapped to swig. So in that case just don't use SetIgnoredFields()
- # to avoid issue raised in #4015
- if poSrcLayer.TestCapability(ogr.OLCIgnoreFields) and pszWHERE is None:
- papszIgnoredFields = []
- for iSrcField in range(nSrcFieldCount):
- pszFieldName = poSrcFDefn.GetFieldDefn(iSrcField).GetNameRef()
- bFieldRequested = False
- for iField in range(len(papszSelFields)):
- if EQUAL(pszFieldName, papszSelFields[iField]):
- bFieldRequested = True
- break
- if pszZField is not None and EQUAL(pszFieldName, pszZField):
- bFieldRequested = True
- # If source field not requested, add it to ignored files list
- if not bFieldRequested:
- papszIgnoredFields.append(pszFieldName)
- poSrcLayer.SetIgnoredFields(papszIgnoredFields)
- elif not bAppend:
- nDstFieldCount = 0
- if poDstFDefn is not None:
- nDstFieldCount = poDstFDefn.GetFieldCount()
- for iField in range(nSrcFieldCount):
- poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField)
- oFieldDefn = ogr.FieldDefn( poSrcFieldDefn.GetNameRef(),
- poSrcFieldDefn.GetType() )
- oFieldDefn.SetWidth( poSrcFieldDefn.GetWidth() )
- oFieldDefn.SetPrecision( poSrcFieldDefn.GetPrecision() )
- if papszFieldTypesToString is not None and \
- (CSLFindString(papszFieldTypesToString, "All") != -1 or \
- CSLFindString(papszFieldTypesToString, \
- ogr.GetFieldTypeName(poSrcFieldDefn.GetType())) != -1):
- oFieldDefn.SetType(ogr.OFTString)
- # The field may have been already created at layer creation
- iDstField = -1
- if poDstFDefn is not None:
- iDstField = poDstFDefn.GetFieldIndex(oFieldDefn.GetNameRef())
- if iDstField >= 0:
- panMap[iField] = iDstField
- elif poDstLayer.CreateField( oFieldDefn ) == 0:
- # now that we've created a field, GetLayerDefn() won't return NULL
- if poDstFDefn is None:
- poDstFDefn = poDstLayer.GetLayerDefn()
- # Sanity check : if it fails, the driver is buggy
- if poDstFDefn is not None and \
- poDstFDefn.GetFieldCount() != nDstFieldCount + 1:
- print("The output driver has claimed to have added the %s field, but it did not!" % oFieldDefn.GetNameRef() )
- else:
- panMap[iField] = nDstFieldCount
- nDstFieldCount = nDstFieldCount + 1
- else:
- # For an existing layer, build the map by fetching the index in the destination
- # layer for each source field
- if poDstFDefn is None:
- print( "poDstFDefn == NULL.\n" )
- return None
- for iField in range(nSrcFieldCount):
- poSrcFieldDefn = poSrcFDefn.GetFieldDefn(iField)
- iDstField = poDstFDefn.GetFieldIndex(poSrcFieldDefn.GetNameRef())
- if iDstField >= 0:
- panMap[iField] = iDstField
- iSrcZField = -1
- if pszZField is not None:
- iSrcZField = poSrcFDefn.GetFieldIndex(pszZField)
- psInfo = TargetLayerInfo()
- psInfo.poDstLayer = poDstLayer
- psInfo.poCT = poCT
- #psInfo.papszTransformOptions = papszTransformOptions
- psInfo.panMap = panMap
- psInfo.iSrcZField = iSrcZField
- return psInfo
- #**********************************************************************
- # TranslateLayer()
- #**********************************************************************
- def TranslateLayer( psInfo, poSrcDS, poSrcLayer, poDstDS, \
- poOutputSRS, bNullifyOutputSRS, \
- eGType, bPromoteToMulti, nCoordDim, eGeomOp, dfGeomOpParam, \
- nCountLayerFeatures, \
- poClipSrc, poClipDst, bExplodeCollections, nSrcFileSize, \
- pnReadFeatureCount, pfnProgress, pProgressArg) :
- bForceToPolygon = False
- bForceToMultiPolygon = False
- bForceToMultiLineString = False
- poDstLayer = psInfo.poDstLayer
- #papszTransformOptions = psInfo.papszTransformOptions
- poCT = psInfo.poCT
- panMap = psInfo.panMap
- iSrcZField = psInfo.iSrcZField
- if poOutputSRS is None and not bNullifyOutputSRS:
- poOutputSRS = poSrcLayer.GetSpatialRef()
- if wkbFlatten(eGType) == ogr.wkbPolygon:
- bForceToPolygon = True
- elif wkbFlatten(eGType) == ogr.wkbMultiPolygon:
- bForceToMultiPolygon = True
- elif wkbFlatten(eGType) == ogr.wkbMultiLineString:
- bForceToMultiLineString = True
- # --------------------------------------------------------------------
- # Transfer features.
- # --------------------------------------------------------------------
- nFeaturesInTransaction = 0
- nCount = 0
- if nGroupTransactions > 0:
- poDstLayer.StartTransaction()
- while True:
- poDstFeature = None
- if nFIDToFetch != ogr.NullFID:
- #// Only fetch feature on first pass.
- if nFeaturesInTransaction == 0:
- poFeature = poSrcLayer.GetFeature(nFIDToFetch)
- else:
- poFeature = None
- else:
- poFeature = poSrcLayer.GetNextFeature()
- if poFeature is None:
- break
- nParts = 0
- nIters = 1
- if bExplodeCollections:
- poSrcGeometry = poFeature.GetGeometryRef()
- if poSrcGeometry is not None:
- eSrcType = wkbFlatten(poSrcGeometry.GetGeometryType())
- if eSrcType == ogr.wkbMultiPoint or \
- eSrcType == ogr.wkbMultiLineString or \
- eSrcType == ogr.wkbMultiPolygon or \
- eSrcType == ogr.wkbGeometryCollection:
- nParts = poSrcGeometry.GetGeometryCount()
- nIters = nParts
- if nIters == 0:
- nIters = 1
- for iPart in range(nIters):
- nFeaturesInTransaction = nFeaturesInTransaction + 1
- if nFeaturesInTransaction == nGroupTransactions:
- poDstLayer.CommitTransaction()
- poDstLayer.StartTransaction()
- nFeaturesInTransaction = 0
- gdal.ErrorReset()
- poDstFeature = ogr.Feature( poDstLayer.GetLayerDefn() )
- if poDstFeature.SetFromWithMap( poFeature, 1, panMap ) != 0:
- if nGroupTransactions > 0:
- poDstLayer.CommitTransaction()
- print("Unable to translate feature %d from layer %s" % (poFeature.GetFID() , poSrcLayer.GetName() ))
- return False
- if bPreserveFID:
- poDstFeature.SetFID( poFeature.GetFID() )
- poDstGeometry = poDstFeature.GetGeometryRef()
- if poDstGeometry is not None:
- if nParts > 0:
- # For -explodecollections, extract the iPart(th) of the geometry
- poPart = poDstGeometry.GetGeometryRef(iPart).Clone()
- poDstFeature.SetGeometryDirectly(poPart)
- poDstGeometry = poPart
- if iSrcZField != -1:
- SetZ(poDstGeometry, poFeature.GetFieldAsDouble(iSrcZField))
- # This will correct the coordinate dimension to 3
- poDupGeometry = poDstGeometry.Clone()
- poDstFeature.SetGeometryDirectly(poDupGeometry)
- poDstGeometry = poDupGeometry
- if nCoordDim == 2 or nCoordDim == 3:
- poDstGeometry.SetCoordinateDimension( nCoordDim )
- if eGeomOp == GeomOperation.SEGMENTIZE:
- pass
- #if (poDstFeature.GetGeometryRef() is not None and dfGeomOpParam > 0)
- # poDstFeature.GetGeometryRef().segmentize(dfGeomOpParam);
- elif eGeomOp == GeomOperation.SIMPLIFY_PRESERVE_TOPOLOGY and dfGeomOpParam > 0:
- poNewGeom = poDstGeometry.SimplifyPreserveTopology(dfGeomOpParam)
- if poNewGeom is not None:
- poDstFeature.SetGeometryDirectly(poNewGeom)
- poDstGeometry = poNewGeom
- if poClipSrc is not None:
- poClipped = poDstGeometry.Intersection(poClipSrc)
- if poClipped is None or poClipped.IsEmpty():
- # Report progress
- nCount = nCount +1
- if pfnProgress is not None:
- pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg)
- continue
- poDstFeature.SetGeometryDirectly(poClipped)
- poDstGeometry = poClipped
- if poCT is not None:
- eErr = poDstGeometry.Transform( poCT )
- if eErr != 0:
- if nGroupTransactions > 0:
- poDstLayer.CommitTransaction()
- print("Failed to reproject feature %d (geometry probably out of source or destination SRS)." % poFeature.GetFID())
- if not bSkipFailures:
- return False
- elif poOutputSRS is not None:
- poDstGeometry.AssignSpatialReference(poOutputSRS)
- if poClipDst is not None:
- poClipped = poDstGeometry.Intersection(poClipDst)
- if poClipped is None or poClipped.IsEmpty():
- continue
- poDstFeature.SetGeometryDirectly(poClipped)
- poDstGeometry = poClipped
- if bForceToPolygon:
- poDstFeature.SetGeometryDirectly(ogr.ForceToPolygon(poDstGeometry))
- elif bForceToMultiPolygon or \
- (bPromoteToMulti and wkbFlatten(poDstGeometry.GetGeometryType()) == ogr.wkbPolygon):
- poDstFeature.SetGeometryDirectly(ogr.ForceToMultiPolygon(poDstGeometry))
- elif bForceToMultiLineString or \
- (bPromoteToMulti and wkbFlatten(poDstGeometry.GetGeometryType()) == ogr.wkbLineString):
- poDstFeature.SetGeometryDirectly(ogr.ForceToMultiLineString(poDstGeometry))
- gdal.ErrorReset()
- if poDstLayer.CreateFeature( poDstFeature ) != 0 and not bSkipFailures:
- if nGroupTransactions > 0:
- poDstLayer.RollbackTransaction()
- return False
- # Report progress
- nCount = nCount + 1
- if pfnProgress is not None:
- if nSrcFileSize != 0:
- if (nCount % 1000) == 0:
- poFCLayer = poSrcDS.ExecuteSQL("GetBytesRead()", None, None)
- if poFCLayer is not None:
- poFeat = poFCLayer.GetNextFeature()
- if poFeat is not None:
- pszReadSize = poFeat.GetFieldAsString(0)
- nReadSize = int(pszReadSize)
- pfnProgress(nReadSize * 1.0 / nSrcFileSize, "", pProgressArg)
- poSrcDS.ReleaseResultSet(poFCLayer)
- else:
- pfnProgress(nCount * 1.0 / nCountLayerFeatures, "", pProgressArg)
- if pnReadFeatureCount is not None:
- pnReadFeatureCount[0] = nCount
- if nGroupTransactions > 0:
- poDstLayer.CommitTransaction()
- return True
- if __name__ == '__main__':
- version_num = int(gdal.VersionInfo('VERSION_NUM'))
- if version_num < 1800: # because of ogr.GetFieldTypeName
- print('ERROR: Python bindings of GDAL 1.8.0 or later required')
- sys.exit(1)
- if not main(sys.argv):
- sys.exit(1)
- else:
- sys.exit(0)
|