Skip to content

Commit c9c1f32

Browse files
committed
Allow GeoJSON with only geometry in extract
Most GeoJSON files have Features or FeatureCollections in them. But it is allowed to have only geometries without a Feature around them. For our use case we don't need any properties on the features, just the (multi)polygon geometry. So lets support this. Fixes #286
1 parent 4b787e0 commit c9c1f32

File tree

4 files changed

+180
-11
lines changed

4 files changed

+180
-11
lines changed

src/extract/geojson_file_parser.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,19 @@ GeoJSONFileParser::GeoJSONFileParser(osmium::memory::Buffer& buffer, std::string
179179
}
180180
}
181181

182+
const nlohmann::json& GeoJSONFileParser::get_coordinates(const nlohmann::json& json_geometry) {
183+
const auto json_coordinates = json_geometry.find("coordinates");
184+
if (json_coordinates == json_geometry.end()) {
185+
error("Missing 'coordinates' name in 'geometry' object.");
186+
}
187+
188+
if (!json_coordinates->is_array()) {
189+
error("Expected 'geometry.coordinates' value to be an array.");
190+
}
191+
192+
return *json_coordinates;
193+
}
194+
182195
std::size_t GeoJSONFileParser::parse_top(const nlohmann::json& top) {
183196
const auto json_geometry = top.find("geometry");
184197
if (json_geometry == top.end()) {
@@ -197,20 +210,13 @@ std::size_t GeoJSONFileParser::parse_top(const nlohmann::json& top) {
197210
error("Expected 'geometry.type' value to be 'Polygon' or 'MultiPolygon'.");
198211
}
199212

200-
const auto json_coordinates = json_geometry->find("coordinates");
201-
if (json_coordinates == json_geometry->end()) {
202-
error("Missing 'coordinates' name in 'geometry' object.");
203-
}
204-
205-
if (!json_coordinates->is_array()) {
206-
error("Expected 'geometry.coordinates' value to be an array.");
207-
}
213+
const auto json_coordinates = get_coordinates(*json_geometry);
208214

209215
if (geometry_type == "Polygon") {
210-
return parse_polygon_array(*json_coordinates, &m_buffer);
216+
return parse_polygon_array(json_coordinates, &m_buffer);
211217
}
212218

213-
return parse_multipolygon_array(*json_coordinates, &m_buffer);
219+
return parse_multipolygon_array(json_coordinates, &m_buffer);
214220
}
215221

216222
std::size_t GeoJSONFileParser::operator()() {
@@ -223,7 +229,17 @@ std::size_t GeoJSONFileParser::operator()() {
223229

224230
const std::string type{get_value_as_string(doc, "type")};
225231
if (type.empty()) {
226-
error("Expected 'type' name with the value 'Feature' or 'FeatureCollection'.");
232+
error("Expected 'type' name with the value 'Feature', 'FeatureCollection', 'Polygon', or 'MultiPolygon'.");
233+
}
234+
235+
if (type == "Polygon") {
236+
const auto json_coordinates = get_coordinates(doc);
237+
return parse_polygon_array(json_coordinates, &m_buffer);
238+
}
239+
240+
if (type == "MultiPolygon") {
241+
const auto json_coordinates = get_coordinates(doc);
242+
return parse_multipolygon_array(json_coordinates, &m_buffer);
227243
}
228244

229245
if (type == "Feature") {

src/extract/geojson_file_parser.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class GeoJSONFileParser {
4545

4646
[[noreturn]] void error(const std::string& message);
4747

48+
const nlohmann::json& get_coordinates(const nlohmann::json& json_geometry);
49+
4850
std::size_t parse_top(const nlohmann::json& top);
4951

5052
public:

test/extract/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,6 @@ check_extract_opl(antimeridian-alaska-west-json w46113981.osm w46113981.opl "--p
4747
check_extract_opl(antimeridian-alaska-east-poly w42394837.osm w42394837.opl "--polygon=extract/polygon-us-alaska.poly")
4848
check_extract_opl(antimeridian-alaska-west-poly w46113981.osm w46113981.opl "--polygon=extract/polygon-us-alaska.poly")
4949

50+
check_extract_opl(antimeridian-alaska-east-json-no-feature w42394837.osm w42394837.opl "--polygon=extract/polygon-us-alaska-no-feature.geojson")
51+
5052
#-----------------------------------------------------------------------------
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
{
2+
"type": "MultiPolygon",
3+
"coordinates": [
4+
[
5+
[
6+
[
7+
180,
8+
54.19453
9+
],
10+
[
11+
180,
12+
51.11044
13+
],
14+
[
15+
171.7602,
16+
51.13801
17+
],
18+
[
19+
171.8152,
20+
54.08518
21+
],
22+
[
23+
180,
24+
54.19453
25+
]
26+
]
27+
],
28+
[
29+
[
30+
[
31+
-180,
32+
49.80942
33+
],
34+
[
35+
-180,
36+
60.09775
37+
],
38+
[
39+
-169.0686,
40+
65.40802
41+
],
42+
[
43+
-168.9478,
44+
66.01132
45+
],
46+
[
47+
-169.1147,
48+
71.19564
49+
],
50+
[
51+
-140.9715,
52+
72.98845
53+
],
54+
[
55+
-140.9775,
56+
60.31064
57+
],
58+
[
59+
-139.0488,
60+
60.36127
61+
],
62+
[
63+
-139.1508,
64+
60.10438
65+
],
66+
[
67+
-138.6734,
68+
59.9144
69+
],
70+
[
71+
-138.6363,
72+
59.81201
73+
],
74+
[
75+
-137.5517,
76+
59.23372
77+
],
78+
[
79+
-137.4664,
80+
58.94576
81+
],
82+
[
83+
-136.7081,
84+
59.21237
85+
],
86+
[
87+
-136.3698,
88+
59.61097
89+
],
90+
[
91+
-135.3911,
92+
59.82867
93+
],
94+
[
95+
-134.7243,
96+
59.3922
97+
],
98+
[
99+
-134.4972,
100+
59.15539
101+
],
102+
[
103+
-133.3385,
104+
58.42044
105+
],
106+
[
107+
-131.6441,
108+
56.6537
109+
],
110+
[
111+
-129.7998,
112+
56.04294
113+
],
114+
[
115+
-130.1171,
116+
55.74696
117+
],
118+
[
119+
-129.8715,
120+
55.26134
121+
],
122+
[
123+
-130.5575,
124+
54.64634
125+
],
126+
[
127+
-131.6262,
128+
54.4781
129+
],
130+
[
131+
-132.6944,
132+
54.45706
133+
],
134+
[
135+
-133.7018,
136+
54.51622
137+
],
138+
[
139+
-133.5648,
140+
53.42951
141+
],
142+
[
143+
-180,
144+
49.80942
145+
]
146+
]
147+
]
148+
]
149+
}

0 commit comments

Comments
 (0)