Skip to content

Commit

Permalink
[FEATURE] Reworked processing 'Join by location' alg
Browse files Browse the repository at this point in the history
Improvements:
- transparently handle different source/join CRS
- added option to create output feature for EVERY joined
feature (i.e. 1 to many type join)
- added option to select joined fields to take
- optimised performance of algorithm

The previous option to create a summary of joined features has been
removed, and will be moved to a separate 'Join by location (summary)'
algorithm.
  • Loading branch information
nyalldawson committed Sep 12, 2017
1 parent 5614df4 commit 458e994
Show file tree
Hide file tree
Showing 15 changed files with 1,054 additions and 190 deletions.
6 changes: 2 additions & 4 deletions python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py
Expand Up @@ -150,6 +150,7 @@
from .SnapGeometries import SnapGeometriesToLayer
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
from .SpatialIndex import SpatialIndex
from .SpatialJoin import SpatialJoin
from .SplitWithLines import SplitWithLines
from .StatisticsByCategories import StatisticsByCategories
from .SumLines import SumLines
Expand All @@ -166,7 +167,6 @@
from .VoronoiPolygons import VoronoiPolygons
from .ZonalStatistics import ZonalStatistics

# from .SpatialJoin import SpatialJoin

pluginPath = os.path.normpath(os.path.join(
os.path.split(os.path.dirname(__file__))[0], os.pardir))
Expand All @@ -180,9 +180,6 @@ def __init__(self):
self.externalAlgs = []

def getAlgs(self):
# algs = [
# SpatialJoin(),
# ]
algs = [AddTableField(),
Aggregate(),
Aspect(),
Expand Down Expand Up @@ -293,6 +290,7 @@ def getAlgs(self):
SnapGeometriesToLayer(),
SpatialiteExecuteSQL(),
SpatialIndex(),
SpatialJoin(),
SplitWithLines(),
StatisticsByCategories(),
SumLines(),
Expand Down
323 changes: 138 additions & 185 deletions python/plugins/processing/algs/qgis/SpatialJoin.py

Large diffs are not rendered by default.

@@ -0,0 +1,48 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>join_by_location_intersect</Name>
<ElementPath>join_by_location_intersect</ElementPath>
<!--POLYGON-->
<GeometryType>3</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>10</FeatureCount>
<ExtentXMin>-1.00000</ExtentXMin>
<ExtentXMax>10.00000</ExtentXMax>
<ExtentYMin>-3.00000</ExtentYMin>
<ExtentYMax>6.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>5</Width>
</PropertyDefn>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>floatval</Name>
<ElementPath>floatval</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>fid_2</Name>
<ElementPath>fid_2</ElementPath>
<Type>String</Type>
<Width>8</Width>
</PropertyDefn>
<PropertyDefn>
<Name>id</Name>
<ElementPath>id</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>id2</Name>
<ElementPath>id2</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
<gml:coord><gml:X>10</gml:X><gml:Y>6</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.0</ogr:fid_2>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.1</ogr:fid_2>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.5">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>elim</ogr:name>
<ogr:intval>2</ogr:intval>
<ogr:floatval>3.33</ogr:floatval>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.5">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>elim</ogr:name>
<ogr:intval>2</ogr:intval>
<ogr:floatval>3.33</ogr:floatval>
<ogr:fid_2>points.4</ogr:fid_2>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.3">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,1 10,1 10,-3 6,-3 6,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>7,0 7,-2 9,-2 9,0 7,0</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>ASDF</ogr:name>
<ogr:intval>0</ogr:intval>
<ogr:fid_2>points.7</ogr:fid_2>
<ogr:id>8</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.8</ogr:fid_2>
<ogr:id>9</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.2">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>bbaaa</ogr:name>
<ogr:floatval>0.123</ogr:floatval>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.1">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,5 6,4 4,4 5,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>Aaaaa</ogr:name>
<ogr:intval>-33</ogr:intval>
<ogr:floatval>0</ogr:floatval>
</ogr:join_by_location_intersect>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect fid="polys.4">
<ogr:intval>120</ogr:intval>
<ogr:floatval>-100291.43213</ogr:floatval>
</ogr:join_by_location_intersect>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,48 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>join_by_location_intersect_discardnomatch</Name>
<ElementPath>join_by_location_intersect_discardnomatch</ElementPath>
<!--POLYGON-->
<GeometryType>3</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>7</FeatureCount>
<ExtentXMin>-1.00000</ExtentXMin>
<ExtentXMax>10.00000</ExtentXMax>
<ExtentYMin>-3.00000</ExtentYMin>
<ExtentYMax>3.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>5</Width>
</PropertyDefn>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>floatval</Name>
<ElementPath>floatval</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>fid_2</Name>
<ElementPath>fid_2</ElementPath>
<Type>String</Type>
<Width>8</Width>
</PropertyDefn>
<PropertyDefn>
<Name>id</Name>
<ElementPath>id</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>id2</Name>
<ElementPath>id2</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>
@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
<gml:coord><gml:X>10</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.0</ogr:fid_2>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.1</ogr:fid_2>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.5">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>elim</ogr:name>
<ogr:intval>2</ogr:intval>
<ogr:floatval>3.33</ogr:floatval>
<ogr:fid_2>points.2</ogr:fid_2>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.5">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>3,2 6,1 6,-3 2,-1 2,2 3,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>elim</ogr:name>
<ogr:intval>2</ogr:intval>
<ogr:floatval>3.33</ogr:floatval>
<ogr:fid_2>points.4</ogr:fid_2>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.3">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>6,1 10,1 10,-3 6,-3 6,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>7,0 7,-2 9,-2 9,0 7,0</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>ASDF</ogr:name>
<ogr:intval>0</ogr:intval>
<ogr:fid_2>points.7</ogr:fid_2>
<ogr:id>8</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_intersect_discardnomatch fid="polys.0">
<ogr:geometryProperty><gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-1,-1 -1,3 3,3 3,2 2,2 2,-1 -1,-1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>
<ogr:name>aaaaa</ogr:name>
<ogr:intval>33</ogr:intval>
<ogr:floatval>44.123456</ogr:floatval>
<ogr:fid_2>points.8</ogr:fid_2>
<ogr:id>9</ogr:id>
<ogr:id2>0</ogr:id2>
</ogr:join_by_location_intersect_discardnomatch>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,48 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>join_by_location_intersect_first_only</Name>
<ElementPath>join_by_location_intersect_first_only</ElementPath>
<!--POLYGON-->
<GeometryType>3</GeometryType>
<SRSName>EPSG:4326</SRSName>
<DatasetSpecificInfo>
<FeatureCount>6</FeatureCount>
<ExtentXMin>-1.00000</ExtentXMin>
<ExtentXMax>10.00000</ExtentXMax>
<ExtentYMin>-3.00000</ExtentYMin>
<ExtentYMax>6.00000</ExtentYMax>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>5</Width>
</PropertyDefn>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>floatval</Name>
<ElementPath>floatval</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>fid_2</Name>
<ElementPath>fid_2</ElementPath>
<Type>String</Type>
<Width>8</Width>
</PropertyDefn>
<PropertyDefn>
<Name>id</Name>
<ElementPath>id</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>id2</Name>
<ElementPath>id2</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

0 comments on commit 458e994

Please sign in to comment.