|
12 | 12 | from math import ceil |
13 | 13 | from typing import Optional |
14 | 14 |
|
15 | | -import geojson |
16 | 15 | import requests |
17 | | -from shapely.geometry import Point, Polygon |
| 16 | +from osm2geojson import json2geojson |
18 | 17 |
|
19 | 18 | from .errors import ( |
20 | 19 | MultipleRequestsError, |
@@ -131,7 +130,7 @@ def get(self, query, responseformat="geojson", verbosity="body", build=True, dat |
131 | 130 | return response |
132 | 131 |
|
133 | 132 | # construct geojson |
134 | | - return self._as_geojson(response["elements"]) |
| 133 | + return json2geojson(response) |
135 | 134 |
|
136 | 135 | @staticmethod |
137 | 136 | def _api_status() -> dict: |
@@ -275,94 +274,16 @@ def _get_from_overpass(self, query): |
275 | 274 |
|
276 | 275 | self._status = r.status_code |
277 | 276 |
|
278 | | - if self._status == 200: |
279 | | - r.encoding = "utf-8" |
280 | | - return r |
281 | | - elif self._status == 400: |
282 | | - raise OverpassSyntaxError(query) |
283 | | - elif self._status == 429: |
284 | | - raise MultipleRequestsError() |
285 | | - elif self._status == 504: |
286 | | - raise ServerLoadError(self._timeout) |
287 | | - else: |
| 277 | + if self._status != 200: |
| 278 | + if self._status == 400: |
| 279 | + raise OverpassSyntaxError(query) |
| 280 | + elif self._status == 429: |
| 281 | + raise MultipleRequestsError() |
| 282 | + elif self._status == 504: |
| 283 | + raise ServerLoadError(self._timeout) |
288 | 284 | raise UnknownOverpassError( |
289 | | - f"The request returned status code {self._status}" |
| 285 | + "The request returned status code {code}".format(code=self._status) |
290 | 286 | ) |
291 | | - |
292 | | - def _as_geojson(self, elements): |
293 | | - ids_already_seen = set() |
294 | | - features = [] |
295 | | - geometry = None |
296 | | - for elem in elements: |
297 | | - try: |
298 | | - if elem["id"] in ids_already_seen: |
299 | | - continue |
300 | | - ids_already_seen.add(elem["id"]) |
301 | | - except KeyError: |
302 | | - raise UnknownOverpassError("Received corrupt data from Overpass (no id).") |
303 | | - elem_type = elem.get("type") |
304 | | - elem_tags = elem.get("tags", {}) |
305 | | - elem_nodes = elem.get("nodes", None) |
306 | | - elem_timestamp = elem.get("timestamp", None) |
307 | | - elem_user = elem.get("user", None) |
308 | | - elem_uid = elem.get("uid", None) |
309 | | - elem_version = elem.get("version", None) |
310 | | - if elem_nodes: |
311 | | - elem_tags["nodes"] = elem_nodes |
312 | | - if elem_user: |
313 | | - elem_tags["user"] = elem_user |
314 | | - if elem_uid: |
315 | | - elem_tags["uid"] = elem_uid |
316 | | - if elem_version: |
317 | | - elem_tags["version"] = elem_version |
318 | | - elem_geom = elem.get("geometry", []) |
319 | | - if elem_type == "node": |
320 | | - # Create Point geometry |
321 | | - geometry = geojson.Point((elem.get("lon"), elem.get("lat"))) |
322 | | - elif elem_type == "way": |
323 | | - # Create LineString geometry |
324 | | - geometry = geojson.LineString([(coords["lon"], coords["lat"]) for coords in elem_geom]) |
325 | | - elif elem_type == "relation": |
326 | | - # Initialize polygon list |
327 | | - polygons = [] |
328 | | - # First obtain the outer polygons |
329 | | - for member in elem.get("members", []): |
330 | | - if member["role"] == "outer": |
331 | | - points = [(coords["lon"], coords["lat"]) for coords in member.get("geometry", [])] |
332 | | - # Check that the outer polygon is complete |
333 | | - if points and points[-1] == points[0]: |
334 | | - polygons.append([points]) |
335 | | - else: |
336 | | - raise UnknownOverpassError("Received corrupt data from Overpass (incomplete polygon).") |
337 | | - # Then get the inner polygons |
338 | | - for member in elem.get("members", []): |
339 | | - if member["role"] == "inner": |
340 | | - points = [(coords["lon"], coords["lat"]) for coords in member.get("geometry", [])] |
341 | | - # Check that the inner polygon is complete |
342 | | - if not points or points[-1] != points[0]: |
343 | | - raise UnknownOverpassError("Received corrupt data from Overpass (incomplete polygon).") |
344 | | - # We need to check to which outer polygon the inner polygon belongs |
345 | | - point = Point(points[0]) |
346 | | - for poly in polygons: |
347 | | - polygon = Polygon(poly[0]) |
348 | | - if polygon.contains(point): |
349 | | - poly.append(points) |
350 | | - break |
351 | | - else: |
352 | | - raise UnknownOverpassError("Received corrupt data from Overpass (inner polygon cannot " |
353 | | - "be matched to outer polygon).") |
354 | | - # Finally create MultiPolygon geometry |
355 | | - if polygons: |
356 | | - geometry = geojson.MultiPolygon(polygons) |
357 | | - else: |
358 | | - raise UnknownOverpassError("Received corrupt data from Overpass (invalid element).") |
359 | | - |
360 | | - if geometry: |
361 | | - feature = geojson.Feature( |
362 | | - id=elem["id"], |
363 | | - geometry=geometry, |
364 | | - properties=elem_tags |
365 | | - ) |
366 | | - features.append(feature) |
367 | | - |
368 | | - return geojson.FeatureCollection(features) |
| 287 | + else: |
| 288 | + r.encoding = "utf-8" |
| 289 | + return r |
0 commit comments