Skip to content

Commit

Permalink
[FEATURE] New Processing algorithm "Join attributes by nearest"
Browse files Browse the repository at this point in the history
K-nearest neighbour joins from the Processing toolbox!

This algorithm takes an input vector layer and creates a new
vector layer that is an with additional attributes in its attribute table
The additional attributes and their values are taken from a second
vector layer, where features are joined by finding the closest features
from each layer.

By default only the single nearest feature is joined, but optionally
the join can use the n-nearest neighboring features instead.

If a maximum distance is specified, then only features which are
closer than this distance will be matched.
  • Loading branch information
nyalldawson committed Apr 2, 2019
1 parent 8d6e3dc commit 95af4d4
Show file tree
Hide file tree
Showing 28 changed files with 1,996 additions and 1 deletion.
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ snap_lines_3857.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-111319.4907932723</gml:X><gml:Y>-557305.2572745769</gml:Y></gml:coord>
<gml:coord><gml:X>1263118.772597438</gml:X><gml:Y>589605.7184501204</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.0">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>664056.507372498,256164.946276216 963271.043268034,178910.815565725 1263118.77259744,589605.71845012</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.1">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>-111319.490793272,-111325.142866386 111319.490793272,-111325.142866386</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.2">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>222638.981586547,-0.000000000708115 203336.794650833,238136.038774373 246182.324006617,233067.497373915 364841.971476963,202083.784506753</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.3">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>333958.47237982,-334111.171401961 333958.47237982,-557305.257274577</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.4">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>779236.435552915,-334111.171401961 1113194.90793273,-334111.171401961</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.5">
<ogr:geometryProperty><gml:LineString srsName="EPSG:3857"><gml:coordinates>648614.757823928,-318649.196224542 862884.352006337,-182767.696351667 1012154.59764253,36015.6211455719 1136357.53225559,94594.3964176019</gml:coordinates></gml:LineString></ogr:geometryProperty>
</ogr:snap_lines_3857>
</gml:featureMember>
<gml:featureMember>
<ogr:snap_lines_3857 fid="lines.6">
</ogr:snap_lines_3857>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,23 @@
<?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="snap_lines_3857" type="ogr:snap_lines_3857_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="snap_lines_3857_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:LineStringPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ join_points_to_layers_discard.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0.220296465222349</gml:X><gml:Y>-1.268187001140251</gml:Y></gml:coord>
<gml:coord><gml:X>7.181984036488029</gml:X><gml:Y>2.74139110604333</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.915920625957996</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3.13409350057012,2.74139110604333</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.860133820101952</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.117399851996412</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3.68392246294185,0.961687571265678</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.945227772283215</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.7">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7.18198403648803,-1.26818700114025</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.5</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.620215569426356</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
<gml:featureMember>
<ogr:join_points_to_layers_discard fid="points.8">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0.220296465222349,-1.21071835803877</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>lines.1</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>0.210718358038768</ogr:distance>
</ogr:join_points_to_layers_discard>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -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="join_points_to_layers_discard" type="ogr:join_points_to_layers_discard_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="join_points_to_layers_discard_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="fid_2" 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="n" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</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>
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ join_to_nearest_no_matches.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0.201140250855188</gml:X><gml:Y>-4.827594070695552</gml:Y></gml:coord>
<gml:coord><gml:X>7.971265678449257</gml:X><gml:Y>1.578563283922463</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_to_nearest_no_matches fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.25860889395667,1.57856328392246</gml:coordinates></gml:Point></ogr:geometryProperty>
</ogr:join_to_nearest_no_matches>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_no_matches fid="points.5">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0.201140250855188,-4.82759407069555</gml:coordinates></gml:Point></ogr:geometryProperty>
</ogr:join_to_nearest_no_matches>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_no_matches fid="points.6">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7.97126567844926,0.609122006841505</gml:coordinates></gml:Point></ogr:geometryProperty>
</ogr:join_to_nearest_no_matches>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,23 @@
<?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="join_to_nearest_no_matches" type="ogr:join_to_nearest_no_matches_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="join_to_nearest_no_matches_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ogr.maptools.org/ join_to_nearest_self.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0.201140250855188</gml:X><gml:Y>-4.827594070695552</gml:Y></gml:coord>
<gml:coord><gml:X>7.971265678449257</gml:X><gml:Y>2.74139110604333</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_to_nearest_self fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>1.4142135623731</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3.13409350057012,2.74139110604333</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>1.3549276143601</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.1</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>1.3549276143601</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5.25860889395667,1.57856328392246</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.4</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>1.69120460054011</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3.68392246294185,0.961687571265678</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.3</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>1.69120460054011</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.5">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0.201140250855188,-4.82759407069555</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.8</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>3.61692644124198</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.6">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7.97126567844926,0.609122006841505</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.7</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>2.03648094068824</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.7">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7.18198403648803,-1.26818700114025</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.6</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>2.03648094068824</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
<gml:featureMember>
<ogr:join_to_nearest_self fid="points.8">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0.220296465222349,-1.21071835803877</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:fid_2>points.0</ogr:fid_2>
<ogr:n>1</ogr:n>
<ogr:distance>2.34418712152302</ogr:distance>
</ogr:join_to_nearest_self>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -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="join_to_nearest_self" type="ogr:join_to_nearest_self_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="join_to_nearest_self_Type">
<xs:complexContent>
<xs:extension base="gml:AbstractFeatureType">
<xs:sequence>
<xs:element name="geometryProperty" type="gml:PointPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
<xs:element name="fid_2" 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="n" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:totalDigits value="10"/>
</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>

0 comments on commit 95af4d4

Please sign in to comment.