diff --git a/include/motis/endpoints/initial.h b/include/motis/endpoints/initial.h index 1949a2b2f8..b9bac2df63 100644 --- a/include/motis/endpoints/initial.h +++ b/include/motis/endpoints/initial.h @@ -11,6 +11,7 @@ struct initial { api::initial_response operator()(boost::urls::url_view const&) const; nigiri::timetable const& tt_; + config const& config_; }; } // namespace motis::ep \ No newline at end of file diff --git a/openapi.yaml b/openapi.yaml index 640d9b4253..5aeaf36bcb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1716,7 +1716,7 @@ paths: schema: $ref: '#/components/schemas/Error' '200': - description: latitude, longitude and zoom level to set the map to + description: latitude, longitude, zoom level to set the map to, and routing options configuration and limits content: application/json: schema: @@ -1735,6 +1735,8 @@ paths: zoom: description: zoom level type: number + serverConfig: + $ref: '#/components/schemas/ServerConfig' /api/v1/map/stops: get: @@ -3587,6 +3589,35 @@ components: true = many to one false = one to many type: boolean + ServerConfig: + Description: server configuration + type: object + required: + - hasElevation + - hasRoutedTransfers + - hasStreetRouting + - maxTravelTimeLimit + - maxPrePostTransitTimeLimit + - maxDirectTimeLimit + properties: + hasElevation: + description: true if elevation is loaded + type: boolean + hasRoutedTransfers: + description: true if routed transfers available + type: boolean + hasStreetRouting: + description: true if street routing is available + type: boolean + maxOneToAllTravelTimeLimit: + description: limit for maxTravelTime API param in minutes + type: number + maxPrePostTransitTimeLimit: + description: limit for maxPrePostTransitTime API param in seconds + type: number + maxDirectTimeLimit: + description: limit for maxDirectTime API param in seconds + type: number Error: type: object properties: diff --git a/src/endpoints/initial.cc b/src/endpoints/initial.cc index 0ecb92d98b..f578ba763c 100644 --- a/src/endpoints/initial.cc +++ b/src/endpoints/initial.cc @@ -1,4 +1,5 @@ #include "motis/endpoints/initial.h" +#include "motis/config.h" #include "utl/erase_if.h" #include "utl/to_vec.h" @@ -51,9 +52,31 @@ api::initial_response initial::operator()(boost::urls::url_view const&) const { } } + auto const onetoall_max_travel_minutes = + config_.limits_->onetoall_max_travel_minutes_; + auto const street_routing_max_direct_seconds = + config_.limits_->street_routing_max_direct_seconds_; + auto const street_routing_max_prepost_transit_seconds = + config_.limits_->street_routing_max_prepost_transit_seconds_; + auto const has_osr_footpath = config_.osr_footpath_; + auto const has_street_routing = config_.get_street_routing().has_value(); + auto const has_elevation_data_dir = + has_street_routing && + config_.get_street_routing()->elevation_data_dir_.has_value(); + return {.lat_ = center.lat_, .lon_ = center.lng_, - .zoom_ = static_cast(zoom)}; + .zoom_ = static_cast(zoom), + .serverConfig_ = api::ServerConfig{ + .hasElevation_ = has_elevation_data_dir, + .hasRoutedTransfers_ = has_osr_footpath, + .hasStreetRouting_ = has_street_routing, + .maxOneToAllTravelTimeLimit_ = + static_cast(onetoall_max_travel_minutes), + .maxPrePostTransitTimeLimit_ = static_cast( + street_routing_max_prepost_transit_seconds), + .maxDirectTimeLimit_ = + static_cast(street_routing_max_direct_seconds)}}; } } // namespace motis::ep \ No newline at end of file diff --git a/ui/api/openapi/schemas.gen.ts b/ui/api/openapi/schemas.gen.ts index ba8b4d8f70..5b54bd6df6 100644 --- a/ui/api/openapi/schemas.gen.ts +++ b/ui/api/openapi/schemas.gen.ts @@ -1737,6 +1737,38 @@ false = one to many } } as const; +export const ServerConfigSchema = { + Description: 'server configuration', + type: 'object', + required: ['hasElevation', 'hasRoutedTransfers', 'hasStreetRouting', 'maxTravelTimeLimit', 'maxPrePostTransitTimeLimit', 'maxDirectTimeLimit'], + properties: { + hasElevation: { + description: 'true if elevation is loaded', + type: 'boolean' + }, + hasRoutedTransfers: { + description: 'true if routed transfers available', + type: 'boolean' + }, + hasStreetRouting: { + description: 'true if street routing is available', + type: 'boolean' + }, + maxOneToAllTravelTimeLimit: { + description: 'limit for maxTravelTime API param in minutes', + type: 'number' + }, + maxPrePostTransitTimeLimit: { + description: 'limit for maxPrePostTransitTime API param in seconds', + type: 'number' + }, + maxDirectTimeLimit: { + description: 'limit for maxDirectTime API param in seconds', + type: 'number' + } + } +} as const; + export const ErrorSchema = { type: 'object', properties: { diff --git a/ui/api/openapi/types.gen.ts b/ui/api/openapi/types.gen.ts index 6940096da9..e026f52805 100644 --- a/ui/api/openapi/types.gen.ts +++ b/ui/api/openapi/types.gen.ts @@ -1389,6 +1389,33 @@ export type OneToManyParams = { arriveBy: boolean; }; +export type ServerConfig = { + /** + * true if elevation is loaded + */ + hasElevation: boolean; + /** + * true if routed transfers available + */ + hasRoutedTransfers: boolean; + /** + * true if street routing is available + */ + hasStreetRouting: boolean; + /** + * limit for maxTravelTime API param in minutes + */ + maxOneToAllTravelTimeLimit?: number; + /** + * limit for maxPrePostTransitTime API param in seconds + */ + maxPrePostTransitTimeLimit: number; + /** + * limit for maxDirectTime API param in seconds + */ + maxDirectTimeLimit: number; +}; + export type Error = { error?: string; }; @@ -2463,6 +2490,7 @@ export type InitialResponse = ({ * zoom level */ zoom: number; + serverConfig?: ServerConfig; }); export type InitialError = (Error); diff --git a/ui/src/lib/AdvancedOptions.svelte b/ui/src/lib/AdvancedOptions.svelte index b9fda58aff..eb7e328b9b 100644 --- a/ui/src/lib/AdvancedOptions.svelte +++ b/ui/src/lib/AdvancedOptions.svelte @@ -5,7 +5,7 @@ import * as Select from '$lib/components/ui/select'; import { ChevronUp, ChevronDown } from '@lucide/svelte'; import { Switch } from './components/ui/switch'; - import type { ElevationCosts } from '@motis-project/motis-client'; + import type { ElevationCosts, ServerConfig } from '@motis-project/motis-client'; import { defaultQuery } from '$lib/defaults'; import { formatDurationSec } from './formatDuration'; import { @@ -18,9 +18,11 @@ import StreetModes from '$lib/StreetModes.svelte'; import TransitModeSelect from '$lib/TransitModeSelect.svelte'; import { type NumberSelectOption } from '$lib/NumberSelect.svelte'; + import { generateTimes } from './generateTimes'; let { useRoutedTransfers = $bindable(), + serverConfig, wheelchair = $bindable(), requireBikeTransport = $bindable(), requireCarTransport = $bindable(), @@ -44,6 +46,7 @@ additionalComponents }: { useRoutedTransfers: boolean; + serverConfig: ServerConfig | undefined; wheelchair: boolean; requireBikeTransport: boolean; requireCarTransport: boolean; @@ -72,37 +75,13 @@ label: i.toString() })); - const possibleDirectDurations = [ - 5 * 60, - 10 * 60, - 15 * 60, - 20 * 60, - 25 * 60, - 30 * 60, - 35 * 60, - 40 * 60, - 45 * 60, - 50 * 60, - 60 * 60, - 90 * 60, - 120 * 60, - 180 * 60, - 240 * 60, - 300 * 60, - 360 * 60 - ]; - const possiblePrePostDurations = [ - 1 * 60, - 5 * 60, - 10 * 60, - 15 * 60, - 20 * 60, - 25 * 60, - 30 * 60, - 40 * 60, - 50 * 60, - 60 * 60 - ]; + const possibleDirectDurations = $derived( + generateTimes(serverConfig?.maxDirectTimeLimit ?? 60 * 60) + ); + const possiblePrePostDurations = $derived( + generateTimes(serverConfig?.maxPrePostTransitTimeLimit ?? 60 * 60) + ); + function setModes(mode: PrePostDirectMode) { return function (checked: boolean) { if (checked) { @@ -129,11 +108,14 @@ ]; let expanded = $state(false); let allowElevationCosts = $derived( - requireBikeTransport || - preTransitModes.includes('BIKE') || - postTransitModes.includes('BIKE') || - directModes?.includes('BIKE') + serverConfig?.hasElevation && + (requireBikeTransport || + preTransitModes.includes('BIKE') || + postTransitModes.includes('BIKE') || + directModes?.includes('BIKE')) ); + let allowStreetRouting = $derived(serverConfig?.hasStreetRouting); + let allowRoutedTransfers = $derived(serverConfig?.hasRoutedTransfers);