"""Component to locate the simulation objects."""
from typing import Optional
import pyproj
import shapely.geometry
from shapely.geometry.base import BaseGeometry
[docs]
class Locatable:
"""Something with a geometry (geojson format). Can be a point as well as a
polygon. The object can also be located on a graph (with a node). That
requires the extra and optional node attribute. Make sure to also update the
geometry when sailing over graphs.
Parameters
----------
geometry : Shapely Geometry that determines the position of an object.
Coordinates are expected to be in wgs84 lon, lat.
node: Optional string that locates an object on a graph.
"""
def __init__(
self, geometry: BaseGeometry, node: Optional[str] = None, *args, **kwargs
):
super().__init__(*args, **kwargs)
"""Initialization"""
self.geometry = geometry
# an optional node for locating an object on a network
self.node = node
# used for distance computation
self.wgs84 = pyproj.Geod(ellps="WGS84")
[docs]
def is_at(self, locatable, tolerance=100):
current_location = shapely.geometry.shape(self.geometry)
other_location = shapely.geometry.shape(locatable.geometry)
_, _, distance = self.wgs84.inv(
current_location.x, current_location.y, other_location.x, other_location.y
)
return distance < tolerance
[docs]
def get_state(self):
state = {}
if hasattr(super(), "get_state"):
state = super().get_state()
state.update({"geometry": self.geometry})
if self.node is not None:
state["node"] = self.node
return state