Skip to content

Commit

Permalink
[processing] Allow choice of field prefix for Join algorithms
Browse files Browse the repository at this point in the history
Avoids clash of field names resulting in potentially misleading results
  • Loading branch information
nyalldawson committed Jun 7, 2018
1 parent 42c0b39 commit 22a98fb
Show file tree
Hide file tree
Showing 7 changed files with 423 additions and 1 deletion.
15 changes: 14 additions & 1 deletion python/plugins/processing/algs/qgis/SpatialJoin.py
Expand Up @@ -40,7 +40,8 @@
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSink)
QgsProcessingParameterFeatureSink,
QgsProcessingParameterString)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import vector
Expand All @@ -55,6 +56,7 @@ class SpatialJoin(QgisAlgorithm):
JOIN_FIELDS = "JOIN_FIELDS"
METHOD = "METHOD"
DISCARD_NONMATCHING = "DISCARD_NONMATCHING"
PREFIX = "PREFIX"
OUTPUT = "OUTPUT"

def group(self):
Expand Down Expand Up @@ -115,6 +117,8 @@ def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterBoolean(self.DISCARD_NONMATCHING,
self.tr('Discard records which could not be joined'),
defaultValue=False))
self.addParameter(QgsProcessingParameterString(self.PREFIX,
self.tr('Joined field prefix'), optional=True))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT,
self.tr('Joined layer')))

Expand All @@ -139,6 +143,7 @@ def processAlgorithm(self, parameters, context, feedback):
join_fields = self.parameterAsFields(parameters, self.JOIN_FIELDS, context)
method = self.parameterAsEnum(parameters, self.METHOD, context)
discard_nomatch = self.parameterAsBool(parameters, self.DISCARD_NONMATCHING, context)
prefix = self.parameterAsString(parameters, self.PREFIX, context)

source_fields = source.fields()
fields_to_join = QgsFields()
Expand All @@ -153,6 +158,14 @@ def processAlgorithm(self, parameters, context, feedback):
if idx >= 0:
fields_to_join.append(join_source.fields().at(idx))

if prefix:
prefixed_fields = QgsFields()
for i in range(len(fields_to_join)):
field = fields_to_join[i]
field.setName(prefix + field.name())
prefixed_fields.append(field)
fields_to_join = prefixed_fields

out_fields = QgsProcessingUtils.combineFields(source_fields, fields_to_join)

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
Expand Down
@@ -0,0 +1,104 @@
<?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_attributes_with_prefix.xsd"
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy>
<gml:Box>
<gml:coord><gml:X>0</gml:X><gml:Y>-5</gml:Y></gml:coord>
<gml:coord><gml:X>8</gml:X><gml:Y>3</gml:Y></gml:coord>
</gml:Box>
</gml:boundedBy>

<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.0">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>1,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>1</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:j_ID>1</ogr:j_ID>
<ogr:j_NUM_A>1.100000</ogr:j_NUM_A>
<ogr:j_ST_A>string a</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.1">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>3,3</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>2</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:j_ID>2</ogr:j_ID>
<ogr:j_NUM_A>2.200000</ogr:j_NUM_A>
<ogr:j_ST_A>string a</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.2">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>2,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>3</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:j_ID>3</ogr:j_ID>
<ogr:j_NUM_A>3.300000</ogr:j_NUM_A>
<ogr:j_ST_A>string a</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.3">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>5,2</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>4</ogr:id>
<ogr:id2>2</ogr:id2>
<ogr:j_ID>4</ogr:j_ID>
<ogr:j_NUM_A>4.400000</ogr:j_NUM_A>
<ogr:j_ST_A>string b</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.4">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>4,1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>5</ogr:id>
<ogr:id2>1</ogr:id2>
<ogr:j_ID>5</ogr:j_ID>
<ogr:j_NUM_A>5.500000</ogr:j_NUM_A>
<ogr:j_ST_A>string b</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.5">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-5</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>6</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:j_ID>6</ogr:j_ID>
<ogr:j_NUM_A>6.600000</ogr:j_NUM_A>
<ogr:j_ST_A>string b</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.6">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>8,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>7</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:j_ID>7</ogr:j_ID>
<ogr:j_NUM_A>7.700000</ogr:j_NUM_A>
<ogr:j_ST_A>string b</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.7">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>7,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>8</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:j_ID>8</ogr:j_ID>
<ogr:j_NUM_A>8.800000</ogr:j_NUM_A>
<ogr:j_ST_A>string b</ogr:j_ST_A>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_attributes_with_prefix fid="points.8">
<ogr:geometryProperty><gml:Point srsName="EPSG:4326"><gml:coordinates>0,-1</gml:coordinates></gml:Point></ogr:geometryProperty>
<ogr:id>9</ogr:id>
<ogr:id2>0</ogr:id2>
<ogr:j_ID xsi:nil="true"/>
<ogr:j_NUM_A xsi:nil="true"/>
<ogr:j_ST_A xsi:nil="true"/>
</ogr:join_attributes_with_prefix>
</gml:featureMember>
</ogr:FeatureCollection>
@@ -0,0 +1,59 @@
<?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_attributes_with_prefix" type="ogr:join_attributes_with_prefix_Type" substitutionGroup="gml:_Feature"/>
<xs:complexType name="join_attributes_with_prefix_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="id" 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="id2" 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="j_ID" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:long">
<xs:totalDigits value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="j_NUM_A" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="19"/>
<xs:fractionDigits value="6"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="j_ST_A" nillable="true" minOccurs="0" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
@@ -0,0 +1,123 @@
<?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_by_location_prefix.xsd"
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_prefix 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:j_fid>points.0</ogr:j_fid>
<ogr:j_id>1</ogr:j_id>
<ogr:j_id2>2</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid>points.1</ogr:j_fid>
<ogr:j_id>2</ogr:j_id>
<ogr:j_id2>1</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid>points.2</ogr:j_fid>
<ogr:j_id>3</ogr:j_id>
<ogr:j_id2>0</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid>points.2</ogr:j_fid>
<ogr:j_id>3</ogr:j_id>
<ogr:j_id2>0</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid>points.4</ogr:j_fid>
<ogr:j_id>5</ogr:j_id>
<ogr:j_id2>1</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:floatval xsi:nil="true"/>
<ogr:j_fid>points.7</ogr:j_fid>
<ogr:j_id>8</ogr:j_id>
<ogr:j_id2>0</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid>points.8</ogr:j_fid>
<ogr:j_id>9</ogr:j_id>
<ogr:j_id2>0</ogr:j_id2>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix fid="polys.4">
<ogr:name xsi:nil="true"/>
<ogr:intval>120</ogr:intval>
<ogr:floatval>-100291.43213</ogr:floatval>
<ogr:j_fid xsi:nil="true"/>
<ogr:j_id xsi:nil="true"/>
<ogr:j_id2 xsi:nil="true"/>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:j_fid xsi:nil="true"/>
<ogr:j_id xsi:nil="true"/>
<ogr:j_id2 xsi:nil="true"/>
</ogr:join_by_location_prefix>
</gml:featureMember>
<gml:featureMember>
<ogr:join_by_location_prefix 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:intval xsi:nil="true"/>
<ogr:floatval>0.123</ogr:floatval>
<ogr:j_fid xsi:nil="true"/>
<ogr:j_id xsi:nil="true"/>
<ogr:j_id2 xsi:nil="true"/>
</ogr:join_by_location_prefix>
</gml:featureMember>
</ogr:FeatureCollection>

0 comments on commit 22a98fb

Please sign in to comment.