Skip to content
Permalink
Browse files

[processing] restore and fix extraction of OGR layer names

  • Loading branch information
alexbruy committed Nov 12, 2016
1 parent 2287230 commit 75bd622ccc582f0d81ea80206e1049c6afee4104
Showing with 96 additions and 33 deletions.
  1. +59 −3 python/plugins/processing/tests/ToolsTest.py
  2. +37 −30 python/plugins/processing/tools/vector.py
@@ -25,17 +25,33 @@

__revision__ = '$Format:%H$'

from qgis.testing import start_app, unittest
from processing.tests.TestData import points
from processing.tools import vector
import os
import shutil
import tempfile

from qgis.core import (QgsVectorLayer, QgsFeatureRequest)
from qgis.testing import start_app, unittest

from processing.core.ProcessingConfig import ProcessingConfig
from processing.tests.TestData import testDataPath, points
from processing.tools import vector

testDataPath = os.path.join(os.path.dirname(__file__), 'testdata')

start_app()


class VectorTest(unittest.TestCase):

@classmethod
def setUpClass(cls):
cls.cleanup_paths = []

@classmethod
def tearDownClass(cls):
for path in cls.cleanup_paths:
shutil.rmtree(path)

def testFeatures(self):
ProcessingConfig.initialize()

@@ -148,6 +164,46 @@ def testUniqueValues(self):

ProcessingConfig.setSettingValue(ProcessingConfig.USE_SELECTED, previous_value)

def testOgrLayerNameExtraction(self):
outdir = tempfile.mkdtemp()
self.cleanup_paths.append(outdir)

def _copyFile(dst):
shutil.copyfile(os.path.join(testDataPath, 'custom', 'grass7', 'weighted.csv'), dst)

# OGR provider - single layer
_copyFile(os.path.join(outdir, 'a.csv'))
name = vector.ogrLayerName(outdir)
self.assertEqual(name, 'a')

# OGR provider - multiple layers
_copyFile(os.path.join(outdir, 'b.csv'))
name = vector.ogrLayerName(outdir + '|layerid=0')
self.assertEqual(name, 'b')
name = vector.ogrLayerName(outdir + '|layerid=1')
self.assertEqual(name, 'a')

name = vector.ogrLayerName(outdir + '|layerid=2')
self.assertIsNone(name)

# OGR provider - layername takes precedence
name = vector.ogrLayerName(outdir + '|layername=f')
self.assertEqual(name, 'f')

name = vector.ogrLayerName(outdir + '|layerid=0|layername=f')
self.assertEqual(name, 'f')

name = vector.ogrLayerName(outdir + '|layername=f|layerid=0')
self.assertEqual(name, 'f')

# SQLiite provider
name = vector.ogrLayerName('dbname=\'/tmp/x.sqlite\' table="t" (geometry) sql=')
self.assertEqual(name, 't')

# PostgreSQL provider
name = vector.ogrLayerName('port=5493 sslmode=disable key=\'edge_id\' srid=0 type=LineString table="city_data"."edge" (geom) sql=')
self.assertEqual(name, 'city_data.edge')


if __name__ == '__main__':
unittest.main()
@@ -40,6 +40,7 @@
import io

import psycopg2
from osgeo import ogr

from qgis.PyQt.QtCore import QVariant, QSettings
from qgis.core import (Qgis, QgsFields, QgsField, QgsGeometry, QgsRectangle, QgsWkbTypes,
@@ -536,41 +537,47 @@ def ogrConnectionString(uri):
return '"' + ogrstr + '"'


# The uri parameter is an URI from any QGIS provider,
# so could have different formats.
# Example formats:
#
# -- PostgreSQL provider
# port=5493 sslmode=disable key='edge_id' srid=0 type=LineString table="city_data"."edge" (geom) sql=
#
# -- Spatialite provider
# dbname='/tmp/x.sqlite' table="t" (geometry) sql='
#
# -- OGR provider (single-layer directory)
# /tmp/x.gdb
#
# -- OGR provider (multi-layer directory)
# /tmp/x.gdb|layerid=1
#
# -- OGR provider (multi-layer directory)
# /tmp/x.gdb|layername=thelayer
#
def ogrLayerName(uri):
if 'host' in uri:
regex = re.compile('(table=")(.+?)(\.)(.+?)"')
r = regex.search(uri)
return '"' + r.groups()[1] + '.' + r.groups()[3] + '"'
elif 'dbname' in uri:
regex = re.compile('(table=")(.+?)"')
r = regex.search(uri)
return r.groups()[1]
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=)(.*)')
regex = re.compile('(layername=)([^|]*)')
r = regex.search(uri)
return r.groups()[1]
else:
return os.path.basename(os.path.splitext(uri)[0])

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


class VectorWriter(object):

0 comments on commit 75bd622

Please sign in to comment.
You can’t perform that action at this time.