mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Add ability to select output fields from both layers to Intersection algorithm
This commit is contained in:
parent
02bf88c4b7
commit
a6736ceb77
@ -31,6 +31,7 @@ from qgis.PyQt.QtGui import QIcon
|
||||
|
||||
from qgis.core import (QgsFeatureRequest,
|
||||
QgsFeature,
|
||||
QgsFields,
|
||||
QgsFeatureSink,
|
||||
QgsGeometry,
|
||||
QgsWkbTypes,
|
||||
@ -38,7 +39,7 @@ from qgis.core import (QgsFeatureRequest,
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsSpatialIndex,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingParameterField)
|
||||
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.tools import vector
|
||||
@ -60,6 +61,8 @@ class Intersection(QgisAlgorithm):
|
||||
INPUT = 'INPUT'
|
||||
OVERLAY = 'OVERLAY'
|
||||
OUTPUT = 'OUTPUT'
|
||||
INPUT_FIELDS = 'INPUT_FIELDS'
|
||||
OVERLAY_FIELDS = 'OVERLAY_FIELDS'
|
||||
|
||||
def icon(self):
|
||||
return QIcon(os.path.join(pluginPath, 'images', 'ftools', 'intersect.png'))
|
||||
@ -76,6 +79,17 @@ class Intersection(QgisAlgorithm):
|
||||
self.addParameter(QgsProcessingParameterFeatureSource(self.OVERLAY,
|
||||
self.tr('Intersection layer')))
|
||||
|
||||
self.addParameter(QgsProcessingParameterField(
|
||||
self.INPUT_FIELDS,
|
||||
self.tr('Input fields to keep (leave empty to keep all fields)'),
|
||||
parentLayerParameterName=self.INPUT,
|
||||
optional=True, allowMultiple=True))
|
||||
self.addParameter(QgsProcessingParameterField(
|
||||
self.OVERLAY_FIELDS,
|
||||
self.tr('Intersect fields to keep (leave empty to keep all fields)'),
|
||||
parentLayerParameterName=self.OVERLAY,
|
||||
optional=True, allowMultiple=True))
|
||||
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Intersection')))
|
||||
|
||||
def name(self):
|
||||
@ -89,10 +103,40 @@ class Intersection(QgisAlgorithm):
|
||||
sourceB = self.parameterAsSource(parameters, self.OVERLAY, context)
|
||||
|
||||
geomType = QgsWkbTypes.multiType(sourceA.wkbType())
|
||||
fields = vector.combineFields(sourceA.fields(), sourceB.fields())
|
||||
|
||||
fieldsA = self.parameterAsFields(parameters, self.INPUT_FIELDS, context)
|
||||
fieldsB = self.parameterAsFields(parameters, self.OVERLAY_FIELDS, context)
|
||||
|
||||
fieldListA = QgsFields()
|
||||
field_indices_a = []
|
||||
if len(fieldsA) > 0:
|
||||
for f in fieldsA:
|
||||
idxA = sourceA.fields().lookupField(f)
|
||||
if idxA >= 0:
|
||||
field_indices_a.append(idxA)
|
||||
fieldListA.append(sourceA.fields()[idxA])
|
||||
else:
|
||||
fieldListA = sourceA.fields()
|
||||
field_indices_a = [i for i in range(0, fieldListA.count())]
|
||||
|
||||
fieldListB = QgsFields()
|
||||
field_indices_b = []
|
||||
if len(fieldsB) > 0:
|
||||
for f in fieldsB:
|
||||
idxB = sourceB.fields().lookupField(f)
|
||||
if idxB >= 0:
|
||||
field_indices_b.append(idxB)
|
||||
fieldListB.append(sourceB.fields()[idxB])
|
||||
else:
|
||||
fieldListB = sourceB.fields()
|
||||
field_indices_b = [i for i in range(0, fieldListB.count())]
|
||||
|
||||
fieldListB = vector.testForUniqueness(fieldListA, fieldListB)
|
||||
for b in fieldListB:
|
||||
fieldListA.append(b)
|
||||
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, geomType, sourceA.sourceCrs())
|
||||
fieldListA, geomType, sourceA.sourceCrs())
|
||||
|
||||
outFeat = QgsFeature()
|
||||
indexB = QgsSpatialIndex(sourceB.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(sourceA.sourceCrs())), feedback)
|
||||
@ -100,16 +144,20 @@ class Intersection(QgisAlgorithm):
|
||||
total = 100.0 / sourceA.featureCount() if sourceA.featureCount() else 1
|
||||
count = 0
|
||||
|
||||
for featA in sourceA.getFeatures():
|
||||
for featA in sourceA.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(field_indices_a)):
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
if not featA.hasGeometry():
|
||||
continue
|
||||
|
||||
geom = featA.geometry()
|
||||
atMapA = featA.attributes()
|
||||
intersects = indexB.intersects(geom.boundingBox())
|
||||
|
||||
request = QgsFeatureRequest().setFilterFids(intersects)
|
||||
request.setDestinationCrs(sourceA.sourceCrs())
|
||||
request.setSubsetOfAttributes(field_indices_b)
|
||||
|
||||
engine = None
|
||||
if len(intersects) > 0:
|
||||
@ -123,7 +171,8 @@ class Intersection(QgisAlgorithm):
|
||||
|
||||
tmpGeom = featB.geometry()
|
||||
if engine.intersects(tmpGeom.geometry()):
|
||||
atMapB = featB.attributes()
|
||||
out_attributes = [featA.attributes()[i] for i in field_indices_a]
|
||||
out_attributes.extend([featB.attributes()[i] for i in field_indices_b])
|
||||
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)
|
||||
@ -139,10 +188,7 @@ class Intersection(QgisAlgorithm):
|
||||
try:
|
||||
if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
|
||||
outFeat.setGeometry(int_geom)
|
||||
attrs = []
|
||||
attrs.extend(atMapA)
|
||||
attrs.extend(atMapB)
|
||||
outFeat.setAttributes(attrs)
|
||||
outFeat.setAttributes(out_attributes)
|
||||
sink.addFeature(outFeat, QgsFeatureSink.FastInsert)
|
||||
except:
|
||||
raise QgsProcessingException(
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user