Skip to content

Commit a9216c7

Browse files
committedJul 9, 2014
[processing] refactor OGR algorithms to use commandline tools, not
bindings
1 parent 0df2b01 commit a9216c7

File tree

6 files changed

+91
-350
lines changed

6 files changed

+91
-350
lines changed
 

‎python/plugins/processing/algs/gdal/GdalUtils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ def getFormatShortNameFromFilename(filename):
138138
def escapeAndJoin(strList):
139139
joined = ''
140140
for s in strList:
141-
if s[0]!='-' and ' ' in s:
141+
if s[0] != '-' and ' ' in s:
142142
escaped = '"' + s.replace('\\', '\\\\').replace('"', '\\"') \
143143
+ '"'
144144
else:
145145
escaped = s
146146
joined += escaped + ' '
147-
return joined.strip()
147+
return joined.strip()

‎python/plugins/processing/algs/gdal/OgrAlgorithm.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@
4444

4545
class OgrAlgorithm(GdalAlgorithm):
4646

47-
DB = 'DB'
48-
4947
def ogrConnectionString(self, uri):
5048
ogrstr = None
5149

‎python/plugins/processing/algs/gdal/information.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ def processAlgorithm(self, progress):
6464
progress)
6565
output = self.getOutputValue(information.OUTPUT)
6666
f = open(output, 'w')
67+
f.write('<pre>')
6768
for s in GdalUtils.getConsoleOutput()[1:]:
68-
f.write('<p>' + str(s) + '</p>')
69+
f.write(unicode(s))
70+
f.write('</pre>')
6971
f.close()

‎python/plugins/processing/algs/gdal/ogr2ogr.py

Lines changed: 43 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,22 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
29-
try:
30-
from osgeo import gdal, ogr, osr
31-
gdalAvailable = True
32-
except:
33-
gdalAvailable = False
28+
import os
3429

3530
from PyQt4.QtCore import *
3631
from PyQt4.QtGui import *
32+
3733
from qgis.core import *
38-
from processing.core.GeoAlgorithmExecutionException import \
39-
GeoAlgorithmExecutionException
34+
4035
from processing.parameters.ParameterVector import ParameterVector
4136
from processing.parameters.ParameterString import ParameterString
4237
from processing.parameters.ParameterSelection import ParameterSelection
4338
from processing.outputs.OutputVector import OutputVector
4439

45-
from OgrAlgorithm import OgrAlgorithm
46-
from pyogr.ogr2ogr import *
40+
from processing.tools.system import *
4741

48-
GeomOperation = Enum(['NONE', 'SEGMENTIZE', 'SIMPLIFY_PRESERVE_TOPOLOGY'])
42+
from processing.algs.gdal.OgrAlgorithm import OgrAlgorithm
43+
from processing.algs.gdal.GdalUtils import GdalUtils
4944

5045
FORMATS = [
5146
'ESRI Shapefile',
@@ -101,147 +96,60 @@ class Ogr2Ogr(OgrAlgorithm):
10196

10297
OUTPUT_LAYER = 'OUTPUT_LAYER'
10398
INPUT_LAYER = 'INPUT_LAYER'
104-
DEST_DS = 'DEST_DS'
105-
DEST_FORMAT = 'DEST_FORMAT'
106-
DEST_DSCO = 'DEST_DSCO'
99+
FORMAT = 'FORMAT'
100+
OPTIONS = 'OPTIONS'
107101

108102
def defineCharacteristics(self):
109103
self.name = 'Convert format'
110104
self.group = '[OGR] Conversion'
111105

112106
self.addParameter(ParameterVector(self.INPUT_LAYER, 'Input layer',
113107
[ParameterVector.VECTOR_TYPE_ANY], False))
114-
self.addParameter(ParameterSelection(self.DEST_FORMAT,
108+
self.addParameter(ParameterSelection(self.FORMAT,
115109
'Destination Format', FORMATS))
116-
self.addParameter(ParameterString(self.DEST_DSCO, 'Creation Options',
117-
''))
110+
self.addParameter(ParameterString(self.OPTIONS, 'Creation Options',
111+
'', optional=True))
118112

119113
self.addOutput(OutputVector(self.OUTPUT_LAYER, 'Output layer'))
120114

121115
def commandLineName(self):
122116
return "gdalogr:ogr2ogr"
123117

124-
125118
def processAlgorithm(self, progress):
126-
if not gdalAvailable:
127-
raise GeoAlgorithmExecutionException(
128-
'GDAL bindings not installed.')
129-
130-
input = self.getParameterValue(self.INPUT_LAYER)
131-
ogrLayer = self.ogrConnectionString(input)
119+
inLayer = self.getParameterValue(self.INPUT_LAYER)
120+
ogrLayer = self.ogrConnectionString(inLayer)
132121

133122
output = self.getOutputFromName(self.OUTPUT_LAYER)
134-
outfile = output.value
135-
136-
formatIdx = self.getParameterValue(self.DEST_FORMAT)
123+
outFile = output.value
137124

125+
formatIdx = self.getParameterValue(self.FORMAT)
126+
outFormat = FORMATS[formatIdx]
138127
ext = EXTS[formatIdx]
139-
if not outfile.endswith(ext):
140-
outfile = outfile + ext
141-
output.value = outfile
142-
143-
dst_ds = self.ogrConnectionString(outfile)
144-
dst_format = FORMATS[formatIdx]
145-
ogr_dsco = [self.getParameterValue(self.DEST_DSCO)]
146-
147-
poDS = ogr.Open(ogrLayer, False)
148-
if poDS is None:
149-
raise GeoAlgorithmExecutionException(self.failure(ogrLayer))
150-
151-
if dst_format == 'SQLite' and os.path.isfile(dst_ds):
152-
os.remove(dst_ds)
153-
driver = ogr.GetDriverByName(str(dst_format))
154-
poDstDS = driver.CreateDataSource(dst_ds, options=ogr_dsco)
155-
if poDstDS is None:
156-
raise GeoAlgorithmExecutionException('Error creating %s' % dst_ds)
157-
return
158-
self.ogrtransform(poDS, poDstDS, bOverwrite=True)
159-
160-
def ogrtransform(
161-
self,
162-
poSrcDS,
163-
poDstDS,
164-
papszLayers=[],
165-
papszLCO=[],
166-
bTransform=False,
167-
bAppend=False,
168-
bUpdate=False,
169-
bOverwrite=False,
170-
poOutputSRS=None,
171-
poSourceSRS=None,
172-
pszNewLayerName=None,
173-
pszWHERE=None,
174-
papszSelFields=None,
175-
eGType=-2,
176-
eGeomOp=GeomOperation.NONE,
177-
dfGeomOpParam=0,
178-
papszFieldTypesToString=[],
179-
pfnProgress=None,
180-
pProgressData=None,
181-
nCountLayerFeatures=0,
182-
poClipSrc=None,
183-
poClipDst=None,
184-
bExplodeCollections=False,
185-
pszZField=None,
186-
):
187-
188-
# Process each data source layer
189-
if len(papszLayers) == 0:
190-
nLayerCount = poSrcDS.GetLayerCount()
191-
papoLayers = [None for i in range(nLayerCount)]
192-
iLayer = 0
193-
194-
for iLayer in range(nLayerCount):
195-
poLayer = poSrcDS.GetLayer(iLayer)
196-
197-
if poLayer is None:
198-
raise GeoAlgorithmExecutionException(
199-
"FAILURE: Couldn't fetch advertised layer %d!"
200-
% iLayer)
201-
202-
papoLayers[iLayer] = poLayer
203-
iLayer = iLayer + 1
128+
if not outFile.endswith(ext):
129+
outFile += ext
130+
output.value = outFile
131+
132+
output = self.ogrConnectionString(outFile)
133+
options = unicode(self.getParameterValue(self.OPTIONS))
134+
135+
if outFormat == 'SQLite' and os.path.isfile(output):
136+
os.remove(output)
137+
138+
arguments = []
139+
arguments.append('-f')
140+
arguments.append(outFormat)
141+
if len(options) > 0:
142+
arguments.append(options)
143+
144+
arguments.append(output)
145+
arguments.append(ogrLayer)
146+
147+
commands = []
148+
if isWindows():
149+
commands = ['cmd.exe', '/C ', 'ogr2ogr.exe',
150+
GdalUtils.escapeAndJoin(arguments)]
204151
else:
205-
# Process specified data source layers
206-
nLayerCount = len(papszLayers)
207-
papoLayers = [None for i in range(nLayerCount)]
208-
iLayer = 0
209-
210-
for layername in papszLayers:
211-
poLayer = poSrcDS.GetLayerByName(layername)
212-
213-
if poLayer is None:
214-
raise GeoAlgorithmExecutionException(
215-
"FAILURE: Couldn't fetch advertised layer %s!"
216-
% layername)
217-
218-
papoLayers[iLayer] = poLayer
219-
iLayer = iLayer + 1
220-
221-
for poSrcLayer in papoLayers:
222-
ok = TranslateLayer(
223-
poSrcDS,
224-
poSrcLayer,
225-
poDstDS,
226-
papszLCO,
227-
pszNewLayerName,
228-
bTransform,
229-
poOutputSRS,
230-
poSourceSRS,
231-
papszSelFields,
232-
bAppend,
233-
eGType,
234-
bOverwrite,
235-
eGeomOp,
236-
dfGeomOpParam,
237-
papszFieldTypesToString,
238-
nCountLayerFeatures,
239-
poClipSrc,
240-
poClipDst,
241-
bExplodeCollections,
242-
pszZField,
243-
pszWHERE,
244-
pfnProgress,
245-
pProgressData,
246-
)
247-
return True
152+
commands = ['ogr2ogr', GdalUtils.escapeAndJoin(arguments)]
153+
154+
GdalUtils.runGdal(commands, progress)
155+

‎python/plugins/processing/algs/gdal/ogrinfo.py

Lines changed: 17 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -25,159 +25,45 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
import string
29-
import re
30-
31-
try:
32-
from osgeo import ogr
33-
ogrAvailable = True
34-
except:
35-
ogrAvailable = False
3628

3729
from PyQt4.QtCore import *
3830
from PyQt4.QtGui import *
3931
from qgis.core import *
4032

4133
from processing.parameters.ParameterVector import ParameterVector
4234
from processing.outputs.OutputHTML import OutputHTML
43-
from OgrAlgorithm import OgrAlgorithm
35+
36+
from processing.algs.gdal.GdalUtils import GdalUtils
37+
from processing.algs.gdal.OgrAlgorithm import OgrAlgorithm
4438

4539

4640
class OgrInfo(OgrAlgorithm):
4741

42+
INPUT = 'INPUT'
4843
OUTPUT = 'OUTPUT'
49-
INPUT_LAYER = 'INPUT_LAYER'
5044

5145
def defineCharacteristics(self):
5246
self.name = 'Information'
5347
self.group = '[OGR] Miscellaneous'
5448

55-
self.addParameter(ParameterVector(self.INPUT_LAYER, 'Input layer',
49+
self.addParameter(ParameterVector(self.INPUT, 'Input layer',
5650
[ParameterVector.VECTOR_TYPE_ANY], False))
5751

5852
self.addOutput(OutputHTML(self.OUTPUT, 'Layer information'))
5953

60-
def commandLineName(self):
61-
return "gdalogr:vectorinfo"
62-
6354
def processAlgorithm(self, progress):
64-
65-
input = self.getParameterValue(self.INPUT_LAYER)
66-
ogrLayer = self.ogrConnectionString(input)
67-
55+
arguments = []
56+
arguments.append('-al')
57+
arguments.append('-so')
58+
layer = self.getParameterValue(self.INPUT)
59+
conn = self.ogrConnectionString(layer)
60+
arguments.append(conn)
61+
GdalUtils.runGdal(['ogrinfo', GdalUtils.escapeAndJoin(arguments)],
62+
progress)
6863
output = self.getOutputValue(self.OUTPUT)
69-
70-
self.ogrinfo(ogrLayer)
71-
7264
f = open(output, 'w')
73-
f.write('<pre>' + self.info + '</pre>')
65+
f.write('<pre>')
66+
for s in GdalUtils.getConsoleOutput()[1:]:
67+
f.write(unicode(s))
68+
f.write('</pre>')
7469
f.close()
75-
76-
def out(self, text):
77-
self.info = self.info + text + '\n'
78-
79-
def ogrinfo(self, pszDataSource):
80-
bVerbose = True
81-
bSummaryOnly = True
82-
self.info = ''
83-
84-
if not ogrAvailable:
85-
self.info = 'OGR bindings not installed'
86-
return
87-
88-
qDebug("Opening data source '%s'" % pszDataSource)
89-
poDS = ogr.Open(pszDataSource, False)
90-
91-
if poDS is None:
92-
self.info = self.failure(pszDataSource)
93-
return
94-
95-
poDriver = poDS.GetDriver()
96-
97-
if bVerbose:
98-
self.out("INFO: Open of `%s'\n using driver `%s' successful."
99-
% (pszDataSource, poDriver.GetName()))
100-
101-
poDS_Name = poDS.GetName()
102-
if str(type(pszDataSource)) == "<type 'unicode'>" \
103-
and str(type(poDS_Name)) == "<type 'str'>":
104-
poDS_Name = unicode(poDS_Name, 'utf8')
105-
if bVerbose and pszDataSource != poDS_Name:
106-
self.out("INFO: Internal data source name '%s'\n \
107-
different from user name '%s'." \
108-
% (poDS_Name, pszDataSource))
109-
110-
# --------------------------------------------------------------------
111-
# Process each data source layer.
112-
# --------------------------------------------------------------------
113-
114-
for iLayer in range(poDS.GetLayerCount()):
115-
poLayer = poDS.GetLayer(iLayer)
116-
117-
if poLayer is None:
118-
self.out("FAILURE: Couldn't fetch advertised layer %d!"
119-
% iLayer)
120-
return 1
121-
122-
self.ReportOnLayer(poLayer)
123-
124-
def ReportOnLayer(
125-
self,
126-
poLayer,
127-
pszWHERE=None,
128-
poSpatialFilter=None,
129-
):
130-
bVerbose = True
131-
132-
poDefn = poLayer.GetLayerDefn()
133-
134-
# --------------------------------------------------------------------
135-
# Set filters if provided.
136-
# --------------------------------------------------------------------
137-
138-
if pszWHERE is not None:
139-
if poLayer.SetAttributeFilter(pszWHERE) != 0:
140-
self.out('FAILURE: SetAttributeFilter(%s) failed.' % pszWHERE)
141-
return
142-
143-
if poSpatialFilter is not None:
144-
poLayer.SetSpatialFilter(poSpatialFilter)
145-
146-
# --------------------------------------------------------------------
147-
# Report various overall information.
148-
# --------------------------------------------------------------------
149-
150-
self.out('')
151-
152-
self.out('Layer name: %s' % poDefn.GetName())
153-
154-
if bVerbose:
155-
self.out('Geometry: %s'
156-
% ogr.GeometryTypeToName(poDefn.GetGeomType()))
157-
158-
self.out('Feature Count: %d' % poLayer.GetFeatureCount())
159-
160-
oExt = poLayer.GetExtent(True, can_return_null=True)
161-
if oExt is not None:
162-
self.out('Extent: (%f, %f) - (%f, %f)' % (oExt[0], oExt[1],
163-
oExt[2], oExt[3]))
164-
165-
if poLayer.GetSpatialRef() is None:
166-
pszWKT = '(unknown)'
167-
else:
168-
pszWKT = poLayer.GetSpatialRef().ExportToPrettyWkt()
169-
170-
self.out('Layer SRS WKT:\n%s' % pszWKT)
171-
172-
if len(poLayer.GetFIDColumn()) > 0:
173-
self.out('FID Column = %s' % poLayer.GetFIDColumn())
174-
175-
if len(poLayer.GetGeometryColumn()) > 0:
176-
self.out('Geometry Column = %s' % poLayer.GetGeometryColumn())
177-
178-
for iAttr in range(poDefn.GetFieldCount()):
179-
poField = poDefn.GetFieldDefn(iAttr)
180-
181-
self.out('%s: %s (%d.%d)' % (poField.GetNameRef(),
182-
poField.GetFieldTypeName(poField.GetType()),
183-
poField.GetWidth(), poField.GetPrecision()))

‎python/plugins/processing/algs/gdal/ogrsql.py

Lines changed: 26 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -25,106 +25,53 @@
2525

2626
__revision__ = '$Format:%H$'
2727

28-
import string
29-
import re
30-
31-
try:
32-
from osgeo import ogr
33-
ogrAvailable = True
34-
except:
35-
ogrAvailable = False
36-
3728
from PyQt4.QtCore import *
3829
from PyQt4.QtGui import *
3930
from qgis.core import *
4031

41-
from processing.core.ProcessingLog import ProcessingLog
32+
from processing.core.GeoAlgorithmExecutionException import \
33+
GeoAlgorithmExecutionException
4234
from processing.parameters.ParameterVector import ParameterVector
4335
from processing.parameters.ParameterString import ParameterString
44-
from processing.outputs.OutputHTML import OutputHTML
36+
from processing.outputs.OutputVector import OutputVector
4537

46-
from OgrAlgorithm import OgrAlgorithm
38+
from processing.algs.gdal.GdalUtils import GdalUtils
39+
from processing.algs.gdal.OgrAlgorithm import OgrAlgorithm
4740

4841

4942
class OgrSql(OgrAlgorithm):
5043

44+
INPUT = 'INPUT'
5145
OUTPUT = 'OUTPUT'
52-
INPUT_LAYER = 'INPUT_LAYER'
5346
SQL = 'SQL'
5447

5548
def defineCharacteristics(self):
5649
self.name = 'Execute SQL'
5750
self.group = '[OGR] Miscellaneous'
5851

59-
self.addParameter(ParameterVector(self.INPUT_LAYER, 'Input layer',
52+
self.addParameter(ParameterVector(self.INPUT, 'Input layer',
6053
[ParameterVector.VECTOR_TYPE_ANY], False))
6154
self.addParameter(ParameterString(self.SQL, 'SQL', ''))
6255

63-
self.addOutput(OutputHTML(self.OUTPUT, 'SQL result'))
56+
self.addOutput(OutputVector(self.OUTPUT, 'SQL result'))
6457

6558
def processAlgorithm(self, progress):
66-
if not ogrAvailable:
67-
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
68-
'OGR bindings not installed')
69-
return
70-
71-
input = self.getParameterValue(self.INPUT_LAYER)
7259
sql = self.getParameterValue(self.SQL)
73-
ogrLayer = self.ogrConnectionString(input)
74-
75-
output = self.getOutputValue(self.OUTPUT)
76-
77-
qDebug("Opening data source '%s'" % ogrLayer)
78-
poDS = ogr.Open(ogrLayer, False)
79-
if poDS is None:
80-
ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
81-
self.failure(ogrLayer))
82-
return
83-
84-
result = self.select_values(poDS, sql)
85-
86-
f = open(output, 'w')
87-
f.write('<table>')
88-
for row in result:
89-
f.write('<tr>')
90-
for col in row:
91-
f.write('<td>' + col + '</td>')
92-
f.write('</tr>')
93-
f.write('</table>')
94-
f.close()
95-
96-
def execute_sql(self, ds, sql_statement):
97-
poResultSet = ds.ExecuteSQL(sql_statement, None, None)
98-
if poResultSet is not None:
99-
ds.ReleaseResultSet(poResultSet)
100-
101-
def select_values(self, ds, sql_statement):
102-
"""Returns an array of the columns and values of SELECT
103-
statement:
104-
105-
select_values(ds, "SELECT id FROM companies") => [['id'],[1],[2],[3]]
106-
"""
107-
108-
poResultSet = ds.ExecuteSQL(sql_statement, None, None)
109-
110-
# TODO: Redirect error messages
111-
fields = []
112-
rows = []
113-
if poResultSet is not None:
114-
poDefn = poResultSet.GetLayerDefn()
115-
for iField in range(poDefn.GetFieldCount()):
116-
poFDefn = poDefn.GetFieldDefn(iField)
117-
fields.append(poFDefn.GetNameRef())
118-
119-
poFeature = poResultSet.GetNextFeature()
120-
while poFeature is not None:
121-
values = []
122-
for iField in range(poDefn.GetFieldCount()):
123-
if poFeature.IsFieldSet(iField):
124-
values.append(poFeature.GetFieldAsString(iField))
125-
else:
126-
values.append('(null)')
127-
rows.append(values)
128-
poFeature = poResultSet.GetNextFeature()
129-
ds.ReleaseResultSet(poResultSet)
130-
return [fields] + rows
60+
if sql == '':
61+
raise GeoAlgorithmExecutionException(
62+
'Empty SQL. Please enter valid SQL expression and try again.')
63+
64+
arguments = []
65+
arguments.append('-sql')
66+
arguments.append(sql)
67+
68+
output = self.getOutputFromName(self.OUTPUT)
69+
outFile = output.value
70+
arguments.append(outFile)
71+
72+
layer = self.getParameterValue(self.INPUT)
73+
conn = self.ogrConnectionString(layer)
74+
arguments.append(conn)
75+
76+
GdalUtils.runGdal(['ogr2ogr', GdalUtils.escapeAndJoin(arguments)],
77+
progress)

0 commit comments

Comments
 (0)
Please sign in to comment.