Skip to content

Commit 08c4eea

Browse files
committed
[processing] Fix Distance Matrix alg considers distances to
same points Add more unit tests Fixes #17350 (cherry-picked from 7fa9d41)
1 parent 75fe8ed commit 08c4eea

10 files changed

+1296
-296
lines changed

python/plugins/processing/algs/qgis/PointDistance.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def processAlgorithm(self, parameters, context, feedback):
111111
source_field = self.parameterAsString(parameters, self.INPUT_FIELD, context)
112112
target_source = self.parameterAsSource(parameters, self.TARGET, context)
113113
target_field = self.parameterAsString(parameters, self.TARGET_FIELD, context)
114+
same_source_and_target = parameters[self.INPUT] == parameters[self.TARGET]
114115
matType = self.parameterAsEnum(parameters, self.MATRIX_TYPE, context)
115116
nPoints = self.parameterAsInt(parameters, self.NEAREST_POINTS, context)
116117

@@ -119,19 +120,25 @@ def processAlgorithm(self, parameters, context, feedback):
119120

120121
if matType == 0:
121122
# Linear distance matrix
122-
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field,
123+
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field, same_source_and_target,
123124
matType, nPoints, feedback)
124125
elif matType == 1:
125126
# Standard distance matrix
126127
return self.regularMatrix(parameters, context, source, source_field, target_source, target_field,
127128
nPoints, feedback)
128129
elif matType == 2:
129130
# Summary distance matrix
130-
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field,
131+
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field, same_source_and_target,
131132
matType, nPoints, feedback)
132133

133-
def linearMatrix(self, parameters, context, source, inField, target_source, targetField,
134+
def linearMatrix(self, parameters, context, source, inField, target_source, targetField, same_source_and_target,
134135
matType, nPoints, feedback):
136+
137+
if same_source_and_target:
138+
# need to fetch an extra point from the index, since the closest match will always be the same
139+
# as the input feature
140+
nPoints += 1
141+
135142
inIdx = source.fields().lookupField(inField)
136143
outIdx = target_source.fields().lookupField(targetField)
137144

@@ -176,6 +183,9 @@ def linearMatrix(self, parameters, context, source, inField, target_source, targ
176183
if feedback.isCanceled():
177184
break
178185

186+
if same_source_and_target and inFeat.id() == outFeat.id():
187+
continue
188+
179189
outID = outFeat.attributes()[outIdx]
180190
outGeom = outFeat.geometry()
181191
dist = distArea.measureLine(inGeom.asPoint(),
@@ -207,6 +217,7 @@ def linearMatrix(self, parameters, context, source, inField, target_source, targ
207217

208218
def regularMatrix(self, parameters, context, source, inField, target_source, targetField,
209219
nPoints, feedback):
220+
210221
distArea = QgsDistanceArea()
211222
distArea.setSourceCrs(source.sourceCrs(), context.transformContext())
212223
distArea.setEllipsoid(context.project().ellipsoid())

python/plugins/processing/tests/testdata/expected/linear_matrix.gml

Lines changed: 194 additions & 266 deletions
Large diffs are not rendered by default.

python/plugins/processing/tests/testdata/expected/linear_matrix_diff.gml

Lines changed: 518 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<xs:schema targetNamespace="http://ogr.maptools.org/" xmlns:ogr="http://ogr.maptools.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" elementFormDefault="qualified" version="1.0">
3+
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
4+
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
5+
<xs:complexType name="FeatureCollectionType">
6+
<xs:complexContent>
7+
<xs:extension base="gml:AbstractFeatureCollectionType">
8+
<xs:attribute name="lockId" type="xs:string" use="optional"/>
9+
<xs:attribute name="scope" type="xs:string" use="optional"/>
10+
</xs:extension>
11+
</xs:complexContent>
12+
</xs:complexType>
13+
<xs:element name="linear_matrix_diff" type="ogr:linear_matrix_diff_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="linear_matrix_diff_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="InputID" nillable="true" minOccurs="0" maxOccurs="1">
20+
<xs:simpleType>
21+
<xs:restriction base="xs:string">
22+
<xs:maxLength value="255"/>
23+
</xs:restriction>
24+
</xs:simpleType>
25+
</xs:element>
26+
<xs:element name="TargetID" nillable="true" minOccurs="0" maxOccurs="1">
27+
<xs:simpleType>
28+
<xs:restriction base="xs:string">
29+
<xs:maxLength value="255"/>
30+
</xs:restriction>
31+
</xs:simpleType>
32+
</xs:element>
33+
<xs:element name="Distance" nillable="true" minOccurs="0" maxOccurs="1">
34+
<xs:simpleType>
35+
<xs:restriction base="xs:decimal">
36+
</xs:restriction>
37+
</xs:simpleType>
38+
</xs:element>
39+
</xs:sequence>
40+
</xs:extension>
41+
</xs:complexContent>
42+
</xs:complexType>
43+
</xs:schema>

0 commit comments

Comments
 (0)