Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
improved processing extract/select by location
  • Loading branch information
giohappy committed Jun 30, 2014
1 parent 35eb5f6 commit 24c1c95
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
53 changes: 52 additions & 1 deletion python/plugins/processing/algs/qgis/ftools/ExtractByLocation.py
Expand Up @@ -29,6 +29,7 @@
from qgis.core import *
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.parameters.ParameterVector import ParameterVector
from processing.parameters.ParameterBoolean import ParameterBoolean
from processing.outputs.OutputVector import OutputVector
from processing.tools import dataobjects, vector

Expand All @@ -37,7 +38,15 @@ class ExtractByLocation(GeoAlgorithm):

INPUT = 'INPUT'
INTERSECT = 'INTERSECT'
TOUCHES = 'TOUCHES'
OVERLAPS = 'OVERLAPS'
WITHIN = 'WITHIN'
OUTPUT = 'OUTPUT'

METHODS = ['creating new selection', 'adding to current selection',
'removing from current selection']
opFlags = 0
operators = {'TOUCHES':1,'OVERLAPS':2,'WITHIN':4}

def defineCharacteristics(self):
self.name = 'Extract by location'
Expand All @@ -47,6 +56,15 @@ def defineCharacteristics(self):
self.addParameter(ParameterVector(self.INTERSECT,
'Additional layer (intersection layer)',
[ParameterVector.VECTOR_TYPE_ANY]))
self.addParameter(ParameterBoolean(self.TOUCHES,
'Include input features that touch the selection features',
[True]))
self.addParameter(ParameterBoolean(self.OVERLAPS,
'Include input features that overlap/cross the selection features',
[True]))
self.addParameter(ParameterBoolean(self.WITHIN,
'Include input features completely within the selection features',
[True]))
self.addOutput(OutputVector(self.OUTPUT, 'Selection'))

def processAlgorithm(self, progress):
Expand All @@ -55,6 +73,39 @@ def processAlgorithm(self, progress):
filename = self.getParameterValue(self.INTERSECT)
selectLayer = dataobjects.getObjectFromUri(filename)
index = vector.spatialindex(layer)

def _points_op(geomA,geomB):
return geomA.intersects(geomB)

def _poly_lines_op(geomA,geomB):
if geomA.disjoint(geomB):
return False
intersects = False
if self.opFlags & self.operators['TOUCHES']:
intersects |= geomA.touches(geomB)
if not intersects and (self.opFlags & self.operators['OVERLAPS']):
if geomB.type() == QGis.Line or geomA.type() == QGis.Line:
intersects |= geomA.crosses(geomB)
intersects |= geomA.overlaps(geomB)
if not intersects and (self.opFlags & self.operators['WITHIN']):
intersects |= geomA.contains(geomB)
return intersects

def _sp_operator():
if layer.geometryType() == QGis.Point:
return _points_op
else:
return _poly_lines_op

self.opFlags = 0
if self.getParameterValue(self.TOUCHES):
self.opFlags |= self.operators['TOUCHES']
if self.getParameterValue(self.OVERLAPS):
self.opFlags |= self.operators['OVERLAPS']
if self.getParameterValue(self.WITHIN):
self.opFlags |= self.operators['WITHIN']

sp_operator = _sp_operator()

output = self.getOutputFromName(self.OUTPUT)
writer = output.getVectorWriter(layer.pendingFields(),
Expand All @@ -73,7 +124,7 @@ def processAlgorithm(self, progress):
request = QgsFeatureRequest().setFilterFid(i)
feat = layer.getFeatures(request).next()
tmpGeom = QgsGeometry(feat.geometry())
if geom.intersects(tmpGeom):
if sp_operator(geom,tmpGeom):
selectedSet.append(feat.id())
progress.setPercentage(int(current * total))

Expand Down
50 changes: 49 additions & 1 deletion python/plugins/processing/algs/qgis/ftools/SelectByLocation.py
Expand Up @@ -30,6 +30,7 @@
from processing.core.GeoAlgorithm import GeoAlgorithm
from processing.parameters.ParameterSelection import ParameterSelection
from processing.parameters.ParameterVector import ParameterVector
from processing.parameters.ParameterBoolean import ParameterBoolean
from processing.outputs.OutputVector import OutputVector
from processing.tools import dataobjects, vector

Expand All @@ -38,11 +39,16 @@ class SelectByLocation(GeoAlgorithm):

INPUT = 'INPUT'
INTERSECT = 'INTERSECT'
TOUCHES = 'TOUCHES'
OVERLAPS = 'OVERLAPS'
WITHIN = 'WITHIN'
METHOD = 'METHOD'
OUTPUT = 'OUTPUT'

METHODS = ['creating new selection', 'adding to current selection',
'removing from current selection']
opFlags = 0
operators = {'TOUCHES':1,'OVERLAPS':2,'WITHIN':4}


def defineCharacteristics(self):
Expand All @@ -53,6 +59,15 @@ def defineCharacteristics(self):
self.addParameter(ParameterVector(self.INTERSECT,
'Additional layer (intersection layer)',
[ParameterVector.VECTOR_TYPE_ANY]))
self.addParameter(ParameterBoolean(self.TOUCHES,
'Include input features that touch the selection features',
[True]))
self.addParameter(ParameterBoolean(self.OVERLAPS,
'Include input features that overlap/cross the selection features',
[True]))
self.addParameter(ParameterBoolean(self.WITHIN,
'Include input features completely within the selection features',
[True]))
self.addParameter(ParameterSelection(self.METHOD,
'Modify current selection by', self.METHODS, 0))
self.addOutput(OutputVector(self.OUTPUT, 'Selection', True))
Expand All @@ -66,6 +81,39 @@ def processAlgorithm(self, progress):

oldSelection = set(inputLayer.selectedFeaturesIds())
index = vector.spatialindex(inputLayer)

def _points_op(geomA,geomB):
return geomA.intersects(geomB)

def _poly_lines_op(geomA,geomB):
if geomA.disjoint(geomB):
return False
intersects = False
if self.opFlags & self.operators['TOUCHES']:
intersects |= geomA.touches(geomB)
if not intersects and (self.opFlags & self.operators['OVERLAPS']):
if geomB.type() == QGis.Line or geomA.type() == QGis.Line:
intersects |= geomA.crosses(geomB)
intersects |= geomA.overlaps(geomB)
if not intersects and (self.opFlags & self.operators['WITHIN']):
intersects |= geomA.contains(geomB)
return intersects

def _sp_operator():
if inputLayer.geometryType() == QGis.Point:
return _points_op
else:
return _poly_lines_op

self.opFlags = 0
if self.getParameterValue(self.TOUCHES):
self.opFlags |= self.operators['TOUCHES']
if self.getParameterValue(self.OVERLAPS):
self.opFlags |= self.operators['OVERLAPS']
if self.getParameterValue(self.WITHIN):
self.opFlags |= self.operators['WITHIN']

sp_operator = _sp_operator()

geom = QgsGeometry()
selectedSet = []
Expand All @@ -79,7 +127,7 @@ def processAlgorithm(self, progress):
request = QgsFeatureRequest().setFilterFid(i)
feat = inputLayer.getFeatures(request).next()
tmpGeom = QgsGeometry(feat.geometry())
if geom.intersects(tmpGeom):
if sp_operator(geom,tmpGeom):
selectedSet.append(feat.id())
current += 1
progress.setPercentage(int(current * total))
Expand Down

0 comments on commit 24c1c95

Please sign in to comment.