Skip to content

Commit 6e16651

Browse files
Gustrynirvn
authored andcommittedNov 9, 2018
[FEATURE] explode hstore algorithm (#8212)
1 parent df81e55 commit 6e16651

File tree

11 files changed

+673
-0
lines changed

11 files changed

+673
-0
lines changed
 
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ hstore.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10</gml:X><gml:Y>6</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:hstore fid="polys.0">
16+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
17+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;barrier&quot;=&gt;&quot;wall&quot;,&quot;cuisine&quot;=&gt;&quot;chinese&quot;,&quot;internet_access&quot;=&gt;&quot;yes&quot;</ogr:hstore>
18+
</ogr:hstore>
19+
</gml:featureMember>
20+
<gml:featureMember>
21+
<ogr:hstore fid="polys.1">
22+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,5 6,4 4,4 5,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
23+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;fuel&quot;,&quot;building&quot;=&gt;&quot;roof&quot;,&quot;name&quot;=&gt;&quot;foo&quot;</ogr:hstore>
24+
</ogr:hstore>
25+
</gml:featureMember>
26+
<gml:featureMember>
27+
<ogr:hstore fid="polys.2">
28+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
29+
<ogr:hstore>&quot;building&quot;=&gt;&quot;yes&quot;</ogr:hstore>
30+
</ogr:hstore>
31+
</gml:featureMember>
32+
<gml:featureMember>
33+
<ogr:hstore fid="polys.3">
34+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
35+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;cuisine&quot;=&gt;&quot;burger&quot;,&quot;name&quot;=&gt;&quot;bar&quot;,&quot;operator&quot;=&gt;&quot;foo&quot;</ogr:hstore>
36+
</ogr:hstore>
37+
</gml:featureMember>
38+
<gml:featureMember>
39+
<ogr:hstore fid="polys.4">
40+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;bank&quot;,&quot;atm&quot;=&gt;&quot;yes&quot;</ogr:hstore>
41+
</ogr:hstore>
42+
</gml:featureMember>
43+
<gml:featureMember>
44+
<ogr:hstore fid="polys.5">
45+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
46+
<ogr:hstore>&quot;stars&quot;=&gt;&quot;5&quot;,&quot;tourism&quot;=&gt;&quot;hotel&quot;</ogr:hstore>
47+
</ogr:hstore>
48+
</gml:featureMember>
49+
</ogr:FeatureCollection>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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="hstore" type="ogr:hstore_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="hstore_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="hstore" 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:sequence>
27+
</xs:extension>
28+
</xs:complexContent>
29+
</xs:complexType>
30+
</xs:schema>
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ hstore_all_keys.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10</gml:X><gml:Y>6</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:hstore_all_keys fid="polys.0">
16+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
17+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;barrier&quot;=&gt;&quot;wall&quot;,&quot;cuisine&quot;=&gt;&quot;chinese&quot;,&quot;internet_access&quot;=&gt;&quot;yes&quot;</ogr:hstore>
18+
<ogr:tourism xsi:nil="true"/>
19+
<ogr:stars xsi:nil="true"/>
20+
<ogr:atm xsi:nil="true"/>
21+
<ogr:operator xsi:nil="true"/>
22+
<ogr:name xsi:nil="true"/>
23+
<ogr:building xsi:nil="true"/>
24+
<ogr:internet_access>yes</ogr:internet_access>
25+
<ogr:cuisine>chinese</ogr:cuisine>
26+
<ogr:barrier>wall</ogr:barrier>
27+
<ogr:amenity>restaurant</ogr:amenity>
28+
</ogr:hstore_all_keys>
29+
</gml:featureMember>
30+
<gml:featureMember>
31+
<ogr:hstore_all_keys fid="polys.1">
32+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,5 6,4 4,4 5,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
33+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;fuel&quot;,&quot;building&quot;=&gt;&quot;roof&quot;,&quot;name&quot;=&gt;&quot;foo&quot;</ogr:hstore>
34+
<ogr:tourism xsi:nil="true"/>
35+
<ogr:stars xsi:nil="true"/>
36+
<ogr:atm xsi:nil="true"/>
37+
<ogr:operator xsi:nil="true"/>
38+
<ogr:name>foo</ogr:name>
39+
<ogr:building>roof</ogr:building>
40+
<ogr:internet_access xsi:nil="true"/>
41+
<ogr:cuisine xsi:nil="true"/>
42+
<ogr:barrier xsi:nil="true"/>
43+
<ogr:amenity>fuel</ogr:amenity>
44+
</ogr:hstore_all_keys>
45+
</gml:featureMember>
46+
<gml:featureMember>
47+
<ogr:hstore_all_keys fid="polys.2">
48+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
49+
<ogr:hstore>&quot;building&quot;=&gt;&quot;yes&quot;</ogr:hstore>
50+
<ogr:tourism xsi:nil="true"/>
51+
<ogr:stars xsi:nil="true"/>
52+
<ogr:atm xsi:nil="true"/>
53+
<ogr:operator xsi:nil="true"/>
54+
<ogr:name xsi:nil="true"/>
55+
<ogr:building>yes</ogr:building>
56+
<ogr:internet_access xsi:nil="true"/>
57+
<ogr:cuisine xsi:nil="true"/>
58+
<ogr:barrier xsi:nil="true"/>
59+
<ogr:amenity xsi:nil="true"/>
60+
</ogr:hstore_all_keys>
61+
</gml:featureMember>
62+
<gml:featureMember>
63+
<ogr:hstore_all_keys fid="polys.3">
64+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
65+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;cuisine&quot;=&gt;&quot;burger&quot;,&quot;name&quot;=&gt;&quot;bar&quot;,&quot;operator&quot;=&gt;&quot;foo&quot;</ogr:hstore>
66+
<ogr:tourism xsi:nil="true"/>
67+
<ogr:stars xsi:nil="true"/>
68+
<ogr:atm xsi:nil="true"/>
69+
<ogr:operator>foo</ogr:operator>
70+
<ogr:name>bar</ogr:name>
71+
<ogr:building xsi:nil="true"/>
72+
<ogr:internet_access xsi:nil="true"/>
73+
<ogr:cuisine>burger</ogr:cuisine>
74+
<ogr:barrier xsi:nil="true"/>
75+
<ogr:amenity>restaurant</ogr:amenity>
76+
</ogr:hstore_all_keys>
77+
</gml:featureMember>
78+
<gml:featureMember>
79+
<ogr:hstore_all_keys fid="polys.4">
80+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;bank&quot;,&quot;atm&quot;=&gt;&quot;yes&quot;</ogr:hstore>
81+
<ogr:tourism xsi:nil="true"/>
82+
<ogr:stars xsi:nil="true"/>
83+
<ogr:atm>yes</ogr:atm>
84+
<ogr:operator xsi:nil="true"/>
85+
<ogr:name xsi:nil="true"/>
86+
<ogr:building xsi:nil="true"/>
87+
<ogr:internet_access xsi:nil="true"/>
88+
<ogr:cuisine xsi:nil="true"/>
89+
<ogr:barrier xsi:nil="true"/>
90+
<ogr:amenity>bank</ogr:amenity>
91+
</ogr:hstore_all_keys>
92+
</gml:featureMember>
93+
<gml:featureMember>
94+
<ogr:hstore_all_keys fid="polys.5">
95+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
96+
<ogr:hstore>&quot;stars&quot;=&gt;&quot;5&quot;,&quot;tourism&quot;=&gt;&quot;hotel&quot;</ogr:hstore>
97+
<ogr:tourism>hotel</ogr:tourism>
98+
<ogr:stars>5</ogr:stars>
99+
<ogr:atm xsi:nil="true"/>
100+
<ogr:operator xsi:nil="true"/>
101+
<ogr:name xsi:nil="true"/>
102+
<ogr:building xsi:nil="true"/>
103+
<ogr:internet_access xsi:nil="true"/>
104+
<ogr:cuisine xsi:nil="true"/>
105+
<ogr:barrier xsi:nil="true"/>
106+
<ogr:amenity xsi:nil="true"/>
107+
</ogr:hstore_all_keys>
108+
</gml:featureMember>
109+
</ogr:FeatureCollection>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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="hstore_all_keys" type="ogr:hstore_all_keys_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="hstore_all_keys_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="hstore" 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="tourism" 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="stars" nillable="true" minOccurs="0" maxOccurs="1">
34+
<xs:simpleType>
35+
<xs:restriction base="xs:string">
36+
<xs:maxLength value="255"/>
37+
</xs:restriction>
38+
</xs:simpleType>
39+
</xs:element>
40+
<xs:element name="atm" nillable="true" minOccurs="0" maxOccurs="1">
41+
<xs:simpleType>
42+
<xs:restriction base="xs:string">
43+
<xs:maxLength value="255"/>
44+
</xs:restriction>
45+
</xs:simpleType>
46+
</xs:element>
47+
<xs:element name="operator" nillable="true" minOccurs="0" maxOccurs="1">
48+
<xs:simpleType>
49+
<xs:restriction base="xs:string">
50+
<xs:maxLength value="255"/>
51+
</xs:restriction>
52+
</xs:simpleType>
53+
</xs:element>
54+
<xs:element name="name" nillable="true" minOccurs="0" maxOccurs="1">
55+
<xs:simpleType>
56+
<xs:restriction base="xs:string">
57+
<xs:maxLength value="255"/>
58+
</xs:restriction>
59+
</xs:simpleType>
60+
</xs:element>
61+
<xs:element name="building" nillable="true" minOccurs="0" maxOccurs="1">
62+
<xs:simpleType>
63+
<xs:restriction base="xs:string">
64+
<xs:maxLength value="255"/>
65+
</xs:restriction>
66+
</xs:simpleType>
67+
</xs:element>
68+
<xs:element name="internet_access" nillable="true" minOccurs="0" maxOccurs="1">
69+
<xs:simpleType>
70+
<xs:restriction base="xs:string">
71+
<xs:maxLength value="255"/>
72+
</xs:restriction>
73+
</xs:simpleType>
74+
</xs:element>
75+
<xs:element name="cuisine" nillable="true" minOccurs="0" maxOccurs="1">
76+
<xs:simpleType>
77+
<xs:restriction base="xs:string">
78+
<xs:maxLength value="255"/>
79+
</xs:restriction>
80+
</xs:simpleType>
81+
</xs:element>
82+
<xs:element name="barrier" nillable="true" minOccurs="0" maxOccurs="1">
83+
<xs:simpleType>
84+
<xs:restriction base="xs:string">
85+
<xs:maxLength value="255"/>
86+
</xs:restriction>
87+
</xs:simpleType>
88+
</xs:element>
89+
<xs:element name="amenity" nillable="true" minOccurs="0" maxOccurs="1">
90+
<xs:simpleType>
91+
<xs:restriction base="xs:string">
92+
<xs:maxLength value="255"/>
93+
</xs:restriction>
94+
</xs:simpleType>
95+
</xs:element>
96+
</xs:sequence>
97+
</xs:extension>
98+
</xs:complexContent>
99+
</xs:complexType>
100+
</xs:schema>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ogr:FeatureCollection
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://ogr.maptools.org/ hstore_two_fields.xsd"
5+
xmlns:ogr="http://ogr.maptools.org/"
6+
xmlns:gml="http://www.opengis.net/gml">
7+
<gml:boundedBy>
8+
<gml:Box>
9+
<gml:coord><gml:X>-1</gml:X><gml:Y>-3</gml:Y></gml:coord>
10+
<gml:coord><gml:X>10</gml:X><gml:Y>6</gml:Y></gml:coord>
11+
</gml:Box>
12+
</gml:boundedBy>
13+
14+
<gml:featureMember>
15+
<ogr:hstore_two_fields fid="polys.0">
16+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
17+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;barrier&quot;=&gt;&quot;wall&quot;</ogr:hstore>
18+
<ogr:internet_access>yes</ogr:internet_access>
19+
<ogr:cuisine>chinese</ogr:cuisine>
20+
<ogr:doesntexist xsi:nil="true"/>
21+
</ogr:hstore_two_fields>
22+
</gml:featureMember>
23+
<gml:featureMember>
24+
<ogr:hstore_two_fields fid="polys.1">
25+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>5,5 6,4 4,4 5,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
26+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;fuel&quot;,&quot;building&quot;=&gt;&quot;roof&quot;,&quot;name&quot;=&gt;&quot;foo&quot;</ogr:hstore>
27+
<ogr:internet_access xsi:nil="true"/>
28+
<ogr:cuisine xsi:nil="true"/>
29+
<ogr:doesntexist xsi:nil="true"/>
30+
</ogr:hstore_two_fields>
31+
</gml:featureMember>
32+
<gml:featureMember>
33+
<ogr:hstore_two_fields fid="polys.2">
34+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,5 2,6 3,6 3,5 2,5</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
35+
<ogr:hstore>&quot;building&quot;=&gt;&quot;yes&quot;</ogr:hstore>
36+
<ogr:internet_access xsi:nil="true"/>
37+
<ogr:cuisine xsi:nil="true"/>
38+
<ogr:doesntexist xsi:nil="true"/>
39+
</ogr:hstore_two_fields>
40+
</gml:featureMember>
41+
<gml:featureMember>
42+
<ogr:hstore_two_fields fid="polys.3">
43+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
44+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;restaurant&quot;,&quot;name&quot;=&gt;&quot;bar&quot;,&quot;operator&quot;=&gt;&quot;foo&quot;</ogr:hstore>
45+
<ogr:internet_access xsi:nil="true"/>
46+
<ogr:cuisine>burger</ogr:cuisine>
47+
<ogr:doesntexist xsi:nil="true"/>
48+
</ogr:hstore_two_fields>
49+
</gml:featureMember>
50+
<gml:featureMember>
51+
<ogr:hstore_two_fields fid="polys.4">
52+
<ogr:hstore>&quot;amenity&quot;=&gt;&quot;bank&quot;,&quot;atm&quot;=&gt;&quot;yes&quot;</ogr:hstore>
53+
<ogr:internet_access xsi:nil="true"/>
54+
<ogr:cuisine xsi:nil="true"/>
55+
<ogr:doesntexist xsi:nil="true"/>
56+
</ogr:hstore_two_fields>
57+
</gml:featureMember>
58+
<gml:featureMember>
59+
<ogr:hstore_two_fields fid="polys.5">
60+
<ogr:geometryProperty><gml:MultiPolygon srsName="EPSG:4326"><gml:polygonMember><gml:Polygon><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></gml:polygonMember></gml:MultiPolygon></ogr:geometryProperty>
61+
<ogr:hstore>&quot;stars&quot;=&gt;&quot;5&quot;,&quot;tourism&quot;=&gt;&quot;hotel&quot;</ogr:hstore>
62+
<ogr:internet_access xsi:nil="true"/>
63+
<ogr:cuisine xsi:nil="true"/>
64+
<ogr:doesntexist xsi:nil="true"/>
65+
</ogr:hstore_two_fields>
66+
</gml:featureMember>
67+
</ogr:FeatureCollection>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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="hstore_two_fields" type="ogr:hstore_two_fields_Type" substitutionGroup="gml:_Feature"/>
14+
<xs:complexType name="hstore_two_fields_Type">
15+
<xs:complexContent>
16+
<xs:extension base="gml:AbstractFeatureType">
17+
<xs:sequence>
18+
<xs:element name="geometryProperty" type="gml:MultiPolygonPropertyType" nillable="true" minOccurs="0" maxOccurs="1"/>
19+
<xs:element name="hstore" 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="internet_access" 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="cuisine" nillable="true" minOccurs="0" maxOccurs="1">
34+
<xs:simpleType>
35+
<xs:restriction base="xs:string">
36+
<xs:maxLength value="255"/>
37+
</xs:restriction>
38+
</xs:simpleType>
39+
</xs:element>
40+
<xs:element name="doesntexist" nillable="true" minOccurs="0" maxOccurs="1">
41+
<xs:simpleType>
42+
<xs:restriction base="xs:string">
43+
<xs:maxLength value="255"/>
44+
</xs:restriction>
45+
</xs:simpleType>
46+
</xs:element>
47+
</xs:sequence>
48+
</xs:extension>
49+
</xs:complexContent>
50+
</xs:complexType>
51+
</xs:schema>

‎python/plugins/processing/tests/testdata/qgis_algorithm_tests.yaml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,32 @@ tests:
914914
name: expected/zm_dropped.shp
915915
type: vector
916916

917+
- algorithm: native:explodehstorefield
918+
name: Test explode HStore field with all keys
919+
params:
920+
EXPECTED_FIELDS: ''
921+
FIELD: hstore
922+
INPUT:
923+
name: custom/hstore.gml
924+
type: vector
925+
results:
926+
OUTPUT:
927+
name: expected/hstore_all_keys.gml
928+
type: vector
929+
930+
- algorithm: native:explodehstorefield
931+
name: Test explode HStore field with 2 fields
932+
params:
933+
EXPECTED_FIELDS: internet_access,cuisine,doesntexist
934+
FIELD: hstore
935+
INPUT:
936+
name: custom/hstore.gml
937+
type: vector
938+
results:
939+
OUTPUT:
940+
name: expected/hstore_two_fields.gml
941+
type: vector
942+
917943
- algorithm: native:pointonsurface
918944
name: Point on polygon surface
919945
params:

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ SET(QGIS_ANALYSIS_SRCS
3838
processing/qgsalgorithmdropgeometry.cpp
3939
processing/qgsalgorithmdropmzvalues.cpp
4040
processing/qgsalgorithmexplode.cpp
41+
processing/qgsalgorithmexplodehstore.cpp
4142
processing/qgsalgorithmextendlines.cpp
4243
processing/qgsalgorithmextenttolayer.cpp
4344
processing/qgsalgorithmextractbyattribute.cpp
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/***************************************************************************
2+
qgsalgorithmexplodehstore.h
3+
---------------------
4+
begin : September 2018
5+
copyright : (C) 2018 by Etienne Trimaille
6+
email : etienne dot trimaille at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgis.h"
19+
#include "qgsalgorithmexplodehstore.h"
20+
#include "qgshstoreutils.h"
21+
#include "qgsprocessingutils.h"
22+
23+
///@cond PRIVATE
24+
25+
QString QgsExplodeHstoreAlgorithm::name() const
26+
{
27+
return QStringLiteral( "explodehstorefield" );
28+
}
29+
30+
QString QgsExplodeHstoreAlgorithm::displayName() const
31+
{
32+
return QObject::tr( "Explode HStore Field" );
33+
}
34+
35+
QStringList QgsExplodeHstoreAlgorithm::tags() const
36+
{
37+
return QObject::tr( "field,explode,hstore,osm,openstreetmap" ).split( ',' );
38+
}
39+
40+
QString QgsExplodeHstoreAlgorithm::group() const
41+
{
42+
return QObject::tr( "Vector table" );
43+
}
44+
45+
QString QgsExplodeHstoreAlgorithm::groupId() const
46+
{
47+
return QStringLiteral( "vectortable" );
48+
}
49+
50+
QString QgsExplodeHstoreAlgorithm::shortHelpString() const
51+
{
52+
return QObject::tr( "This algorithm creates a copy of the input layer and adds a new field for every unique key in the HStore field.\n"
53+
"The expected field list is an optional comma separated list. By default, all unique keys are added. If this list is specified, only these fields are added and the HStore field is updated." );
54+
}
55+
56+
QgsProcessingAlgorithm *QgsExplodeHstoreAlgorithm::createInstance() const
57+
{
58+
return new QgsExplodeHstoreAlgorithm();
59+
}
60+
61+
void QgsExplodeHstoreAlgorithm::initAlgorithm( const QVariantMap & )
62+
{
63+
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ),
64+
QObject::tr( "Input layer" ) ) );
65+
addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ),
66+
QObject::tr( "HStore field" ), QVariant(), QStringLiteral( "INPUT" ) ) );
67+
addParameter( new QgsProcessingParameterString( QStringLiteral( "EXPECTED_FIELDS" ), QObject::tr( "Expected list of fields separated by a comma" ), QVariant(), false, true ) );
68+
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Exploded" ) ) );
69+
}
70+
71+
QVariantMap QgsExplodeHstoreAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
72+
{
73+
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
74+
if ( !source )
75+
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
76+
int attrSourceCount = source->fields().count();
77+
78+
QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
79+
int fieldIndex = source->fields().lookupField( fieldName );
80+
if ( fieldIndex < 0 )
81+
throw QgsProcessingException( QObject::tr( "Invalid HStore field" ) );
82+
83+
QStringList expectedFields;
84+
QString fieldList = parameterAsString( parameters, QStringLiteral( "EXPECTED_FIELDS" ), context );
85+
if ( ! fieldList.trimmed().isEmpty() )
86+
{
87+
expectedFields = fieldList.split( ',' );
88+
}
89+
90+
QList<QString> fieldsToAdd;
91+
QHash<QgsFeatureId, QVariantMap> hstoreFeatures;
92+
QList<QgsFeature> features;
93+
94+
double step = source->featureCount() > 0 ? 50.0 / source->featureCount() : 1;
95+
int i = 0;
96+
QgsFeatureIterator featIterator = source->getFeatures( );
97+
QgsFeature feat;
98+
while ( featIterator.nextFeature( feat ) )
99+
{
100+
i++;
101+
if ( feedback->isCanceled() )
102+
break;
103+
104+
double progress = i * step;
105+
if ( progress >= 50 )
106+
feedback->setProgress( 50.0 );
107+
else
108+
feedback->setProgress( progress );
109+
110+
QVariantMap currentHStore = QgsHstoreUtils::parse( feat.attribute( fieldName ).toString() );
111+
for ( const QString &key : currentHStore.keys() )
112+
{
113+
if ( expectedFields.isEmpty() && ! fieldsToAdd.contains( key ) )
114+
fieldsToAdd.insert( 0, key );
115+
}
116+
hstoreFeatures.insert( feat.id(), currentHStore );
117+
features.append( feat );
118+
}
119+
120+
if ( ! expectedFields.isEmpty() )
121+
{
122+
fieldsToAdd = expectedFields;
123+
}
124+
125+
QgsFields hstoreFields;
126+
for ( const QString &fieldName : fieldsToAdd )
127+
{
128+
hstoreFields.append( QgsField( fieldName, QVariant::String ) );
129+
}
130+
131+
QgsFields outFields = QgsProcessingUtils::combineFields( source->fields(), hstoreFields );
132+
133+
QString sinkId;
134+
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, sinkId, outFields, source->wkbType(), source->sourceCrs() ) );
135+
if ( !sink )
136+
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
137+
138+
QList<int> fieldIndicesInput = QgsProcessingUtils::fieldNamesToIndices( QStringList(), source->fields() );
139+
int attrCount = attrSourceCount + fieldsToAdd.count();
140+
QgsFeature outFeature;
141+
step = !features.empty() ? 50.0 / features.count() : 1;
142+
i = 0;
143+
for ( const QgsFeature &feat : qgis::as_const( features ) )
144+
{
145+
i++;
146+
if ( feedback->isCanceled() )
147+
break;
148+
149+
feedback->setProgress( i * step + 50.0 );
150+
151+
QgsAttributes outAttributes( attrCount );
152+
153+
const QgsAttributes attrs( feat.attributes() );
154+
for ( int i = 0; i < fieldIndicesInput.count(); ++i )
155+
outAttributes[i] = attrs[fieldIndicesInput[i]];
156+
157+
QVariantMap currentHStore = hstoreFeatures.take( feat.id() );
158+
159+
QString current;
160+
for ( int i = 0; i < fieldsToAdd.count(); ++i )
161+
{
162+
current = fieldsToAdd.at( i );
163+
if ( currentHStore.contains( current ) )
164+
{
165+
outAttributes[attrSourceCount + i] = currentHStore.take( current );
166+
}
167+
}
168+
169+
if ( ! expectedFields.isEmpty() )
170+
{
171+
outAttributes[fieldIndex] = QgsHstoreUtils::build( currentHStore );
172+
}
173+
174+
outFeature.setGeometry( QgsGeometry( feat.geometry() ) );
175+
outFeature.setAttributes( outAttributes );
176+
sink->addFeature( outFeature, QgsFeatureSink::FastInsert );
177+
}
178+
179+
QVariantMap outputs;
180+
outputs.insert( QStringLiteral( "OUTPUT" ), sinkId );
181+
return outputs;
182+
}
183+
184+
///@endcond
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/***************************************************************************
2+
qgsalgorithmexplodehstore.h
3+
---------------------
4+
begin : September 2018
5+
copyright : (C) 2018 by Etienne Trimaille
6+
email : etienne dot trimaille at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSALGORITHMEXPLODEHSTORE_H
19+
#define QGSALGORITHMEXPLODEHSTORE_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgsprocessingalgorithm.h"
25+
26+
///@cond PRIVATE
27+
28+
/**
29+
* Native explode hstore algorithm.
30+
*/
31+
class QgsExplodeHstoreAlgorithm : public QgsProcessingAlgorithm
32+
{
33+
34+
public:
35+
QgsExplodeHstoreAlgorithm() = default;
36+
QString name() const override;
37+
QString displayName() const override;
38+
QString group() const override;
39+
QString groupId() const override;
40+
QStringList tags() const override;
41+
QString shortHelpString() const override;
42+
43+
protected:
44+
QgsProcessingAlgorithm *createInstance() const override;
45+
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
46+
QVariantMap processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
47+
48+
};
49+
50+
///@endcond PRIVATE
51+
52+
#endif // QGSALGORITHMEXPLODEHSTORE_H
53+
54+

‎src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "qgsalgorithmdropgeometry.h"
3434
#include "qgsalgorithmdropmzvalues.h"
3535
#include "qgsalgorithmexplode.h"
36+
#include "qgsalgorithmexplodehstore.h"
3637
#include "qgsalgorithmextendlines.h"
3738
#include "qgsalgorithmextenttolayer.h"
3839
#include "qgsalgorithmextractbyattribute.h"
@@ -158,6 +159,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
158159
addAlgorithm( new QgsDropGeometryAlgorithm() );
159160
addAlgorithm( new QgsDropMZValuesAlgorithm() );
160161
addAlgorithm( new QgsExplodeAlgorithm() );
162+
addAlgorithm( new QgsExplodeHstoreAlgorithm() );
161163
addAlgorithm( new QgsExtendLinesAlgorithm() );
162164
addAlgorithm( new QgsExtentToLayerAlgorithm() );
163165
addAlgorithm( new QgsExtractByAttributeAlgorithm() );

0 commit comments

Comments
 (0)
Please sign in to comment.