Source code for openlr_dereferencer.decoding.point_locations

"Decoding logic for point (along line, ...) locations"

from typing import NamedTuple, Tuple, Optional
from openlr import (
    Coordinates,
    PointAlongLineLocationReference,
    Orientation,
    SideOfRoad,
    PoiWithAccessPointLocationReference,
)
from ..maps import MapReader, path_length
from ..maps.abstract import Line
from ..observer import DecoderObserver
from ..maps.wgs84 import interpolate
from .line_decoding import dereference_path
from .line_location import get_lines, Route, combine_routes
from .configuration import Config
from . import LRDecodeError


[docs]class PointAlongLine(NamedTuple): """A dereferenced point along line location. Contains the coordinates as well as the road on which it was located.""" line: Line positive_offset: float side: SideOfRoad orientation: Orientation
[docs] def coordinates(self) -> Coordinates: "Returns the geo coordinates of the point" return interpolate(list(self.line.coordinates()), self.positive_offset)
[docs]def point_along_linelocation(route: Route, length: float) -> Tuple[Line, float]: """Steps `length` meters into the `route` and returns the Line + offset of the point in meters. If the path is exhausted (`length` longer than `route`), raises an LRDecodeError.""" leftover_length = length leftover_length -= route.start.line.length * (1.0 - route.start.relative_offset) if leftover_length < 0.0: return route.start.line, route.start.line.length * route.start.relative_offset + length for road in route.path_inbetween: if leftover_length > road.length: leftover_length -= road.length else: return road, leftover_length end_offset = route.end.line.length * route.end.relative_offset leftover_length -= end_offset if leftover_length < 0.0: return route.end.line, end_offset raise LRDecodeError("Path length exceeded while projecting point")
[docs]def decode_pointalongline( reference: PointAlongLineLocationReference, reader: MapReader, config: Config, observer: Optional[DecoderObserver] ) -> PointAlongLine: "Decodes a point along line location reference into a PointAlongLine object" path = combine_routes(dereference_path(reference.points, reader, config, observer)) absolute_offset = path.length() * reference.poffs line_object, line_offset = point_along_linelocation(path, absolute_offset) return PointAlongLine(line_object, line_offset, reference.sideOfRoad, reference.orientation)
[docs]class PoiWithAccessPoint(NamedTuple): "A dereferenced POI with access point location." line: Line positive_offset: float side: SideOfRoad orientation: Orientation poi: Coordinates
[docs] def access_point_coordinates(self) -> Coordinates: "Returns the geo coordinates of the access point" return interpolate(list(self.line.coordinates()), self.positive_offset)
[docs]def decode_poi_with_accesspoint( reference: PoiWithAccessPointLocationReference, reader: MapReader, config: Config, observer: Optional[DecoderObserver] ) -> PoiWithAccessPoint: "Decodes a poi with access point location reference into a PoiWithAccessPoint" path = combine_routes(dereference_path(reference.points, reader, config, observer)) absolute_offset = path_length(get_lines([path])) * reference.poffs line, line_offset = point_along_linelocation(path, absolute_offset) return PoiWithAccessPoint( line, line_offset, reference.sideOfRoad, reference.orientation, Coordinates(reference.lon, reference.lat), )