Skip to content

Commit

Permalink
[processing] Fix Distance Matrix alg considers distances to
Browse files Browse the repository at this point in the history
same points

Add more unit tests

Fixes #17350
  • Loading branch information
nyalldawson committed Apr 9, 2018
1 parent 887db6e commit 7fa9d41
Show file tree
Hide file tree
Showing 10 changed files with 1,296 additions and 296 deletions.
17 changes: 14 additions & 3 deletions python/plugins/processing/algs/qgis/PointDistance.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def processAlgorithm(self, parameters, context, feedback):
source_field = self.parameterAsString(parameters, self.INPUT_FIELD, context)
target_source = self.parameterAsSource(parameters, self.TARGET, context)
target_field = self.parameterAsString(parameters, self.TARGET_FIELD, context)
same_source_and_target = parameters[self.INPUT] == parameters[self.TARGET]
matType = self.parameterAsEnum(parameters, self.MATRIX_TYPE, context)
nPoints = self.parameterAsInt(parameters, self.NEAREST_POINTS, context)

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

if matType == 0:
# Linear distance matrix
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field,
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field, same_source_and_target,
matType, nPoints, feedback)
elif matType == 1:
# Standard distance matrix
return self.regularMatrix(parameters, context, source, source_field, target_source, target_field,
nPoints, feedback)
elif matType == 2:
# Summary distance matrix
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field,
return self.linearMatrix(parameters, context, source, source_field, target_source, target_field, same_source_and_target,
matType, nPoints, feedback)

def linearMatrix(self, parameters, context, source, inField, target_source, targetField,
def linearMatrix(self, parameters, context, source, inField, target_source, targetField, same_source_and_target,
matType, nPoints, feedback):

if same_source_and_target:
# need to fetch an extra point from the index, since the closest match will always be the same
# as the input feature
nPoints += 1

inIdx = source.fields().lookupField(inField)
outIdx = target_source.fields().lookupField(targetField)

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

if same_source_and_target and inFeat.id() == outFeat.id():
continue

outID = outFeat.attributes()[outIdx]
outGeom = outFeat.geometry()
dist = distArea.measureLine(inGeom.asPoint(),
Expand Down Expand Up @@ -207,6 +217,7 @@ def linearMatrix(self, parameters, context, source, inField, target_source, targ

def regularMatrix(self, parameters, context, source, inField, target_source, targetField,
nPoints, feedback):

distArea = QgsDistanceArea()
distArea.setSourceCrs(source.sourceCrs(), context.transformContext())
distArea.setEllipsoid(context.project().ellipsoid())
Expand Down
460 changes: 194 additions & 266 deletions python/plugins/processing/tests/testdata/expected/linear_matrix.gml

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<xs:import namespace="http://www.opengis.net/gml" schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd"/>
<xs:element name="FeatureCollection" type="ogr:FeatureCollectionType" substitutionGroup="gml:_FeatureCollection"/>
<xs:complexType name="FeatureCollectionType">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureCollectionType">
<xs:attribute name="lockId" type="xs:string" use="optional"/>
<xs:attribute name="scope" type="xs:string" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="linear_matrix_diff" type="ogr:linear_matrix_diff_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="linear_matrix_diff_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:MultiPointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="InputID" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="255"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="TargetID" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="255"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Distance" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:decimal">
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Loading

0 comments on commit 7fa9d41

Please sign in to comment.