Skip to content

Commit

Permalink
WFS with exotic CRS, Improved Download
Browse files Browse the repository at this point in the history
  • Loading branch information
warrieka committed Apr 29, 2019
1 parent 0ee7953 commit 0a0cd20
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 32 deletions.
58 changes: 41 additions & 17 deletions dataCatalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.<br/>
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.<br/>
U kunt de laag downloaden voor het huidige kaartbeeld als GML. Mogelijk worden ook dan niet alle gegevens correct weergegeven.
<br/><br/>U kunt eventueel de plugin
<a href='https://plugins.qgis.org/plugins/gml_application_schema_toolbox'>GML Application Schema Toolbox</a>
installeren een WFS die complexe features correcter te raadplegen."
<br/><br/>U kunt eventueel de plugin <a href='https://plugins.qgis.org/plugins/gml_application_schema_toolbox'>
GML Application Schema Toolbox</a> installeren, een plugin die GML met complexe features kan laden.
Na installatie, vindt u deze tool op de menubalk onder: <strong>Plugins > QGIS GML Application Schema Toolbox > Wizard</strong>
<br/><br/> Wilt u in de plaats proberen deze laag te downloaden vor het huidge kaartbeeld en in te laden?
<br/><br/>Klik op <em>Ja/Yes</em> 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.",
Expand Down Expand Up @@ -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("<strong>De GML-file bevat geen data:</strong><br/> 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):
Expand Down Expand Up @@ -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"""
Expand Down
12 changes: 12 additions & 0 deletions doc/source/Changelog.rst
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 2 additions & 2 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion metadata.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 protected]

Expand Down
43 changes: 31 additions & 12 deletions metadataParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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):
Expand All @@ -574,34 +574,53 @@ 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()
opener = urllib.request.build_opener(proxy, auth, urllib.request.HTTPHandler)
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

0 comments on commit 0a0cd20

Please sign in to comment.