pyroutelib3¶
Route finding¶
- pyroutelib3.find_route(g: ~pyroutelib3.protocols.GraphLike[~pyroutelib3.protocols.NodeLike], start: int, end: int, distance: ~typing.Callable[[~typing.Tuple[float, float], ~typing.Tuple[float, float]], float] = <function haversine_earth_distance>, step_limit: int | None = 1000000) List[int]¶
find_route uses the A* algorithm to find the shortest route between two nodes in the provided graph.
Returns an empty list if there is no route between the two nodes.
For graphs with turn restrictions, use
find_route_without_turn_around(), as this implementation will generate instructions with immediate turn-arounds (A-B-A) to circumvent any restrictions.step_limit(if not None) limits how many nodes may be expanded during the search before raisingStepLimitExceeded. Concluding that no route exists requires expanding all nodes accessible from the start, which is usually very time-consuming, especially on large datasets (like the whole planet). Defaults toDEFAULT_STEP_LIMIT. Only set toNoneon small, contained graphs.
- pyroutelib3.find_route_without_turn_around(g: ~pyroutelib3.protocols.GraphLike[~pyroutelib3.protocols.ExternalNodeLike], start: int, end: int, distance: ~typing.Callable[[~typing.Tuple[float, float], ~typing.Tuple[float, float]], float] = <function haversine_earth_distance>, step_limit: int | None = 1000000) List[int]¶
find_route_without_turn_around uses the A* algorithm to find the shortest route between two points in the provided graph.
Returns an empty list if there is no route between the two points.
For graphs without turn restrictions, use
find_route(), as it runs faster.find_route_without_turn_aroundhas an extra search dimension - it needs to not only consider the node, but also what was the previous node to prevent A-B-A immediate turn-around instructions.step_limit(if not None) limits how many nodes may be expanded during the search before raisingStepLimitExceeded. Concluding that no route exists requires expanding all nodes accessible from the start, which is usually very time-consuming, especially on large datasets (like the whole planet). Defaults toDEFAULT_STEP_LIMIT. Only set toNoneon small, contained graphs.
- exception pyroutelib3.StepLimitExceeded¶
Bases:
ValueErrorException used when a route search has exceeded its limit of steps. Either the nodes are really far apart, or no route exists.
Concluding that no route exists requires traversing the whole graph, which on real OpenStreetMap data may require going through the whole planet, hence this exception.
- pyroutelib3.DEFAULT_STEP_LIMIT = 1000000¶
int([x]) -> integer int(x, base=10) -> integer
Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.__int__(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by ‘+’ or ‘-’ and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer literal. >>> int(‘0b100’, base=0) 4
Simple graphs¶
- class pyroutelib3.SimpleGraph(nodes: ~typing.Dict[int, ~pyroutelib3.protocols.NodeLikeT_co] = <factory>, edges: ~typing.Dict[int, ~typing.Dict[int, float]] = <factory>)¶
Bases:
GraphLike[NodeLikeT_co]SimpleGraph provides a base class and a simple implementation of the
GraphLikeprotocol over two dictionaries: one holding nodes, and another holding edge costs.- get_edges(id: int) Iterable[Tuple[int, float]]¶
get_edges must return all edges outgoing from a node with the provided ID. The edges are a pair of (node_id, cost). All returned neighbor nodes must exist in the graph.
If there are no outgoing edges from the provided node, must return an empty iterable. If a node with the given ID, may return an empty iterable, or raise KeyError.
- get_node(id: int) NodeLikeT_co¶
get_node must return a
NodeLikeof a node by the provided ID. If such a node doesn’t exist, must raise KeyError.
- edges: Dict[int, Dict[int, float]]¶
- nodes: Dict[int, NodeLikeT_co]¶
- class pyroutelib3.SimpleNode(id: int, position: Tuple[float, float])¶
Bases:
objectSimpleNode provides a base class and a simple implementation of the
NodeLikeprotocol.- id: int¶
- position: Tuple[float, float]¶
- class pyroutelib3.SimpleExternalNode(id: int, position: Tuple[float, float], external_id: int)¶
Bases:
objectSimpleExternalNode provides a base class and a simple implementation of the
ExternalNodeLikeprotocol.- classmethod with_same_external_id(id: int, position: Tuple[float, float]) Self¶
with_same_external_id instantiates a SimpleExternalNode with
external_idset to the same value asid.
- external_id: int¶
- id: int¶
- position: Tuple[float, float]¶
k-d tree¶
- class pyroutelib3.KDTree(pivot: WithPositionT, left: KDTree[WithPositionT] | None = None, right: KDTree[WithPositionT] | None = None)¶
Bases:
Generic[WithPositionT]KDTree implements the k-d tree data structure, which can be used to speed up nearest-neighbor search for large datasets. Practice shows that
osm.Graph.find_nearest_neighbor()takes significantly more time thanfind_route()when generating multiple routes withpyroutelib3. A k-d tree can help with that, trading memory usage for CPU time.This implementation assumes euclidean geometry, even though the default distance function used is
haversine_earth_distance(). This results in undefined behavior when points are close to the ante meridian (180°/-180° longitude) or poles (90°/-90° latitude), or when the data spans multiple continents.- classmethod build(points: Iterable[WithPositionT]) Self | None¶
Creates a new K-D tree with all of the provided objects with a
Position.Note that the type-complaint usage of class methods on generic types requires explicitly providing the type argument, e.g.:
tree = KDTree[Node].build(nodes)
- find_nearest_neighbor(root: ~typing.Tuple[float, float], distance: ~typing.Callable[[~typing.Tuple[float, float], ~typing.Tuple[float, float]], float] = <function haversine_earth_distance>) WithPositionT¶
Find the closest node to
root, as determined by the provided distance function.
- pivot: WithPositionT¶
Distance functions¶
- pyroutelib3.euclidean_distance(p, q, /)¶
Return the Euclidean distance between two points p and q.
The points should be specified as sequences (or iterables) of coordinates. Both inputs must have the same dimension.
- Roughly equivalent to:
sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))
- pyroutelib3.haversine_earth_distance(a: Tuple[float, float], b: Tuple[float, float]) float¶
Calculates the great-circle distance between two lat-lon positions on Earth using the haversine formula. Returns the result in kilometers.
- pyroutelib3.taxicab_distance(a: Tuple[float, float], b: Tuple[float, float]) float¶
Calculates the Taxicab distance between two points, in the same units as the input positions.