Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add alternates to valhalla #87

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## **Unreleased**

### Added
- `alternates` for Valhalla

### Fixed
- Unit conversion did not work properly in ors' directions method
- Docstring for `intersections` parameter in ors' isochrones method was missing
Expand Down
44 changes: 31 additions & 13 deletions routingpy/routers/valhalla.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
from .. import utils
from ..client_base import DEFAULT
from ..client_default import Client
from ..direction import Direction
from ..direction import Direction, Directions
from ..expansion import Edge, Expansions
from ..isochrone import Isochrone, Isochrones
from ..matrix import Matrix
Expand Down Expand Up @@ -134,6 +134,7 @@ def directions(
avoid_locations=None,
avoid_polygons=None,
date_time=None,
alternatives=None,
id=None,
dry_run=None,
**kwargs
Expand Down Expand Up @@ -186,6 +187,8 @@ def directions(
in ISO 8601 format (YYYY-MM-DDThh:mm), local time.
E.g. date_time = {type: 0, value: 2021-03-03T08:06:23}

:param int alternatives: The amount of alternatives to request. Note, with 1 you'll get 2 routes. Default 0.

:param Union[str|int|float] id: Name your route request. If id is specified, the naming will be sent thru to the response.

:param bool dry_run: Print URL and parameters without sending the request.
Expand All @@ -207,6 +210,7 @@ def directions(
directions_type,
avoid_locations,
avoid_polygons,
alternatives,
date_time,
id,
**kwargs
Expand All @@ -217,6 +221,7 @@ def directions(
return self.parse_direction_json(
self.client._request("/route", get_params=get_params, post_params=params, dry_run=dry_run),
units,
alternatives,
)

@staticmethod
Expand All @@ -231,6 +236,7 @@ def get_direction_params(
directions_type=None,
avoid_locations=None,
avoid_polygons=None,
alternatives=None,
date_time=None,
id=None,
**kwargs
Expand Down Expand Up @@ -267,6 +273,9 @@ def get_direction_params(
if avoid_polygons:
params["avoid_polygons"] = avoid_polygons

if alternatives:
params["alternates"] = alternatives

if date_time:
params["date_time"] = date_time

Expand All @@ -279,19 +288,28 @@ def get_direction_params(
return params

@staticmethod
def parse_direction_json(response, units):
if response is None: # pragma: no cover
return Direction()

geometry, duration, distance = [], 0, 0
for leg in response["trip"]["legs"]:
geometry.extend(utils.decode_polyline6(leg["shape"]))
duration += leg["summary"]["time"]

factor = 0.621371 if units == "mi" else 1
distance += int(leg["summary"]["length"] * 1000 * factor)
def parse_direction_json(response, units, alternatives):
routes = response["alternates"] + [response] if alternatives else [response]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, this needs to be the normal route first as that's the lowest cost

if response is None:
return Directions() if alternatives else Direction()

directions = []
for route in routes:
geometry, duration, distance = [], 0, 0
for leg in route["trip"]["legs"]:
geometry.extend(utils.decode_polyline6(leg["shape"]))
duration += leg["summary"]["time"]

factor = 0.621371 if units == "mi" else 1
distance += int(leg["summary"]["length"] * 1000 * factor)

directions.append(
Direction(
geometry=geometry, duration=int(duration), distance=int(distance), raw=response
)
)

return Direction(geometry=geometry, duration=int(duration), distance=int(distance), raw=response)
return Directions(directions, response) if alternatives else directions[0]

def isochrones( # noqa: C901
self,
Expand Down