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.
This commit is contained in:
Nyall Dawson 2017-09-08 16:46:19 +10:00
parent 24a4ab7f0d
commit a9f4540081
4 changed files with 4 additions and 40 deletions

View File

@ -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':

View File

@ -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):

View File

@ -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:

View File

@ -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',