Skip to content
Permalink
Browse files

[processing] restore intersection algorithm (#4849)

  • Loading branch information
nirvn committed Jul 13, 2017
1 parent 93a8025 commit d3ad9131f46a36ec5c62b93733cab90876dfd7e1
@@ -34,13 +34,13 @@
QgsFeatureSink,
QgsGeometry,
QgsWkbTypes,
QgsMessageLog,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsSpatialIndex,
QgsProcessingUtils)

from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.outputs import OutputVector
from processing.tools import vector

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
@@ -58,7 +58,7 @@
class Intersection(QgisAlgorithm):

INPUT = 'INPUT'
INPUT2 = 'INPUT2'
OVERLAY = 'OVERLAY'
OUTPUT = 'OUTPUT'

def icon(self):
@@ -71,11 +71,12 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer')))
self.addParameter(ParameterVector(self.INPUT2,
self.tr('Intersect layer')))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Intersection')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterFeatureSource(self.OVERLAY,
self.tr('Intersection layer')))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Intersection')))

def name(self):
return 'intersection'
@@ -84,33 +85,45 @@ def displayName(self):
return self.tr('Intersection')

def processAlgorithm(self, parameters, context, feedback):
vlayerA = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
vlayerB = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT2), context)
sourceA = self.parameterAsSource(parameters, self.INPUT, context)
sourceB = self.parameterAsSource(parameters, self.OVERLAY, context)

geomType = QgsWkbTypes.multiType(sourceA.wkbType())
fields = vector.combineFields(sourceA.fields(), sourceB.fields())

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, geomType, sourceA.sourceCrs())

geomType = QgsWkbTypes.multiType(vlayerA.wkbType())
fields = vector.combineVectorFields(vlayerA, vlayerB)
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, geomType, vlayerA.crs(), context)
outFeat = QgsFeature()
index = QgsProcessingUtils.createSpatialIndex(vlayerB, context)
selectionA = QgsProcessingUtils.getFeatures(vlayerA, context)
total = 100.0 / vlayerA.featureCount() if vlayerA.featureCount() else 0
for current, inFeatA in enumerate(selectionA):
feedback.setProgress(int(current * total))
geom = inFeatA.geometry()
atMapA = inFeatA.attributes()
intersects = index.intersects(geom.boundingBox())
indexB = QgsSpatialIndex(sourceB.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(sourceA.sourceCrs())))

total = 100.0 / sourceA.featureCount() if sourceA.featureCount() else 1
count = 0

for featA in sourceA.getFeatures():
if feedback.isCanceled():
break

geom = featA.geometry()
atMapA = featA.attributes()
intersects = indexB.intersects(geom.boundingBox())

request = QgsFeatureRequest().setFilterFids(intersects)
request.setDestinationCrs(sourceA.sourceCrs())

engine = None
if len(intersects) > 0:
# use prepared geometries for faster intersection tests
engine = QgsGeometry.createGeometryEngine(geom.geometry())
engine.prepareGeometry()

for inFeatB in vlayerB.getFeatures(request):
tmpGeom = inFeatB.geometry()
for featB in sourceB.getFeatures(request):
if feedback.isCanceled():
break

tmpGeom = featB.geometry()
if engine.intersects(tmpGeom.geometry()):
atMapB = inFeatB.attributes()
atMapB = featB.attributes()
int_geom = QgsGeometry(geom.intersection(tmpGeom))
if int_geom.wkbType() == QgsWkbTypes.Unknown or QgsWkbTypes.flatType(int_geom.geometry().wkbType()) == QgsWkbTypes.GeometryCollection:
int_com = geom.combine(tmpGeom)
@@ -130,11 +143,14 @@ def processAlgorithm(self, parameters, context, feedback):
attrs.extend(atMapA)
attrs.extend(atMapB)
outFeat.setAttributes(attrs)
writer.addFeature(outFeat, QgsFeatureSink.FastInsert)
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
except:
raise GeoAlgorithmExecutionException(
self.tr('Feature geometry error: One or more '
'output features ignored due to invalid '
'geometry.'))

del writer
count += 1
feedback.setProgress(int(count * total))

return {self.OUTPUT: dest_id}
@@ -61,6 +61,7 @@
from .GridPolygon import GridPolygon
from .ImportIntoPostGIS import ImportIntoPostGIS
from .ImportIntoSpatialite import ImportIntoSpatialite
from .Intersection import Intersection
from .Merge import Merge
from .PointsLayerFromTable import PointsLayerFromTable
from .PostGISExecuteSQL import PostGISExecuteSQL
@@ -98,7 +99,6 @@
# from .ConvexHull import ConvexHull
# from .FixedDistanceBuffer import FixedDistanceBuffer
# from .VariableDistanceBuffer import VariableDistanceBuffer
# from .Intersection import Intersection
# from .RandomSelection import RandomSelection
# from .RandomSelectionWithinSubsets import RandomSelectionWithinSubsets
# from .SelectByLocation import SelectByLocation
@@ -194,7 +194,6 @@ def getAlgs(self):
# PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
# ConvexHull(), FixedDistanceBuffer(),
# VariableDistanceBuffer(),
# Intersection(),
# RandomSelection(), RandomSelectionWithinSubsets(),
# SelectByLocation(),
# ExtractByLocation(),
@@ -260,6 +259,7 @@ def getAlgs(self):
GridPolygon(),
ImportIntoPostGIS(),
ImportIntoSpatialite(),
Intersection(),
Merge(),
PointsLayerFromTable(),
PostGISExecuteSQL(),
@@ -115,20 +115,20 @@ tests:
# # check this behavior.
# # This test should stay in place because for shapefiles there should always
# # be a polygon result created since it does not support geometry collections.
# - name: Intersection (Collection Fallback)
# algorithm: qgis:intersection
# params:
# INPUT:
# name: multipolys.gml
# type: vector
# INPUT2:
# name: polys.gml
# type: vector
# results:
# OUTPUT:
# name: expected/intersection_collection_fallback.shp
# type: vector
#
- algorithm: qgis:intersection
name: Intersects multipolygons with polygons
params:
INPUT:
name: multipolys.gml
type: vector
OVERLAY:
name: polys.gml
type: vector
results:
OUTPUT:
name: expected/intersection_collection_fallback.shp
type: vector

- name: Densify geometries
algorithm: qgis:densifygeometries
params:

0 comments on commit d3ad913

Please sign in to comment.
You can’t perform that action at this time.