|
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