From 0a0cd200ce3145b63777b6fccc4c8e126fec5ee2 Mon Sep 17 00:00:00 2001 From: Kay Warrie Date: Mon, 29 Apr 2019 14:19:20 +0200 Subject: [PATCH] WFS with exotic CRS, Improved Download --- dataCatalog.py | 58 ++++++++++++++++++++++++++++------------ doc/source/Changelog.rst | 12 +++++++++ doc/source/conf.py | 4 +-- metadata.txt | 2 +- metadataParser.py | 43 ++++++++++++++++++++--------- 5 files changed, 87 insertions(+), 32 deletions(-) diff --git a/dataCatalog.py b/dataCatalog.py index b5a4afb..b811398 100644 --- a/dataCatalog.py +++ b/dataCatalog.py @@ -9,7 +9,7 @@ from .settings import settings from . import metadataParser as metadata from .metadataParser import MDReader, MDdata, getWmsLayerNames, getWFSLayerNames, makeWFSuri, getWMTSlayersNames, makeWMTSuri, getWCSlayerNames, makeWCSuri -import sys, os, webbrowser, json +import sys, os, webbrowser, json, urllib class dataCatalog(QDialog): """The dialog for the catalog searchwindow @@ -311,15 +311,14 @@ def complexWFS(self): :return: True if user wants to download else false. """ msg = """ - Deze laag kon niet correct ingeladen worden als WFS-laag, het vermoedelijk gaat om een service met complexe features.
- U kunt de laag downloaden voor het huidge kaartbeeld als GML. Mogelijk worden ook dan niet alle gegeven correct waergegeven. + Deze laag kon niet correct ingeladen worden als WFS-laag, omdat het vermoedelijk gaat om een service met complexe features.
+ U kunt de laag downloaden voor het huidige kaartbeeld als GML. Mogelijk worden ook dan niet alle gegevens correct weergegeven. -

U kunt eventueel de plugin - GML Application Schema Toolbox - installeren een WFS die complexe features correcter te raadplegen." +

U kunt eventueel de plugin + GML Application Schema Toolbox installeren, een plugin die GML met complexe features kan laden. Na installatie, vindt u deze tool op de menubalk onder: Plugins > QGIS GML Application Schema Toolbox > Wizard -

Wilt u in de plaats proberen deze laag te downloaden vor het huidge kaartbeeld en in te laden? +

Klik op Ja/Yes als u wilt proberen deze laag te downloaden voor het huidige kaartbeeld en vervolgens in te laden? """ buttonDlg = QMessageBox.warning(self.iface.mainWindow(), "Kan features niet correct lezen.", @@ -358,7 +357,21 @@ def dlWFS(self, url, layerName="", crs="EPSG:4326", wfsVersion="2.0.0"): bbox = [ eMin.x(), eMin.y(), eMax.x(), eMax.y() ] metadata.downloadWFS(url, layerName, fileName, crs, 50000, wfsVersion, bbox, self.s.proxyUrl, 120) - layer = self.iface.addVectorLayer(fileName , layerName, "ogr") + + if metadata.xmlIsEmpty( fileName ): + with open(fileName, 'r') as file: + xmlStr = file.read() + + msg = QMessageBox() + msg.setIcon(QMessageBox.Warning) + msg.setText("De GML-file bevat geen data:
Wellicht is er geen intersecterende data.") + msg.setWindowTitle("Geen geldige GML-file") + msg.setDetailedText(xmlStr) + msg.setStandardButtons(QMessageBox.Ok) + msg.exec_() + + else: + self.iface.addVectorLayer(fileName , layerName, "ogr") def addWMTS(self): @@ -431,16 +444,27 @@ def dlClicked(self): return if len(self.dl) == 1: - self.openUrl( self.dl[0][1] ) - return + layerTitle = self.dl[0][0] + dlName = self.dl[0][1] + else: + layerTitle, accept = QInputDialog.getItem(self, "Laag downloaden", + "Kies een download", [n[0] for n in self.dl], editable=0) + if not accept: + return + else: + dlName = [n[1] for n in self.dl if n[0] == layerTitle ][0] - layerTitle, accept = QInputDialog.getItem(self, "Laag downloaden", - "Kies een download", [n[0] for n in self.dl], editable=0) - if not accept: - return - - dlName = [n[1] for n in self.dl if n[0] == layerTitle ][0] - self.openUrl( dlName ) + file_name, file_ext = os.path.splitext( os.path.basename( dlName ).split("?")[0] ) + if file_ext == "": + file_name = layerTitle + ".xml" + file_ext = ".xml" + + flname = os.path.join( os.path.expanduser("~") , file_name ) + + fileName, _ = QFileDialog.getSaveFileName(self,"Opslaan als", flname, "{0} (*{0});;All Files (*)".format(file_ext) ) + if fileName: + urllib.request.urlretrieve(dlName, fileName) + def clean(self): """Reset the UI to initial positions""" diff --git a/doc/source/Changelog.rst b/doc/source/Changelog.rst index 803ebd6..1d15272 100644 --- a/doc/source/Changelog.rst +++ b/doc/source/Changelog.rst @@ -1,6 +1,18 @@ Changelog ========= +Version 2.5 +----------- +- Further improved WFS with exotic CRS +- Improved Download-function: no longer use webbrowser. +- Changed some maessages a request of customer + +Version 2.4 +----------- +- Improved WFS CRS handling including working with inverted axis. +- User notificaton improvements. +- Spell fixes. + Version 2.3 ------------ - Option to download WFS instead of loading as a service. diff --git a/doc/source/conf.py b/doc/source/conf.py index d9e008f..f63b310 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -24,9 +24,9 @@ author = u'Kay Warrie' # The short X.Y version -version = u'2.3' +version = u'2.5' # The full version, including alpha/beta/rc tags -release = u'Version 2.3 for QGIS 3' +release = u'Version 2.5 for QGIS 3' # -- General configuration --------------------------------------------------- diff --git a/metadata.txt b/metadata.txt index ee8eedb..ece7dc6 100644 --- a/metadata.txt +++ b/metadata.txt @@ -6,7 +6,7 @@ qgisMinimumVersion=3.0 description= EN: A tool to query INSPIRE datasets of the Dutch national dataportal "National Georegistry (NGR)" and add it to QGIS. NL: Een tool om de INSPIRE datasets uit het Nationaal Georegister te bevragen en toe te voegen aan QGIS. -version=2.3 +version=2.5 author=Kay Warrie email=kaywarrie@gmail.com diff --git a/metadataParser.py b/metadataParser.py index 449e614..baa9d24 100644 --- a/metadataParser.py +++ b/metadataParser.py @@ -68,7 +68,7 @@ def _findDownloads(self , node): return [] if len(links) > 0 and len(atoms) == 0: - results = [[n.attrib["name"], n.text ] for n in links] + results = [ [ n.attrib["name"] if "name" in n.attrib else n.text , n.text ] for n in links ] return results atom = atoms[0] @@ -554,7 +554,7 @@ def testComplex(url, typeName, version="1.1.0", proxyUrl='', timeout=5 ): return False except: - print("Error in finding out WFS-complex:" + str( sys.exc_info()[1] ) ) + print("Error in finding out WFS-complex:" + str( sys.exc_info() ) ) return False def downloadWFS(url, typeName, outputLocation, crs="EPSG:4326", maxCount=10000, version="1.1.0", bbox=[], proxyUrl='', timeout=5): @@ -574,21 +574,25 @@ def downloadWFS(url, typeName, outputLocation, crs="EPSG:4326", maxCount=10000, if version not in ["1.1.0", "2.0.0"]: version = "1.1.0" - if version == "1.1.0": countStr = "maxFeatures" - if version == "2.0.0": countStr = "count" + if version == "1.1.0": + typeNameStr = "TYPENAME" + countStr = "maxFeatures" + if version == "2.0.0": + typeNameStr = "TYPENAMES" + countStr = "count" if bbox: bboxS = ",".join([str(n) for n in bbox]) # Thijs Brentjens, suggestiont for workaround different axis order for 4258, 4326 # TODO: which CRSes should take into account different axis order for WFS download? - if 'http://www.opengis.net/def/crs/EPSG' in crs and ('4258' in crs or '4326' in crs) and bbox: - bboxS = str(bbox[1])+','+str(bbox[0])+','+str(bbox[3])+','+str(bbox[2]) - elif bbox: bboxS = ",".join([str(n) for n in bbox]) + if 'EPSG' in crs and ('4258' in crs or '4326' in crs) and bbox: + bboxS = str(bbox[1])+','+str(bbox[0])+','+str(bbox[3])+','+str(bbox[2]) + elif bbox: bboxS = ",".join([str(n) for n in bbox]) baseUrl = url.split("?")[0] - qryString = "?{}={}&SERVICE=WFS&VERSION={}&REQUEST=GetFeature&TYPENAME={}&srsName={}&bbox={}".format( - countStr, maxCount, version, typeName, crs, bboxS) + qryString = "?{}={}&SERVICE=WFS&VERSION={}&REQUEST=GetFeature&{}={}&srsName={}&bbox={}".format( + countStr, maxCount, version, typeNameStr, typeName, crs, bboxS) fullUrl = baseUrl + qryString - + if proxyUrl: proxy = urllib.request.ProxyHandler({'http': proxyUrl}) auth = urllib.request.HTTPBasicAuthHandler() @@ -596,12 +600,27 @@ def downloadWFS(url, typeName, outputLocation, crs="EPSG:4326", maxCount=10000, response = opener.open(fullUrl, timeout=timeout) else: response = urllib.request.urlopen(fullUrl, timeout=timeout) - + with response, open(outputLocation, 'wb') as out_file: data = response.read() out_file.write(data) - + return outputLocation +def xmlIsEmpty(xml_file, gmlException=True): + """test if a xml file contais data + :param xml_file: a path to a xml file. + :param gmlException: also return if gmlException + return: True if empty else False + """ + try: + tree = ET.parse(xml_file) + root = tree.getroot() + if gmlException and "ExceptionReport" in root.tag: + return True + + return not len(root) + except: + return True