Skip to content

Commit

Permalink
Move OGR processing provider specific methods to GdalUtils
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 13, 2017
1 parent 97a8d1a commit e33647d
Show file tree
Hide file tree
Showing 21 changed files with 222 additions and 254 deletions.
3 changes: 1 addition & 2 deletions python/plugins/processing/algs/gdal/ClipByMask.py
Expand Up @@ -45,7 +45,6 @@
from processing.algs.gdal.GdalUtils import GdalUtils

from processing.tools import dataobjects
from processing.tools.vector import ogrConnectionString

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]

Expand Down Expand Up @@ -109,7 +108,7 @@ def getConsoleCommands(self, parameters, context, feedback):
mask = self.getParameterValue(self.MASK)
context = dataobjects.createContext()
maskLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.MASK), context)
ogrMask = ogrConnectionString(mask, context)[1:-1]
ogrMask = GdalUtils.ogrConnectionString(mask, context)[1:-1]
noData = self.getParameterValue(self.NO_DATA)
opts = self.getParameterValue(self.OPTIONS)

Expand Down
16 changes: 5 additions & 11 deletions python/plugins/processing/algs/gdal/GdalAlgorithm.py
Expand Up @@ -32,16 +32,10 @@

from qgis.core import (QgsApplication,
QgsVectorFileWriter,
QgsProcessingUtils,
QgsProcessingAlgorithm,
QgsProject)
QgsProcessingAlgorithm)

from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.algs.gdal.GdalAlgorithmDialog import GdalAlgorithmDialog
from processing.algs.gdal.GdalUtils import GdalUtils
from processing.tools.vector import ogrConnectionString, ogrLayerName

from processing.tools import dataobjects

pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
Expand Down Expand Up @@ -80,19 +74,19 @@ def getOgrCompatibleSource(self, parameter_name, parameters, context, feedback):
ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context,
QgsVectorFileWriter.supportedFormatExtensions(),
feedback=feedback)
ogr_layer_name = ogrLayerName(ogr_data_path)
ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path)
elif input_layer.dataProvider().name() == 'ogr':
# parameter is a vector layer, with OGR data provider
# so extract selection if required
ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context,
QgsVectorFileWriter.supportedFormatExtensions(),
feedback=feedback)
ogr_layer_name = ogrLayerName(input_layer.dataProvider().dataSourceUri())
ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri())
else:
# vector layer, but not OGR - get OGR compatible path
# TODO - handle "selected features only" mode!!
ogr_data_path = ogrConnectionString(input_layer.dataProvider().dataSourceUri(), context)[1:-1]
ogr_layer_name = ogrLayerName(input_layer.dataProvider().dataSourceUri())
ogr_data_path = GdalUtils.ogrConnectionString(input_layer.dataProvider().dataSourceUri(), context)[1:-1]
ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri())
return ogr_data_path, ogr_layer_name

def processAlgorithm(self, parameters, context, feedback):
Expand Down
128 changes: 127 additions & 1 deletion python/plugins/processing/algs/gdal/GdalUtils.py
Expand Up @@ -31,15 +31,21 @@
import os
import subprocess
import platform
import re

import psycopg2

from osgeo import gdal
from osgeo import ogr

from qgis.core import (QgsApplication,
QgsVectorFileWriter,
QgsProcessingFeedback,
QgsProcessingUtils,
QgsMessageLog,
QgsSettings)
QgsSettings,
QgsCredentials,
QgsDataSourceUri)
from processing.core.ProcessingConfig import ProcessingConfig
from processing.tools.system import isWindows, isMac

Expand Down Expand Up @@ -220,3 +226,123 @@ def gdalHelpPath():
break

return helpPath if helpPath is not None else 'http://www.gdal.org/'

@staticmethod
def ogrConnectionString(uri, context):
"""Generates OGR connection sting from layer source
"""
ogrstr = None

layer = QgsProcessingUtils.mapLayerFromString(uri, context, False)
if layer is None:
return '"' + uri + '"'

provider = layer.dataProvider().name()
if provider == 'spatialite':
# dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
regex = re.compile("dbname='(.+)'")
r = regex.search(str(layer.source()))
ogrstr = r.groups()[0]
elif provider == 'postgres':
# dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
# user='ktryjh_iuuqef' password='xyqwer' sslmode=disable
# key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
# table="t4" (geom) sql=
dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
conninfo = dsUri.connectionInfo()
conn = None
ok = False
while not conn:
try:
conn = psycopg2.connect(dsUri.connectionInfo())
except psycopg2.OperationalError:
(ok, user, passwd) = QgsCredentials.instance().get(conninfo, dsUri.username(), dsUri.password())
if not ok:
break

dsUri.setUsername(user)
dsUri.setPassword(passwd)

if not conn:
raise RuntimeError('Could not connect to PostgreSQL database - check connection info')

if ok:
QgsCredentials.instance().put(conninfo, user, passwd)

ogrstr = "PG:%s" % dsUri.connectionInfo()
elif provider == "oracle":
# OCI:user/password@host:port/service:table
dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
ogrstr = "OCI:"
if dsUri.username() != "":
ogrstr += dsUri.username()
if dsUri.password() != "":
ogrstr += "/" + dsUri.password()
delim = "@"

if dsUri.host() != "":
ogrstr += delim + dsUri.host()
delim = ""
if dsUri.port() != "" and dsUri.port() != '1521':
ogrstr += ":" + dsUri.port()
ogrstr += "/"
if dsUri.database() != "":
ogrstr += dsUri.database()
elif dsUri.database() != "":
ogrstr += delim + dsUri.database()

if ogrstr == "OCI:":
raise RuntimeError('Invalid oracle data source - check connection info')

ogrstr += ":"
if dsUri.schema() != "":
ogrstr += dsUri.schema() + "."

ogrstr += dsUri.table()
else:
ogrstr = str(layer.source()).split("|")[0]

return '"' + ogrstr + '"'

@staticmethod
def ogrLayerName(uri):
if os.path.isfile(uri):
return os.path.basename(os.path.splitext(uri)[0])

if ' table=' in uri:
# table="schema"."table"
re_table_schema = re.compile(' table="([^"]*)"\\."([^"]*)"')
r = re_table_schema.search(uri)
if r:
return r.groups()[0] + '.' + r.groups()[1]
# table="table"
re_table = re.compile(' table="([^"]*)"')
r = re_table.search(uri)
if r:
return r.groups()[0]
elif 'layername' in uri:
regex = re.compile('(layername=)([^|]*)')
r = regex.search(uri)
return r.groups()[1]

fields = uri.split('|')
basePath = fields[0]
fields = fields[1:]
layerid = 0
for f in fields:
if f.startswith('layername='):
return f.split('=')[1]
if f.startswith('layerid='):
layerid = int(f.split('=')[1])

ds = ogr.Open(basePath)
if not ds:
return None

ly = ds.GetLayer(layerid)
if not ly:
return None

name = ly.GetName()
ds = None
return name
9 changes: 4 additions & 5 deletions python/plugins/processing/algs/gdal/offsetcurve.py
Expand Up @@ -35,7 +35,6 @@

from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


class OffsetCurve(GdalAlgorithm):
Expand Down Expand Up @@ -80,14 +79,14 @@ def getConsoleCommands(self, parameters, context, feedback):
distance = self.getParameterValue(self.RADIUS)
options = self.getParameterValue(self.OPTIONS)

ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
layername = "'" + ogrLayerName(inLayer) + "'"
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
layername = "'" + GdalUtils.ogrLayerName(inLayer) + "'"

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value
output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)

layername = ogrLayerName(inLayer)
layername = GdalUtils.ogrLayerName(inLayer)

arguments = []
arguments.append(output)
Expand Down
7 changes: 3 additions & 4 deletions python/plugins/processing/algs/gdal/ogr2ogr.py
Expand Up @@ -37,7 +37,6 @@
from processing.algs.gdal.GdalUtils import GdalUtils

from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


FORMATS = [
Expand Down Expand Up @@ -124,7 +123,7 @@ def group(self):

def getConsoleCommands(self, parameters, context, feedback):
inLayer = self.getParameterValue(self.INPUT_LAYER)
ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value
Expand All @@ -136,7 +135,7 @@ def getConsoleCommands(self, parameters, context, feedback):
outFile += ext
output.value = outFile

output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)
options = str(self.getParameterValue(self.OPTIONS))

if outFormat == 'SQLite' and os.path.isfile(output):
Expand All @@ -151,7 +150,7 @@ def getConsoleCommands(self, parameters, context, feedback):

arguments.append(output)
arguments.append(ogrLayer)
arguments.append(ogrLayerName(inLayer))
arguments.append(GdalUtils.ogrLayerName(inLayer))

commands = []
if isWindows():
Expand Down
7 changes: 3 additions & 4 deletions python/plugins/processing/algs/gdal/ogr2ogrbuffer.py
Expand Up @@ -37,7 +37,6 @@

from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


class Ogr2OgrBuffer(GdalAlgorithm):
Expand Down Expand Up @@ -94,13 +93,13 @@ def getConsoleCommands(self, parameters, context, feedback):
multi = self.getParameterValue(self.MULTI)
options = self.getParameterValue(self.OPTIONS)

ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
layername = ogrLayerName(inLayer)
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
layername = GdalUtils.ogrLayerName(inLayer)

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value

output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)

arguments = []
arguments.append(output)
Expand Down
11 changes: 5 additions & 6 deletions python/plugins/processing/algs/gdal/ogr2ogrclip.py
Expand Up @@ -35,7 +35,6 @@

from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


class Ogr2OgrClip(GdalAlgorithm):
Expand Down Expand Up @@ -69,28 +68,28 @@ def group(self):

def getConsoleCommands(self, parameters, context, feedback):
inLayer = self.getParameterValue(self.INPUT_LAYER)
ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
clipLayer = self.getParameterValue(self.CLIP_LAYER)
ogrClipLayer = ogrConnectionString(clipLayer, context)[1:-1]
ogrClipLayer = GdalUtils.ogrConnectionString(clipLayer, context)[1:-1]

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value

output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)
options = str(self.getParameterValue(self.OPTIONS))

arguments = []
arguments.append('-clipsrc')
arguments.append(ogrClipLayer)
arguments.append("-clipsrclayer")
arguments.append(ogrLayerName(clipLayer))
arguments.append(GdalUtils.ogrLayerName(clipLayer))

if options is not None and len(options.strip()) > 0:
arguments.append(options)

arguments.append(output)
arguments.append(ogrLayer)
arguments.append(ogrLayerName(inLayer))
arguments.append(GdalUtils.ogrLayerName(inLayer))

commands = []
if isWindows():
Expand Down
7 changes: 3 additions & 4 deletions python/plugins/processing/algs/gdal/ogr2ogrclipextent.py
Expand Up @@ -35,7 +35,6 @@
from processing.algs.gdal.GdalUtils import GdalUtils

from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


class Ogr2OgrClipExtent(GdalAlgorithm):
Expand Down Expand Up @@ -69,15 +68,15 @@ def group(self):

def getConsoleCommands(self, parameters, context, feedback):
inLayer = self.getParameterValue(self.INPUT_LAYER)
ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
clipExtent = self.getParameterValue(self.CLIP_EXTENT)
if not clipExtent:
clipExtent = QgsProcessingUtils.combineLayerExtents([inLayer])

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value

output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)
options = str(self.getParameterValue(self.OPTIONS))

arguments = []
Expand All @@ -94,7 +93,7 @@ def getConsoleCommands(self, parameters, context, feedback):

arguments.append(output)
arguments.append(ogrLayer)
arguments.append(ogrLayerName(inLayer))
arguments.append(GdalUtils.ogrLayerName(inLayer))

commands = []
if isWindows():
Expand Down
7 changes: 3 additions & 4 deletions python/plugins/processing/algs/gdal/ogr2ogrdissolve.py
Expand Up @@ -36,7 +36,6 @@

from processing.tools import dataobjects
from processing.tools.system import isWindows
from processing.tools.vector import ogrConnectionString, ogrLayerName


class Ogr2OgrDissolve(GdalAlgorithm):
Expand Down Expand Up @@ -103,13 +102,13 @@ def getConsoleCommands(self, parameters, context, feedback):
statsatt = self.getParameterValue(self.STATSATT)
options = self.getParameterValue(self.OPTIONS)

ogrLayer = ogrConnectionString(inLayer, context)[1:-1]
layername = ogrLayerName(inLayer)
ogrLayer = GdalUtils.ogrConnectionString(inLayer, context)[1:-1]
layername = GdalUtils.ogrLayerName(inLayer)

output = self.getOutputFromName(self.OUTPUT_LAYER)
outFile = output.value

output = ogrConnectionString(outFile, context)
output = GdalUtils.ogrConnectionString(outFile, context)

arguments = []
arguments.append(output)
Expand Down

0 comments on commit e33647d

Please sign in to comment.