Skip to content

Commit

Permalink
Adding time-map-fast json and geojson
Browse files Browse the repository at this point in the history
  • Loading branch information
arnasbr committed Oct 21, 2024
1 parent 389a1e0 commit 2c8b9bf
Show file tree
Hide file tree
Showing 5 changed files with 299 additions and 3 deletions.
71 changes: 70 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,75 @@ async def main():
asyncio.run(main())
```

### [Time Map (Fast)](https://docs.traveltime.com/api/reference/isochrones-fast)

A very fast version of `time_map()`. However, the request parameters are much more limited.

#### Takes:

* coordinates: List[Coordinates] - Isochrones coordinates.
* [transportation]: Transportation - Transportation mode and related parameters.
* travel_time: int - Maximum journey time (in seconds). Maximum value is 10800. Default value is 3600.
* one_to_many: boolean - returns the reachable area for journeys arriving at the chosen arrival location if false,
returns the reachable area for journeys departing from the chosen departure location if true.
* [snapping](#snapping): Snapping - Adjusts the process of looking up the nearest roads from the departure / arrival points.

### JSON response

#### Returns:

* results: List[TimeMapResult] - The list of isochrone shapes.

#### Example:

```python
import asyncio

from traveltimepy import Coordinates, TravelTimeSdk
from traveltimepy.dto.requests.time_map_fast import Transportation

async def main():
sdk = TravelTimeSdk("YOUR_APP_ID", "YOUR_APP_KEY")

results = await sdk.time_map_fast_async(
coordinates=[Coordinates(lat=51.507609, lng=-0.128315), Coordinates(lat=51.517609, lng=-0.138315)],
transportation=Transportation(type="driving+ferry"),
travel_time=900
)

print(results)

asyncio.run(main())
```

### GEOJSON response

#### Returns:

* results: List[TimeMapGeojsonResult] - The list of Features.

#### Example:

```python
import asyncio

from traveltimepy import Coordinates, TravelTimeSdk
from traveltimepy.dto.requests.time_map_fast import Transportation

async def main():
sdk = TravelTimeSdk("YOUR_APP_ID", "YOUR_APP_KEY")

results = await sdk.time_map_fast_geojson_async(
coordinates=[Coordinates(lat=51.507609, lng=-0.128315), Coordinates(lat=51.517609, lng=-0.138315)],
transportation=Transportation(type="driving+ferry"),
travel_time=900
)

print(results)

asyncio.run(main())
```

### [Distance Map](https://docs.traveltime.com/api/reference/distance-map)

Given origin coordinates, find shapes of zones reachable within corresponding travel distance.
Expand Down Expand Up @@ -394,7 +463,7 @@ A very fast version of `time_filter()`. However, the request parameters are much
* locations: List[Locations] - All locations. Location ids must be unique.
* search_ids: Dict[str, List[str]] - Searches from a target location to destinations. You can define up to 100,000
destinations
* [transportation](#transportation): Union - Transportation mode and related parameters.
* [transportation]: Transportation - Transportation mode and related parameters.
* travel_time: int - Maximum journey time (in seconds). Maximum value is 10800. Default value is 3600.
* properties: List[Property] - Properties to be returned about the points. Default value is travel_time.
* one_to_many: boolean - if one_to_many is equal to true, then it'll be a forward search (one to many matrix), false -
Expand Down
61 changes: 61 additions & 0 deletions traveltimepy/dto/requests/time_map_fast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from typing import List, Optional
from typing_extensions import Literal

from pydantic import BaseModel

from traveltimepy.dto.common import (
Coordinates,
LevelOfDetail,
Snapping,
)
from traveltimepy.dto.requests.request import TravelTimeRequest
from traveltimepy.dto.responses.time_map import TimeMapResponse
from traveltimepy.itertools import split, flatten


class Transportation(BaseModel):
type: Literal[
"public_transport",
"walking+ferry",
"cycling+ferry",
"driving+ferry",
"driving+public_transport",
]


class Search(BaseModel):
id: str
coords: Coordinates
transportation: Transportation
travel_time: int
arrival_time_period: str
level_of_detail: Optional[LevelOfDetail] = None
snapping: Optional[Snapping] = None


class ArrivalSearches(BaseModel):
many_to_one: List[Search]
one_to_many: List[Search]


class TimeMapFastRequest(TravelTimeRequest[TimeMapResponse]):
arrival_searches: ArrivalSearches

def split_searches(self, window_size: int) -> List[TravelTimeRequest]:
return [
TimeMapFastRequest(
arrival_searches=ArrivalSearches(
one_to_many=one_to_many, many_to_one=many_to_one
),
)
for one_to_many, many_to_one in split(
self.arrival_searches.one_to_many,
self.arrival_searches.many_to_one,
window_size,
)
]

def merge(self, responses: List[TimeMapResponse]) -> TimeMapResponse:
return TimeMapResponse(
results=flatten([response.results for response in responses])
)
28 changes: 28 additions & 0 deletions traveltimepy/dto/requests/time_map_fast_geojson.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import List
from geojson_pydantic import FeatureCollection

from traveltimepy.dto.requests.request import TravelTimeRequest
from traveltimepy.dto.requests.time_map_fast import ArrivalSearches
from traveltimepy.itertools import split, flatten


class TimeMapFastGeojsonRequest(TravelTimeRequest[FeatureCollection]):
arrival_searches: ArrivalSearches

def split_searches(self, window_size: int) -> List[TravelTimeRequest]:
return [
TimeMapFastGeojsonRequest(
arrival_searches=ArrivalSearches(
one_to_many=one_to_many, many_to_one=many_to_one
),
)
for one_to_many, many_to_one in split(
self.arrival_searches.one_to_many,
self.arrival_searches.many_to_one,
window_size,
)
]

def merge(self, responses: List[FeatureCollection]) -> FeatureCollection:
merged_features = flatten([response.features for response in responses])
return FeatureCollection(type="FeatureCollection", features=merged_features)
93 changes: 91 additions & 2 deletions traveltimepy/mapper.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import math
from typing import Dict, Union, List, Optional

from traveltimepy.dto.requests import time_map_fast
from traveltimepy.dto.requests.distance_map import DistanceMapRequest
from traveltimepy.dto.requests.time_map_geojson import TimeMapRequestGeojson
from traveltimepy.dto.requests.time_map_wkt import TimeMapWKTRequest
Expand Down Expand Up @@ -36,6 +37,8 @@
from traveltimepy.dto.requests.routes import RoutesRequest
from traveltimepy.dto.requests.time_filter import TimeFilterRequest
from traveltimepy.dto.requests.time_filter_fast import TimeFilterFastRequest
from traveltimepy.dto.requests.time_map_fast import TimeMapFastRequest
from traveltimepy.dto.requests.time_map_fast_geojson import TimeMapFastGeojsonRequest
from traveltimepy.dto.requests.time_filter_proto import ProtoTransportation
from traveltimepy.dto.requests.postcodes_zones import (
PostcodesDistrictsRequest,
Expand Down Expand Up @@ -118,6 +121,92 @@ def create_time_filter(
raise ApiError("arrival_time or departure_time should be specified")


def create_time_map_fast(
coordinates: List[Coordinates],
transportation: time_map_fast.Transportation,
travel_time: int = 3600,
one_to_many: bool = False,
snapping: Optional[Snapping] = None,
) -> TimeMapFastRequest:
if one_to_many:
return TimeMapFastRequest(
arrival_searches=time_map_fast.ArrivalSearches(
one_to_many=[
time_map_fast.Search(
id=f"Search {ind}",
coords=cur_coordinates,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
snapping=snapping,
)
for ind, cur_coordinates in enumerate(coordinates)
],
many_to_one=[],
),
)
else:
return TimeMapFastRequest(
arrival_searches=time_map_fast.ArrivalSearches(
many_to_one=[
time_map_fast.Search(
id=f"Search {ind}",
coords=cur_coordinates,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
snapping=snapping,
)
for ind, cur_coordinates in enumerate(coordinates)
],
one_to_many=[],
),
)


def create_time_map_fast_geojson(
coordinates: List[Coordinates],
transportation: time_map_fast.Transportation,
travel_time: int = 3600,
one_to_many: bool = False,
snapping: Optional[Snapping] = None,
) -> TimeMapFastGeojsonRequest:
if one_to_many:
return TimeMapFastGeojsonRequest(
arrival_searches=time_map_fast.ArrivalSearches(
one_to_many=[
time_map_fast.Search(
id=f"Search {ind}",
coords=cur_coordinates,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
snapping=snapping,
)
for ind, cur_coordinates in enumerate(coordinates)
],
many_to_one=[],
),
)
else:
return TimeMapFastGeojsonRequest(
arrival_searches=time_map_fast.ArrivalSearches(
many_to_one=[
time_map_fast.Search(
id=f"Search {ind}",
coords=cur_coordinates,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
snapping=snapping,
)
for ind, cur_coordinates in enumerate(coordinates)
],
one_to_many=[],
),
)


def create_time_filter_fast(
locations: List[Location],
search_ids: Dict[str, List[str]],
Expand All @@ -140,7 +229,7 @@ def create_time_filter_fast(
arrival_location_ids=arrival_ids,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning",
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
properties=properties,
snapping=snapping,
)
Expand All @@ -160,7 +249,7 @@ def create_time_filter_fast(
departure_location_ids=departure_ids,
transportation=transportation,
travel_time=travel_time,
arrival_time_period="weekday_morning",
arrival_time_period="weekday_morning", # TODO: make customizable with enum / literal
properties=properties,
snapping=snapping,
)
Expand Down
49 changes: 49 additions & 0 deletions traveltimepy/sdk.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
ArrivalTime,
Snapping,
)
from traveltimepy.dto.requests import time_map_fast
from traveltimepy.dto.responses.time_map_wkt import (
TimeMapWKTResponse,
)
Expand Down Expand Up @@ -68,6 +69,8 @@
create_proto_request,
create_time_map,
create_intersection,
create_time_map_fast,
create_time_map_fast_geojson,
create_union,
create_time_map_geojson,
create_time_map_wkt,
Expand Down Expand Up @@ -215,6 +218,52 @@ async def supported_locations_async(
self._sdk_params,
)

async def time_map_fast_async(
self,
coordinates: List[Coordinates],
transportation: time_map_fast.Transportation,
travel_time: int = 3600,
one_to_many: bool = True,
snapping: Optional[Snapping] = None,
) -> List[TimeMapResult]:
resp = await send_post_async(
TimeMapResponse,
"time-map/fast",
self._headers(AcceptType.JSON),
create_time_map_fast(
coordinates,
transportation,
travel_time,
one_to_many,
snapping,
),
self._sdk_params,
)
return resp.results

async def time_map_fast_geojson_async(
self,
coordinates: List[Coordinates],
transportation: time_map_fast.Transportation,
travel_time: int = 3600,
one_to_many: bool = True,
snapping: Optional[Snapping] = None,
) -> FeatureCollection:
resp = await send_post_async(
FeatureCollection,
"time-map/fast",
self._headers(AcceptType.GEO_JSON),
create_time_map_fast_geojson(
coordinates,
transportation,
travel_time,
one_to_many,
snapping,
),
self._sdk_params,
)
return resp

async def time_filter_fast_async(
self,
locations: List[Location],
Expand Down

0 comments on commit 2c8b9bf

Please sign in to comment.