here.platform.utils.geo

Source code for here.platform.utils.geo

Copyright (C) 2019-2022 HERE Global B.V. and its affiliate(s).

All rights reserved.

This software and other materials contain proprietary information

controlled by HERE and are protected by applicable copyright legislation.

Any use and utilization of this software and other materials and

disclosure to any third parties is conditional upon having a separate

agreement with HERE for the access, use, utilization or disclosure of this

software. In the absence of such agreement, the use of the software is not

allowed.

"""
Utilities to convert geometries from non-standard formats
"""
from typing import Mapping, Sequence, Tuple

from geojson.geometry import Geometry, LineString, Point

[docs]
def is_geojson_geometry(x) -> bool:
"""
Check if an object is a mapping that represents a GeoJSON geometry.

:param x: the object to test
:return: if the object is in a supported, non-standard format
"""
return (
isinstance(x, Mapping)
and "type" in x
and x["type"]
in ["Point", "LineString", "Polygon", "MultiLineString", "MultiPoint", "MultiPolygon"]
and "coordinates" in x
and isinstance(x["coordinates"], Sequence)
)

def _is_point(x: Mapping) -> bool:
return "longitude" in x and "latitude" in x

def _is_pointseq(x: Sequence) -> bool:
return bool(x) and all(map(_is_point, x))

def _to_coords(x: Mapping) -> Tuple[float, float]:
return x["longitude"], x["latitude"]

[docs]
def is_nonstandard_geometry(x) -> bool:
"""
Check if an object is a geometry in a non-standard, supported format.

Supported formats:

{"longitude": 43.23, "latitude": 10.5}

[
{"longitude": 43.23, "latitude": 10.5},
{"longitude": 44.01, "latitude": 11.57}
]

:param x: the object to test
:return: if the object is in a supported, non-standard format
"""
if isinstance(x, Mapping) and _is_point(x):
return True
elif isinstance(x, Sequence) and _is_pointseq(x):
return True
return False

[docs]
def nonstandard_to_geometry(x) -> Geometry:
"""
Convert an object from a non-standard format to a GeoJSON geometry.

:param x: the object to convert
:return: the object converted to GeoJSON geometry
:raises ValueError: if the format of the object is not supported
"""
if isinstance(x, Mapping) and _is_point(x):
return Point(coordinates=_to_coords(x))
elif isinstance(x, Sequence) and _is_pointseq(x):
return LineString(coordinates=list(map(_to_coords, x)))
else:

This assert makes sure the two functions are in sync, at least in one direction

assert not is_nonstandard_geometry(x)
raise ValueError("Object in non-standard format cannot be converted to valid geometry")