From 260885e0ccbde87b15b1657630eef7a0f03094a8 Mon Sep 17 00:00:00 2001 From: Etienne Trimaille Date: Wed, 1 Sep 2021 15:51:09 +0200 Subject: [PATCH] Processing - Always reproject the extent to 4326 when fetching parameters --- Makefile | 4 ++ .../advanced/build_query.py | 26 +++-------- .../advanced/raw_query.py | 24 +++------- QuickOSM/quick_osm_processing/build_input.py | 31 +++++++++---- .../quick_osm_processing/quickosm_process.py | 5 +- QuickOSM/test/test_processing_network.py | 46 ++++++++++++++++++- 6 files changed, 87 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index dae4992a..23b0b8db 100644 --- a/Makefile +++ b/Makefile @@ -17,3 +17,7 @@ processing-doc: code-doc: cd .docker && ./code_doc.sh + +lint: + flake8 + pylint --rcfile=setup.cfg ./QuickOSM diff --git a/QuickOSM/quick_osm_processing/advanced/build_query.py b/QuickOSM/quick_osm_processing/advanced/build_query.py index f6e43a89..f98ddf6e 100644 --- a/QuickOSM/quick_osm_processing/advanced/build_query.py +++ b/QuickOSM/quick_osm_processing/advanced/build_query.py @@ -1,25 +1,18 @@ """Processing algorithm for building a query.""" +__copyright__ = 'Copyright 2021, 3Liz' +__license__ = 'GPL version 3' +__email__ = 'info@3liz.org' + from typing import Dict from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm -from qgis.core import ( - QgsCoordinateReferenceSystem, - QgsCoordinateTransform, - QgsProcessingAlgorithm, - QgsProcessingOutputString, - QgsProject, -) +from qgis.core import QgsProcessingAlgorithm, QgsProcessingOutputString from QuickOSM.core.query_factory import QueryFactory from QuickOSM.core.query_preparation import QueryPreparation from QuickOSM.definitions.osm import QueryLanguage from QuickOSM.qgis_plugin_tools.tools.i18n import tr - -__copyright__ = 'Copyright 2021, 3Liz' -__license__ = 'GPL version 3' -__email__ = 'info@3liz.org' - from QuickOSM.quick_osm_processing.build_input import ( BuildBasedAroundAreaQuery, BuildBasedExtentQuery, @@ -86,7 +79,7 @@ def build_query(self) -> Dict[str, str]: query_preparation = QueryPreparation( raw_query, area=self.area, - extent=self.extent, + extent=self.extent, # It must be already in 4326 when fetching parameters overpass=self.server ) raw_query = query_preparation.prepare_query() @@ -177,11 +170,4 @@ def processAlgorithm(self, parameters, context, feedback) -> Dict[str, str]: self.feedback = feedback self.fetch_based_parameters(parameters, context) - crs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) - - crs_4326 = QgsCoordinateReferenceSystem(4326) - transform = QgsCoordinateTransform( - crs, crs_4326, QgsProject.instance()) - self.extent = transform.transform(self.extent) - return self.build_query() diff --git a/QuickOSM/quick_osm_processing/advanced/raw_query.py b/QuickOSM/quick_osm_processing/advanced/raw_query.py index bc22332d..66dd5895 100644 --- a/QuickOSM/quick_osm_processing/advanced/raw_query.py +++ b/QuickOSM/quick_osm_processing/advanced/raw_query.py @@ -1,22 +1,15 @@ """Generate a raw query.""" +__copyright__ = 'Copyright 2021, 3Liz' +__license__ = 'GPL version 3' +__email__ = 'info@3liz.org' + from typing import Dict -from qgis.core import ( - QgsCoordinateReferenceSystem, - QgsCoordinateTransform, - QgsProcessingAlgorithm, - QgsProcessingOutputString, - QgsProject, -) +from qgis.core import QgsProcessingAlgorithm, QgsProcessingOutputString from QuickOSM.core.query_preparation import QueryPreparation from QuickOSM.qgis_plugin_tools.tools.i18n import tr - -__copyright__ = 'Copyright 2021, 3Liz' -__license__ = 'GPL version 3' -__email__ = 'info@3liz.org' - from QuickOSM.quick_osm_processing.build_input import BuildRaw @@ -70,16 +63,11 @@ def processAlgorithm(self, parameters, context, feedback) -> Dict[str, str]: self.feedback = feedback self.fetch_based_parameters(parameters, context) - crs_4326 = QgsCoordinateReferenceSystem(4326) - transform = QgsCoordinateTransform( - self.crs, crs_4326, QgsProject.instance()) - self.extent = transform.transform(self.extent) - self.feedback.pushInfo('Prepare the url.') query_preparation = QueryPreparation( self.query, - extent=self.extent, + extent=self.extent, # It should be in 4326 already in this stage area=self.area, overpass=self.server ) diff --git a/QuickOSM/quick_osm_processing/build_input.py b/QuickOSM/quick_osm_processing/build_input.py index 2add71b7..de96205a 100644 --- a/QuickOSM/quick_osm_processing/build_input.py +++ b/QuickOSM/quick_osm_processing/build_input.py @@ -1,17 +1,19 @@ """Set up the parameters for the processing algorithms.""" +__copyright__ = 'Copyright 2021, 3Liz' +__license__ = 'GPL version 3' +__email__ = 'info@3liz.org' + from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm from qgis.core import ( + QgsCoordinateReferenceSystem, + QgsCoordinateTransform, QgsProcessingParameterDefinition, QgsProcessingParameterExtent, QgsProcessingParameterNumber, QgsProcessingParameterString, ) -__copyright__ = 'Copyright 2021, 3Liz' -__license__ = 'GPL version 3' -__email__ = 'info@3liz.org' - from QuickOSM.core.utilities.tools import get_setting from QuickOSM.definitions.osm import QueryType from QuickOSM.definitions.overpass import OVERPASS_SERVERS @@ -30,6 +32,7 @@ def __init__(self): self.feedback = None self.area = None self.extent = None + self.extent_crs = None self.server = None self.timeout = None @@ -74,14 +77,20 @@ def __init__(self): """Constructor""" super().__init__() self.query = None - self.crs = None def fetch_based_parameters(self, parameters, context): """Get the parameters.""" super().fetch_based_parameters(parameters, context) self.query = self.parameterAsString(parameters, self.QUERY, context) self.extent = self.parameterAsExtent(parameters, self.EXTENT, context) - self.crs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) + self.extent_crs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) + + # Always transform to 4326 + crs_4326 = QgsCoordinateReferenceSystem(4326) + transform = QgsCoordinateTransform(self.extent_crs, crs_4326, context.project()) + self.extent = transform.transform(self.extent) + self.extent_crs = crs_4326 + self.area = self.parameterAsString(parameters, self.AREA, context) def add_top_parameters(self): @@ -241,12 +250,18 @@ def fetch_based_parameters(self, parameters, context): """Get the parameters.""" super().fetch_based_parameters(parameters, context) self.extent = self.parameterAsExtent(parameters, self.EXTENT, context) + self.extent_crs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) + + # Always transform to 4326 + crs_4326 = QgsCoordinateReferenceSystem(4326) + transform = QgsCoordinateTransform(self.extent_crs, crs_4326, context.project()) + self.extent = transform.transform(self.extent) + self.extent_crs = crs_4326 def add_top_parameters(self): """Set up the parameter.""" super().add_top_parameters() param = QgsProcessingParameterExtent(self.EXTENT, tr('Extent'), optional=False) - help_string = tr('The extent as a rectangle to use when building the query.') - param.setHelp(help_string) + param.setHelp(tr('The extent as a rectangle to use when building the query.')) self.addParameter(param) diff --git a/QuickOSM/quick_osm_processing/quickosm_process.py b/QuickOSM/quick_osm_processing/quickosm_process.py index 9ecbe74d..4d6e3ee1 100644 --- a/QuickOSM/quick_osm_processing/quickosm_process.py +++ b/QuickOSM/quick_osm_processing/quickosm_process.py @@ -12,6 +12,7 @@ QgsProcessingOutputVectorLayer, QgsProcessingParameterFileDestination, QgsProcessingUtils, + QgsReferencedRectangle, ) from qgis.PyQt.QtGui import QIcon @@ -248,7 +249,7 @@ def processAlgorithm(self, parameters, context, feedback): "quickosm:buildrawquery", { 'AREA': self.area, - 'EXTENT': self.extent, + 'EXTENT': QgsReferencedRectangle(self.extent, self.extent_crs), 'QUERY': self.query, 'SERVER': self.server }, @@ -430,7 +431,7 @@ def processAlgorithm(self, parameters, context, feedback): query = processing.run( "quickosm:buildqueryextent", { - 'EXTENT': self.extent, + 'EXTENT': QgsReferencedRectangle(self.extent, self.extent_crs), 'KEY': self.key, 'SERVER': self.server, 'TIMEOUT': self.timeout, diff --git a/QuickOSM/test/test_processing_network.py b/QuickOSM/test/test_processing_network.py index ef0cf949..88cb603d 100644 --- a/QuickOSM/test/test_processing_network.py +++ b/QuickOSM/test/test_processing_network.py @@ -2,7 +2,13 @@ import processing -from qgis.core import QgsApplication, QgsVectorLayer +from qgis.core import ( + QgsApplication, + QgsCoordinateReferenceSystem, + QgsProcessingContext, + QgsProject, + QgsVectorLayer, +) from qgis.testing import unittest from QuickOSM.qgis_plugin_tools.tools.resources import plugin_test_data_path @@ -193,6 +199,44 @@ def test_process_extent_query(self): self.assertIsInstance(result['OUTPUT_MULTILINESTRINGS'], QgsVectorLayer) self.assertIsInstance(result['OUTPUT_MULTIPOLYGONS'], QgsVectorLayer) + def test_reprojection_extent_query(self): + """Test for the reprojection from the project CRS.""" + # In processing.run, we can see some 2154 coordinates. + # In the query, coordinates in 4326 + handler = SequentialHandler() + handler.add( + 'GET', + '/interpreter?data=[out:xml]%20[timeout:25];%0A(%0A%20%20%20%20node[%22landuse%22]' + '(%2045.0843,-0.3832,45.09649,-0.36385);%0A%20%20%20%20way[%22landuse%22]' + '(%2045.0843,-0.3832,45.09649,-0.36385);%0A%20%20%20%20relation[%22landuse%22]' + '(%2045.0843,-0.3832,45.09649,-0.36385);%0A);%0A(._;%3E;);%0Aout%20body;&info=QgisQuickOSMPlugin', + 200, + {'Content-type': 'text/xml'}, + open(plugin_test_data_path('overpass', 'empty_osm_file.xml'), 'r', encoding='utf8').read(), + ) + project = QgsProject() + project.setCrs(QgsCoordinateReferenceSystem(2154)) + context = QgsProcessingContext() + context.setProject(project) + + with install_http_handler(handler): + result = processing.run( + 'quickosm:downloadosmdataextentquery', + { + 'KEY': 'landuse', + 'VALUE': '', + 'EXTENT': '433888.4776000,435466.5863000,6448484.3786000,6449771.2615000 [EPSG:2154]', + 'TIMEOUT': 25, + 'SERVER': 'http://localhost:{}/interpreter'.format(self.port), + }, + context=context + ) + + self.assertIsInstance(result['OUTPUT_POINTS'], QgsVectorLayer) + self.assertIsInstance(result['OUTPUT_LINES'], QgsVectorLayer) + self.assertIsInstance(result['OUTPUT_MULTILINESTRINGS'], QgsVectorLayer) + self.assertIsInstance(result['OUTPUT_MULTIPOLYGONS'], QgsVectorLayer) + if __name__ == '__main__': unittest.main()