Skip to content

Commit 4da1ce9

Browse files
committedOct 24, 2015
Merge pull request #2341 from arnaud-morvan/processing_precisionmodel
[Processing] Add precision parameter to by location algorithms
2 parents 88d4605 + fa12502 commit 4da1ce9

File tree

4 files changed

+63
-22
lines changed

4 files changed

+63
-22
lines changed
 

‎python/plugins/processing/algs/qgis/ExtractByLocation.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from processing.core.GeoAlgorithm import GeoAlgorithm
3030
from processing.core.parameters import ParameterVector
3131
from processing.core.parameters import ParameterGeometryPredicate
32+
from processing.core.parameters import ParameterNumber
3233
from processing.core.outputs import OutputVector
3334
from processing.tools import dataobjects, vector
3435

@@ -38,6 +39,7 @@ class ExtractByLocation(GeoAlgorithm):
3839
INPUT = 'INPUT'
3940
INTERSECT = 'INTERSECT'
4041
PREDICATE = 'PREDICATE'
42+
PRECISION = 'PRECISION'
4143
OUTPUT = 'OUTPUT'
4244

4345
def defineCharacteristics(self):
@@ -52,6 +54,9 @@ def defineCharacteristics(self):
5254
self.addParameter(ParameterGeometryPredicate(self.PREDICATE,
5355
self.tr('Geometric predicate'),
5456
left=self.INPUT, right=self.INTERSECT))
57+
self.addParameter(ParameterNumber(self.PRECISION,
58+
self.tr('Precision'),
59+
0.0, None, 0.0))
5560
self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (location)')))
5661

5762
def processAlgorithm(self, progress):
@@ -60,6 +65,7 @@ def processAlgorithm(self, progress):
6065
filename = self.getParameterValue(self.INTERSECT)
6166
selectLayer = dataobjects.getObjectFromUri(filename)
6267
predicates = self.getParameterValue(self.PREDICATE)
68+
precision = self.getParameterValue(self.PRECISION)
6369

6470
index = vector.spatialindex(layer)
6571

@@ -79,12 +85,13 @@ def processAlgorithm(self, progress):
7985
featureCount = len(features)
8086
total = 100.0 / float(len(features))
8187
for current, f in enumerate(features):
82-
geom = QgsGeometry(f.geometry())
83-
intersects = index.intersects(geom.boundingBox())
88+
geom = vector.snapToPrecision(f.geometry(), precision)
89+
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
90+
intersects = index.intersects(bbox)
8491
for i in intersects:
8592
request = QgsFeatureRequest().setFilterFid(i)
8693
feat = layer.getFeatures(request).next()
87-
tmpGeom = QgsGeometry(feat.geometry())
94+
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
8895
res = False
8996
for predicate in predicates:
9097
if predicate == 'disjoint':

‎python/plugins/processing/algs/qgis/SelectByLocation.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from processing.core.parameters import ParameterSelection
3131
from processing.core.parameters import ParameterVector
3232
from processing.core.parameters import ParameterGeometryPredicate
33+
from processing.core.parameters import ParameterNumber
3334
from processing.core.outputs import OutputVector
3435
from processing.tools import dataobjects, vector
3536

@@ -39,6 +40,7 @@ class SelectByLocation(GeoAlgorithm):
3940
INPUT = 'INPUT'
4041
INTERSECT = 'INTERSECT'
4142
PREDICATE = 'PREDICATE'
43+
PRECISION = 'PRECISION'
4244
METHOD = 'METHOD'
4345
OUTPUT = 'OUTPUT'
4446

@@ -59,6 +61,9 @@ def defineCharacteristics(self):
5961
self.addParameter(ParameterGeometryPredicate(self.PREDICATE,
6062
self.tr('Geometric predicate'),
6163
left=self.INPUT, right=self.INTERSECT))
64+
self.addParameter(ParameterNumber(self.PRECISION,
65+
self.tr('Precision'),
66+
0.0, None, 0.0))
6267
self.addParameter(ParameterSelection(self.METHOD,
6368
self.tr('Modify current selection by'),
6469
self.methods, 0))
@@ -71,6 +76,7 @@ def processAlgorithm(self, progress):
7176
filename2 = self.getParameterValue(self.INTERSECT)
7277
selectLayer = dataobjects.getObjectFromUri(filename2)
7378
predicates = self.getParameterValue(self.PREDICATE)
79+
precision = self.getParameterValue(self.PRECISION)
7480

7581
oldSelection = set(inputLayer.selectedFeaturesIds())
7682
inputLayer.removeSelection()
@@ -87,13 +93,15 @@ def processAlgorithm(self, progress):
8793
features = vector.features(selectLayer)
8894
total = 100.0 / float(len(features))
8995
for f in features:
90-
geom = QgsGeometry(f.geometry())
96+
geom = vector.snapToPrecision(f.geometry(), precision)
97+
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
98+
intersects = index.intersects(bbox)
9199

92-
intersects = index.intersects(geom.boundingBox())
93100
for i in intersects:
94101
request = QgsFeatureRequest().setFilterFid(i)
95102
feat = inputLayer.getFeatures(request).next()
96-
tmpGeom = QgsGeometry(feat.geometry())
103+
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
104+
97105
res = False
98106
for predicate in predicates:
99107
if predicate == 'disjoint':

‎python/plugins/processing/algs/qgis/SpatialJoin.py

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from processing.core.GeoAlgorithm import GeoAlgorithm
3030
from processing.core.parameters import ParameterVector
3131
from processing.core.parameters import ParameterGeometryPredicate
32+
from processing.core.parameters import ParameterNumber
3233
from processing.core.parameters import ParameterSelection
3334
from processing.core.parameters import ParameterString
3435
from processing.core.outputs import OutputVector
@@ -39,6 +40,7 @@ class SpatialJoin(GeoAlgorithm):
3940
TARGET = "TARGET"
4041
JOIN = "JOIN"
4142
PREDICATE = "PREDICATE"
43+
PRECISION = 'PRECISION'
4244
SUMMARY = "SUMMARY"
4345
STATS = "STATS"
4446
KEEP = "KEEP"
@@ -70,6 +72,9 @@ def defineCharacteristics(self):
7072
self.tr('Geometric predicate'),
7173
left=self.TARGET, right=self.JOIN,
7274
enabledPredicates=predicates))
75+
self.addParameter(ParameterNumber(self.PRECISION,
76+
self.tr('Precision'),
77+
0.0, None, 0.0))
7378
self.addParameter(ParameterSelection(self.SUMMARY,
7479
self.tr('Attribute summary'), self.summarys))
7580
self.addParameter(ParameterString(self.STATS,
@@ -85,6 +90,7 @@ def processAlgorithm(self, progress):
8590
join = dataobjects.getObjectFromUri(
8691
self.getParameterValue(self.JOIN))
8792
predicates = self.getParameterValue(self.PREDICATE)
93+
precision = self.getParameterValue(self.PRECISION)
8894

8995
summary = self.getParameterValue(self.SUMMARY) == 1
9096
keep = self.getParameterValue(self.KEEP) == 1
@@ -140,29 +146,22 @@ def processAlgorithm(self, progress):
140146
features = vector.features(target)
141147
total = 100.0 / len(features)
142148
for c, f in enumerate(features):
143-
inGeom = f.geometry()
144149
atMap1 = f.attributes()
145-
outFeat.setGeometry(inGeom)
150+
outFeat.setGeometry(f.geometry())
151+
inGeom = vector.snapToPrecision(f.geometry(), precision)
146152
none = True
147153
joinList = []
148154
if inGeom.type() == QGis.Point:
149-
joinList = index.intersects(inGeom.buffer(10, 2).boundingBox())
150-
if len(joinList) > 0:
151-
check = 0
152-
else:
153-
check = 1
155+
bbox = inGeom.buffer(10, 2).boundingBox()
154156
else:
155-
joinList = index.intersects(inGeom.boundingBox())
156-
if len(joinList) > 0:
157-
check = 0
158-
else:
159-
check = 1
160-
161-
if check == 0:
157+
bbox = inGeom.boundingBox()
158+
bufferedBox = vector.bufferedBoundingBox(bbox, 0.51 * precision)
159+
joinList = index.intersects(bufferedBox)
160+
if len(joinList) > 0:
162161
count = 0
163162
for i in joinList:
164163
inFeatB = mapP2[i]
165-
inGeomB = inFeatB.geometry()
164+
inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision)
166165

167166
res = False
168167
for predicate in predicates:

‎python/plugins/processing/tools/vector.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import cStringIO
3232

3333
from PyQt4.QtCore import QVariant, QSettings
34-
from qgis.core import QGis, QgsFields, QgsField, QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer, QgsVectorFileWriter, QgsDistanceArea
34+
from qgis.core import QGis, QgsFields, QgsField, QgsGeometry, QgsRectangle, QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer, QgsVectorFileWriter, QgsDistanceArea
3535
from processing.core.ProcessingConfig import ProcessingConfig
3636

3737

@@ -381,6 +381,33 @@ def _toQgsField(f):
381381
return QgsField(f[0], TYPE_MAP.get(f[1], QVariant.String))
382382

383383

384+
def snapToPrecision(geom, precision):
385+
snapped = QgsGeometry(geom)
386+
if precision == 0.0:
387+
return snapped
388+
389+
i = 0
390+
p = snapped.vertexAt(i)
391+
while p.x() != 0.0 and p.y() != 0.0:
392+
x = round(p.x() / precision,0) * precision
393+
y = round(p.y() / precision,0) * precision
394+
snapped.moveVertex(x,y,i)
395+
i = i + 1
396+
p = snapped.vertexAt(i)
397+
return snapped
398+
399+
400+
def bufferedBoundingBox(bbox, buffer_size):
401+
if buffer_size == 0.0:
402+
return QgsRectangle(bbox)
403+
404+
return QgsRectangle(
405+
bbox.xMinimum() - buffer_size,
406+
bbox.yMinimum() - buffer_size,
407+
bbox.xMaximum() + buffer_size,
408+
bbox.yMaximum() + buffer_size)
409+
410+
384411
class VectorWriter:
385412

386413
MEMORY_LAYER_PREFIX = 'memory:'

0 commit comments

Comments
 (0)
Please sign in to comment.