From a9f45400810f5c18e2fff9d0a4ff131409afe05e Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 8 Sep 2017 16:46:19 +1000 Subject: [PATCH] Remove 'precision' option from spatial relation processing algs Rationale: - the correct use for this option is unclear, and users are mistakenly using it as a 'tolerance' option - it's very likely to generate invalid geometries as a result of the snapping, causing unreliable results Given these substantial issues, it's safer to remove this option and require that users who need the snap to grid precision change explicitly do this via an extra model step before running the algorithm. --- .../processing/algs/qgis/ExtractByLocation.py | 10 ++-------- .../processing/algs/qgis/SelectByLocation.py | 8 -------- .../plugins/processing/algs/qgis/SpatialJoin.py | 10 ++-------- python/plugins/processing/tools/vector.py | 16 ---------------- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/python/plugins/processing/algs/qgis/ExtractByLocation.py b/python/plugins/processing/algs/qgis/ExtractByLocation.py index ef87e46e602..5a39563a7b5 100644 --- a/python/plugins/processing/algs/qgis/ExtractByLocation.py +++ b/python/plugins/processing/algs/qgis/ExtractByLocation.py @@ -42,7 +42,6 @@ class ExtractByLocation(QgisAlgorithm): INPUT = 'INPUT' INTERSECT = 'INTERSECT' PREDICATE = 'PREDICATE' - PRECISION = 'PRECISION' OUTPUT = 'OUTPUT' def tags(self): @@ -73,9 +72,6 @@ class ExtractByLocation(QgisAlgorithm): self.tr('Geometric predicate'), self.predicates, multiple=True)) - self.addParameter(ParameterNumber(self.PRECISION, - self.tr('Precision'), - 0.0, None, 0.0)) self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (location)'))) def name(self): @@ -90,7 +86,6 @@ class ExtractByLocation(QgisAlgorithm): filename = self.getParameterValue(self.INTERSECT) selectLayer = QgsProcessingUtils.mapLayerFromString(filename, context) predicates = self.getParameterValue(self.PREDICATE) - precision = self.getParameterValue(self.PRECISION) index = QgsProcessingUtils.createSpatialIndex(layer, context) @@ -106,13 +101,12 @@ class ExtractByLocation(QgisAlgorithm): features = QgsProcessingUtils.getFeatures(selectLayer, context) total = 100.0 / selectLayer.featureCount() if selectLayer.featureCount() else 0 for current, f in enumerate(features): - geom = vector.snapToPrecision(f.geometry(), precision) + geom = f.geometry() bbox = geom.boundingBox() - bbox.grow(0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for feat in layer.getFeatures(request): - tmpGeom = vector.snapToPrecision(feat.geometry(), precision) + tmpGeom = feat.geometry() res = False for predicate in predicates: if predicate == 'disjoint': diff --git a/python/plugins/processing/algs/qgis/SelectByLocation.py b/python/plugins/processing/algs/qgis/SelectByLocation.py index 15da9246422..870a3377cdd 100644 --- a/python/plugins/processing/algs/qgis/SelectByLocation.py +++ b/python/plugins/processing/algs/qgis/SelectByLocation.py @@ -31,12 +31,10 @@ from qgis.PyQt.QtGui import QIcon from qgis.core import (QgsGeometry, QgsFeatureRequest, - QgsProcessingUtils, QgsProcessing, QgsProcessingParameterVectorLayer, QgsProcessingParameterFeatureSource, QgsProcessingParameterEnum, - QgsProcessingParameterNumber, QgsProcessingOutputVectorLayer, QgsVectorLayer) @@ -52,7 +50,6 @@ class SelectByLocation(QgisAlgorithm): INPUT = 'INPUT' INTERSECT = 'INTERSECT' PREDICATE = 'PREDICATE' - PRECISION = 'PRECISION' METHOD = 'METHOD' OUTPUT = 'OUTPUT' @@ -98,9 +95,6 @@ class SelectByLocation(QgisAlgorithm): allowMultiple=True, defaultValue=[0])) self.addParameter(QgsProcessingParameterFeatureSource(self.INTERSECT, self.tr('By comparing to the features from'), types=[QgsProcessing.TypeVectorAnyGeometry])) - self.addParameter(QgsProcessingParameterNumber(self.PRECISION, - self.tr('Precision'), type=QgsProcessingParameterNumber.Double, - minValue=0.0, defaultValue=0.0)) self.addParameter(QgsProcessingParameterEnum(self.METHOD, self.tr('Modify current selection by'), options=self.methods, defaultValue=0)) @@ -121,7 +115,6 @@ class SelectByLocation(QgisAlgorithm): # we actually test the reverse of what the user wants (allowing us # to prepare geometries and optimise the algorithm) predicates = [self.reversed_predicates[self.predicates[i][0]] for i in self.parameterAsEnums(parameters, self.PREDICATE, context)] - precision = self.parameterAsDouble(parameters, self.PRECISION, context) if 'disjoint' in predicates: disjoint_set = select_layer.allFeatureIds() @@ -142,7 +135,6 @@ class SelectByLocation(QgisAlgorithm): engine = QgsGeometry.createGeometryEngine(f.geometry().geometry()) engine.prepareGeometry() bbox = f.geometry().boundingBox() - bbox.grow(0.51 * precision) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setFilterRect(bbox).setSubsetOfAttributes([]) for test_feat in select_layer.getFeatures(request): diff --git a/python/plugins/processing/algs/qgis/SpatialJoin.py b/python/plugins/processing/algs/qgis/SpatialJoin.py index 02c290dee68..5fe3cc2ce30 100644 --- a/python/plugins/processing/algs/qgis/SpatialJoin.py +++ b/python/plugins/processing/algs/qgis/SpatialJoin.py @@ -50,7 +50,6 @@ class SpatialJoin(QgisAlgorithm): TARGET = "TARGET" JOIN = "JOIN" PREDICATE = "PREDICATE" - PRECISION = 'PRECISION' SUMMARY = "SUMMARY" STATS = "STATS" KEEP = "KEEP" @@ -93,9 +92,6 @@ class SpatialJoin(QgisAlgorithm): self.tr('Geometric predicate'), self.predicates, multiple=True)) - self.addParameter(ParameterNumber(self.PRECISION, - self.tr('Precision'), - 0.0, None, 0.0)) self.addParameter(ParameterSelection(self.SUMMARY, self.tr('Attribute summary'), self.summarys)) self.addParameter(ParameterString(self.STATS, @@ -115,7 +111,6 @@ class SpatialJoin(QgisAlgorithm): target = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.TARGET), context) join = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.JOIN), context) predicates = self.getParameterValue(self.PREDICATE) - precision = self.getParameterValue(self.PRECISION) summary = self.getParameterValue(self.SUMMARY) == 1 keep = self.getParameterValue(self.KEEP) == 1 @@ -169,20 +164,19 @@ class SpatialJoin(QgisAlgorithm): for c, f in enumerate(features): atMap1 = f.attributes() outFeat.setGeometry(f.geometry()) - inGeom = vector.snapToPrecision(f.geometry(), precision) + inGeom = f.geometry() none = True joinList = [] if inGeom.type() == QgsWkbTypes.PointGeometry: bbox = inGeom.buffer(10, 2).boundingBox() else: bbox = inGeom.boundingBox() - bbox.grow(0.51 * precision) joinList = index.intersects(bbox) if len(joinList) > 0: count = 0 for i in joinList: inFeatB = mapP2[i] - inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision) + inGeomB = inFeatB.geometry() res = False for predicate in predicates: diff --git a/python/plugins/processing/tools/vector.py b/python/plugins/processing/tools/vector.py index e518093adae..968c5e75ec3 100644 --- a/python/plugins/processing/tools/vector.py +++ b/python/plugins/processing/tools/vector.py @@ -216,22 +216,6 @@ def checkMinDistance(point, index, distance, points): return True -def snapToPrecision(geom, precision): - snapped = QgsGeometry(geom) - if precision == 0.0: - return snapped - - i = 0 - p = snapped.vertexAt(i) - while p.x() != 0.0 and p.y() != 0.0: - x = round(p.x() / precision, 0) * precision - y = round(p.y() / precision, 0) * precision - snapped.moveVertex(x, y, i) - i = i + 1 - p = snapped.vertexAt(i) - return QgsPointXY(snapped.x(), snapped.y()) - - NOGEOMETRY_EXTENSIONS = [ u'csv', u'dbf',