diff --git a/tests/data/polygon.geojson b/tests/data/polygon.geojson new file mode 100644 index 0000000..adfa55a --- /dev/null +++ b/tests/data/polygon.geojson @@ -0,0 +1,9 @@ +{ +"type": "FeatureCollection", +"name": "test_polygon", +"features": [ +{ +"type": "Feature", + "properties": { "id": 1, "name": "éù%@ > 1" }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 3.80, 43.50 ], [ 3.80, 43.60 ], [ 3.90, 43.60 ], [ 3.90, 43.50 ], [ 3.80, 43.50 ] ] ] } } +] +} diff --git a/tests/data/polygon.qgs b/tests/data/polygon.qgs new file mode 100644 index 0000000..7ea970b --- /dev/null +++ b/tests/data/polygon.qgs @@ -0,0 +1,376 @@ + + + + + + + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + polygon_d135b711_320e_40e1_848f_c601703deaf2 + + + + + + + + + + degrees + + 3.79749999999999943 + 43.49749999999999517 + 3.90249999999999986 + 43.60249999999999915 + + 0 + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + + + + + + + + + degrees + + 0 + 0 + 0 + 0 + + 0 + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + degrees + + 0 + 0 + 0 + 0 + + 0 + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + degrees + + 0 + 0 + 0 + 0 + + 0 + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + + + 3.79999999999999982 + 43.5 + 3.89999999999999991 + 43.60000000000000142 + + polygon_d135b711_320e_40e1_848f_c601703deaf2 + ./polygon.geojson + + + + polygon + + + GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["unknown"],AREA["World"],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + dataset + + + + + + + + + + 0 + 0 + + + + + false + + + + + ogr + + + + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + generatedlayout + + + + + + + + + + + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + EPSG:7030 + + + m2 + meters + + + 50 + 16 + 30 + false + false + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 1 + + + + + + + + + + + + + Etienne + 2021-01-06T18:39:46 + + + + + + + + \ No newline at end of file diff --git a/tests/test_getcapabilities.py b/tests/test_getcapabilities.py index b6427bf..ad876ca 100644 --- a/tests/test_getcapabilities.py +++ b/tests/test_getcapabilities.py @@ -27,3 +27,26 @@ def test_getcapabilties(client): expected = ['SHP', 'KML', 'GPKG'] for output_format in expected: assert "{}".format(output_format) in data, output_format + + +def test_getcapabilties_geom(client): + """ Test GetCapabilities with polygon layer. """ + query_string = ( + "?" + "SERVICE=WFS&" + "VERSION=1.1.0&" + "REQUEST=GetCapabilities&" + "MAP=polygon.qgs" + ).format(PROJECT) + rv = client.get(query_string, PROJECT) + assert rv.status_code == 200 + assert rv.headers.get('Content-Type', '').find('text/xml') == 0 + + data = rv.content.decode('utf-8') + + expected = ['SHP', 'KML', 'GPKG'] + for output_format in expected: + assert "{}".format(output_format) in data, output_format + + print(data) + assert False diff --git a/wfsOutputExtension/wfs_filter.py b/wfsOutputExtension/wfs_filter.py index a32166d..5d78996 100644 --- a/wfsOutputExtension/wfs_filter.py +++ b/wfsOutputExtension/wfs_filter.py @@ -1,7 +1,6 @@ -__copyright__ = 'Copyright 2020, 3Liz' +__copyright__ = 'Copyright 2021, 3Liz' __license__ = 'GPL version 3' __email__ = 'info@3liz.org' -__revision__ = '$Format:%H$' import tempfile import time @@ -20,6 +19,7 @@ QgsProject, QgsVectorFileWriter, QgsVectorLayer, + QgsWkbTypes, ) from qgis.PyQt.QtCore import QFile, QTemporaryFile from qgis.server import QgsServerFilter @@ -32,7 +32,14 @@ 'ogrProvider': 'ESRI Shapefile', 'ogrDatasourceOptions': None, 'zip': True, - 'extToZip': ['shx', 'dbf', 'prj'] + 'extToZip': ['shx', 'dbf', 'prj'], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'tab': { 'contentType': 'application/x-zipped-tab', @@ -41,7 +48,14 @@ 'ogrProvider': 'Mapinfo File', 'ogrDatasourceOptions': None, 'zip': True, - 'extToZip': ['dat', 'map', 'id'] + 'extToZip': ['dat', 'map', 'id'], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'mif': { 'contentType': 'application/x-zipped-mif', @@ -50,7 +64,14 @@ 'ogrProvider': 'Mapinfo File', 'ogrDatasourceOptions': ['FORMAT=MIF'], 'zip': True, - 'extToZip': ['mid'] + 'extToZip': ['mid'], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'kml': { 'contentType': 'application/vnd.google-earth.kml+xml', @@ -59,7 +80,14 @@ 'ogrProvider': 'KML', 'ogrDatasourceOptions': None, 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'gpkg': { 'contentType': 'application/geopackage+vnd.sqlite3', @@ -68,7 +96,14 @@ 'ogrProvider': 'GPKG', 'ogrDatasourceOptions': None, 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'gpx': { 'contentType': 'application/gpx+xml', @@ -81,7 +116,11 @@ 'GPX_EXTENSION_NS_URL=http://osgeo.org/gdal', ], 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + ], }, 'ods': { 'contentType': 'application/vnd.oasis.opendocument.spreadsheet', @@ -90,7 +129,14 @@ 'ogrProvider': 'ODS', 'ogrDatasourceOptions': None, 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'xlsx': { 'contentType': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', @@ -99,7 +145,14 @@ 'ogrProvider': 'XLSX', 'ogrDatasourceOptions': None, 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], }, 'csv': { 'contentType': 'text/csv', @@ -108,7 +161,14 @@ 'ogrProvider': 'CSV', 'ogrDatasourceOptions': None, 'zip': False, - 'extToZip': [] + 'extToZip': [], + 'geom': [ + QgsWkbTypes.Point, + QgsWkbTypes.LineGeometry, + QgsWkbTypes.Polygon, + QgsWkbTypes.NullGeometry, + QgsWkbTypes.UnknownGeometry, + ], } } @@ -370,6 +430,8 @@ def responseComplete(self): if request == 'GETCAPABILITIES': data = handler.body().data() + print('GET CAPABILITIES') + print(data) dom = minidom.parseString(data) ver = dom.documentElement.attributes['version'].value if ver == '1.0.0': @@ -392,6 +454,24 @@ def responseComplete(self): if paramNode.attributes['name'].value != 'outputFormat': continue for k in WFSFormats.keys(): + # if WFSFormats.get(k).get('geom') + v_node = dom.createElement('ows:Value') + v_text = dom.createTextNode(k.upper()) + v_node.appendChild(v_text) + paramNode.appendChild(v_node) + for opmNode in dom.getElementsByTagName('ows:OperationsMetadata'): + for opNode in opmNode.getElementsByTagName('ows:Operation'): + if 'name' not in opNode.attributes: + continue + if opNode.attributes['name'].value != 'GetFeature': + continue + for paramNode in opNode.getElementsByTagName('ows:Parameter'): + if 'name' not in paramNode.attributes: + continue + if paramNode.attributes['name'].value != 'outputFormat': + continue + for k in WFSFormats.keys(): + # if WFSFormats.get(k).get('geom') v_node = dom.createElement('ows:Value') v_text = dom.createTextNode(k.upper()) v_node.appendChild(v_text)