31
31
32
32
from qgis .core import (QgsFeatureRequest ,
33
33
QgsFeature ,
34
+ QgsFields ,
34
35
QgsFeatureSink ,
35
36
QgsGeometry ,
36
37
QgsWkbTypes ,
37
38
QgsProcessingException ,
38
39
QgsProcessingParameterFeatureSource ,
39
40
QgsProcessingParameterFeatureSink ,
40
41
QgsSpatialIndex ,
41
- QgsProcessingUtils )
42
+ QgsProcessingParameterField )
42
43
43
44
from processing .algs .qgis .QgisAlgorithm import QgisAlgorithm
44
45
from processing .tools import vector
@@ -60,6 +61,8 @@ class Intersection(QgisAlgorithm):
60
61
INPUT = 'INPUT'
61
62
OVERLAY = 'OVERLAY'
62
63
OUTPUT = 'OUTPUT'
64
+ INPUT_FIELDS = 'INPUT_FIELDS'
65
+ OVERLAY_FIELDS = 'OVERLAY_FIELDS'
63
66
64
67
def icon (self ):
65
68
return QIcon (os .path .join (pluginPath , 'images' , 'ftools' , 'intersect.png' ))
@@ -76,6 +79,17 @@ def initAlgorithm(self, config=None):
76
79
self .addParameter (QgsProcessingParameterFeatureSource (self .OVERLAY ,
77
80
self .tr ('Intersection layer' )))
78
81
82
+ self .addParameter (QgsProcessingParameterField (
83
+ self .INPUT_FIELDS ,
84
+ self .tr ('Input fields to keep (leave empty to keep all fields)' ),
85
+ parentLayerParameterName = self .INPUT ,
86
+ optional = True , allowMultiple = True ))
87
+ self .addParameter (QgsProcessingParameterField (
88
+ self .OVERLAY_FIELDS ,
89
+ self .tr ('Intersect fields to keep (leave empty to keep all fields)' ),
90
+ parentLayerParameterName = self .OVERLAY ,
91
+ optional = True , allowMultiple = True ))
92
+
79
93
self .addParameter (QgsProcessingParameterFeatureSink (self .OUTPUT , self .tr ('Intersection' )))
80
94
81
95
def name (self ):
@@ -89,27 +103,61 @@ def processAlgorithm(self, parameters, context, feedback):
89
103
sourceB = self .parameterAsSource (parameters , self .OVERLAY , context )
90
104
91
105
geomType = QgsWkbTypes .multiType (sourceA .wkbType ())
92
- fields = vector .combineFields (sourceA .fields (), sourceB .fields ())
106
+
107
+ fieldsA = self .parameterAsFields (parameters , self .INPUT_FIELDS , context )
108
+ fieldsB = self .parameterAsFields (parameters , self .OVERLAY_FIELDS , context )
109
+
110
+ fieldListA = QgsFields ()
111
+ field_indices_a = []
112
+ if len (fieldsA ) > 0 :
113
+ for f in fieldsA :
114
+ idxA = sourceA .fields ().lookupField (f )
115
+ if idxA >= 0 :
116
+ field_indices_a .append (idxA )
117
+ fieldListA .append (sourceA .fields ()[idxA ])
118
+ else :
119
+ fieldListA = sourceA .fields ()
120
+ field_indices_a = [i for i in range (0 , fieldListA .count ())]
121
+
122
+ fieldListB = QgsFields ()
123
+ field_indices_b = []
124
+ if len (fieldsB ) > 0 :
125
+ for f in fieldsB :
126
+ idxB = sourceB .fields ().lookupField (f )
127
+ if idxB >= 0 :
128
+ field_indices_b .append (idxB )
129
+ fieldListB .append (sourceB .fields ()[idxB ])
130
+ else :
131
+ fieldListB = sourceB .fields ()
132
+ field_indices_b = [i for i in range (0 , fieldListB .count ())]
133
+
134
+ fieldListB = vector .testForUniqueness (fieldListA , fieldListB )
135
+ for b in fieldListB :
136
+ fieldListA .append (b )
93
137
94
138
(sink , dest_id ) = self .parameterAsSink (parameters , self .OUTPUT , context ,
95
- fields , geomType , sourceA .sourceCrs ())
139
+ fieldListA , geomType , sourceA .sourceCrs ())
96
140
97
141
outFeat = QgsFeature ()
98
142
indexB = QgsSpatialIndex (sourceB .getFeatures (QgsFeatureRequest ().setSubsetOfAttributes ([]).setDestinationCrs (sourceA .sourceCrs ())), feedback )
99
143
100
144
total = 100.0 / sourceA .featureCount () if sourceA .featureCount () else 1
101
145
count = 0
102
146
103
- for featA in sourceA .getFeatures ():
147
+ for featA in sourceA .getFeatures (QgsFeatureRequest (). setSubsetOfAttributes ( field_indices_a ) ):
104
148
if feedback .isCanceled ():
105
149
break
106
150
151
+ if not featA .hasGeometry ():
152
+ continue
153
+
107
154
geom = featA .geometry ()
108
155
atMapA = featA .attributes ()
109
156
intersects = indexB .intersects (geom .boundingBox ())
110
157
111
158
request = QgsFeatureRequest ().setFilterFids (intersects )
112
159
request .setDestinationCrs (sourceA .sourceCrs ())
160
+ request .setSubsetOfAttributes (field_indices_b )
113
161
114
162
engine = None
115
163
if len (intersects ) > 0 :
@@ -123,7 +171,8 @@ def processAlgorithm(self, parameters, context, feedback):
123
171
124
172
tmpGeom = featB .geometry ()
125
173
if engine .intersects (tmpGeom .geometry ()):
126
- atMapB = featB .attributes ()
174
+ out_attributes = [featA .attributes ()[i ] for i in field_indices_a ]
175
+ out_attributes .extend ([featB .attributes ()[i ] for i in field_indices_b ])
127
176
int_geom = QgsGeometry (geom .intersection (tmpGeom ))
128
177
if int_geom .wkbType () == QgsWkbTypes .Unknown or QgsWkbTypes .flatType (int_geom .geometry ().wkbType ()) == QgsWkbTypes .GeometryCollection :
129
178
int_com = geom .combine (tmpGeom )
@@ -139,10 +188,7 @@ def processAlgorithm(self, parameters, context, feedback):
139
188
try :
140
189
if int_geom .wkbType () in wkbTypeGroups [wkbTypeGroups [int_geom .wkbType ()]]:
141
190
outFeat .setGeometry (int_geom )
142
- attrs = []
143
- attrs .extend (atMapA )
144
- attrs .extend (atMapB )
145
- outFeat .setAttributes (attrs )
191
+ outFeat .setAttributes (out_attributes )
146
192
sink .addFeature (outFeat , QgsFeatureSink .FastInsert )
147
193
except :
148
194
raise QgsProcessingException (
0 commit comments