Add bus journeys.
This commit is contained in:
parent
bc2c884589
commit
960b4a1fc7
3 changed files with 56 additions and 2 deletions
|
|
@ -124,6 +124,38 @@ def load_coaches(
|
||||||
return coaches
|
return coaches
|
||||||
|
|
||||||
|
|
||||||
|
def load_buses(
|
||||||
|
data_dir: str, route_distances: travel.RouteDistances | None = None
|
||||||
|
) -> list[StrDict]:
|
||||||
|
"""Load buses."""
|
||||||
|
items = load_travel("bus", "buses", data_dir)
|
||||||
|
stops = travel.parse_yaml("bus_stops", data_dir)
|
||||||
|
by_name = {stop["name"]: stop for stop in stops}
|
||||||
|
|
||||||
|
for item in items:
|
||||||
|
add_station_objects(item, by_name)
|
||||||
|
# Add route distance and CO2 calculation if available
|
||||||
|
if route_distances:
|
||||||
|
travel.add_leg_route_distance(item, route_distances)
|
||||||
|
if "distance" in item:
|
||||||
|
# Calculate CO2 emissions for bus (0.027 kg CO2e per passenger per km)
|
||||||
|
item["co2_kg"] = item["distance"] * 0.1
|
||||||
|
# Include GeoJSON route if defined in stations data
|
||||||
|
from_station = item.get("from_stop")
|
||||||
|
to_station = item.get("to_stop")
|
||||||
|
if from_station and to_station:
|
||||||
|
# Support scalar or mapping routes: string or dict of station name -> geojson base name
|
||||||
|
routes_val = from_station.get("routes", {})
|
||||||
|
if isinstance(routes_val, str):
|
||||||
|
geo = routes_val
|
||||||
|
else:
|
||||||
|
geo = routes_val.get(to_station.get("name"))
|
||||||
|
if geo:
|
||||||
|
item["geojson_filename"] = geo
|
||||||
|
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
def process_flight(
|
def process_flight(
|
||||||
flight: StrDict, by_iata: dict[str, Airline], airports: list[StrDict]
|
flight: StrDict, by_iata: dict[str, Airline], airports: list[StrDict]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
@ -179,7 +211,8 @@ def collect_travel_items(
|
||||||
load_flights(load_flight_bookings(data_dir))
|
load_flights(load_flight_bookings(data_dir))
|
||||||
+ load_trains(data_dir, route_distances=route_distances)
|
+ load_trains(data_dir, route_distances=route_distances)
|
||||||
+ load_ferries(data_dir, route_distances=route_distances)
|
+ load_ferries(data_dir, route_distances=route_distances)
|
||||||
+ load_coaches(data_dir, route_distances=route_distances),
|
+ load_coaches(data_dir, route_distances=route_distances)
|
||||||
|
+ load_buses(data_dir, route_distances=route_distances),
|
||||||
key=depart_datetime,
|
key=depart_datetime,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ from agenda import format_list_with_ampersand
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
StrDict = dict[str, typing.Any]
|
StrDict = dict[str, typing.Any]
|
||||||
DateOrDateTime = datetime.datetime | datetime.date
|
DateOrDateTime = datetime.datetime | datetime.date
|
||||||
|
|
||||||
|
|
@ -44,6 +45,7 @@ class TripElement:
|
||||||
"flight": ":airplane:",
|
"flight": ":airplane:",
|
||||||
"ferry": ":ferry:",
|
"ferry": ":ferry:",
|
||||||
"coach": ":bus:",
|
"coach": ":bus:",
|
||||||
|
"bus": ":bus:",
|
||||||
}
|
}
|
||||||
|
|
||||||
alias = emoji_map.get(self.element_type)
|
alias = emoji_map.get(self.element_type)
|
||||||
|
|
@ -414,6 +416,25 @@ class Trip:
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if item["type"] == "bus":
|
||||||
|
# Include bus journeys in trip elements
|
||||||
|
from_country = agenda.get_country(item["from_stop"]["country"])
|
||||||
|
to_country = agenda.get_country(item["to_stop"]["country"])
|
||||||
|
name = f"{item['from']} → {item['to']}"
|
||||||
|
elements.append(
|
||||||
|
TripElement(
|
||||||
|
start_time=item["depart"],
|
||||||
|
end_time=item.get("arrive"),
|
||||||
|
title=name,
|
||||||
|
detail=item,
|
||||||
|
element_type="bus",
|
||||||
|
start_loc=item["from"],
|
||||||
|
end_loc=item["to"],
|
||||||
|
start_country=from_country,
|
||||||
|
end_country=to_country,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return sorted(elements, key=lambda e: utils.as_datetime(e.start_time))
|
return sorted(elements, key=lambda e: utils.as_datetime(e.start_time))
|
||||||
|
|
||||||
def elements_grouped_by_day(self) -> list[tuple[datetime.date, list[TripElement]]]:
|
def elements_grouped_by_day(self) -> list[tuple[datetime.date, list[TripElement]]]:
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ function build_map(map_id, coordinates, routes) {
|
||||||
|
|
||||||
// Draw routes
|
// Draw routes
|
||||||
routes.forEach(function(route) {
|
routes.forEach(function(route) {
|
||||||
var color = {"train": "blue", "flight": "red", "unbooked_flight": "orange", "coach": "green"}[route.type];
|
var color = {"train": "blue", "flight": "red", "unbooked_flight": "orange", "coach": "green", "bus": "purple"}[route.type];
|
||||||
var style = { weight: 3, opacity: 0.5, color: color };
|
var style = { weight: 3, opacity: 0.5, color: color };
|
||||||
if (route.geojson) {
|
if (route.geojson) {
|
||||||
L.geoJSON(JSON.parse(route.geojson), {
|
L.geoJSON(JSON.parse(route.geojson), {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue