Merge pull request #2341 from arnaud-morvan/processing_precisionmodel

[Processing] Add precision parameter to by location algorithms
This commit is contained in:
volaya 2015-10-24 15:42:36 +02:00
commit 4da1ce9eee
4 changed files with 63 additions and 22 deletions

View File

@ -29,6 +29,7 @@ from qgis.core import QGis, QgsFeatureRequest, QgsGeometry
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterGeometryPredicate
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector
@ -38,6 +39,7 @@ class ExtractByLocation(GeoAlgorithm):
INPUT = 'INPUT'
INTERSECT = 'INTERSECT'
PREDICATE = 'PREDICATE'
PRECISION = 'PRECISION'
OUTPUT = 'OUTPUT'
def defineCharacteristics(self):
@ -52,6 +54,9 @@ class ExtractByLocation(GeoAlgorithm):
self.addParameter(ParameterGeometryPredicate(self.PREDICATE,
self.tr('Geometric predicate'),
left=self.INPUT, right=self.INTERSECT))
self.addParameter(ParameterNumber(self.PRECISION,
self.tr('Precision'),
0.0, None, 0.0))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Extracted (location)')))
def processAlgorithm(self, progress):
@ -60,6 +65,7 @@ class ExtractByLocation(GeoAlgorithm):
filename = self.getParameterValue(self.INTERSECT)
selectLayer = dataobjects.getObjectFromUri(filename)
predicates = self.getParameterValue(self.PREDICATE)
precision = self.getParameterValue(self.PRECISION)
index = vector.spatialindex(layer)
@ -79,12 +85,13 @@ class ExtractByLocation(GeoAlgorithm):
featureCount = len(features)
total = 100.0 / float(len(features))
for current, f in enumerate(features):
geom = QgsGeometry(f.geometry())
intersects = index.intersects(geom.boundingBox())
geom = vector.snapToPrecision(f.geometry(), precision)
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
intersects = index.intersects(bbox)
for i in intersects:
request = QgsFeatureRequest().setFilterFid(i)
feat = layer.getFeatures(request).next()
tmpGeom = QgsGeometry(feat.geometry())
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
res = False
for predicate in predicates:
if predicate == 'disjoint':

View File

@ -30,6 +30,7 @@ from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterGeometryPredicate
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects, vector
@ -39,6 +40,7 @@ class SelectByLocation(GeoAlgorithm):
INPUT = 'INPUT'
INTERSECT = 'INTERSECT'
PREDICATE = 'PREDICATE'
PRECISION = 'PRECISION'
METHOD = 'METHOD'
OUTPUT = 'OUTPUT'
@ -59,6 +61,9 @@ class SelectByLocation(GeoAlgorithm):
self.addParameter(ParameterGeometryPredicate(self.PREDICATE,
self.tr('Geometric predicate'),
left=self.INPUT, right=self.INTERSECT))
self.addParameter(ParameterNumber(self.PRECISION,
self.tr('Precision'),
0.0, None, 0.0))
self.addParameter(ParameterSelection(self.METHOD,
self.tr('Modify current selection by'),
self.methods, 0))
@ -71,6 +76,7 @@ class SelectByLocation(GeoAlgorithm):
filename2 = self.getParameterValue(self.INTERSECT)
selectLayer = dataobjects.getObjectFromUri(filename2)
predicates = self.getParameterValue(self.PREDICATE)
precision = self.getParameterValue(self.PRECISION)
oldSelection = set(inputLayer.selectedFeaturesIds())
inputLayer.removeSelection()
@ -87,13 +93,15 @@ class SelectByLocation(GeoAlgorithm):
features = vector.features(selectLayer)
total = 100.0 / float(len(features))
for f in features:
geom = QgsGeometry(f.geometry())
geom = vector.snapToPrecision(f.geometry(), precision)
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
intersects = index.intersects(bbox)
intersects = index.intersects(geom.boundingBox())
for i in intersects:
request = QgsFeatureRequest().setFilterFid(i)
feat = inputLayer.getFeatures(request).next()
tmpGeom = QgsGeometry(feat.geometry())
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
res = False
for predicate in predicates:
if predicate == 'disjoint':

View File

@ -29,6 +29,7 @@ from qgis.core import QGis, QgsFields, QgsField, QgsFeature, QgsGeometry, NULL
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterGeometryPredicate
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterSelection
from processing.core.parameters import ParameterString
from processing.core.outputs import OutputVector
@ -39,6 +40,7 @@ class SpatialJoin(GeoAlgorithm):
TARGET = "TARGET"
JOIN = "JOIN"
PREDICATE = "PREDICATE"
PRECISION = 'PRECISION'
SUMMARY = "SUMMARY"
STATS = "STATS"
KEEP = "KEEP"
@ -70,6 +72,9 @@ class SpatialJoin(GeoAlgorithm):
self.tr('Geometric predicate'),
left=self.TARGET, right=self.JOIN,
enabledPredicates=predicates))
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,
@ -85,6 +90,7 @@ class SpatialJoin(GeoAlgorithm):
join = dataobjects.getObjectFromUri(
self.getParameterValue(self.JOIN))
predicates = self.getParameterValue(self.PREDICATE)
precision = self.getParameterValue(self.PRECISION)
summary = self.getParameterValue(self.SUMMARY) == 1
keep = self.getParameterValue(self.KEEP) == 1
@ -140,29 +146,22 @@ class SpatialJoin(GeoAlgorithm):
features = vector.features(target)
total = 100.0 / len(features)
for c, f in enumerate(features):
inGeom = f.geometry()
atMap1 = f.attributes()
outFeat.setGeometry(inGeom)
outFeat.setGeometry(f.geometry())
inGeom = vector.snapToPrecision(f.geometry(), precision)
none = True
joinList = []
if inGeom.type() == QGis.Point:
joinList = index.intersects(inGeom.buffer(10, 2).boundingBox())
if len(joinList) > 0:
check = 0
else:
check = 1
bbox = inGeom.buffer(10, 2).boundingBox()
else:
joinList = index.intersects(inGeom.boundingBox())
if len(joinList) > 0:
check = 0
else:
check = 1
if check == 0:
bbox = inGeom.boundingBox()
bufferedBox = vector.bufferedBoundingBox(bbox, 0.51 * precision)
joinList = index.intersects(bufferedBox)
if len(joinList) > 0:
count = 0
for i in joinList:
inFeatB = mapP2[i]
inGeomB = inFeatB.geometry()
inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision)
res = False
for predicate in predicates:

View File

@ -31,7 +31,7 @@ import codecs
import cStringIO
from PyQt4.QtCore import QVariant, QSettings
from qgis.core import QGis, QgsFields, QgsField, QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer, QgsVectorFileWriter, QgsDistanceArea
from qgis.core import QGis, QgsFields, QgsField, QgsGeometry, QgsRectangle, QgsSpatialIndex, QgsMapLayerRegistry, QgsMapLayer, QgsVectorLayer, QgsVectorFileWriter, QgsDistanceArea
from processing.core.ProcessingConfig import ProcessingConfig
@ -381,6 +381,33 @@ def _toQgsField(f):
return QgsField(f[0], TYPE_MAP.get(f[1], QVariant.String))
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 snapped
def bufferedBoundingBox(bbox, buffer_size):
if buffer_size == 0.0:
return QgsRectangle(bbox)
return QgsRectangle(
bbox.xMinimum() - buffer_size,
bbox.yMinimum() - buffer_size,
bbox.xMaximum() + buffer_size,
bbox.yMaximum() + buffer_size)
class VectorWriter:
MEMORY_LAYER_PREFIX = 'memory:'