diff --git a/openapi.yaml b/openapi.yaml index ab8038ca6..d07f5e8e1 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -936,17 +936,11 @@ components: description: | # Street modes - - `WALK`: Walking some or all of the way of the route. - - `BIKE`: Cycling for the entirety of the route or taking a bicycle onto the public transport (if enabled) and cycling from the arrival station to the destination. - - `BIKE_RENTAL`: Taking a rented, shared-mobility bike for part or the entirety of the route. - - `BIKE_TO_PARK`: Leaving the bicycle at the departure station and walking from the arrival station to the destination. This mode needs to be combined with at least one transit mode otherwise it behaves like an ordinary bicycle journey. - - `CAR`: Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a Kiss & Ride component. This means that the car is not parked in a permanent parking area but rather the passenger is dropped off (for example, at an airport) and the driver continues driving the car away from the drop off location. - - `CAR_PARK` | `CAR_TO_PARK`: Driving a car to the park-and-ride facilities near a station and taking publictransport. This mode needs to be combined with at least one transit mode otherwise, it behaves like an ordinary car journey. - - `CAR_HAILING`: Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. - - `CAR_PICKUP`: Walking to a pickup point along the road, driving to a drop-off point along the road, and walking the rest of the way. This can include various taxi-services or kiss & ride. - - `CAR_RENTAL`: Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services. - - `FLEXIBLE`: Encompasses all types of on-demand and flexible transportation for example GTFS Flex or NeTEx Flexible Stop Places. - - `SCOOTER_RENTAL`: Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services. + - `WALK` + - `BIKE` + - `BIKE_RENTAL` + - `CAR` + - `CAR_PARKING` # Transit modes @@ -971,14 +965,7 @@ components: - BIKE - CAR - BIKE_RENTAL - - BIKE_TO_PARK - - CAR_TO_PARK - - CAR_HAILING - - CAR_SHARING - - CAR_PICKUP - - CAR_RENTAL - - FLEXIBLE - - SCOOTER_RENTAL + - CAR_PARKING # === Transit === - TRANSIT - TRAM diff --git a/src/endpoints/graph.cc b/src/endpoints/graph.cc index 453284c08..150e7d0f4 100644 --- a/src/endpoints/graph.cc +++ b/src/endpoints/graph.cc @@ -1,7 +1,7 @@ #include "motis/endpoints/graph.h" #include "osr/geojson.h" -#include "osr/routing/profiles/bike_sharing.h" +#include "osr/routing/profiles/car_parking.h" #include "osr/routing/route.h" namespace json = boost::json; @@ -58,7 +58,7 @@ json::value graph::operator()(json::value const& query) const { } }); - gj.finish(&osr::get_dijkstra()); + gj.finish(&osr::get_dijkstra>()); return gj.json(); } diff --git a/src/endpoints/routing.cc b/src/endpoints/routing.cc index 44feab536..f964fd4b2 100644 --- a/src/endpoints/routing.cc +++ b/src/endpoints/routing.cc @@ -240,6 +240,7 @@ std::pair, n::duration_t> routing::route_direct( auto itineraries = std::vector{}; for (auto const& m : modes) { if (m == api::ModeEnum::CAR || m == api::ModeEnum::BIKE || + m == api::ModeEnum::CAR_PARKING || (!omit_walk && m == api::ModeEnum::WALK)) { auto itinerary = route( *w_, *l_, gbfs, e, from, to, m, wheelchair, start_time, std::nullopt, @@ -320,9 +321,6 @@ void remove_slower_than_fastest_direct(n::routing::query& q) { min_dest = std::min(min_dest, get_min_duration(v)); } - utl::verify(min_start != kMaxDuration, "no valid start offset"); - utl::verify(min_dest != kMaxDuration, "no valid dest offset"); - utl::erase_if(q.start_, worse_than_fastest_direct(min_dest)); utl::erase_if(q.destination_, worse_than_fastest_direct(min_start)); for (auto& [k, v] : q.td_start_) { @@ -492,16 +490,22 @@ api::plan_response routing::operator()(boost::urls::url_view const& url) const { raptor_state.reset(new n::routing::raptor_state{}); } + auto const query_stats = + stats_map_t{{"direct", UTL_TIMING_MS(direct)}, + {"query_preparation", UTL_TIMING_MS(query_preparation)}, + {"n_start_offsets", q.start_.size()}, + {"n_dest_offsets", q.destination_.size()}, + {"n_td_start_offsets", q.td_start_.size()}, + {"n_td_dest_offsets", q.td_dest_.size()}}; + auto const r = n::routing::raptor_search( *tt_, rtt, *search_state, *raptor_state, std::move(q), query.arriveBy_ ? n::direction::kBackward : n::direction::kForward, std::nullopt); return { - .debugOutput_ = join(stats_map_t{{"direct", UTL_TIMING_MS(direct)}, - {"query_preparation", - UTL_TIMING_MS(query_preparation)}}, - r.search_stats_.to_map(), r.algo_stats_.to_map()), + .debugOutput_ = join(std::move(query_stats), r.search_stats_.to_map(), + r.algo_stats_.to_map()), .from_ = from_p, .to_ = to_p, .direct_ = std::move(direct), diff --git a/src/journey_to_response.cc b/src/journey_to_response.cc index 28da5ae2a..36080dcdd 100644 --- a/src/journey_to_response.cc +++ b/src/journey_to_response.cc @@ -30,7 +30,7 @@ namespace motis { api::ModeEnum to_mode(osr::search_profile const m) { switch (m) { case osr::search_profile::kCarParkingWheelchair: [[fallthrough]]; - case osr::search_profile::kCarParking: return api::ModeEnum::CAR_TO_PARK; + case osr::search_profile::kCarParking: return api::ModeEnum::CAR_PARKING; case osr::search_profile::kFoot: [[fallthrough]]; case osr::search_profile::kWheelchair: return api::ModeEnum::WALK; case osr::search_profile::kCar: return api::ModeEnum::CAR; diff --git a/src/mode_to_profile.cc b/src/mode_to_profile.cc index 4a69454d5..996655e7f 100644 --- a/src/mode_to_profile.cc +++ b/src/mode_to_profile.cc @@ -21,6 +21,9 @@ osr::search_profile to_profile(api::ModeEnum const m, bool const wheelchair) { : osr::search_profile::kFoot; case api::ModeEnum::BIKE: return osr::search_profile::kBike; case api::ModeEnum::CAR: return osr::search_profile::kCar; + case api::ModeEnum::CAR_PARKING: + return wheelchair ? osr::search_profile::kCarParkingWheelchair + : osr::search_profile::kCarParking; case api::ModeEnum::BIKE_RENTAL: return osr::search_profile::kBikeSharing; default: throw utl::fail("unsupported mode"); } diff --git a/ui/src/lib/AddressTypeahead.svelte b/ui/src/lib/AddressTypeahead.svelte index 5c6dd1cf1..d6fe7698b 100644 --- a/ui/src/lib/AddressTypeahead.svelte +++ b/ui/src/lib/AddressTypeahead.svelte @@ -17,15 +17,13 @@ selected = $bindable(), placeholder, class: className, - name, - theme + name }: { items?: Array; selected: Location; placeholder?: string; class?: string; name?: string; - theme?: 'light' | 'dark'; } = $props(); let inputValue = $state(''); @@ -113,10 +111,7 @@ {#if items.length !== 0} {#each items as item (item.value)} { switch (m) { case 'WALK': - return 'Fußweg'; + return t.walk; case 'BIKE': case 'BIKE_RENTAL': - case 'BIKE_TO_PARK': - return 'Fahrrad'; + return t.bike; case 'CAR': - case 'CAR_TO_PARK': - case 'CAR_HAILING': - case 'CAR_PICKUP': - case 'CAR_RENTAL': - case 'CAR_SHARING': - return 'Auto'; + case 'CAR_PARKING': + return t.car; default: return `${m}`; } diff --git a/ui/src/lib/i18n/de.ts b/ui/src/lib/i18n/de.ts index 1bcdfb718..718a6cc9a 100644 --- a/ui/src/lib/i18n/de.ts +++ b/ui/src/lib/i18n/de.ts @@ -1,6 +1,9 @@ import type { Translations } from './translation'; const translations: Translations = { + walk: 'Fußweg', + bike: 'Fahrrad', + car: 'Auto', from: 'Von', to: 'Nach', arrival: 'Ankunft', diff --git a/ui/src/lib/i18n/en.ts b/ui/src/lib/i18n/en.ts index 00a28e598..775756ea5 100644 --- a/ui/src/lib/i18n/en.ts +++ b/ui/src/lib/i18n/en.ts @@ -1,6 +1,9 @@ import type { Translations } from './translation'; const translations: Translations = { + walk: 'Walk', + bike: 'Bike', + car: 'Car', from: 'From', to: 'To', arrival: 'Arrival', diff --git a/ui/src/lib/i18n/translation.ts b/ui/src/lib/i18n/translation.ts index 3627589e9..3a262fe1f 100644 --- a/ui/src/lib/i18n/translation.ts +++ b/ui/src/lib/i18n/translation.ts @@ -3,6 +3,9 @@ import en from './en'; import de from './de'; export type Translations = { + walk: string; + bike: string; + car: string; from: string; to: string; arrival: string; diff --git a/ui/src/lib/modeStyle.ts b/ui/src/lib/modeStyle.ts index f586c4b88..1e5c6ef75 100644 --- a/ui/src/lib/modeStyle.ts +++ b/ui/src/lib/modeStyle.ts @@ -16,22 +16,15 @@ export type LegLike = Colorable & TripInfo; export const getModeStyle = (mode: Mode): [string, string, string] => { switch (mode) { case 'WALK': - case 'FLEXIBLE': return ['walk', 'hsl(var(--foreground) / 1)', 'hsl(var(--background) / 1)']; case 'BIKE': - case 'BIKE_TO_PARK': case 'BIKE_RENTAL': - case 'SCOOTER_RENTAL': return ['bike', '#075985', 'white']; case 'CAR': - case 'CAR_TO_PARK': - case 'CAR_HAILING': - case 'CAR_SHARING': - case 'CAR_PICKUP': - case 'CAR_RENTAL': - return ['car', '#333', 'white']; + case 'CAR_PARKING': + return ['car', '#333333', 'white']; case 'TRANSIT': case 'BUS': diff --git a/ui/src/lib/openapi/schemas.gen.ts b/ui/src/lib/openapi/schemas.gen.ts index 6bd235a63..bf361e301 100644 --- a/ui/src/lib/openapi/schemas.gen.ts +++ b/ui/src/lib/openapi/schemas.gen.ts @@ -116,17 +116,11 @@ export const MatchSchema = { export const ModeSchema = { description: `# Street modes - - \`WALK\`: Walking some or all of the way of the route. - - \`BIKE\`: Cycling for the entirety of the route or taking a bicycle onto the public transport (if enabled) and cycling from the arrival station to the destination. - - \`BIKE_RENTAL\`: Taking a rented, shared-mobility bike for part or the entirety of the route. - - \`BIKE_TO_PARK\`: Leaving the bicycle at the departure station and walking from the arrival station to the destination. This mode needs to be combined with at least one transit mode otherwise it behaves like an ordinary bicycle journey. - - \`CAR\`: Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a Kiss & Ride component. This means that the car is not parked in a permanent parking area but rather the passenger is dropped off (for example, at an airport) and the driver continues driving the car away from the drop off location. - - \`CAR_PARK\` | \`CAR_TO_PARK\`: Driving a car to the park-and-ride facilities near a station and taking publictransport. This mode needs to be combined with at least one transit mode otherwise, it behaves like an ordinary car journey. - - \`CAR_HAILING\`: Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. - - \`CAR_PICKUP\`: Walking to a pickup point along the road, driving to a drop-off point along the road, and walking the rest of the way. This can include various taxi-services or kiss & ride. - - \`CAR_RENTAL\`: Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services. - - \`FLEXIBLE\`: Encompasses all types of on-demand and flexible transportation for example GTFS Flex or NeTEx Flexible Stop Places. - - \`SCOOTER_RENTAL\`: Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services. + - \`WALK\` + - \`BIKE\` + - \`BIKE_RENTAL\` + - \`CAR\` + - \`CAR_PARKING\` # Transit modes @@ -146,7 +140,7 @@ export const ModeSchema = { - \`REGIONAL_RAIL\`: regional train `, type: 'string', - enum: ['WALK', 'BIKE', 'CAR', 'BIKE_RENTAL', 'BIKE_TO_PARK', 'CAR_TO_PARK', 'CAR_HAILING', 'CAR_SHARING', 'CAR_PICKUP', 'CAR_RENTAL', 'FLEXIBLE', 'SCOOTER_RENTAL', 'TRANSIT', 'TRAM', 'SUBWAY', 'FERRY', 'AIRPLANE', 'METRO', 'BUS', 'COACH', 'RAIL', 'HIGHSPEED_RAIL', 'LONG_DISTANCE', 'NIGHT_RAIL', 'REGIONAL_FAST_RAIL', 'REGIONAL_RAIL', 'OTHER'] + enum: ['WALK', 'BIKE', 'CAR', 'BIKE_RENTAL', 'CAR_PARKING', 'TRANSIT', 'TRAM', 'SUBWAY', 'FERRY', 'AIRPLANE', 'METRO', 'BUS', 'COACH', 'RAIL', 'HIGHSPEED_RAIL', 'LONG_DISTANCE', 'NIGHT_RAIL', 'REGIONAL_FAST_RAIL', 'REGIONAL_RAIL', 'OTHER'] } as const; export const VertexTypeSchema = { @@ -467,7 +461,19 @@ export const LegSchema = { '$ref': '#/components/schemas/Place' }, duration: { - description: 'Leg duration in seconds', + description: `Leg duration in seconds + +If leg is footpath: + The footpath duration is derived from the default footpath + duration using the query parameters \`transferTimeFactor\` and + \`additionalTransferTime\` as follows: + \`leg.duration = defaultDuration * transferTimeFactor + additionalTransferTime.\` + In case the defaultDuration is needed, it can be calculated by + \`defaultDuration = (leg.duration - additionalTransferTime) / transferTimeFactor\`. + Note that the default values are \`transferTimeFactor = 1\` and + \`additionalTransferTime = 0\` in case they are not explicitly + provided in the query. +`, type: 'integer' }, startTime: { diff --git a/ui/src/lib/openapi/types.gen.ts b/ui/src/lib/openapi/types.gen.ts index cb35f90cd..ed46a1f9c 100644 --- a/ui/src/lib/openapi/types.gen.ts +++ b/ui/src/lib/openapi/types.gen.ts @@ -106,17 +106,11 @@ export type type = 'ADDRESS' | 'PLACE' | 'STOP'; /** * # Street modes * - * - `WALK`: Walking some or all of the way of the route. - * - `BIKE`: Cycling for the entirety of the route or taking a bicycle onto the public transport (if enabled) and cycling from the arrival station to the destination. - * - `BIKE_RENTAL`: Taking a rented, shared-mobility bike for part or the entirety of the route. - * - `BIKE_TO_PARK`: Leaving the bicycle at the departure station and walking from the arrival station to the destination. This mode needs to be combined with at least one transit mode otherwise it behaves like an ordinary bicycle journey. - * - `CAR`: Driving your own car the entirety of the route. This can be combined with transit, where will return routes with a Kiss & Ride component. This means that the car is not parked in a permanent parking area but rather the passenger is dropped off (for example, at an airport) and the driver continues driving the car away from the drop off location. - * - `CAR_PARK` | `CAR_TO_PARK`: Driving a car to the park-and-ride facilities near a station and taking publictransport. This mode needs to be combined with at least one transit mode otherwise, it behaves like an ordinary car journey. - * - `CAR_HAILING`: Using a car hailing app like Uber or Lyft to get to a train station or all the way to the destination. - * - `CAR_PICKUP`: Walking to a pickup point along the road, driving to a drop-off point along the road, and walking the rest of the way. This can include various taxi-services or kiss & ride. - * - `CAR_RENTAL`: Walk to a car rental point, drive to a car rental drop-off point and walk the rest of the way. This can include car rental at fixed locations or free-floating services. - * - `FLEXIBLE`: Encompasses all types of on-demand and flexible transportation for example GTFS Flex or NeTEx Flexible Stop Places. - * - `SCOOTER_RENTAL`: Walking to a scooter rental point, riding a scooter to a scooter rental drop-off point, and walking the rest of the way. This can include scooter rental at fixed locations or free-floating services. + * - `WALK` + * - `BIKE` + * - `BIKE_RENTAL` + * - `CAR` + * - `CAR_PARKING` * * # Transit modes * @@ -136,7 +130,7 @@ export type type = 'ADDRESS' | 'PLACE' | 'STOP'; * - `REGIONAL_RAIL`: regional train * */ -export type Mode = 'WALK' | 'BIKE' | 'CAR' | 'BIKE_RENTAL' | 'BIKE_TO_PARK' | 'CAR_TO_PARK' | 'CAR_HAILING' | 'CAR_SHARING' | 'CAR_PICKUP' | 'CAR_RENTAL' | 'FLEXIBLE' | 'SCOOTER_RENTAL' | 'TRANSIT' | 'TRAM' | 'SUBWAY' | 'FERRY' | 'AIRPLANE' | 'METRO' | 'BUS' | 'COACH' | 'RAIL' | 'HIGHSPEED_RAIL' | 'LONG_DISTANCE' | 'NIGHT_RAIL' | 'REGIONAL_FAST_RAIL' | 'REGIONAL_RAIL' | 'OTHER'; +export type Mode = 'WALK' | 'BIKE' | 'CAR' | 'BIKE_RENTAL' | 'CAR_PARKING' | 'TRANSIT' | 'TRAM' | 'SUBWAY' | 'FERRY' | 'AIRPLANE' | 'METRO' | 'BUS' | 'COACH' | 'RAIL' | 'HIGHSPEED_RAIL' | 'LONG_DISTANCE' | 'NIGHT_RAIL' | 'REGIONAL_FAST_RAIL' | 'REGIONAL_RAIL' | 'OTHER'; /** * - `NORMAL` - latitude / longitude coordinate or address @@ -387,6 +381,18 @@ export type Leg = { to: Place; /** * Leg duration in seconds + * + * If leg is footpath: + * The footpath duration is derived from the default footpath + * duration using the query parameters `transferTimeFactor` and + * `additionalTransferTime` as follows: + * `leg.duration = defaultDuration * transferTimeFactor + additionalTransferTime.` + * In case the defaultDuration is needed, it can be calculated by + * `defaultDuration = (leg.duration - additionalTransferTime) / transferTimeFactor`. + * Note that the default values are `transferTimeFactor = 1` and + * `additionalTransferTime = 0` in case they are not explicitly + * provided in the query. + * */ duration: number; /** @@ -596,6 +602,26 @@ export type StoptimesData = { * */ arriveBy?: boolean; + /** + * This parameter will be ignored in case `pageCursor` is set. + * + * Optional. Default is + * - `LATER` for `arriveBy=false` + * - `EARLIER` for `arriveBy=true` + * + * The response will contain the next `n` arrivals / departures + * in case `EARLIER` is selected and the previous `n` + * arrivals / departures if `LATER` is selected. + * + */ + direction?: 'EARLIER' | 'LATER'; + /** + * Optional. Default is all transit modes. + * + * Only return arrivals/departures of the given modes. + * + */ + mode?: Array; /** * the number of events */ @@ -653,6 +679,13 @@ export type StoptimesError = unknown; export type PlanData = { query: { + /** + * Optional. Default is 0 minutes. + * + * Additional transfer time reserved for each transfer in minutes. + * + */ + additionalTransferTime?: number; /** * Optional. Default is `false`. * @@ -669,7 +702,7 @@ export type PlanData = { * * Note: Direct connections will only be returned on the first call. For paging calls, they can be omitted. * - * Note: Transit connections that are slower than the fastest direct walking connection will not show up. + * Note: Transit connections that are slower than the fastest direct connection will not show up. * This is being used as a cut-off during transit routing to speed up the search. * To prevent this, it's possible to send two separate requests (one with only `transitModes` and one with only `directModes`). * diff --git a/ui/src/routes/+page.svelte b/ui/src/routes/+page.svelte index 88c76d448..f4b3ea36b 100644 --- a/ui/src/routes/+page.svelte +++ b/ui/src/routes/+page.svelte @@ -221,15 +221,7 @@ - + diff --git a/ui/src/routes/SearchMask.svelte b/ui/src/routes/SearchMask.svelte index 49936ce3f..7342d5629 100644 --- a/ui/src/routes/SearchMask.svelte +++ b/ui/src/routes/SearchMask.svelte @@ -17,8 +17,7 @@ time = $bindable(), timeType = $bindable(), wheelchair = $bindable(), - bikeRental = $bindable(), - theme + bikeRental = $bindable() }: { from: Location; to: Location; @@ -26,7 +25,6 @@ timeType: string; wheelchair: boolean; bikeRental: boolean; - theme?: 'light' | 'dark'; } = $props(); let fromItems = $state>([]); @@ -40,7 +38,6 @@ placeholder={t.from} bind:selected={from} bind:items={fromItems} - {theme} />