Showing preview only (2,272K chars total). Download the full file or copy to clipboard to get everything.
Repository: motis-project/motis
Branch: master
Commit: 2b88cb38965c
Files: 443
Total size: 18.0 MB
Directory structure:
gitextract_8b0p7zjl/
├── .clang-format
├── .clang-tidy.in
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .pkg
├── CMakeLists.txt
├── CMakePresets.json
├── CODE_OF_CONDUCT.md
├── Dockerfile
├── LICENSE
├── README.md
├── cmake/
│ ├── buildcache.cmake
│ ├── clang-tidy.cmake
│ └── pkg.cmake
├── docs/
│ ├── STYLE.md
│ ├── dev-setup-server.md
│ ├── elevation-setup.md
│ ├── linux-dev-setup.md
│ ├── macos-dev-setup.md
│ ├── python-client.md
│ ├── scripting.md
│ ├── setup.md
│ └── windows-dev-setup.md
├── exe/
│ ├── batch.cc
│ ├── compare.cc
│ ├── extract.cc
│ ├── flags.h
│ ├── generate.cc
│ ├── main.cc
│ └── params.cc
├── include/
│ └── motis/
│ ├── adr_extend_tt.h
│ ├── analyze_shapes.h
│ ├── box_rtree.h
│ ├── clog_redirect.h
│ ├── compute_footpaths.h
│ ├── config.h
│ ├── constants.h
│ ├── ctx_data.h
│ ├── ctx_exec.h
│ ├── data.h
│ ├── direct_filter.h
│ ├── elevators/
│ │ ├── elevators.h
│ │ ├── get_state_changes.h
│ │ ├── match_elevator.h
│ │ ├── parse_elevator_id_osm_mapping.h
│ │ ├── parse_fasta.h
│ │ ├── parse_siri_fm.h
│ │ └── update_elevators.h
│ ├── endpoints/
│ │ ├── adr/
│ │ │ ├── filter_conv.h
│ │ │ ├── geocode.h
│ │ │ ├── reverse_geocode.h
│ │ │ └── suggestions_to_response.h
│ │ ├── elevators.h
│ │ ├── graph.h
│ │ ├── gtfsrt.h
│ │ ├── initial.h
│ │ ├── levels.h
│ │ ├── map/
│ │ │ ├── flex_locations.h
│ │ │ ├── rental.h
│ │ │ ├── route_details.h
│ │ │ ├── routes.h
│ │ │ ├── shapes_debug.h
│ │ │ ├── stops.h
│ │ │ └── trips.h
│ │ ├── matches.h
│ │ ├── metrics.h
│ │ ├── ojp.h
│ │ ├── one_to_all.h
│ │ ├── one_to_many.h
│ │ ├── one_to_many_post.h
│ │ ├── osr_routing.h
│ │ ├── platforms.h
│ │ ├── routing.h
│ │ ├── stop_times.h
│ │ ├── tiles.h
│ │ ├── transfers.h
│ │ ├── trip.h
│ │ └── update_elevator.h
│ ├── flex/
│ │ ├── flex.h
│ │ ├── flex_areas.h
│ │ ├── flex_output.h
│ │ ├── flex_routing_data.h
│ │ └── mode_id.h
│ ├── fwd.h
│ ├── gbfs/
│ │ ├── compression.h
│ │ ├── data.h
│ │ ├── gbfs_output.h
│ │ ├── geofencing.h
│ │ ├── lru_cache.h
│ │ ├── mode.h
│ │ ├── osr_mapping.h
│ │ ├── osr_profile.h
│ │ ├── parser.h
│ │ ├── partition.h
│ │ ├── routing_data.h
│ │ └── update.h
│ ├── get_loc.h
│ ├── get_stops_with_traffic.h
│ ├── hashes.h
│ ├── http_req.h
│ ├── import.h
│ ├── journey_to_response.h
│ ├── location_routes.h
│ ├── logging.h
│ ├── match_platforms.h
│ ├── metrics_registry.h
│ ├── motis_instance.h
│ ├── odm/
│ │ ├── bounds.h
│ │ ├── journeys.h
│ │ ├── meta_router.h
│ │ ├── odm.h
│ │ ├── prima.h
│ │ ├── query_factory.h
│ │ ├── shorten.h
│ │ └── td_offsets.h
│ ├── osr/
│ │ ├── max_distance.h
│ │ ├── mode_to_profile.h
│ │ ├── parameters.h
│ │ └── street_routing.h
│ ├── parse_location.h
│ ├── place.h
│ ├── point_rtree.h
│ ├── polyline.h
│ ├── railviz.h
│ ├── route_shapes.h
│ ├── rt/
│ │ ├── auser.h
│ │ └── rt_metrics.h
│ ├── rt_update.h
│ ├── server.h
│ ├── tag_lookup.h
│ ├── tiles_data.h
│ ├── timetable/
│ │ ├── clasz_to_mode.h
│ │ ├── modes_to_clasz_mask.h
│ │ └── time_conv.h
│ ├── transport_mode_ids.h
│ ├── tt_location_rtree.h
│ ├── types.h
│ └── update_rtt_td_footpaths.h
├── openapi.yaml
├── src/
│ ├── adr_extend_tt.cc
│ ├── analyze_shapes.cc
│ ├── clog_redirect.cc
│ ├── compute_footpaths.cc
│ ├── config.cc
│ ├── data.cc
│ ├── direct_filter.cc
│ ├── elevators/
│ │ ├── elevators.cc
│ │ ├── match_elevators.cc
│ │ ├── parse_elevator_id_osm_mapping.cc
│ │ ├── parse_fasta.cc
│ │ ├── parse_siri_fm.cc
│ │ └── update_elevators.cc
│ ├── endpoints/
│ │ ├── adr/
│ │ │ ├── filter_conv.cc
│ │ │ ├── geocode.cc
│ │ │ ├── reverse_geocode.cc
│ │ │ └── suggestions_to_response.cc
│ │ ├── elevators.cc
│ │ ├── graph.cc
│ │ ├── gtfsrt.cc
│ │ ├── initial.cc
│ │ ├── levels.cc
│ │ ├── map/
│ │ │ ├── flex.cc
│ │ │ ├── rental.cc
│ │ │ ├── route_details.cc
│ │ │ ├── routes.cc
│ │ │ ├── shapes_debug.cc
│ │ │ ├── stops.cc
│ │ │ └── trips.cc
│ │ ├── matches.cc
│ │ ├── metrics.cc
│ │ ├── ojp.cc
│ │ ├── one_to_all.cc
│ │ ├── one_to_many.cc
│ │ ├── one_to_many_post.cc
│ │ ├── osr_routing.cc
│ │ ├── platforms.cc
│ │ ├── routing.cc
│ │ ├── stop_times.cc
│ │ ├── tiles.cc
│ │ ├── transfers.cc
│ │ ├── trip.cc
│ │ └── update_elevator.cc
│ ├── flex/
│ │ ├── flex.cc
│ │ ├── flex_areas.cc
│ │ └── flex_output.cc
│ ├── gbfs/
│ │ ├── data.cc
│ │ ├── gbfs_output.cc
│ │ ├── geofencing.cc
│ │ ├── mode.cc
│ │ ├── osr_mapping.cc
│ │ ├── osr_profile.cc
│ │ ├── parser.cc
│ │ ├── routing_data.cc
│ │ └── update.cc
│ ├── get_stops_with_traffic.cc
│ ├── hashes.cc
│ ├── http_req.cc
│ ├── import.cc
│ ├── journey_to_response.cc
│ ├── logging.cc
│ ├── match_platforms.cc
│ ├── metrics_registry.cc
│ ├── odm/
│ │ ├── blacklist_taxi.cc
│ │ ├── bounds.cc
│ │ ├── journeys.cc
│ │ ├── meta_router.cc
│ │ ├── odm.cc
│ │ ├── prima.cc
│ │ ├── query_factory.cc
│ │ ├── shorten.cc
│ │ ├── td_offsets.cc
│ │ ├── whitelist_ridesharing.cc
│ │ └── whitelist_taxi.cc
│ ├── osr/
│ │ ├── max_distance.cc
│ │ ├── mode_to_profile.cc
│ │ ├── parameters.cc
│ │ └── street_routing.cc
│ ├── parse_location.cc
│ ├── place.cc
│ ├── polyline.cc
│ ├── railviz.cc
│ ├── route_shapes.cc
│ ├── rt/
│ │ └── auser.cc
│ ├── rt_update.cc
│ ├── server.cc
│ ├── tag_lookup.cc
│ ├── timetable/
│ │ ├── clasz_to_mode.cc
│ │ └── modes_to_clasz_mask.cc
│ └── update_rtt_td_footpaths.cc
├── test/
│ ├── combinations_test.cc
│ ├── config_test.cc
│ ├── elevators/
│ │ ├── parse_elevator_id_osm_mapping_test.cc
│ │ ├── parse_fasta_test.cc
│ │ ├── parse_siri_fm_test.cc
│ │ └── siri_fm_routing_test.cc
│ ├── endpoints/
│ │ ├── map_routes_test.cc
│ │ ├── ojp_test.cc
│ │ ├── one_to_many_test.cc
│ │ ├── siri_sx_test.cc
│ │ ├── stop_group_geocoding_test.cc
│ │ ├── stop_times_test.cc
│ │ └── trip_test.cc
│ ├── ffm_hbf.osm
│ ├── flex_mode_id_test.cc
│ ├── gbfs_partition_test.cc
│ ├── main.cc
│ ├── matching_test.cc
│ ├── odm/
│ │ ├── csv_journey_test.cc
│ │ ├── prima_test.cc
│ │ └── td_offsets_test.cc
│ ├── read_test.cc
│ ├── resources/
│ │ ├── gbfs/
│ │ │ ├── free_bike_status.json
│ │ │ ├── gbfs.json
│ │ │ ├── geofencing_zones.json
│ │ │ ├── station_information.json
│ │ │ ├── station_status.json
│ │ │ ├── system_information.json
│ │ │ └── vehicle_types.json
│ │ ├── ojp/
│ │ │ ├── geocoding_request.xml
│ │ │ ├── geocoding_response.xml
│ │ │ ├── intermodal_routing_request.xml
│ │ │ ├── intermodal_routing_response.xml
│ │ │ ├── map_stops_request.xml
│ │ │ ├── map_stops_response.xml
│ │ │ ├── routing_request.xml
│ │ │ ├── routing_response.xml
│ │ │ ├── stop_event_request.xml
│ │ │ ├── stop_event_response.xml
│ │ │ ├── trip_info_request.xml
│ │ │ └── trip_info_response.xml
│ │ └── test_case.geojson
│ ├── routing_shrink_results_test.cc
│ ├── routing_slow_direct_test.cc
│ ├── routing_test.cc
│ ├── tag_lookup_test.cc
│ ├── test_case/
│ │ └── .gitignore
│ ├── test_case.cc
│ ├── test_case.h
│ ├── test_dir.h.in
│ ├── util.cc
│ └── util.h
├── tools/
│ ├── buildcache-clang-tidy.lua
│ ├── suppress.txt
│ ├── try-reproduce.py
│ └── ubsan-suppress.txt
└── ui/
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── README.md
├── api/
│ ├── LICENSE
│ ├── README.md
│ ├── openapi/
│ │ ├── index.ts
│ │ ├── schemas.gen.ts
│ │ ├── services.gen.ts
│ │ └── types.gen.ts
│ ├── package.json
│ └── tsconfig.json
├── components.json
├── eslint.config.js
├── package.json
├── playwright.config.ts
├── pnpm-workspace.yaml
├── postcss.config.js
├── src/
│ ├── app.css
│ ├── app.d.ts
│ ├── app.html
│ ├── index.test.ts
│ ├── lib/
│ │ ├── AddressTypeahead.svelte
│ │ ├── AdvancedOptions.svelte
│ │ ├── Alerts.svelte
│ │ ├── Color.ts
│ │ ├── ConnectionDetail.svelte
│ │ ├── DateInput.svelte
│ │ ├── Debug.svelte
│ │ ├── DeparturesMask.svelte
│ │ ├── DirectConnection.svelte
│ │ ├── ErrorMessage.svelte
│ │ ├── IsochronesInfo.svelte
│ │ ├── IsochronesMask.svelte
│ │ ├── ItineraryList.svelte
│ │ ├── LevelSelect.svelte
│ │ ├── Location.ts
│ │ ├── Modes.ts
│ │ ├── NumberSelect.svelte
│ │ ├── Precision.ts
│ │ ├── RailViz.svelte
│ │ ├── Route.svelte
│ │ ├── SearchMask.svelte
│ │ ├── StopTimes.svelte
│ │ ├── StreetModes.svelte
│ │ ├── Time.svelte
│ │ ├── TransitModeSelect.svelte
│ │ ├── ViaStopOptions.svelte
│ │ ├── components/
│ │ │ └── ui/
│ │ │ ├── button/
│ │ │ │ ├── button.svelte
│ │ │ │ └── index.ts
│ │ │ ├── card/
│ │ │ │ ├── card-content.svelte
│ │ │ │ ├── card-description.svelte
│ │ │ │ ├── card-footer.svelte
│ │ │ │ ├── card-header.svelte
│ │ │ │ ├── card-title.svelte
│ │ │ │ ├── card.svelte
│ │ │ │ └── index.ts
│ │ │ ├── dialog/
│ │ │ │ ├── dialog-content.svelte
│ │ │ │ ├── dialog-description.svelte
│ │ │ │ ├── dialog-footer.svelte
│ │ │ │ ├── dialog-header.svelte
│ │ │ │ ├── dialog-overlay.svelte
│ │ │ │ ├── dialog-title.svelte
│ │ │ │ └── index.ts
│ │ │ ├── label/
│ │ │ │ ├── index.ts
│ │ │ │ └── label.svelte
│ │ │ ├── radio-group/
│ │ │ │ ├── index.ts
│ │ │ │ ├── radio-group-item.svelte
│ │ │ │ └── radio-group.svelte
│ │ │ ├── select/
│ │ │ │ ├── index.ts
│ │ │ │ ├── select-content.svelte
│ │ │ │ ├── select-group-heading.svelte
│ │ │ │ ├── select-item.svelte
│ │ │ │ ├── select-scroll-down-button.svelte
│ │ │ │ ├── select-scroll-up-button.svelte
│ │ │ │ ├── select-separator.svelte
│ │ │ │ └── select-trigger.svelte
│ │ │ ├── separator/
│ │ │ │ ├── index.ts
│ │ │ │ └── separator.svelte
│ │ │ ├── switch/
│ │ │ │ ├── index.ts
│ │ │ │ └── switch.svelte
│ │ │ ├── table/
│ │ │ │ ├── index.ts
│ │ │ │ ├── table-body.svelte
│ │ │ │ ├── table-caption.svelte
│ │ │ │ ├── table-cell.svelte
│ │ │ │ ├── table-footer.svelte
│ │ │ │ ├── table-head.svelte
│ │ │ │ ├── table-header.svelte
│ │ │ │ ├── table-row.svelte
│ │ │ │ └── table.svelte
│ │ │ ├── tabs/
│ │ │ │ ├── index.ts
│ │ │ │ ├── tabs-content.svelte
│ │ │ │ ├── tabs-list.svelte
│ │ │ │ ├── tabs-trigger.svelte
│ │ │ │ └── tabs.svelte
│ │ │ └── toggle/
│ │ │ ├── index.ts
│ │ │ └── toggle.svelte
│ │ ├── constants.ts
│ │ ├── defaults.ts
│ │ ├── formatDuration.ts
│ │ ├── generateTimes.ts
│ │ ├── getModeName.ts
│ │ ├── i18n/
│ │ │ ├── bg.ts
│ │ │ ├── cs.ts
│ │ │ ├── de.ts
│ │ │ ├── en.ts
│ │ │ ├── fr.ts
│ │ │ ├── pl.ts
│ │ │ └── translation.ts
│ │ ├── lngLatToStr.ts
│ │ ├── map/
│ │ │ ├── Control.svelte
│ │ │ ├── Drawer.svelte
│ │ │ ├── GeoJSON.svelte
│ │ │ ├── Isochrones.svelte
│ │ │ ├── IsochronesShapeWorker.ts
│ │ │ ├── IsochronesShared.ts
│ │ │ ├── IsochronesWorker.ts
│ │ │ ├── Layer.svelte
│ │ │ ├── Map.svelte
│ │ │ ├── Marker.svelte
│ │ │ ├── Popup.svelte
│ │ │ ├── colors.ts
│ │ │ ├── createTripIcon.ts
│ │ │ ├── getModeLabel.ts
│ │ │ ├── handleScroll.ts
│ │ │ ├── itineraries/
│ │ │ │ ├── ItineraryGeoJSON.svelte
│ │ │ │ ├── itineraryLayers.ts
│ │ │ │ └── layerFilters.ts
│ │ │ ├── rentals/
│ │ │ │ ├── Rentals.svelte
│ │ │ │ ├── StationPopup.svelte
│ │ │ │ ├── VehiclePopup.svelte
│ │ │ │ ├── ZoneLayer.svelte
│ │ │ │ ├── ZonePopup.svelte
│ │ │ │ ├── assets.ts
│ │ │ │ ├── style.ts
│ │ │ │ ├── zone-fill-layer.ts
│ │ │ │ └── zone-types.ts
│ │ │ ├── routes/
│ │ │ │ └── Routes.svelte
│ │ │ ├── shield.ts
│ │ │ ├── stops/
│ │ │ │ └── StopsGeoJSON.svelte
│ │ │ └── style.ts
│ │ ├── modeStyle.ts
│ │ ├── preprocessItinerary.ts
│ │ ├── toDateTime.ts
│ │ ├── tripsWorker.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ └── routes/
│ ├── +layout.svelte
│ ├── +layout.ts
│ └── +page.svelte
├── static/
│ ├── sprite_sdf.json
│ └── sprite_sdf@2x.json
├── svelte.config.js
├── tailwind.config.js
├── tests/
│ └── test.ts
├── tsconfig.json
└── vite.config.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
BasedOnStyle: Google
IndentWidth: 2
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Left
AccessModifierOffset: -2
ConstructorInitializerAllOnOneLineOrOnePerLine: true
AlignTrailingComments: false
KeepEmptyLinesAtTheStartOfBlocks: true
AllowShortCaseLabelsOnASingleLine: true
AlwaysBreakTemplateDeclarations: true
SpacesBeforeTrailingComments: 2
SortIncludes: true
IncludeBlocks: Preserve
BinPackParameters: false
QualifierAlignment: Right
IncludeCategories:
- Regex: '^<.*>'
Priority: 1
- Regex: '^"boost.*'
Priority: 2
- Regex: '^"nigiri/core/common.*'
Priority: 3
- Regex: '^"nigiri/core/schedule.*'
Priority: 4
- Regex: '^"nigiri/core/.*'
Priority: 5
- Regex: '^"nigiri/module/.*'
Priority: 6
- Regex: '^"nigiri/bootstrap/.*'
Priority: 7
- Regex: '^"nigiri/loader/.*'
Priority: 8
- Regex: '^"nigiri/.*'
Priority: 9
- Regex: '^"nigiri/protocol.*'
Priority: 10
- Regex: '^"./.*'
Priority: 11
- Regex: '.*'
Priority: 12
---
BasedOnStyle: Google
IndentWidth: 2
Language: ObjC
DerivePointerAlignment: false
PointerAlignment: Left
AccessModifierOffset: -2
ConstructorInitializerAllOnOneLineOrOnePerLine: true
AlignTrailingComments: false
KeepEmptyLinesAtTheStartOfBlocks: true
AllowShortCaseLabelsOnASingleLine: true
AlwaysBreakTemplateDeclarations: true
SpacesBeforeTrailingComments: 2
ColumnLimit: 80
QualifierAlignment: Right
IncludeCategories:
- Regex: '^<.*>'
Priority: 1
- Regex: '^"boost.*'
Priority: 2
- Regex: '^"nigiri/core/common.*'
Priority: 3
- Regex: '^"nigiri/core/schedule.*'
Priority: 4
- Regex: '^"nigiri/core/.*'
Priority: 5
- Regex: '^"nigiri/module/.*'
Priority: 6
- Regex: '^"nigiri/bootstrap/.*'
Priority: 7
- Regex: '^"nigiri/loader/.*'
Priority: 8
- Regex: '^"nigiri/.*'
Priority: 9
- Regex: '^"nigiri/protocol.*'
Priority: 10
- Regex: '^"./.*'
Priority: 11
- Regex: '.*'
Priority: 12
================================================
FILE: .clang-tidy.in
================================================
Checks: "*,\
-llvmlibc-*,\
-abseil-*,\
-readability-identifier-length,\
-altera-unroll-loops,\
-altera-id-dependent-backward-branch,\
-bugprone-easily-swappable-parameters,\
-bugprone-implicit-widening-of-multiplication-result,\
-llvm-else-after-return,\
-hicpp-named-parameter,\
-cert-err60-cpp,\
-clang-analyzer-core.NonNullParamChecker,\
-misc-unused-parameters,\
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,\
-cppcoreguidelines-pro-bounds-pointer-arithmetic,\
-cppcoreguidelines-pro-type-union-access,\
-readability-simplify-boolean-expr,\
-clang-analyzer-alpha*,\
-google-build-using-namespace,\
-clang-analyzer-optin.osx*,\
-clang-analyzer-osx*,\
-readability-implicit-bool-cast,\
-readability-else-after-return,\
-llvm-include-order,\
-clang-analyzer-alpha.unix.PthreadLock,\
-llvm-header-guard,\
-readability-named-parameter,\
-clang-analyzer-alpha.deadcode.UnreachableCode,\
-cppcoreguidelines-pro-type-reinterpret-cast,\
-cppcoreguidelines-pro-type-vararg,\
-misc-move-const-arg,\
-google-runtime-references,\
-cert-err58-cpp,\
-modernize-use-default-member-init,\
-fuchsia-overloaded-operator,\
-fuchsia-default-arguments,\
-hicpp-vararg,\
-clang-analyzer-optin.cplusplus.VirtualCall,\
-cppcoreguidelines-owning-memory,\
-hicpp-no-array-decay,\
-*-magic-numbers,\
-*-non-private-member-variables-in-classes,\
-fuchsia-statically-constructed-objects,\
-readability-isolate-declaration,\
-fuchsia-multiple-inheritance,\
-fuchsia-trailing-return,\
-portability-simd-intrinsics,\
-modernize-use-nodiscard,\
-cppcoreguidelines-pro-bounds-constant-array-index,\
-*-avoid-c-arrays,\
-*-narrowing-conversions,\
-*-avoid-goto,\
-hicpp-multiway-paths-covered,\
-clang-analyzer-cplusplus.NewDeleteLeaks,\
-clang-analyzer-cplusplus.NewDelete,\
-hicpp-signed-bitwise,\
-cert-msc32-c,\
-cert-msc51-cpp,\
-bugprone-exception-escape,\
-cppcoreguidelines-macro-usage,\
-cert-dcl21-cpp,\
-modernize-use-trailing-return-type,\
-fuchsia-default-arguments-calls,\
-fuchsia-default-arguments-declarations,\
-misc-no-recursion,\
-llvmlibc-callee-namespace,\
-llvm-else-after-return,\
-llvm-qualified-auto,\
-readability-qualified-auto,\
-google-readability-avoid-underscore-in-googletest-name,\
-readability-function-cognitive-complexity,\
-readability-avoid-const-params-in-decls,\
-cppcoreguidelines-avoid-const-or-ref-data-members,\
-cppcoreguidelines-avoid-do-while,\
-altera-struct-pack-align,\
-bugprone-unchecked-optional-access,\
-readability-identifier-naming,\
-cert-dcl37-c,\
-bugprone-reserved-identifier,\
-cert-dcl51-cpp,\
-misc-confusable-identifiers,\
-clang-analyzer-optin.core.EnumCastOutOfRange,\
-clang-analyzer-core.CallAndMessage"
WarningsAsErrors: '*'
HeaderFilterRegex: '^${RELATIVE_SOURCE_DIR}(base|modules|test)/'
AnalyzeTemporaryDtors: false
UseColor: true
User: root
CheckOptions:
- key: cert-err61-cpp.CheckThrowTemporaries
value: '1'
- key: cert-oop11-cpp.IncludeStyle
value: llvm
- key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader
value: ''
- key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle
value: '0'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.BranchThreshold
value: '4294967295'
- key: google-readability-function-size.LineThreshold
value: '4294967295'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: google-runtime-int.SignedTypePrefix
value: int
- key: google-runtime-int.TypeSuffix
value: ''
- key: google-runtime-int.UnsignedTypePrefix
value: uint
- key: llvm-namespace-comment.ShortNamespaceLines
value: '1'
- key: llvm-namespace-comment.SpacesBeforeComments
value: '2'
- key: misc-assert-side-effect.AssertMacros
value: assert
- key: misc-assert-side-effect.CheckFunctionCalls
value: '0'
- key: misc-definitions-in-headers.UseHeaderFileExtension
value: '1'
- key: misc-move-constructor-init.IncludeStyle
value: llvm
- key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries
value: '1'
- key: modernize-loop-convert.MaxCopySize
value: '16'
- key: modernize-loop-convert.MinConfidence
value: reasonable
- key: modernize-loop-convert.NamingStyle
value: lower_case
- key: modernize-pass-by-value.IncludeStyle
value: llvm
- key: modernize-replace-auto-ptr.IncludeStyle
value: llvm
- key: modernize-use-nullptr.NullMacros
value: 'NULL'
- key: readability-braces-around-statements.ShortStatementLines
value: '0'
- key: readability-function-size.BranchThreshold
value: '4294967295'
- key: readability-function-size.LineThreshold
value: '4294967295'
- key: readability-function-size.StatementThreshold
value: '800'
- key: readability-identifier-naming.AbstractClassCase
value: lower_case
- key: readability-identifier-naming.AbstractClassPrefix
value: ''
- key: readability-identifier-naming.AbstractClassSuffix
value: ''
- key: readability-identifier-naming.ClassCase
value: lower_case
- key: readability-identifier-naming.ClassConstantCase
value: aNy_CasE
- key: readability-identifier-naming.ClassConstantPrefix
value: ''
- key: readability-identifier-naming.ClassConstantSuffix
value: ''
- key: readability-identifier-naming.ClassMemberCase
value: lower_case
- key: readability-identifier-naming.ClassMemberPrefix
value: ''
- key: readability-identifier-naming.ClassMemberSuffix
value: '_'
- key: readability-identifier-naming.ClassMethodCase
value: lower_case
- key: readability-identifier-naming.ClassMethodPrefix
value: ''
- key: readability-identifier-naming.ClassMethodSuffix
value: ''
- key: readability-identifier-naming.ClassPrefix
value: ''
- key: readability-identifier-naming.ClassSuffix
value: ''
- key: readability-identifier-naming.ConstantCase
value: aNy_CasE
- key: readability-identifier-naming.ConstantMemberCase
value: aNy_CasE
- key: readability-identifier-naming.ConstantMemberPrefix
value: ''
- key: readability-identifier-naming.ConstantMemberSuffix
value: ''
- key: readability-identifier-naming.ConstantParameterCase
value: aNy_CasE
- key: readability-identifier-naming.ConstantParameterPrefix
value: ''
- key: readability-identifier-naming.ConstantParameterSuffix
value: ''
- key: readability-identifier-naming.ConstantPrefix
value: ''
- key: readability-identifier-naming.ConstantSuffix
value: ''
- key: readability-identifier-naming.ConstexprFunctionCase
value: aNy_CasE
- key: readability-identifier-naming.ConstexprFunctionPrefix
value: ''
- key: readability-identifier-naming.ConstexprFunctionSuffix
value: ''
- key: readability-identifier-naming.ConstexprMethodCase
value: aNy_CasE
- key: readability-identifier-naming.ConstexprMethodPrefix
value: ''
- key: readability-identifier-naming.ConstexprMethodSuffix
value: ''
- key: readability-identifier-naming.ConstexprVariableCase
value: aNy_CasE
- key: readability-identifier-naming.ConstexprVariablePrefix
value: ''
- key: readability-identifier-naming.ConstexprVariableSuffix
value: ''
- key: readability-identifier-naming.EnumCase
value: lower_case
- key: readability-identifier-naming.EnumConstantCase
value: aNy_CasE
- key: readability-identifier-naming.EnumConstantPrefix
value: ''
- key: readability-identifier-naming.EnumConstantSuffix
value: ''
- key: readability-identifier-naming.EnumPrefix
value: ''
- key: readability-identifier-naming.EnumSuffix
value: ''
- key: readability-identifier-naming.FunctionCase
value: lower_case
- key: readability-identifier-naming.FunctionPrefix
value: ''
- key: readability-identifier-naming.FunctionSuffix
value: ''
- key: readability-identifier-naming.GlobalConstantCase
value: aNy_CasE
- key: readability-identifier-naming.GlobalConstantPrefix
value: ''
- key: readability-identifier-naming.GlobalConstantSuffix
value: ''
- key: readability-identifier-naming.GlobalFunctionCase
value: lower_case
- key: readability-identifier-naming.GlobalFunctionPrefix
value: ''
- key: readability-identifier-naming.GlobalFunctionSuffix
value: ''
- key: readability-identifier-naming.GlobalVariableCase
value: aNy_CasE
- key: readability-identifier-naming.GlobalVariablePrefix
value: ''
- key: readability-identifier-naming.GlobalVariableSuffix
value: ''
- key: readability-identifier-naming.IgnoreFailedSplit
value: '0'
- key: readability-identifier-naming.InlineNamespaceCase
value: lower_case
- key: readability-identifier-naming.InlineNamespacePrefix
value: ''
- key: readability-identifier-naming.InlineNamespaceSuffix
value: ''
- key: readability-identifier-naming.LocalConstantCase
value: aNy_CasE
- key: readability-identifier-naming.LocalConstantPrefix
value: ''
- key: readability-identifier-naming.LocalConstantSuffix
value: ''
- key: readability-identifier-naming.LocalVariableCase
value: lower_case
- key: readability-identifier-naming.LocalVariablePrefix
value: ''
- key: readability-identifier-naming.LocalVariableSuffix
value: ''
- key: readability-identifier-naming.MemberCase
value: lower_case
- key: readability-identifier-naming.MemberPrefix
value: ''
- key: readability-identifier-naming.MemberSuffix
value: '_'
- key: readability-identifier-naming.MethodCase
value: lower_case
- key: readability-identifier-naming.MethodPrefix
value: ''
- key: readability-identifier-naming.MethodSuffix
value: ''
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.NamespacePrefix
value: ''
- key: readability-identifier-naming.NamespaceSuffix
value: ''
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.ParameterPackCase
value: lower_case
- key: readability-identifier-naming.ParameterPackPrefix
value: ''
- key: readability-identifier-naming.ParameterPackSuffix
value: ''
- key: readability-identifier-naming.ParameterPrefix
value: ''
- key: readability-identifier-naming.ParameterSuffix
value: ''
- key: readability-identifier-naming.PrivateMemberCase
value: lower_case
- key: readability-identifier-naming.PrivateMemberPrefix
value: ''
- key: readability-identifier-naming.PrivateMemberSuffix
value: '_'
- key: readability-identifier-naming.PrivateMethodCase
value: lower_case
- key: readability-identifier-naming.PrivateMethodPrefix
value: ''
- key: readability-identifier-naming.PrivateMethodSuffix
value: ''
- key: readability-identifier-naming.ProtectedMemberCase
value: lower_case
- key: readability-identifier-naming.ProtectedMemberPrefix
value: ''
- key: readability-identifier-naming.ProtectedMemberSuffix
value: '_'
- key: readability-identifier-naming.ProtectedMethodCase
value: lower_case
- key: readability-identifier-naming.ProtectedMethodPrefix
value: ''
- key: readability-identifier-naming.ProtectedMethodSuffix
value: ''
- key: readability-identifier-naming.PublicMemberCase
value: lower_case
- key: readability-identifier-naming.PublicMemberPrefix
value: ''
- key: readability-identifier-naming.PublicMemberSuffix
value: '_'
- key: readability-identifier-naming.PublicMethodCase
value: lower_case
- key: readability-identifier-naming.PublicMethodPrefix
value: ''
- key: readability-identifier-naming.PublicMethodSuffix
value: ''
- key: readability-identifier-naming.StaticConstantCase
value: aNy_CasE
- key: readability-identifier-naming.StaticConstantPrefix
value: ''
- key: readability-identifier-naming.StaticConstantSuffix
value: ''
- key: readability-identifier-naming.StaticVariableCase
value: lower_case
- key: readability-identifier-naming.StaticVariablePrefix
value: ''
- key: readability-identifier-naming.StaticVariableSuffix
value: ''
- key: readability-identifier-naming.StructCase
value: lower_case
- key: readability-identifier-naming.StructPrefix
value: ''
- key: readability-identifier-naming.StructSuffix
value: ''
- key: readability-identifier-naming.TemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TemplateTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.TypedefCase
value: lower_case
- key: readability-identifier-naming.TypedefPrefix
value: ''
- key: readability-identifier-naming.TypedefSuffix
value: ''
- key: readability-identifier-naming.UnionCase
value: lower_case
- key: readability-identifier-naming.UnionPrefix
value: ''
- key: readability-identifier-naming.UnionSuffix
value: ''
- key: readability-identifier-naming.ValueTemplateParameterCase
value: CamelCase
- key: readability-identifier-naming.ValueTemplateParameterPrefix
value: ''
- key: readability-identifier-naming.ValueTemplateParameterSuffix
value: ''
- key: readability-identifier-naming.VariableCase
value: aNy_CasE
- key: readability-identifier-naming.VariablePrefix
value: ''
- key: readability-identifier-naming.VariableSuffix
value: ''
- key: readability-identifier-naming.VirtualMethodCase
value: lower_case
- key: readability-identifier-naming.VirtualMethodPrefix
value: ''
- key: readability-identifier-naming.VirtualMethodSuffix
value: ''
- key: readability-simplify-boolean-expr.ChainedConditionalAssignment
value: '0'
- key: readability-simplify-boolean-expr.ChainedConditionalReturn
value: '0'
- key: performance-for-range-copy.AllowedTypes
value: 'offset_ptr;ptr'
- key: performance-unnecessary-value-param.AllowedTypes
value: 'offset_ptr;ptr'
- key: readability-identifier-naming.TypeTemplateParameterIgnoredRegexp
value: 'expr-type'
- key: readability-identifier-naming.TemplateParameterIgnoredRegexp
value: 'expr-type'
- key: readability-identifier-naming.TypeTemplateParameterIgnoredRegexp
value: 'expr-type'
- key: readability-identifier-naming.TemplateTemplateParameterIgnoredRegexp
value: 'expr-type'
- key: readability-identifier-naming.ValueTemplateParameterIgnoredRegexp
value: 'expr-type'
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
release:
types:
- published
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
openapi-validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- name: Install Dependencies
run: npm install @openapitools/openapi-generator-cli -g
- name: OpenAPI Lint
run: openapi-generator-cli validate -i openapi.yaml
ui:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Install Dependencies
working-directory: ui
run: pnpm install
- name: Build
working-directory: ui
run: pnpm -r build
- name: Code Lint
working-directory: ui
run: pnpm run lint
- name: Svelte Check
working-directory: ui
run: pnpm run check
formatting:
runs-on: ubuntu-latest
container: ghcr.io/motis-project/docker-cpp-build
steps:
- uses: actions/checkout@v4
- name: Format files
run: |
find include src test \
-type f -a \( -name "*.cc" -o -name "*.h" -o -name ".cuh" -o -name ".cu" \) \
-print0 | xargs -0 clang-format-21 -i
- name: Check for differences
run: |
git config --global --add safe.directory `pwd`
git status --porcelain
git status --porcelain | xargs -I {} -0 test -z \"{}\"
msvc:
runs-on: [ self-hosted, windows, x64 ]
strategy:
fail-fast: false
matrix:
config:
- mode: Debug
- mode: Release
env:
CXX: cl.exe
CC: cl.exe
BUILDCACHE_COMPRESS: true
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_ACCURACY: SLOPPY # not suitable for coverage/debugging
BUILDCACHE_DIR: ${{ github.workspace }}/.buildcache
BUILDCACHE_LUA_PATH: ${{ github.workspace }}/tools
BUILDCACHE_MAX_CACHE_SIZE: 1073741824
CLICOLOR_FORCE: 1
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: pnpm/action-setup@v4
with:
version: 10
dest: "~/setup-pnpm-${{ matrix.config.mode }}"
- uses: ilammy/msvc-dev-cmd@v1
# ==== RESTORE CACHE ====
- name: Restore buildcache Cache
run: |
$buildcachePath = "${{ runner.tool_cache }}\${{ github.event.repository.name }}\buildcache-${{ matrix.config.mode }}"
New-Item -ItemType Directory -Force -Path $buildcachePath
New-Item -Path ${{ github.workspace }}/.buildcache -ItemType SymbolicLink -Value $buildcachePath
- name: Restore Dependencies Cache
run: |
$depsPath = "${{ runner.tool_cache }}\${{ github.event.repository.name }}\deps"
New-Item -ItemType Directory -Force -Path $depsPath
New-Item -Path ${{ github.workspace }}\deps\ -ItemType SymbolicLink -Value $depsPath
- name: Build
run: |
cmake `
-GNinja -S . -B build `
-DCMAKE_BUILD_TYPE=${{ matrix.config.mode }} `
-DMOTIS_MIMALLOC=ON
.\build\buildcache\bin\buildcache.exe -z
cmake --build build --target motis motis-test motis-web-ui
$CompilerExitCode = $LastExitCode
Copy-Item ${env:VCToolsRedistDir}x64\Microsoft.VC143.CRT\*.dll .\build\
.\build\buildcache\bin\buildcache.exe -s
exit $CompilerExitCode
# ==== TESTS ====
- name: Run Tests
run: .\build\motis-test.exe
# ==== DISTRIBUTION ====
- name: Move Profiles
if: matrix.config.mode == 'Release'
run: |
mkdir dist
Copy-Item .\deps\tiles\profile dist\tiles-profiles -Recurse
mv .\build\motis.exe dist
mv .\build\*.dll dist
mv .\ui\build dist\ui
cd dist
7z a motis-windows.zip *
mv motis-windows.zip ..
- name: Upload Distribution
if: matrix.config.mode == 'Release'
uses: actions/upload-artifact@v4
with:
name: motis-windows
path: dist
# ==== RELEASE ====
- name: Upload Release
if: github.event.action == 'published' && matrix.config.mode == 'Release'
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./motis-windows.zip
asset_name: motis-windows.zip
asset_content_type: application/zip
macos:
runs-on: macos-latest
env:
BUILDCACHE_COMPRESS: true
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_ACCURACY: SLOPPY
BUILDCACHE_LUA_PATH: ${{ github.workspace }}/tools
BUILDCACHE_DIR: ${{ github.workspace }}/.buildcache
UBSAN_OPTIONS: halt_on_error=1:abort_on_error=1
ASAN_OPTIONS: alloc_dealloc_mismatch=0
steps:
- uses: actions/checkout@v4
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.2
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Install ninja
run: brew install ninja
# ==== RESTORE CACHE ====
- name: Restore buildcache Cache
uses: actions/cache/restore@v4
id: restore-buildcache
with:
path: ${{ github.workspace }}/.buildcache
key: buildcache-${{ hashFiles('.pkg') }}-${{ hashFiles('**/*.h') }}-${{ hashFiles('**/*.cc') }}
restore-keys: |
buildcache-${{ hashFiles('.pkg') }}-${{ hashFiles('**/*.h') }}-
buildcache-${{ hashFiles('.pkg') }}-
buildcache-
- name: Dependencies Cache
uses: actions/cache/restore@v4
id: restore-deps
with:
path: ${{ github.workspace }}/deps
key: deps-${{ hashFiles('.pkg') }}
restore-keys: deps-
# ==== BUILD ====
- name: CMake
run: cmake -G Ninja -S . -B build --preset=macos-arm64
- name: Build
run: |
./build/buildcache/bin/buildcache -z
cmake --build build --target motis motis-test motis-web-ui
./build/buildcache/bin/buildcache -s
# ==== TESTS ====
- name: Run Tests
if: matrix.config.tests == 'On'
run: build/motis-test
# ==== SAVE CACHE ====
- name: Save buildcache cache
if: always()
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/.buildcache
key: ${{ steps.restore-buildcache.outputs.cache-primary-key }}
- name: Save deps cache
if: always()
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/deps
key: ${{ steps.restore-deps.outputs.cache-primary-key }}
# ==== DISTRIBUTION ====
- name: Create Distribution
run: |
mkdir motis
mv build/motis motis/motis
mv ui/build motis/ui
cp -r deps/tiles/profile motis/tiles-profiles
tar -C ./motis -cjf motis-macos-arm64.tar.bz2 ./motis ./tiles-profiles ./ui
- name: Upload Distribution
uses: actions/upload-artifact@v4
with:
name: motis-macos-arm64
path: motis-macos-arm64.tar.bz2
# ==== RELEASE ====
- name: Upload Release
if: github.event.action == 'published'
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./motis-macos-arm64.tar.bz2
asset_name: motis-macos-arm64.tar.bz2
asset_content_type: application/x-tar
linux:
runs-on: [ self-hosted, linux, x64, '${{ matrix.config.preset }}' ]
container:
image: ghcr.io/motis-project/docker-cpp-build
volumes:
- ${{ github.event.repository.name }}-${{ matrix.config.preset }}-deps:/deps
- ${{ github.event.repository.name }}-${{ matrix.config.preset }}-buildcache:/buildcache
strategy:
fail-fast: false
matrix:
config:
- preset: linux-amd64-release
artifact: linux-amd64
- preset: linux-arm64-release
artifact: linux-arm64
- preset: linux-sanitizer
- preset: linux-debug
emulator: valgrind --suppressions=deps/osr/docs/tbb.supp --suppressions=deps/osr/docs/pthread.supp --suppressions=tools/suppress.txt --leak-check=full --gen-suppressions=all --error-exitcode=1
env:
BUILDCACHE_DIR: /buildcache
BUILDCACHE_DIRECT_MODE: true
BUILDCACHE_MAX_CACHE_SIZE: 26843545600
BUILDCACHE_LUA_PATH: ${{ github.workspace }}/tools
UBSAN_OPTIONS: halt_on_error=1:abort_on_error=1
ASAN_OPTIONS: alloc_dealloc_mismatch=0
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- name: Get deps
run: ln -s /deps deps
- name: CMake
run: |
git config --global --add safe.directory `pwd`
cmake -G Ninja -S . -B build --preset=${{ matrix.config.preset }}
# ==== BUILD ====
- name: Build
run: |
buildcache -z
cmake --build build --target motis motis-test motis-web-ui
buildcache -s
# ==== TESTS ====
- name: Run Integration Tests
if: matrix.config.preset != 'linux-arm64-release'
run: ${{ matrix.config.emulator }} build/motis-test
# ==== FULL DATASET TEST ====
- name: Test Full Dataset
if: matrix.config.preset != 'linux-debug' && matrix.config.preset != 'linux-arm64-release'
run: |
ln -s deps/tiles/profile tiles-profiles
wget -N https://github.com/motis-project/test-data/raw/aachen/aachen.osm.pbf
wget -N https://github.com/motis-project/test-data/raw/aachen/AVV_GTFS_Masten_mit_SPNV.zip
${{ matrix.config.emulator }} ./build/motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
yq -Y -i '.timetable *= {
"route_shapes": {
"missing_shapes": true,
"replace_shapes": true,
"clasz": { "COACH": false }
}
}' config.yml
${{ matrix.config.emulator }} ./build/motis import
${{ matrix.config.emulator }} ./build/motis generate -n 10
${{ matrix.config.emulator }} ./build/motis batch
${{ matrix.config.emulator }} ./build/motis compare -q queries.txt -r responses.txt responses.txt
- name: Test bin_ver compatibility with previous release
if: matrix.config.preset == 'linux-amd64-release' && github.event.action != 'published'
run: |
wget -N https://github.com/motis-project/motis/releases/latest/download/motis-linux-amd64.tar.bz2
tar -xjf motis-linux-amd64.tar.bz2 ./motis
${{ matrix.config.emulator }} ./motis import
${{ matrix.config.emulator }} ./build/motis import
rm ./motis
# ==== DISTRIBUTION ====
- name: Create Distribution
if: matrix.config.artifact
run: |
mkdir motis
mv build/motis motis/motis
mv ui/build motis/ui
cp -r deps/tiles/profile motis/tiles-profiles
tar -C ./motis -cjf motis-${{ matrix.config.artifact }}.tar.bz2 ./motis ./tiles-profiles ./ui
- name: Upload Distribution
if: matrix.config.artifact
uses: actions/upload-artifact@v4
with:
name: motis-${{ matrix.config.artifact }}
path: motis-${{ matrix.config.artifact }}.tar.bz2
# ==== RELEASE ====
- name: Upload Release
if: github.event.action == 'published' && matrix.config.artifact
uses: actions/upload-release-asset@v1.0.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./motis-${{ matrix.config.artifact }}.tar.bz2
asset_name: motis-${{ matrix.config.artifact }}.tar.bz2
asset_content_type: application/x-
docker:
if: ${{ github.event.pull_request.head.repo.full_name == github.event.pull_request.base.repo.full_name }}
runs-on: ubuntu-latest
needs: linux
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
- name: Docker setup-buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Docker Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=edge
- name: Docker build and push
uses: docker/build-push-action@v5
with:
push: true
context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
publish-motis-client:
if: github.event.action == 'published'
runs-on: ubuntu-latest
needs: linux
permissions:
contents: read
packages: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- uses: pnpm/action-setup@v4
with:
version: 10
# for OIDC-based publishing to npm
- name: setup npm v11
run: npm install -g npm@11
# this will override version 2.0.0 from package.json to the current git tag version
- run: npm version from-git --no-git-tag-version
working-directory: ui/api
- run: npm ci
working-directory: ui/api
- run: pnpm run build
working-directory: ui/api
- run: npm publish --provenance --access public
working-directory: ui/api
================================================
FILE: .gitignore
================================================
/tiles-profiles
/*build*
/.pkg.mutex
/.clang-tidy
/.idea
.vscode/
.DS_Store
/deps
*.zip
*.bin
*.pbf
*.csv
/osr
/delfi
/test/test_case_osr
/fasta.json
/adr.cista*
/data
/test/data*
dist/
fasta.json
config.yaml
config.yml
config.ini
================================================
FILE: .pkg
================================================
[nigiri]
url=git@github.com:motis-project/nigiri.git
branch=master
commit=8b07193adf152f258ccfa207f922579d0a0e2195
[cista]
url=git@github.com:felixguendling/cista.git
branch=master
commit=10abc43279bd99586d3433ea3b419727f46b8dd9
[osr]
url=git@github.com:motis-project/osr.git
branch=master
commit=78ed3a45e5b543cf4a266df005faca5c2fad8ed2
[utl]
url=git@github.com:motis-project/utl.git
branch=master
commit=d9930c90e440df761c8c4916c36072de9dd00f49
[adr]
url=git@github.com:triptix-tech/adr.git
branch=master
commit=64ff88efc22622a79d38c7a7e101d4a86e906a1e
[googletest]
url=git@github.com:motis-project/googletest.git
branch=master
commit=7b64fca6ea0833628d6f86255a81424365f7cc0c
[net]
url=git@github.com:motis-project/net.git
branch=master
commit=bb00cafad46dd4ea4064b9651d982f31b9853c19
[openapi-cpp]
url=git@github.com:triptix-tech/openapi-cpp.git
branch=master
commit=1e1e5bee6a3a73270595196b2aa7f41cbe7d9214
[unordered_dense]
url=git@github.com:motis-project/unordered_dense.git
branch=main
commit=2c7230ae7f9c30849a5b089fb4a5d11896b45dcf
[reflect-cpp]
url=git@github.com:motis-project/reflect-cpp.git
branch=main
commit=86fdcdd09a54b0f55de97110e1911d27f60e498a
[tiles]
url=git@github.com:motis-project/tiles.git
branch=master
commit=6bd71d984eb699d7160f5c448bc14d5c57ddb4b7
[boost]
url=git@github.com:motis-project/boost.git
branch=boost-1.89.0
commit=77467bf580d98ea06716e2931cbe3b1f28e0cd37
[tg]
url=git@github.com:triptix-tech/tg.git
branch=main
commit=20c0f298b8ce58de29a790290f44dca7c4ecc364
[mimalloc]
url=git@github.com:motis-project/mimalloc.git
branch=dev3
commit=b88ce9c8fd6b7c9208a43bcdb705de9f499dbad4
[lz4]
url=git@github.com:motis-project/lz4.git
branch=dev
commit=ff69dbd1ad10852104257d5306874a07b76f0dbd
[prometheus-cpp]
url=git@github.com:motis-project/prometheus-cpp.git
branch=master
commit=e420cd7cf3995a994220b40a36c987ac8e67c0bf
[opentelemetry-cpp]
url=git@github.com:motis-project/opentelemetry-cpp.git
branch=main
commit=57a4c01aff876e08d9d37a3dec2c9899f0606909
[ctx]
url=git@github.com:motis-project/ctx.git
branch=master
commit=9b495bdd798520007a4f1c13e51766a26f10ef10
[geo]
url=git@github.com:motis-project/geo.git
branch=master
commit=4a410791d3a2d77eafae917e0607051bbd4fa659
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.20)
project(motis LANGUAGES C CXX ASM)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
option(MOTIS_MIMALLOC "use mimalloc" OFF)
set(MOTIS_STACKTRACE "AUTO" CACHE STRING "Enable stacktrace support (AUTO, ON, OFF)")
set_property(CACHE MOTIS_STACKTRACE PROPERTY STRINGS "AUTO;ON;OFF")
set(_MOTIS_STACKTRACE_ON "$<OR:$<STREQUAL:${MOTIS_STACKTRACE},ON>,$<AND:$<STREQUAL:${MOTIS_STACKTRACE},AUTO>,$<CONFIG:Debug>>>")
if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
if (MOTIS_MIMALLOC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
set(protobuf_MSVC_STATIC_RUNTIME OFF)
else ()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(protobuf_MSVC_STATIC_RUNTIME ON)
endif ()
endif ()
if (MOTIS_MIMALLOC)
set(CISTA_USE_MIMALLOC ON)
set(PPR_MIMALLOC ON)
set(ADR_MIMALLOC ON)
set(OSR_MIMALLOC ON)
set(TILES_MIMALLOC ON)
if(WIN32)
set(MI_BUILD_SHARED ON)
endif()
endif()
include(cmake/buildcache.cmake)
include(cmake/pkg.cmake)
if (MOTIS_MIMALLOC)
if(WIN32)
set(motis-mimalloc-lib mimalloc)
target_link_libraries(cista INTERFACE mimalloc)
else()
set(motis-mimalloc-lib mimalloc-obj)
target_link_libraries(cista INTERFACE mimalloc-static)
endif()
target_compile_definitions(cista INTERFACE CISTA_USE_MIMALLOC=1)
target_compile_definitions(boost INTERFACE BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC=1)
endif()
# --- LINT ---
option(ICC_LINT "Run clang-tidy with the compiler." OFF)
if (ICC_LINT)
# clang-tidy will be run on all targets defined hereafter
include(cmake/clang-tidy.cmake)
endif ()
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(motis-compile-options
-Weverything
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-newline-eof
-Wno-missing-prototypes
-Wno-padded
-Wno-double-promotion
-Wno-undef
-Wno-undefined-reinterpret-cast
-Wno-float-conversion
-Wno-global-constructors
-Wno-exit-time-destructors
-Wno-switch-enum
-Wno-c99-designator
-Wno-zero-as-null-pointer-constant
-Wno-missing-noreturn
-Wno-undefined-func-template
-Wno-unsafe-buffer-usage
-Wno-c++20-compat
-Wno-reserved-macro-identifier
-Wno-documentation-unknown-command
-Wno-duplicate-enum
-Wno-ctad-maybe-unsupported
-Wno-unknown-pragmas
-Wno-c++20-extensions
-Wno-switch-default
-Wno-unused-template
-Wno-shadow-uncaptured-local
-Wno-documentation-deprecated-sync
-Wno-float-equal
-Wno-deprecated-declarations
-Wno-reserved-identifier
-Wno-implicit-int-float-conversion
-Wno-nrvo
-Wno-thread-safety-negative
-Wno-unused-private-field)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
set(motis-compile-options -Wall -Wextra -Wno-unknown-pragmas -Wno-deprecated-declarations)
elseif (MSVC)
set(motis-compile-options
/bigobj
# clang-21 libc++ seems not to have a special overloaded std::atomic<std::shared_ptr<T>>
# check if future version support std::atomic<std::shared_ptr<rt>>
/D_SILENCE_CXX20_OLD_SHARED_PTR_ATOMIC_SUPPORT_DEPRECATION_WARNING
)
else ()
set(motis-compile-options
-Wall
-Wextra
-Wno-array-bounds
-Wno-stringop-overread
-Wno-mismatched-new-delete
-Wno-maybe-uninitialized)
endif ()
# --- OPENAPI ---
openapi_generate(openapi.yaml motis-api motis::api)
# --- LIB ---
file(GLOB_RECURSE motislib-files src/*.cc)
add_library(motislib ${motislib-files})
target_include_directories(motislib PUBLIC include)
target_compile_features(motislib PUBLIC cxx_std_23)
target_compile_options(motislib PRIVATE ${motis-compile-options})
target_link_libraries(motislib
nigiri
osr
adr
ctx
boost-json
motis-api
reflectcpp
web-server
tiles
pbf_sdf_fonts_res
ssl
crypto
tg
lz4_static
lb
web-server
prometheus-cpp::core
opentelemetry_trace
opentelemetry_exporter_otlp_http
lmdb
Boost::stacktrace
"$<${_MOTIS_STACKTRACE_ON}:Boost::stacktrace_from_exception>"
)
# --- EXE ---
execute_process(
COMMAND git describe --always --tags --dirty=-dirty
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE motis-git-tag
OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(GLOB_RECURSE motis-files exe/*.cc)
add_executable(motis ${motis-files})
target_compile_features(motis PUBLIC cxx_std_23)
target_compile_options(motis PRIVATE ${motis-compile-options})
set_source_files_properties(exe/main.cc PROPERTIES COMPILE_DEFINITIONS MOTIS_VERSION="${motis-git-tag}")
target_link_libraries(motis
motislib
ianatzdb-res
pbf_sdf_fonts_res-res
tiles_server_res-res
address_formatting_res-res
)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
target_link_options(motis PRIVATE -Wl,-no_deduplicate)
endif()
# --- TEST ---
add_library(motis-generated INTERFACE)
target_include_directories(motis-generated INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/generated)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/test/test_dir.h.in
${CMAKE_CURRENT_BINARY_DIR}/generated/test_dir.h
)
file(GLOB_RECURSE motis-test-files test/*.cc)
add_executable(motis-test ${motis-test-files})
target_link_libraries(motis-test motislib gmock web-server ianatzdb-res address_formatting_res-res motis-generated)
target_compile_options(motis-test PRIVATE ${motis-compile-options})
# --- TILES ---
set_property(
TARGET motis tiles tiles-import-library
APPEND PROPERTY COMPILE_DEFINITIONS TILES_GLOBAL_PROGRESS_TRACKER=1)
file (CREATE_LINK ${CMAKE_SOURCE_DIR}/deps/tiles/profile ${CMAKE_BINARY_DIR}/tiles-profiles SYMBOLIC)
# --- MIMALLOC ---
if (MOTIS_MIMALLOC)
target_link_libraries(motis ${motis-mimalloc-lib})
target_compile_definitions(motis PUBLIC USE_MIMALLOC=1)
if(WIN32)
add_custom_command(
TARGET motis POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
$<TARGET_FILE:mimalloc>
$<TARGET_FILE_DIR:motis>
COMMENT "Copy mimalloc.dll to output directory"
)
add_custom_command(
TARGET motis POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy
"${CMAKE_SOURCE_DIR}/deps/mimalloc/bin/mimalloc-redirect.dll"
$<TARGET_FILE_DIR:motis>
COMMENT "Copy mimalloc-redirect.dll to output directory"
)
add_custom_command(
TARGET motis POST_BUILD
COMMAND "${CMAKE_SOURCE_DIR}/deps/mimalloc/bin/minject.exe"
--force --inplace
$<$<CONFIG:Debug>:--postfix=debug>
$<TARGET_FILE:motis>
COMMENT "Ensure mimalloc.dll is loaded first"
)
add_custom_command(
TARGET motis-test POST_BUILD
COMMAND "${CMAKE_SOURCE_DIR}/deps/mimalloc/bin/minject.exe"
--force --inplace
$<$<CONFIG:Debug>:--postfix=debug>
$<TARGET_FILE:motis-test>
COMMENT "Ensure mimalloc.dll is loaded first"
)
endif()
if (MSVC)
target_link_options(motis PUBLIC "/include:mi_version")
endif ()
endif()
# --- UI ---
add_custom_target(motis-web-ui
COMMAND pnpm install && pnpm -r build
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ui"
VERBATIM
)
file (CREATE_LINK ${CMAKE_SOURCE_DIR}/ui/build ${CMAKE_BINARY_DIR}/ui SYMBOLIC)
foreach(t adr osr nigiri gtfsrt
geo tiles tiles-import-library
motis motis-api motislib)
target_compile_options(${t} PUBLIC ${MOTIS_TARGET_FLAGS})
endforeach()
if (MOTIS_MIMALLOC)
target_compile_options(mimalloc PUBLIC ${MOTIS_TARGET_FLAGS})
endif()
================================================
FILE: CMakePresets.json
================================================
{
"version": 3,
"cmakeMinimumRequired": {
"major": 3,
"minor": 21,
"patch": 0
},
"configurePresets": [
{
"name": "macos-x86_64",
"displayName": "MacOS x86_64 Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/macos-x86_64-release",
"cacheVariables": {
"BOOST_CONTEXT_ABI": "sysv",
"BOOST_CONTEXT_ARCHITECTURE": "x86_64",
"CMAKE_OSX_ARCHITECTURES": "x86_64",
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "macos-arm64",
"displayName": "MacOS ARM64 Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/macos-arm64-release",
"cacheVariables": {
"CMAKE_OSX_ARCHITECTURES": "arm64",
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
"BOOST_CONTEXT_ARCHITECTURE": "arm64",
"BOOST_CONTEXT_ABI": "aapcs",
"ENABLE_ASM": "OFF",
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "linux-amd64-release",
"displayName": "Linux AMD64 Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/amd64-release",
"toolchainFile": "/opt/x86_64-multilib-linux-musl/toolchain-amd64.cmake",
"cacheVariables": {
"CMAKE_EXE_LINKER_FLAGS": "-B/opt/mold",
"CMAKE_BUILD_TYPE": "Release",
"MOTIS_MIMALLOC": "ON"
},
"environment": {
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
},
{
"name": "linux-arm64-release",
"displayName": "Linux ARM64 Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/arm64-release",
"toolchainFile": "/opt/aarch64-unknown-linux-musl/toolchain-arm64.cmake",
"cacheVariables": {
"CMAKE_CROSSCOMPILING_EMULATOR": "qemu-aarch64-static",
"CMAKE_C_FLAGS": "-mcpu=neoverse-n1",
"CMAKE_CXX_FLAGS": "-mcpu=neoverse-n1",
"CMAKE_EXE_LINKER_FLAGS": "-B/opt/mold",
"CMAKE_BUILD_TYPE": "Release",
"MOTIS_MIMALLOC": "ON"
},
"environment": {
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
},
{
"name": "linux-sanitizer",
"displayName": "Linux Sanitizer",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/sanitizer",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-21",
"CMAKE_CXX_COMPILER": "clang++-21",
"CMAKE_EXE_LINKER_FLAGS": "-lc++abi",
"CMAKE_BUILD_TYPE": "Debug",
"CTX_ASAN": "ON",
"CMAKE_C_FLAGS": "-fsanitize=address,undefined -fsanitize-ignorelist=${sourceDir}/tools/ubsan-suppress.txt -fno-omit-frame-pointer",
"CMAKE_CXX_FLAGS": "-stdlib=libc++ -fsanitize=address,undefined -fno-omit-frame-pointer"
},
"environment": {
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
},
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXE_LINKER_FLAGS": "-B/opt/mold",
"CTX_VALGRIND": "ON"
},
"environment": {
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"CXX": "/usr/bin/g++-13",
"CC": "/usr/bin/gcc-13"
}
},
{
"name": "linux-relwithdebinfo",
"displayName": "Linux RelWithDebInfo",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/relwithdebinfo",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"CMAKE_EXE_LINKER_FLAGS": "-B/opt/mold"
},
"environment": {
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"CXX": "/usr/bin/g++-13",
"CC": "/usr/bin/gcc-13"
}
},
{
"name": "clang-tidy",
"displayName": "Clang Tidy",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/clang-tidy",
"cacheVariables": {
"CMAKE_C_COMPILER": "clang-21",
"CMAKE_CXX_COMPILER": "clang++-21",
"CMAKE_CXX_FLAGS": "-stdlib=libc++",
"CMAKE_EXE_LINKER_FLAGS": "-lc++abi",
"CMAKE_BUILD_TYPE": "Release",
"ICC_LINT": "On"
},
"environment": {
"BUILDCACHE_LUA_PATH": "/opt/buildcache/share/lua-examples",
"PATH": "/opt:/opt/cmake-3.26.3-linux-x86_64/bin:/opt/buildcache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
}
}
],
"buildPresets": [
{
"name": "macos-x86_64",
"configurePreset": "macos-x86_64"
},
{
"name": "macos-arm64",
"configurePreset": "macos-arm64"
},
{
"name": "linux-amd64-release",
"configurePreset": "linux-amd64-release"
},
{
"name": "linux-arm64-release",
"configurePreset": "linux-arm64-release"
},
{
"name": "clang-tidy",
"configurePreset": "clang-tidy"
},
{
"name": "linux-debug",
"configurePreset": "linux-debug"
},
{
"name": "linux-relwithdebinfo",
"configurePreset": "linux-relwithdebinfo"
},
{
"name": "linux-sanitizer",
"configurePreset": "linux-sanitizer"
}
]
}
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, caste, color, religion, or sexual
identity and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or advances of
any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email address,
without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official email address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
felix@triptix.tech.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or permanent
ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within the
community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations
================================================
FILE: Dockerfile
================================================
FROM alpine:3.20
ARG TARGETARCH
ADD motis-linux-$TARGETARCH/motis-linux-$TARGETARCH.tar.bz2 /
RUN addgroup -S motis && adduser -S motis -G motis && \
mkdir /data && \
chown motis:motis /data
EXPOSE 8080
VOLUME ["/data"]
USER motis
CMD ["/motis", "server", "/data"]
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2024 MOTIS Project
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<p align="center"><img src="logo.svg" width="196" height="196"></p>
> [!TIP]
> :sparkles: Join the international MOTIS community at [**motis:matrix.org**](https://matrix.to/#/#motis:matrix.org)
MOTIS stands for **M**odular **O**pen **T**ransportation **I**nformation **S**ystem.
It is an open-source software platform designed to facilitate
efficient planning and routing in multi-modal transportation systems.
Developed to handle *large-scale* transportation data,
MOTIS integrates various modes of transport -
such as walking, cycling, sharing mobility (e-scooters, bike sharing, car
sharing), and public transport -
to provide optimized routing solutions.
MOTIS currently supports the following input formats:
- (One) **OpenStreetMap `osm.pbf`** file for the street network, addresses, indoor-routing, etc.
- (Multiple) **GTFS** (including GTFS Flex and GTFS Fares v2) feeds for static timetables
- (Multiple) **GTFS-RT** feeds for real-time updates (delays, cancellations, track changes, service alerts)
- (Multiple) **GBFS** feeds for sharing mobility
*Working on (funded by [NLnet](https://nlnet.nl/project/MOTIS/))*: NeTEx and SIRI
MOTIS provides an easy-to-use **REST API** (JSON via HTTP) with
an [**OpenAPI specification**](https://redocly.github.io/redoc/?url=https://raw.githubusercontent.com/motis-project/motis/refs/heads/master/openapi.yaml) ([source](openapi.yaml))
that allows you to generate clients for your favorite programming language. You may also directly use the pre-generated [JS client](https://www.npmjs.com/package/@motis-project/motis-client). Some more available client libraries are listed [over at Transitous](https://transitous.org/api/).
Also checkout [**Transitous**](https://transitous.org), which operates a MOTIS instance with global coverage (as far as available) at [api.transitous.org](https://api.transitous.org).
Please make sure to read the [Usage Policy](https://transitous.org/api/) before integrating this endpoint into your app.
# Features
> [!NOTE]
> :rocket: MOTIS is optimized for **high performance** with **low memory usage**.
>
> This enables _planet-sized_ deployments on affordable hardware.
MOTIS is a swiss army knife for mobility and comes with all features you need for a next generation mobility platform:
- **routing**: one mode walking, bike, car, sharing mobility / combined modes
- **geocoding**: multi-language address and stop name completion with fuzzy string matching and resolution to geo coordinates
- **reverse geocoding**: resolving geo coordinates to the closest address
- **tile server**: background map tiles
MOTIS uses efficient traffic day bitsets that allows efficient loading of **full year timetables**!
Loading one year of timetable doesn't take much more RAM than loading one month.
Features can be turned on and off as needed.
# Quick Start
- Create a folder with the following files.
- Download MOTIS from
the [latest release](https://github.com/motis-project/motis/releases) and
extract the archive.
- Download a OpenStreetMap dataset as `osm.pbf` (e.g.
from [Geofabrik](https://download.geofabrik.de/)) and place it in the folder
- Download one or more GTFS datasets and place them in the folder
```bash
./motis config my.osm.pbf gtfs.zip # generates a minimal config.yml
./motis import # preprocesses data
./motis server # starts a HTTP server on port 8080
```
This will preprocess the input files and create a `data` folder.
After that, it will start a server.
> [!IMPORTANT]
> Ensure a valid timetable is used. If the timetable is outdated, it will not contain any trips to consider for upcoming dates.
This script will execute the steps described above for a small dataset for the city of Aachen, Germany:
**Linux / macOS**
```bash
# set TARGET to linux-arm64, macos-arm64, ... to fit your setup
# see release list for supported platforms
TARGET="linux-amd64"
wget https://github.com/motis-project/motis/releases/latest/download/motis-${TARGET}.tar.bz2
tar xf motis-${TARGET}.tar.bz2
wget https://github.com/motis-project/test-data/raw/aachen/aachen.osm.pbf
wget https://opendata.avv.de/current_GTFS/AVV_GTFS_Masten_mit_SPNV.zip
./motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis import
./motis server
```
**Windows**
```pwsh
Invoke-WebRequest https://github.com/motis-project/motis/releases/latest/download/motis-windows.zip -OutFile motis-windows.zip
Expand-Archive motis-windows.zip
Invoke-WebRequest https://github.com/motis-project/test-data/archive/refs/heads/aachen.zip -OutFile aachen.zip
Expand-Archive aachen.zip
./motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
./motis import
./motis server
```
# Documentation
## Developer Setup
Build MOTIS from source:
- [for Linux](docs/linux-dev-setup.md)
- [for Windows](docs/windows-dev-setup.md)
- [for macOS](docs/macos-dev-setup.md)
Set up a server using your build:
- [for Linux](docs/dev-setup-server.md)
MOTIS uses [pkg](https://github.com/motis-project/pkg) for dependency management.
See its [README](https://github.com/motis-project/pkg/blob/master/README.md) for how to work with it.
## Configuration
- [Advanced Setups](docs/setup.md)
================================================
FILE: cmake/buildcache.cmake
================================================
option(NO_BUILDCACHE "Disable build caching using buildcache" Off)
# PDB debug information is not supported by buildcache.
# Store debug info in the object files.
if (DEFINED ENV{GITHUB_ACTIONS})
string(REPLACE "/Zi" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/Zi" "" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
else ()
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
endif ()
set(buildcache-bin ${CMAKE_CURRENT_BINARY_DIR}/buildcache/bin/buildcache)
get_property(rule-launch-set GLOBAL PROPERTY RULE_LAUNCH_COMPILE SET)
if (NO_BUILDCACHE)
message(STATUS "NO_BUILDCACHE set, buildcache disabled")
elseif (rule-launch-set)
message(STATUS "Global property RULE_LAUNCH_COMPILE already set - skipping buildcache")
else ()
find_program(buildcache_program buildcache HINTS ${CMAKE_CURRENT_BINARY_DIR}/buildcache/bin)
if (buildcache_program)
message(STATUS "Using buildcache: ${buildcache_program}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${buildcache_program}")
else ()
message(STATUS "buildcache not found - downloading")
if (APPLE)
set(buildcache-archive "buildcache-macos.zip")
elseif (UNIX AND ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(buildcache-archive "buildcache-linux-arm64.tar.gz")
elseif (UNIX)
set(buildcache-archive "buildcache-linux-amd64.tar.gz")
elseif (WIN32)
set(buildcache-archive "buildcache-windows.zip")
else ()
message(FATAL "Error: NO_BUILDCACHE was not set but buildcache was not in path and system OS detection failed")
endif ()
set(buildcache-url "https://gitlab.com/bits-n-bites/buildcache/-/releases/v0.31.7/downloads/${buildcache-archive}")
message(STATUS "Downloading buildcache binary from ${buildcache-url}")
file(DOWNLOAD "${buildcache-url}" ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive})
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar xf ${CMAKE_CURRENT_BINARY_DIR}/${buildcache-archive}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
message(STATUS "using buildcache: ${buildcache-bin}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${buildcache-bin})
endif ()
endif ()
================================================
FILE: cmake/clang-tidy.cmake
================================================
if (CMake_SOURCE_DIR STREQUAL CMake_BINARY_DIR)
message(FATAL_ERROR "CMake_RUN_CLANG_TIDY requires an out-of-source build!")
endif ()
file(RELATIVE_PATH RELATIVE_SOURCE_DIR ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR})
if (ICC_CLANG_TIDY_COMMAND)
set(CLANG_TIDY_COMMAND "${ICC_CLANG_TIDY_COMMAND}")
else ()
find_program(CLANG_TIDY_COMMAND NAMES clang-tidy-21)
endif ()
if (NOT CLANG_TIDY_COMMAND)
message(FATAL_ERROR "CMake_RUN_CLANG_TIDY is ON but clang-tidy is not found!")
endif ()
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_COMMAND}")
file(SHA1 ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy.in clang_tidy_sha1)
set(CLANG_TIDY_DEFINITIONS "CLANG_TIDY_SHA1=${clang_tidy_sha1}")
unset(clang_tidy_sha1)
configure_file(.clang-tidy.in ${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy)
================================================
FILE: cmake/pkg.cmake
================================================
if (NOT DEFINED PROJECT_IS_TOP_LEVEL OR PROJECT_IS_TOP_LEVEL)
find_program(pkg-bin pkg HINTS /opt/pkg)
if (pkg-bin)
message(STATUS "found pkg ${pkg-bin}")
else ()
set(pkg-bin "${CMAKE_BINARY_DIR}/dl/pkg")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(pkg-url "pkg-linux-arm64")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(pkg-url "pkg")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(pkg-url "pkg.exe")
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
set(pkg-url "pkgosx")
else ()
message(STATUS "Not downloading pkg tool. Using pkg from PATH.")
set(pkg-bin "pkg")
endif ()
if (pkg-url)
if (NOT EXISTS ${pkg-bin})
message(STATUS "Downloading pkg binary from https://github.com/motis-project/pkg/releases/latest/download/${pkg-url}")
file(DOWNLOAD "https://github.com/motis-project/pkg/releases/latest/download/${pkg-url}" ${pkg-bin})
if (UNIX)
execute_process(COMMAND chmod +x ${pkg-bin})
endif ()
else ()
message(STATUS "Pkg binary located in project.")
endif ()
endif ()
endif ()
if (DEFINED ENV{GITHUB_ACTIONS})
message(STATUS "${pkg-bin} -l -h -f")
execute_process(
COMMAND ${pkg-bin} -l -h -f
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE pkg-result
)
else ()
message(STATUS "${pkg-bin} -l")
execute_process(
COMMAND ${pkg-bin} -l
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
RESULT_VARIABLE pkg-result
)
endif ()
if (NOT pkg-result EQUAL 0)
message(FATAL_ERROR "pkg failed: ${pkg-result}")
endif ()
if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/deps")
add_subdirectory(deps)
endif ()
set_property(
DIRECTORY
APPEND
PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/.pkg"
)
endif ()
================================================
FILE: docs/STYLE.md
================================================
# MOTIS C++ Style
# Preamble
Beware that these rules only apply to MOTIS C++ and are very opinionated.
C++ has a big diversity of programming styles from "C with classes" to "Modern C++".
A lot of codebases have specific rules that make sense in this specific context
(e.g. embedded programming, gaming, Google search, etc.) and therefore different
guidelines. Over the years we learned that the rules described here are a good fit
for this specific project.
So in general our goals are:
- We want high-level, maintainable C++ code by default, not "high level assembly"
- but: don’t use features just because you can (like template meta programming, etc.)
# Style
- Header names: **`*.h`**, Implementation names: **`*.cc`**
- Don’t use include guards (`#ifndef #define #endif`), use **`#pragma once`**
- Consistently use **`struct`** instead of `class`
- default visibility: public (which is what we need → no getter / setter)
- you don’t need to write a constructor for 1-line initialization
- Always use ++i instead of i++ if it makes no difference for the program logic:
`for (auto i = 0U; i < 10; ++i) { … }`
- Don't `using namespace std;`
- Don’t use `NULL` or `0`, use **nullptr** instead
- Don’t write `const auto&`, write **`auto const&`**
- Don’t write `const char*`, write **`char const*`**
# Case
- Everything **`snake_case`** (as in the C++ Standard Library)
- Template parameters **`PascalCase`** (as in the C++ Standard Library)
- Constants **`kPascalCase`** (as in the Google C++ Styleguide), not `UPPER_CASE` to prevent collisions with macro names
- Postfix **`member_variables_`** with an underscore to improve code readability when reading code without an IDE
```cpp
constexpr auto kMyConstant = 3.141;
template <typename TemplateType, int Size>
struct my_class : public my_parent {
void member_fn(std::string const& fn_param) const override {
auto const local_cvar = abc();
auto local_var = def();
}
int my_field_;
};
```
# Includes
- Include only what you use (but everything you use!)
- Group includes:
- for `.cc` files: first its own `.h` file
- Standard headers with `<...>` syntax
- C headers (use `<cstring>` instead of `<string.h>`, etc.)
- C++ standard library headers (e.g. `<string>`)
- Non-standard headers with `"..."` syntax
- generic to specific = boost libraries, then more and more specific
- last: project includes
- if available: local includes `"./test_util.h"` from the local folder (only done for tests)
- Do not repeat include files from your own header file
- Repeat everything else - even it's transitiveley included already through other headers.
The include might be removed from the header you include which leads broken compilation.
Try to make the compilation as robust as possible.
Example include files for `message.cc`:
```cpp
#include "motis/module/message.h"
#include <cstring>
#include <string>
#include "boost/asio.hpp"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include "motis/core/common/logging.h"
```
# Simplify Code: Predicate Usage
```cpp
// bad
if (is_valid()) {
set_param(false);
} else {
set_param(true);
}
// bad
set_param(is_valid() ? false : true);
// good
set_param(!is_valid());
```
# Always use Braces
```cpp
// bad
for (auto i = 0u; i < 10; ++i)
if (is_valid())
return get_a();
else
count_b();
// good
for (auto i = 0u; i < 10; ++i) {
if (is_valid()) {
return get_a();
} else {
count_b();
}
}
```
# Use Short Variable Names
Only use shortened version of the variable name if it's still obvious what the variable holds.
- Index = `idx`
- Input = `in`
- Output = `out`
- Request = `req`
- Response = `res`
- Initialization = `init`
- ... etc.
If the context in which the variable is used is short, you can make variable names even shorter. For example `for (auto const& e : events) { /* ... */ }` or `auto const& b = get_buffer()`.
Don't use `lhs` and `rhs` - for comparison with `friend bool operator==`. Use `a` and `b`.
# Signatures in Headers
Omit information that's not needed for a forward declaration.
```cpp
void* get_memory(my_memory_manager& memory_manager); // bad
void* get_memory(my_memory_manager&); // good
// const for value parameters is not needed in headers
void calc_mask(bool const, bool const, bool const, bool const); // bad
void calc_mask(bool local_traffic, // slightly less bad
bool long_distance_traffic,
bool local_stations,
bool long_distance_stations);
void calc_mask(mask_options); // good
```
# Low Indentation
Try to keep indentation at a minimum by handling cases one by one and bailing out early.
Example:
Bad:
```cpp
int main(int argc, char** argv) {
if (argc > 1) {
for (int i = 0; i < argc; ++i) {
if (std::strcmp("hello", argv[i]) == 0) {
/* ... 100 lines of code ... */
}
}
}
}
```
Good:
```cpp
int main(int argc, char** argv) {
if (argc <= 1) {
return 0;
}
for (int i = 0; i < argc; ++i) {
if (std::strcmp("hello", argv[i]) != 0) {
continue;
}
/* ... 100 lines of code ... */
}
}
```
# Function Length / File Length
Functions should have one task only. If they grow over ~50 lines of code, please check if they could be split into several functions to improve readability. But: don't split just randomly to not go over some arbitrary lines of code limit.
- Better: split earlier if it makes sense! Files are free! (more than one responsibility)
- Split later i.e. if you want to keep one block of logic without interruption (easier to understand)
# Pointers
Read C++ data types from right to left:
**`int const* const`**
- `const` (read only) pointer (address can't be modified)
- to `const int` (int value at address can't be modified)
**int const&**
- reference
- on a const `int` value (read only)
**auto const&**
- reference
- on a value (type deduced by the compiler)
# Use RAII
Whenever possible use RAII to manage resource like memory (`std::unique_ptr`, `std::shared_ptr`, etc.), files (`std::fstream`), network sockets (Boost Asio), etc.
This means we do not want `new` or `delete` - except for placement new or placement delete in some very specific cases.
# Use `utl` Library
If there is no tool available in the C++ Standard Library please check first if we already have something in our [utl](https://github.com/motis-project/utl) library.
# Use `strong` types
Use `cista::strong` to define types, that cannot be converted implicitly. Using a `strong` type will ensure, that parameters cannot be mismatched, unlike `int` or `std::size_t`. This also makes function parameters clearer.
# `const`
Make everything (variables, loop variables, member functions, etc.) as `const` as possible. This indicates thread-safety (as long as only `const` methods are used) and helps to catch bugs when our mental model doesn't match the reality (the compiler will tell us).
# Initialization
Use [Aggregate Initialization](https://en.cppreference.com/w/cpp/language/aggregate_initialization) if possible. This also applies to member variables. A big advantage is that it doesn't allow implicit type conversions.
# Namespaces
Rename long namespace names instead of importing them completely.
```cpp
using boost::program_options; // bad
namespace po = boost::program_options; // good
```
This way we still know where functions come from when reading code.
It becomes hard to know where a function came from when several large namespaces are completely imported.
Don't alias or import namespaces in header files.
# AAA-Style
Use [Almost Always Auto (AAA)](https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/) style if possible.
- Program against interfaces
- Abstraction
- Less typing
Example: `for (auto const& el : c())`
No client code change if
- c returns another collection type (i.e. set instead of vector)
- the element type changes but still has a compatible interface
# No Raw Loops
It takes time to understand a raw for loop:
```cpp
for (int i = -1; i <= 9; i += 2) {
if (i % 2 == 0) { continue; }
if (i > 5 && i % 2 == 1) { break; }
printf("%d\n", i/3);
}
```
- Raw for loops can
- do crazy things
- be boring (can often be expressed with a standard library algorithm!!)
- Find an element loop → `std::find`, `std::lower_bound`, ...
- Check each element loop → `std::all_of`, `std::none_of`, `std::any_of`
- Conversion loop → `std::transform`, `utl::to_vec`
- Counting: `std::count_if`, `std::accumulate`
- Sorting: `std::sort`, `std::nth_element`, `std::is_sorted`
- Logic: `std::all_of`, `std::any_of`
- Iterating multiple elements at once: `utl::zip`, `utl::pairwise`, `utl::nwise`
- Erasing elements: `utl::erase_if`, `utl::erase_duplicates`
- etc.
Hint: `utl` provides a cleaner interface wrapping `std::` functions for collections so you don't have to call `begin` and `end` all the time!
Benefits:
- Function name tells the reader of your code already what it does!
- Standard library implementation does not contain errors and is performant!
Alternative (if no function in the standard or `utl` helps):
- Use range based for loop if there's no named function: `for (auto const& el : collection) { .. }`
# Comparators
Either use
- Preferred: mark the operator you need `= default;`
- If that doesn't do the job you can check `CISTA_FRIEND_COMPARABLE`
- If you want to be selective and only compare a subset of member variables: `std::tie(a_, b_) == std::tie(a_, b_)`
# Set/Map vs Vector
Our go-to data structure is `std::vector`. (Hash-)maps and (hash-)sets are very expensive.
Never use `std::unordered_map`. We have better alternatives in all projects (e.g. unordered_dense).
## `vecvec` and `vector_map`
- Use `vector_map` for mappings with a `strong` key type and a continuous domain.
- Prefer using `vecvec<T>` instead of `vector<vector<T>>`, as data is stored and accessed more efficient. To store data, that may appear in any order, you may consider `paged_vecvec` instead.
# Tooling
- Always develop with Address Sanitizer (ASan) and Undefined Behaviour Sanitizer (UBSan) enabled if performance allows it (it's usually worth it to use small data sets to be able to develop with sanitizers enabled!): `CXXFLAGS=-fno-omit-frame-pointer -fsanitize=address,undefined`.
- **Notice**: Some checks can cause false positive and should be disabled if necessary (compare `ci.yml`).
Example: `ASAN_OPTIONS=alloc_dealloc_mismatch=0`
- Check your code with `valgrind`.
# Spirit
- No deep inheritance hierarchies (no "enterprise" code)
- Don't write getters / setters for member variables: just make them public
(which is the default for `struct` - remember: always use structs)
- Don't introduce a new variable for every value if it gets used only one time and the variable doesn't tell the reader any important information (-> inline variables).
- No GoF "design patterns" (Factory, Visitor, ...) if there is a simpler solution (there's always a simpler solution)
- Function / struct length:
- it should be possible to understand every function by shortly looking at it
- hints where to split:
- single responsibility
- short enough to be reusable in another context
- Don’t write “extensible” code that cares for functionality you might need at some point in the future. Just solve the problem at hand.
- Build the **smallest and simplest** solution possible that solves your problem
- Use abstractions to avoid thinking about details: helps to keep functions short
- Comment only the tricky / hacky pieces of your code
(there should not be too many comments, otherwise your code is bad)
- Instead of comments use good (but short!) names for variables and functions
- Less code = less maintenance, less places for bugs, easier to understand
- Write robust code: `utl::verify()` assumptions about input data
================================================
FILE: docs/dev-setup-server.md
================================================
# Setting up a server from a development build
1. Build `motis`. Refer to the respective documentation if necessary:
- [for Linux](linux-dev-setup.md)
- [for Windows](windows-dev-setup.md)
- [for macOS](macos-dev-setup.md)
2. Build the UI:
```shell
motis$ cd ui
motis/ui$ pnpm install
motis/ui$ pnpm -r build
```
3. Move the UI build into the build folder of `motis`:
```shell
motis$ mv ui/build build/ui
```
4. Copy the tiles profiles to the `motis` build folder:
```shell
motis$ cp -r deps/tiles/profile build/tiles-profiles
```
5. Download OpenStreetMap and timetable datasets and place them in the build folder of `motis`:
```shell
motis/build$ wget https://github.com/motis-project/test-data/raw/aachen/aachen.osm.pbf
motis/build$ wget https://opendata.avv.de/current_GTFS/AVV_GTFS_Masten_mit_SPNV.zip
```
6. Run `motis config` on the downloaded datasets to create a config file:
```shell
motis/build$ ./motis config aachen.osm.pbf AVV_GTFS_Masten_mit_SPNV.zip
```
7. Run `motis import` and then start the server using `motis server`:
```shell
motis/build$ ./motis import
motis/build$ ./motis server
```
8. Open `localhost:8080` in a browser to see if everything is working.
================================================
FILE: docs/elevation-setup.md
================================================
# Setting up elevation tiles
This page explains how to set up elevation tiles, that are required for elevation profiles.
For performance reasons, all tile data must be stored uncompressed.
This will require roughly `350 GB` for the full SRTMGL1 data set.
After the import, the elevation data requires less disk space than the
`way_osm_nodes_index.bin` and `way_osm_nodes_data.bin` files.
## Data formats
Elevation data must be provided in a tile data format, which has been implemented in and is supported by `osr`.
Currently supported formats:
- **SRTMHGT**: Format used for SRTMGL1 data
- **EHdr**, also known _BIL format_: Format, that has been used for SRTM data in the past
For more details about these formats and a list of additional raster drivers also see https://gdal.org/en/stable/drivers/raster/
## Set up SRTM files
The SRTMGL1 data is provided by the LP DAAC at https://lpdaac.usgs.gov/products/srtmgl1v003/
Notice that the website will be moving by June 17, 2025.
The data should then be available at the new website: https://www.earthdata.nasa.gov/centers/lp-daac
### Data download
All HGT data tiles can be downloaded using _NASA Earthdata Search_: https://search.earthdata.nasa.gov/search?q=C2763266360-LPCLOUD
Downloading tiles requires a free account.
1. Log in and create an account if necessary
1. Enter https://search.earthdata.nasa.gov/search?q=C2763266360-LPCLOUD and select the _NASA Shuttle Radar Topography Mission Global 1 arc second V003_ data set
1. Select all tiles you want to download
- Use can use the _Search by spatial polygon_ or _Search by spatial rectangle_ options in the bottom right to select smaller regions
1. Press _Download All_, once the tiles have been selected and continue by confirming with _Download Data_
1. Files can now be downloaded directly (_Download Files_) or using the _Download Script_.
Notice: Depending on the number of tiles to download, the server might take several minutes, before all links are created. Wait until the process is completed, as there will be missing tiles otherwise.
1. Move and extract all HGT files into a directory. Make sure the file name isn't changed, as it will be used to match coordinates, e.g. `N52E013.SRTMGL1.hgt`
**Important**: HGT tiles not matching the naming convention will not be found
On Unix based systems the following script can be used to extract all ZIP files into a new subdirectory `hgt`:
```sh
#!/bin/sh
[ -d 'hgt' ] || mkdir 'hgt' # Create directory if necessary
for f in *.hgt.zip; do
[ -s "${f}" ] || continue # Ensure file exists and is not empty
unzip `# Always override` -o "${f}" `# Extract into directory` -d 'hgt'
rm -f "${f}" # Delete compressed file
done
```
### Using the SRTM elevation data
Assume the extracted HGT tiles are stored at `<path>/srtm`.
1. Edit `config.yml`:
```yml
street_routing:
elevation_data_dir: <path>/srtm
```
This replaces any existing setting `street_routing: true|false`
1. Run `motis import` to import the elevation data
## Using multiple data tile formats
For global routing using elevation data, multiple data sources might be required.
It's therefore possible to use tiles with different formats simultaneously.
1. Create a new directory `<elevation-dir>`
1. For each data source create a new sub directory
1. Move all elevation data files into the corresponding directories
1. Set `elevation_data_dir: <elevation-dir>` in `config.yml`
Ensure the directory only contains the elevation data, as adding, removing and renaming files will trigger a new import.
As all sub directories will be searched, it's also possible to split a data set into multiple directories if desired.
================================================
FILE: docs/linux-dev-setup.md
================================================
> [!NOTE]
> Due to developer capacity constraints we cannot support newer or older compilers.
> We also cannot support other versions of dependencies.
> In case of doubt you can check the full release build setup used in our CI [here](https://github.com/motis-project/docker-cpp-build/blob/master/Dockerfile).
> To exactly reproduce the CI build, you need to use the according preset from our [CMakePresets.json](../CMakePresets.json).
Requirements:
- A recent C++ compiler: Either [Clang](https://llvm.org/) 21 or GCC 13
- CMake 3.17 (or newer): [cmake.org](https://cmake.org/download/) ([Ubuntu APT Repository](https://apt.kitware.com/))
- Ninja: [ninja-build.org](https://ninja-build.org/)
- Git
> [!CAUTION]
> Unix Makefiles are not working. Please use Ninja to build.
> [!CAUTION]
> Motis' dependency management `pkg` requires that the project is cloned via SSH using an SSH key without a passphrase.
> See:
> - [GitHub Docs: Generate new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
> - [GitHub Docs: Add a new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
> [!NOTE]
> Using a different compiler version is not officially supported but might work nevertheless when passing
> `--compile-no-warning-as-error` to CMake.
## Build with GCC
```sh
git clone git@github.com:motis-project/motis.git
cd motis
mkdir build && cd build
CXX=g++-13 CC=gcc-13 cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja ..
ninja
```
## Build with Clang
```sh
git clone git@github.com:motis-project/motis.git
cd motis
mkdir build && cd build
CXX=clang++-21 CC=clang-21 CXXFLAGS=-stdlib=libc++ cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja ..
ninja
```
================================================
FILE: docs/macos-dev-setup.md
================================================
Requirements:
- macOS 10.15 or newer
- Command Line Tools for Xcode or Xcode: `xcode-select --install` or [manual download](https://developer.apple.com/downloads)
- [CMake](https://cmake.org/download/) 3.17 (or newer)
- [Ninja](https://ninja-build.org/)
- Git
(Git, Ninja, and CMake can be installed via HomeBrew)
> [!CAUTION]
> Unix Makefiles are not working. Please use Ninja to build.
> [!CAUTION]
> Motis' dependency management `pkg` requires that the project is cloned via SSH using an SSH key without a passphrase.
> See:
> - [GitHub Docs: Generate new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
> - [GitHub Docs: Add a new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
To build `motis`:
```sh
git clone git@github.com:motis-project/motis.git
cd motis
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja ..
ninja
```
================================================
FILE: docs/python-client.md
================================================
# Python client for MOTIS
## Install dependencies
```sh
pip install openapi-python-client
```
## Generate Python code from OpenAPI specifications
```sh
openapi-python-client generate --path openapi.yaml --output-path motis_api_client --meta none
```
## Use code (example)
```python
from motis_api_client import Client
from motis_api_client.api.routing import one_to_all
with Client(base_url='http://localhost:8080') as client:
res = one_to_all.sync(one='52.520806, 13.409420', max_travel_time=30, client=client)
res
```
================================================
FILE: docs/scripting.md
================================================
# User Scripts
MOTIS can post-process GTFS static timetable data using [Lua](https://www.lua.org/) scripts. The main purpose is to fix data in case the MOTIS user is not the owner of the data nd the data owner cannot or does not want to fix the data. In some cases, the scripts can be used to homogenize data across different datasets. Currently, post-processing is available for the following entities:
If no script is defined or a processing function is not given for a type, the default behaviour will be applied.
## Configuration
Scripts are an optional key for each dataset in the timetable. An empty string or not setting the property indicates no processing. Any non-empty string will be interpreted as file path to a `.lua` file. The file has to exist.
Example configuration with script property set:
```
timetable:
datasets:
nl:
path: nl_ovapi.gtfs.zip
rt:
- url: https://gtfs.ovapi.nl/nl/trainUpdates.pb
- url: https://gtfs.ovapi.nl/nl/tripUpdates.pb
script: my-script.lua
```
## Types
### Translation List
Some string fields are translated. Their default getter (e.g. `get_name`) now
returns the default string, while the accompanying `get_*_translations`
functions expose the full translation list. Lists can be accessed with
[sol2 container operations](https://sol2.readthedocs.io/en/latest/containers.html).
Each entry in that list is of type
`translation` and provides:
- `get_language`
- `set_language`
- `get_text`
- `set_text`
Example snippet of how to read and write translations:
```lua
function process_route(route)
route:set_short_name({
translation.new('en', 'EN_SHORT_NAME'),
translation.new('de', 'DE_SHORT_NAME'),
translation.new('fr', 'FR_SHORT_NAME')
})
route:get_short_name_translations():add(translation.new('hu', 'HU_SHORT_NAME'))
print(route:get_short_name_translations():get(1):get_text())
print(route:get_short_name_translations():get(1):get_language())
end
```
### Location (stops, platforms, tracks)
processing via `function process_location()`
- `get_id`
- `get_name`
- `get_name_translations`
- `set_name`
- `get_platform_code`
- `get_platform_code_translations`
- `set_platform_code`
- `get_description`
- `get_description_translations`
- `set_description`
- `get_pos`
- `set_pos`
- `get_timezone`
- `set_timezone`
- `get_transfer_time`
- `set_transfer_time`
### Agency (as defined in GTFS `agencies.txt`)
processing via `function process_agency(agency)`
- `get_id`
- `get_name`
- `get_name_translations`
- `set_name`
- `get_url`
- `get_url_translations`
- `set_url`
- `get_timezone`
- `set_timezone`
### Routes (as defined in GTFS `routes.txt`)
processing via `function process_route(location)`
- `get_id`
- `get_short_name`
- `get_short_name_translations`
- `set_short_name`
- `get_long_name`
- `get_long_name_translations`
- `set_long_name`
- `get_route_type`
- `set_route_type`
- `get_color`
- `set_color`
- `get_clasz` (deprecated, use `get_route_type`)
- `set_clasz` (deprecated, use `set_route_type`)
- `get_text_color`
- `set_text_color`
- `get_agency`
The following constants can be used for `set_route_type`:
- `GTFS_TRAM`
- `GTFS_SUBWAY`
- `GTFS_RAIL`
- `GTFS_BUS`
- `GTFS_FERRY`
- `GTFS_CABLE_TRAM`
- `GTFS_AERIAL_LIFT`
- `GTFS_FUNICULAR`
- `GTFS_TROLLEYBUS`
- `GTFS_MONORAIL`
- `RAILWAY_SERVICE`
- `HIGH_SPEED_RAIL_SERVICE`
- `LONG_DISTANCE_TRAINS_SERVICE`
- `INTER_REGIONAL_RAIL_SERVICE`
- `CAR_TRANSPORT_RAIL_SERVICE`
- `SLEEPER_RAIL_SERVICE`
- `REGIONAL_RAIL_SERVICE`
- `TOURIST_RAILWAY_SERVICE`
- `RAIL_SHUTTLE_WITHIN_COMPLEX_SERVICE`
- `SUBURBAN_RAILWAY_SERVICE`
- `REPLACEMENT_RAIL_SERVICE`
- `SPECIAL_RAIL_SERVICE`
- `LORRY_TRANSPORT_RAIL_SERVICE`
- `ALL_RAILS_SERVICE`
- `CROSS_COUNTRY_RAIL_SERVICE`
- `VEHICLE_TRANSPORT_RAIL_SERVICE`
- `RACK_AND_PINION_RAILWAY_SERVICE`
- `ADDITIONAL_RAIL_SERVICE`
- `COACH_SERVICE`
- `INTERNATIONAL_COACH_SERVICE`
- `NATIONAL_COACH_SERVICE`
- `SHUTTLE_COACH_SERVICE`
- `REGIONAL_COACH_SERVICE`
- `SPECIAL_COACH_SERVICE`
- `SIGHTSEEING_COACH_SERVICE`
- `TOURIST_COACH_SERVICE`
- `COMMUTER_COACH_SERVICE`
- `ALL_COACHS_SERVICE`
- `URBAN_RAILWAY_SERVICE`
- `METRO_SERVICE`
- `UNDERGROUND_SERVICE`
- `URBAN_RAILWAY_2_SERVICE`
- `ALL_URBAN_RAILWAYS_SERVICE`
- `MONORAIL_SERVICE`
- `BUS_SERVICE`
- `REGIONAL_BUS_SERVICE`
- `EXPRESS_BUS_SERVICE`
- `STOPPING_BUS_SERVICE`
- `LOCAL_BUS_SERVICE`
- `NIGHT_BUS_SERVICE`
- `POST_BUS_SERVICE`
- `SPECIAL_NEEDS_BUS_SERVICE`
- `MOBILITY_BUS_SERVICE`
- `MOBILITY_BUS_FOR_REGISTERED_DISABLED_SERVICE`
- `SIGHTSEEING_BUS_SERVICE`
- `SHUTTLE_BUS_SERVICE`
- `SCHOOL_BUS_SERVICE`
- `SCHOOL_AND_PUBLIC_BUS_SERVICE`
- `RAIL_REPLACEMENT_BUS_SERVICE`
- `DEMAND_AND_RESPONSE_BUS_SERVICE`
- `ALL_BUSS_SERVICE`
- `TROLLEYBUS_SERVICE`
- `TRAM_SERVICE`
- `CITY_TRAM_SERVICE`
- `LOCAL_TRAM_SERVICE`
- `REGIONAL_TRAM_SERVICE`
- `SIGHTSEEING_TRAM_SERVICE`
- `SHUTTLE_TRAM_SERVICE`
- `ALL_TRAMS_SERVICE`
- `WATER_TRANSPORT_SERVICE`
- `AIR_SERVICE`
- `FERRY_SERVICE`
- `AERIAL_LIFT_SERVICE`
- `TELECABIN_SERVICE`
- `CABLE_CAR_SERVICE`
- `ELEVATOR_SERVICE`
- `CHAIR_LIFT_SERVICE`
- `DRAG_LIFT_SERVICE`
- `SMALL_TELECABIN_SERVICE`
- `ALL_TELECABINS_SERVICE`
- `FUNICULAR_SERVICE`
- `TAXI_SERVICE`
- `COMMUNAL_TAXI_SERVICE`
- `WATER_TAXI_SERVICE`
- `RAIL_TAXI_SERVICE`
- `BIKE_TAXI_SERVICE`
- `LICENSED_TAXI_SERVICE`
- `PRIVATE_HIRE_VEHICLE_SERVICE`
- `ALL_TAXIS_SERVICE`
- `MISCELLANEOUS_SERVICE`
- `HORSE_DRAWN_CARRIAGE_SERVICE`
The color is currently set as unsigned 32bit integer. In future versions, we might change this to a hex string like `#FF0000`.
### Trips (as defined in GTFS `trips.txt`)
processing via `function process_trip(trip)`
- `get_id`
- `get_headsign`
- `get_headsign_translations`
- `set_headsign`
- `get_short_name`
- `get_short_name_translations`
- `set_short_name`
- `get_display_name`
- `get_display_name_translations`
- `set_display_name`
- `get_route`
### Geo Location
This type is used for stop coordinates in `process_location()` for `location:get_pos()` and `location:set_pos`.
- `get_lat`
- `get_lng`
- `set_lat`
- `set_lng`
## Filtering
Each processing function can return a boolean which will be interpreted as
- `true`: keep this entity
- `false`: don't keep this entity
If nothing is returned from a process function (e.g. no return statement at all), no filtering will be applied (i.e. the default is `keep=true`).
Filtering has the following effects:
- In case an agency is removed, all its routes and trips will be removed as well
- In case a route is removed, all its trips will be removed as well
- If locations are filtered, the locations will not be removed from trips and transfers referencing those stops
## Out of Scope
Scripting is currently aiming at cosmetic changes to existing entities to improve the user experience, not the creation of new entities. The creation of new entities currently has to be done outside of MOTIS in a separate preprocessing step. Currently, it is also not supported to mess with primary/foreign keys (IDs such as `trip_id`, `stop_id`, `route_ìd`).
## Example
This example illustrates the usage of scripting capabilities in MOTIS. Beware that it does not make sense at all and its sole purpose is to demonstrate syntax and usage of available functionality.
```lua
function process_location(stop)
local name = stop:get_name()
if string.sub(name, -7) == ' Berlin' then
stop:set_name(string.sub(name, 1, -8))
end
local pos = stop:get_pos()
pos:set_lat(stop:get_pos():get_lat() + 2.0)
pos:set_lng(stop:get_pos():get_lng() - 2.0)
stop:set_pos(pos)
stop:set_description(stop:get_description() .. ' ' .. stop:get_id() .. ' YEAH')
stop:set_timezone('Europe/Berlin')
stop:set_transfer_time(stop:get_transfer_time() + 98)
stop:set_platform_code(stop:get_platform_code() .. 'A')
return true
end
function process_route(route)
if route:get_id() == 'R_RE4' then
return false
end
if route:get_route_type() == 3 then
route:set_clasz(7)
route:set_route_type(101)
elseif route:get_route_type() == 1 then
route:set_clasz(8)
route:set_route_type(400)
end
if route:get_agency():get_name() == 'Deutsche Bahn' and route:get_route_type() == 101 then
route:set_short_name('RE ' .. route:get_short_name())
end
return true
end
function process_agency(agency)
if agency:get_id() == 'TT' then
return false
end
if agency:get_name() == 'Deutsche Bahn' and agency:get_id() == 'DB' then
agency:set_url(agency:get_timezone())
agency:set_timezone('Europe/Berlin')
agency:set_name('SNCF')
return true
end
return false
end
function process_trip(trip)
if trip:get_route():get_route_type() == 101 then
-- Prepend category and eliminate leading zeros (e.g. '00123' -> 'ICE 123')
trip:set_short_name('ICE ' .. string.format("%d", tonumber(trip:get_short_name())))
trip:set_display_name(trip:get_short_name())
end
return trip:get_id() == 'T_RE1'
end
```
## Future Work
There are more attributes that could be made readable/writable such as `bikes_allowed`, `cars_allowed`. Also trip stop times and their attributes such as stop sequence numbers could be made available to scripting.
Another topic not addressed yet is API versioning for the lua functions. At the moment, this feature is considered experimental which means that breaking changes might occur without prior notice.
================================================
FILE: docs/setup.md
================================================
# Advanced Configuration
This is an example of how to use multiple GTFS-static datasets with multiple real-time feeds, as well as GBFS feeds. You can also see how to set additional headers like `Authorization` to enable the usage of API keys.
```yaml
server:
port: 8080
web_folder: ui
osm: netherlands-latest.osm.pbf
timetable:
datasets:
nl:
path: nl_ovapi.gtfs.zip
rt:
- url: https://gtfs.ovapi.nl/nl/trainUpdates.pb
- url: https://gtfs.ovapi.nl/nl/tripUpdates.pb
ch:
path: ch_opentransportdataswiss.gtfs.zip
rt:
- url: https://api.opentransportdata.swiss/gtfsrt2020
headers:
Authorization: MY_API_KEY
protocol: gtfsrt
gbfs:
feeds:
montreal:
url: https://gbfs.velobixi.com/gbfs/gbfs.json
# Example feed for header usage
example-feed:
url: https://example.org/gbfs
headers:
authorization: MY_OTHER_API_KEY
other-header: other-value
tiles:
profile: tiles-profiles/full.lua
street_routing:
elevation_data_dir: srtm/
geocoding: true
osr_footpath: true
```
This expands to the following configuration:
```yaml
server:
host: 0.0.0.0 # host (default = 0.0.0.0)
port: 8080 # port (default = 8080)
web_folder: ui # folder with static files to serve
n_threads: 24 # default (if not set): number of hardware threads
data_attribution_link: https://creativecommons.org/licenses/by/4.0/ # link to data sources or license exposed in HTTP headers and UI
osm: netherlands-latest.osm.pbf # required by tiles, street routing, geocoding and reverse-geocoding
tiles: # tiles won't be available if this key is missing
profile: tiles-profiles/full.lua # currently `background.lua` (less details) and `full.lua` (more details) are available
db_size: 1099511627776 # default size for the tiles database (influences VIRT memory usage)
flush_threshold: 10000000 # usually don't change this (less = reduced memory usage during tiles import)
timetable: # if not set, no timetable will be loaded
first_day: TODAY # first day of timetable to load, format: "YYYY-MM-DD" (special value "TODAY")
num_days: 365 # number of days to load, default is 365 days
railviz: true # enable viewing vehicles in real-time on the map, requires some extra lookup data structures
with_shapes: true # extract and serve shapes (if disabled, direct lines are used)
adjust_footpaths: true # if footpaths are too fast, they are adjusted if set to true
merge_dupes_intra_src: false # duplicates within the same datasets will be merged
merge_dupes_inter_src: false # duplicates withing different datasets will be merged
link_stop_distance: 100 # stops will be linked by footpaths if they're less than X meters (default=100m) apart
update_interval: 60 # real-time updates are polled every `update_interval` seconds
http_timeout: 30 # maximum time in seconds the real-time feed download may take
incremental_rt_update: false # false = real-time updates are applied to a clean slate, true = no data will be dropped
max_footpath_length: 15 # maximum footpath length when transitively connecting stops or for routing footpaths if `osr_footpath` is set to true
max_matching_distance: 25.0 # maximum distance from geolocation to next OSM ways that will be found
preprocess_max_matching_distance: 250.0 # max. distance for preprocessing matches from nigiri locations (stops) to OSM ways to speed up querying (set to 0 (default) to disable)
datasets: # map of tag -> dataset
ch: # the tag will be used as prefix for stop IDs and trip IDs with `_` as divider, so `_` cannot be part of the dataset tag
path: ch_opentransportdataswiss.gtfs.zip
default_bikes_allowed: false
rt:
- url: https://api.opentransportdata.swiss/gtfsrt2020
headers:
Authorization: MY_API_KEY
protocol: gtfsrt # specify the real time protocol (default: gtfsrt)
nl:
path: nl_ovapi.gtfs.zip
default_bikes_allowed: false
rt:
- url: https://gtfs.ovapi.nl/nl/trainUpdates.pb
- url: https://gtfs.ovapi.nl/nl/tripUpdates.pb
extend_calendar: true # expand the weekly service pattern beyond the end of `feed_info.txt::feed_end_date` if `feed_end_date` matches `calendar.txt::end_date`
gbfs:
feeds:
montreal:
url: https://gbfs.velobixi.com/gbfs/gbfs.json
example-feed:
url: https://example.org/gbfs
headers:
authorization: MY_OTHER_API_KEY
other-header: other-value
street_routing: # enable street routing (default = false; Using boolean values true/false is supported for backward compatibility)
elevation_data_dir: srtm/ # folder which contains elevation data, e.g. SRTMGL1 data tiles in HGT format
limits:
stoptimes_max_results: 256 # maximum number of stoptimes results that can be requested
plan_max_results: 256 # maximum number of plan results that can be requested via numItineraries parameter
plan_max_search_window_minutes: 5760 # maximum (minutes) for searchWindow parameter (seconds), highest possible value: 21600 (15 days)
onetomany_max_many: 128 # maximum accepted number of many locations for one-to-many requests
onetoall_max_results: 65535 # maximum number of one-to-all results that can be requested
onetoall_max_travel_minutes: 90 # maximum travel duration for one-to-all query that can be requested
routing_max_timeout_seconds: 90 # maximum duration a routing query may take
gtfsrt_expose_max_trip_updates: 100 # how many trip updates are allowed to be exposed via the gtfsrt endpoint
street_routing_max_prepost_transit_seconds: 3600 # limit for maxPre/PostTransitTime API params, see below
street_routing_max_direct_seconds: 21600 # limit for maxDirectTime API param, high values can lead to long-running, RAM-hungry queries
logging:
log_level: debug # log-level (default = debug; Supported log-levels: error, info, debug)
osr_footpath: true # enable routing footpaths instead of using transfers from timetable datasets
geocoding: true # enable geocoding for place/stop name autocompletion
reverse_geocoding: false # enable reverse geocoding for mapping a geo coordinate to nearby places/addresses
```
# Scenario with Elevators
This is an example configuration for Germany which enables the real-time update of elevators from Deutsche Bahn's FaSta (Facility Status) JSON API. You need to register and obtain an API key.
```yml
server:
web_folder: ui
tiles:
profile: tiles-profiles/full.lua
geocoding: true
street_routing: true # Alternative notion the enable street routing
osr_footpath: true
elevators:
# init: fasta.json # Can be used for debugging, remove `url` key in this case
url: https://apis.deutschebahn.com/db-api-marketplace/apis/fasta/v2/facilities
headers:
DB-Client-ID: b5d28136ffedb73474cc7c97536554df!
DB-Api-Key: ef27b9ad8149cddb6b5e8ebb559ce245!
osm: germany-latest.osm.pbf
timetable:
extend_missing_footpaths: true
use_osm_stop_coordinates: true
datasets:
de:
path: 20250331_fahrplaene_gesamtdeutschland_gtfs.zip
rt:
- url: https://stc.traines.eu/mirror/german-delfi-gtfs-rt/latest.gtfs-rt.pbf
```
# GBFS Configuration
This examples shows how to configure multiple GBFS feeds.
A GBFS feed might describe a single system or area, `callabike` in this example, or a set of feeds, that are combined to a manifest, like `mobidata-bw` here. For readability, optional headers are not included.
```yaml
gbfs:
feeds:
# GBFS feed:
callabike:
url: https://api.mobidata-bw.de/sharing/gbfs/callabike/gbfs
# GBFS manifest / Lamassu feed:
mobidata-bw:
url: https://api.mobidata-bw.de/sharing/gbfs/v3/manifest.json
update_interval: 300
http_timeout: 10
```
## Provider Groups + Colors
GBFS providers (feeds) can be grouped into "provider groups". For example, a provider may operate in multiple locations and provide a feed per location.
To groups these different feeds into a single provider group, specify the same group name for each feed in the configuration.
Feeds that don't have an explicit group setting in the configuration, their group name is derived from the system name. Group names
may not contain commas. The API supports both provider groups and individual providers.
Provider colors are loaded from the feed (`brand_assets.color`) if available, but can also be set in the configuration
to override the values contained in the feed or to set colors for feeds that don't include color information.
Colors can be set for groups (applies to all providers belonging to the group) or individual providers
(overrides group color for that feed).
```yaml
gbfs:
feeds:
de-CallaBike:
url: https://api.mobidata-bw.de/sharing/gbfs/v2/callabike/gbfs
color: "#db0016"
de-VRNnextbike:
url: https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_vn/gbfs.json
group: nextbike # uses the group color defined below
de-NextbikeFrankfurt:
url: https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_ff/gbfs.json
group: nextbike
de-KVV.nextbike:
url: https://gbfs.nextbike.net/maps/gbfs/v2/nextbike_fg/gbfs.json
group: nextbike
color: "#c30937" # override color for this particular feed
groups:
nextbike:
# name: nextbike # Optional: Override the name (otherwise the group id, here "nextbike", is used)
color: "#0046d6"
```
For aggregated feeds (manifest.json or Lamassu), groups and colors can either be assigned to all providers listed in the aggregated feed
or individually by using the system_id:
```yaml
gbfs:
feeds:
aggregated-single-group:
url: https://example.com/one-provider-group/manifest.json
group: Example
color: "#db0016" # or assign a color to the group
aggregated-multiple-groups:
url: https://example.com/multiple-provider-groups/manifest.json
group:
source-nextbike-westbike: nextbike # "source-nextbike-westbike" is the system_id
source-voi-muenster: VOI
source-voi-duisburg-oberhausen: VOI
# colors can be specified for individual feeds using the same syntax,
# but in this example they are defined for the groups below
#color:
# "source-nextbike-westbike": "#0046d6"
# "source-voi-muenster": "#f26961"
groups:
nextbike:
color: "#0046d6"
VOI:
color: "#f26961"
```
## HTTP Headers + OAuth
If a feed requires specific HTTP headers, they can be defined like this:
```yaml
gbfs:
feeds:
example:
url: https://example.com/gbfs
headers:
authorization: MY_OTHER_API_KEY
other-header: other-value
```
OAuth with client credentials and bearer token types is also supported:
```yaml
gbfs:
feeds:
example:
url: https://example.com/gbfs
oauth:
token_url: https://example.com/openid-connect/token
client_id: gbfs
client_secret: example
```
## Default Restrictions
A GBFS feed can define geofencing zones and rules, that apply to areas within these zones.
For restrictions on areas not included in these geofencing zones, a feed may contain global rules.
If these are missing, it's possible to define `default_restrictions`, that apply to either a single feed or a manifest.
The following example shows possible configurations:
```yaml
gbfs:
feeds:
# GBFS feed:
#callabike:
# url: https://api.mobidata-bw.de/sharing/gbfs/callabike/gbfs
# GBFS manifest / Lamassu feed:
mobidata-bw:
url: https://api.mobidata-bw.de/sharing/gbfs/v3/manifest.json
default_restrictions:
mobidata-bw:callabike: # "callabike" feed contained in the "mobidata-bw" manifest
# these restrictions apply outside of the defined geofencing zones if the feed doesn't contain global rules
ride_start_allowed: true
ride_end_allowed: true
ride_through_allowed: true
#station_parking: false
#return_constraint: roundtrip_station
#mobidata-bw: # default restrictions for all feeds contained in the "mobidata-bw" manifest
#callabike: # default restrictions for standalone GBFS feed "callabike" (when not using the mobidata-bw example)
update_interval: 300
http_timeout: 10
```
# Real time protocols
MOTIS supports multiple protocols for real time feeds. This section shows a list of the protocols, including some pitfalls:
| Protocol | `protocol` | Note |
| ---- | ---- | ---- |
| GTFS-RT | `gtfsrt` | This is the default, if `protocol` is ommitted. |
| SIRI Lite (XML) | `siri` | Currently limited to SIRI Lite ET, FM and SX. Still work in progress. Use with care. |
| SIRI Lite (JSON) | `siri_json` | Same as `siri`, but expects JSON server responses. See below for expected JSON structure. |
| VDV AUS / VDV454 | `auser` | Requires [`auser`](https://github.com/motis-project/auser) for subscription handling |
## Supported SIRI Lite services
SIRI feeds are divided into multiple feeds called services (check for instance
[this](https://en.wikipedia.org/wiki/Service_Interface_for_Real_Time_Information#CEN_SIRI_Functional_Services)
for a list of all services). Right now MOTIS only supports parsing the
"Estimated Timetable" (ET), the "Facility Monitoring" (FM) and the "Situation
Exchange" (SX) SIRI services. You can see examples of such feeds
[here](https://github.com/SIRI-CEN/SIRI/tree/v2.2/examples).
If you are using the `siri_json` protocol, note that MOTIS expects the
following JSON structure:
- **Valid** SIRI Lite JSON response:
```json
{
"ResponseTimestamp": "2004-12-17T09:30:46-05:00",
"ProducerRef": "KUBRICK",
"Status": true,
"MoreData": false,
"EstimatedTimetableDelivery": [
...
]
}
```
- **Invalid** SIRI Lite JSON response:
```json
{
"Siri": {
"ServiceDelivery": {
"ResponseTimestamp": "2004-12-17T09:30:46-05:00",
"ProducerRef": "KUBRICK",
"Status": true,
"MoreData": false,
"EstimatedTimetableDelivery": [
...
]
}
}
}
```
If, as above, the two top keys `"Siri"` and `"ServiceDelivery"` are included in
the JSON response, MOTIS will fail to parse the SIRI Lite feed, throwing
`[VERIFY FAIL] unable to parse time ""` errors.
# Shapes
To enable shapes support (polylines for trips), `timetable.with_shapes` must
be set to `true`. This will load shapes that are present in the datasets
(e.g. GTFS shapes.txt).
It is also possible to compute shapes based on OpenStreetMap data. This
requires:
- `timetable.with_shapes` set to `true`
- `osm` data
- `street_routing` set to `true`
- `timetable.route_shapes` config:
```yaml
timetable:
# with_shapes must be set to true to enable shapes support, otherwise no shapes will be loaded or computed
with_shapes: true
route_shapes: # all these options are optional
# available modes:
# - all: route shapes for all routes, replace existing shapes from the timetable
# - missing: only compute shapes for those routes that don't have existing shapes from the timetable
mode: all
# routing for specific clasz types can be disabled (default = all enabled)
# currently long distance street routing is slow, so in this example
# we disable routing shapes for COACH
# (if there are shapes for the disabled clasz types in the dataset, these will still be used)
clasz:
COACH: false
# disable shape computation for routes with more than X stops (default = no limit)
# (if there are shapes for routes with more than X stops in the dataset, these will still be used)
max_stops: 100
# limit the number of threads used for shape computation (default = number of hardware threads)
n_threads: 6
# enable debug API endpoint (default = false)
debug_api: true
# if you want to use cached shapes even if the osm file has changed since the last import, set this to true (default = false)
cache_reuse_old_osm_data: false
# for debugging purposes, debug information can be written to files
# which can be loaded into the debug ui (see osr project)
debug:
path: /path/to/debug/directory
all: false # debug all routes
all_with_beelines: false # or only those that include beelines
slow: 10000 # or only those that take >10.000ms to compute
# or specific trips/routes:
trips:
- "trip_id_1"
route_ids:
- "route_id_1"
route_indices: # these are internal indices (e.g. from debug UI)
- 123
```
## Cache
Routed shapes can be cached to speed up later imports when a timetable dataset
is updated. If enabled, this will generate an additional cache file. This cache
file and the routed shapes data are then reused during import.
Note that old routes are never removed from the routed shapes data files, i.e.,
these files grow with every import (unless there are no new routes, in which
case the size will stay the same).
It is therefore recommended to monitor the size of the "routed_shapes\*" files
in the data directory.
They can safely be deleted before an import, which will cause all shapes that
are needed for the current datasets to be routed again.
The cache only applies to routed shapes, not shapes contained in the timetables.
================================================
FILE: docs/windows-dev-setup.md
================================================
In the following, we list requirements and a download link. There may be other sources (like package managers) to install these.
- CMake 3.17 (or newer): [cmake.org](https://cmake.org/download/)
- Git: [git-scm.com](https://git-scm.com/download/win)
- Visual Studio 2022 or at least "Build Tools for Visual Studio 2022": [visualstudio.microsoft.com](https://visualstudio.microsoft.com/de/downloads/)
- Ninja: [ninja-build.org](https://ninja-build.org/)
> [!CAUTION]
> Motis' dependency management `pkg` requires that the project is cloned via SSH using an SSH key without a passphrase.
> See:
> - [GitHub Docs: Generate new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
> - [GitHub Docs: Add a new SSH key](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
## Build MOTIS using the command line
Start menu -> `Visual Studio 2022` -> `x64 Native Tools Command Prompt for VS 2022`, then enter:
```bat
git clone "git@github.com:motis-project/motis.git"
cd motis
mkdir build
cd build
cmake -GNinja -DCMAKE_BUILD_TYPE=Release ..
ninja
```
## Build MOTIS using CLion
- Make sure that the architecture is set to `amd64` (Settings -> `Build, Execution, Deployment` -> `Toolchains`).
- You might have to allow users to create symbolic links. Open `Local Security Policy` and go to `User Rights Assignment`.
- You might have to enable `Developer Mode` under `Advanced System Settings`.
================================================
FILE: exe/batch.cc
================================================
#include <fstream>
#include <iostream>
#include "conf/configuration.h"
#include "utl/init_from.h"
#include "utl/parallel_for.h"
#include "utl/parser/cstr.h"
#include "motis/config.h"
#include "motis/data.h"
#include "motis/motis_instance.h"
#include "./flags.h"
namespace fs = std::filesystem;
namespace po = boost::program_options;
namespace json = boost::json;
struct thousands_sep : std::numpunct<char> {
char_type do_thousands_sep() const override { return ','; }
string_type do_grouping() const override { return "\3"; }
};
struct stats {
struct entry {
bool operator<(entry const& o) const { return value_ < o.value_; }
std::uint64_t msg_id_, value_;
};
stats() = default;
stats(std::string name, std::uint64_t count_so_far)
: name_{std::move(name)}, values_{count_so_far} {}
void add(uint64_t msg_id, std::uint64_t value) {
values_.emplace_back(entry{msg_id, value});
sum_ += value;
}
std::string name_;
std::vector<entry> values_;
std::uint64_t sum_{};
};
struct category {
category() = default;
explicit category(std::string name) : name_(std::move(name)) {}
std::string name_;
std::map<std::string, stats> stats_;
};
stats::entry quantile(std::vector<stats::entry> const& sorted_values,
double q) {
if (q == 1.0) {
return sorted_values.back();
} else {
return sorted_values[std::min(
static_cast<std::size_t>(std::round(q * (sorted_values.size() - 1))),
sorted_values.size() - 1)];
}
}
void print_category(category& cat,
std::uint64_t count,
bool const compact,
int const top) {
std::cout << "\n"
<< cat.name_ << "\n"
<< std::string(cat.name_.size(), '=') << "\n"
<< std::endl;
for (auto& s : cat.stats_) {
auto& stat = s.second;
if (stat.values_.empty()) {
continue;
}
utl::sort(stat.values_);
auto const avg = (stat.sum_ / static_cast<double>(count));
if (compact) {
std::cout << std::left << std::setw(30) << stat.name_
<< " avg: " << std::setw(27) << std::setprecision(4)
<< std::fixed << avg << " Q(99): " << std::setw(25)
<< quantile(stat.values_, 0.99).value_
<< " Q(90): " << std::setw(22)
<< quantile(stat.values_, 0.9).value_
<< " Q(80): " << std::setw(22)
<< quantile(stat.values_, 0.8).value_
<< " Q(50): " << std::setw(22)
<< quantile(stat.values_, 0.5).value_;
auto const from = static_cast<std::uint64_t>(
std::max(static_cast<std::int64_t>(0L),
static_cast<std::int64_t>(stat.values_.size()) -
static_cast<std::int64_t>(top)));
for (auto i = from; i != stat.values_.size(); ++i) {
auto const i_rev = stat.values_.size() - (i - from) - 1;
std::cout << "(v=" << stat.values_[i_rev].value_
<< ", i=" << stat.values_[i_rev].msg_id_ << ")";
if (i != stat.values_.size() - 1) {
std::cout << ", ";
}
}
std::cout << std::endl;
} else {
std::cout
<< stat.name_ << "\n average: " << std::right << std::setw(15)
<< std::setprecision(2) << std::fixed << avg
<< "\n max: " << std::right << std::setw(12)
<< std::max_element(begin(stat.values_), end(stat.values_))->value_
<< "\n 99 quantile: " << std::right << std::setw(12)
<< quantile(stat.values_, 0.99).value_
<< "\n 90 quantile: " << std::right << std::setw(12)
<< quantile(stat.values_, 0.9).value_
<< "\n 80 quantile: " << std::right << std::setw(12)
<< quantile(stat.values_, 0.8).value_
<< "\n 50 quantile: " << std::right << std::setw(12)
<< quantile(stat.values_, 0.5).value_
<< "\n min: " << std::right << std::setw(12)
<< std::min_element(begin(stat.values_), end(stat.values_))->value_
<< "\n"
<< std::endl;
}
}
}
namespace motis {
int batch(int ac, char** av) {
auto data_path = fs::path{"data"};
auto queries_path = fs::path{"queries.txt"};
auto responses_path = fs::path{"responses.txt"};
auto mt = true;
auto desc = po::options_description{"Options"};
desc.add_options() //
("help", "Prints this help message") //
("multithreading,mt", po::value(&mt)->default_value(mt)) //
("queries,q", po::value(&queries_path)->default_value(queries_path),
"queries file") //
("responses,r", po::value(&responses_path)->default_value(responses_path),
"response file");
add_data_path_opt(desc, data_path);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}
auto queries = std::vector<std::string_view>{};
auto f = cista::mmap{queries_path.generic_string().c_str(),
cista::mmap::protection::READ};
utl::for_each_line(utl::cstr{f.view()},
[&](utl::cstr s) { queries.push_back(s.view()); });
auto const c = config::read(data_path / "config.yml");
utl::verify(c.timetable_.has_value(), "timetable required");
auto d = data{data_path, c};
utl::verify(d.tt_, "timetable required");
auto response_time = stats{"response_time", 0U};
struct state {};
auto out = std::ofstream{responses_path};
auto m = motis_instance{net::default_exec{}, d, c, ""};
auto const compute_response = [&](state&, std::size_t const id) {
UTL_START_TIMING(request);
auto response = std::string{};
try {
m.qr_(
{boost::beast::http::verb::get,
boost::beast::string_view{queries.at(id)}, 11},
[&](net::web_server::http_res_t const& res) {
std::visit(
[&](auto&& r) {
using ResponseType = std::decay_t<decltype(r)>;
if constexpr (std::is_same_v<ResponseType,
net::web_server::string_res_t>) {
response = r.body();
if (response.empty()) {
std::cout << "empty response for " << id << ": "
<< queries.at(id) << " [status=" << r.result()
<< "]\n";
}
} else {
throw utl::fail("not a valid response type: {}",
cista::type_str<ResponseType>());
}
},
res);
},
false);
} catch (std::exception const& e) {
std::cerr << "ERROR IN QUERY " << id << ": " << e.what() << "\n";
}
return std::pair{UTL_GET_TIMING_MS(request), std::move(response)};
};
auto const pt = utl::activate_progress_tracker("batch");
pt->in_high(queries.size());
if (mt) {
utl::parallel_ordered_collect_threadlocal<state>(
queries.size(), compute_response,
[&](std::size_t const id,
std::pair<std::uint64_t, std::string> const& s) {
response_time.add(id, s.first);
out << s.second << "\n";
},
pt->update_fn());
} else {
auto s = state{};
for (auto i = 0U; i != queries.size(); ++i) {
compute_response(s, i);
pt->increment();
}
}
auto cat = category{};
cat.name_ = "response_time";
cat.stats_.emplace("response_time", std::move(response_time));
std::cout.imbue(std::locale(std::locale::classic(), new thousands_sep));
print_category(cat, queries.size(), false, 10U);
return 0U;
}
} // namespace motis
================================================
FILE: exe/compare.cc
================================================
#include <fstream>
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
#include "conf/configuration.h"
#include "boost/json/parse.hpp"
#include "boost/json/serialize.hpp"
#include "boost/json/value_from.hpp"
#include "boost/json/value_to.hpp"
#include "fmt/std.h"
#include "utl/enumerate.h"
#include "utl/file_utils.h"
#include "utl/get_or_create.h"
#include "utl/helpers/algorithm.h"
#include "utl/overloaded.h"
#include "utl/sorted_diff.h"
#include "utl/to_vec.h"
#include "utl/verify.h"
#include "motis-api/motis-api.h"
#include "motis/types.h"
#include "./flags.h"
namespace fs = std::filesystem;
namespace po = boost::program_options;
namespace json = boost::json;
namespace motis {
int compare(int ac, char** av) {
auto subset_check = false;
auto queries_path = fs::path{"queries.txt"};
auto responses_paths = std::vector<std::string>{};
auto fails_path = fs::path{"fail"};
auto desc = po::options_description{"Options"};
desc.add_options() //
("help", "Prints this help message") //
("queries,q", po::value(&queries_path)->default_value(queries_path),
"queries file") //
("subset_check", po::value(&subset_check)->default_value(subset_check),
"only check subset ([1...N] <= [0])") //
("responses,r",
po::value(&responses_paths)
->multitoken()
->default_value(responses_paths),
"response files");
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}
auto const write_fails = fs::is_directory(fails_path);
if (!write_fails) {
fmt::println("{} is not a directory, not writing fails", fails_path);
}
struct info {
unsigned id_;
std::optional<api::plan_params> params_{};
std::vector<std::optional<api::plan_response>> responses_{};
};
auto const params = [](api::Itinerary const& x) {
return std::tie(x.startTime_, x.endTime_, x.transfers_);
};
auto const equal = [&](std::vector<api::Itinerary> const& a,
std::vector<api::Itinerary> const& b) {
if (subset_check) {
return utl::all_of(a, [&](api::Itinerary const& x) {
return utl::any_of(
b, [&](api::Itinerary const& y) { return params(x) == params(y); });
});
} else {
return std::ranges::equal(a | std::views::transform(params),
b | std::views::transform(params));
}
};
auto const print_params = [](api::Itinerary const& x) {
std::cout << x.startTime_ << ", " << x.endTime_
<< ", transfers=" << std::setw(2) << std::left << x.transfers_;
};
auto const print_none = []() { std::cout << "\t\t\t\t\t\t"; };
auto n_equal = 0U;
auto const print_differences = [&](info const& x) {
auto const is_incomplete =
utl::any_of(x.responses_, [](auto&& x) { return !x.has_value(); });
auto const ref =
x.responses_[0].value_or(api::plan_response{}).itineraries_;
auto mismatch = false;
for (auto i = 1U; i < x.responses_.size(); ++i) {
mismatch |= !x.responses_[i].has_value();
auto const uut =
x.responses_[i].value_or(api::plan_response{}).itineraries_;
if (equal(ref, uut)) {
++n_equal;
continue;
}
mismatch = true;
std::cout << "QUERY=" << x.id_ << " ["
<< x.params_->to_url("/api/v1/plan") << "]";
if (is_incomplete) {
std::cout << " [INCOMPLETE!!]";
}
std::cout << "\n";
utl::sorted_diff(
ref, uut,
[&](api::Itinerary const& a, api::Itinerary const& b) {
return params(a) < params(b);
},
[&](api::Itinerary const&, api::Itinerary const&) {
return false; // always call for equal
},
utl::overloaded{
[&](utl::op op, api::Itinerary const& j) {
if (op == utl::op::kAdd) {
print_none();
std::cout << "\t\t\t\t";
print_params(j);
std::cout << "\n";
} else {
print_params(j);
std::cout << "\t\t\t\t";
print_none();
std::cout << "\n";
}
},
[&](api::Itinerary const& a, api::Itinerary const& b) {
print_params(a);
std::cout << "\t\t\t";
print_params(b);
std::cout << "\n";
}});
std::cout << "\n\n";
}
if (mismatch && write_fails) {
std::ofstream{fails_path / fmt::format("{}_q.txt", x.id_)}
<< x.params_->to_url("/api/v1/plan") << "\n";
for (auto i = 0U; i < x.responses_.size(); ++i) {
if (!x.responses_[i].has_value()) {
continue;
}
std::ofstream{fails_path / fmt::format("{}_{}.json", x.id_, i)}
<< json::serialize(json::value_from(x.responses_[i].value()))
<< "\n";
}
}
};
auto query_file = utl::open_file(queries_path);
auto responses_files =
utl::to_vec(responses_paths, [&](auto&& p) { return utl::open_file(p); });
auto n_consumed = 0U;
auto query_id = 0U;
while (true) {
auto nfo =
info{.id_ = ++query_id,
.responses_ = std::vector<std::optional<api::plan_response>>{
responses_files.size()}};
if (auto const q = utl::read_line(query_file); q.has_value()) {
nfo.params_ = api::plan_params{boost::urls::url{*q}.params()};
} else {
break;
}
for (auto const [i, res_file] : utl::enumerate(responses_files)) {
if (auto const r = utl::read_line(res_file); r.has_value()) {
try {
auto val = boost::json::parse(*r);
if (val.is_object() &&
val.as_object().contains("requestParameters")) {
auto res = json::value_to<api::plan_response>(val);
utl::sort(res.itineraries_, [&](auto&& a, auto&& b) {
return params(a) < params(b);
});
nfo.responses_[i] = std::move(res);
}
} catch (...) {
}
} else {
break;
}
}
print_differences(nfo);
++n_consumed;
}
std::cout << "consumed: " << n_consumed << "\n";
std::cout << " equal: " << n_equal << "\n";
return n_consumed == n_equal ? 0 : 1;
}
} // namespace motis
================================================
FILE: exe/extract.cc
================================================
#include <filesystem>
#include <iterator>
#include "boost/json.hpp"
#include "boost/program_options.hpp"
#include "fmt/ranges.h"
#include "fmt/std.h"
#include "utl/parser/buf_reader.h"
#include "utl/parser/csv_range.h"
#include "utl/parser/split.h"
#include "utl/pipes.h"
#include "utl/progress_tracker.h"
#include "utl/verify.h"
#include "nigiri/loader/dir.h"
#include "nigiri/common/interval.h"
#include "motis-api/motis-api.h"
#include "motis/tag_lookup.h"
#include "motis/types.h"
#include "flags.h"
namespace po = boost::program_options;
namespace fs = std::filesystem;
namespace n = nigiri;
namespace motis {
void copy_stop_times(hash_set<std::string> const& trip_ids,
hash_set<std::string> const& filter_stop_ids,
std::string_view file_content,
hash_set<std::string>& stop_ids,
std::ostream& out) {
struct csv_stop_time {
utl::csv_col<utl::cstr, UTL_NAME("trip_id")> trip_id_;
utl::csv_col<utl::cstr, UTL_NAME("stop_id")> stop_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_stop_time>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_stop_time>(header_permutation, line);
if (trip_ids.contains(row.trip_id_->view()) &&
(filter_stop_ids.empty() ||
filter_stop_ids.contains(row.stop_id_->view()))) {
stop_ids.insert(row.stop_id_->view());
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" stop_times.txt: lines written: {}", n_lines);
}
void copy_stops(hash_set<std::string>& stop_ids,
std::string_view file_content,
std::ostream& out,
bool const filter_stops) {
struct csv_stop {
utl::csv_col<utl::cstr, UTL_NAME("stop_id")> stop_id_;
utl::csv_col<utl::cstr, UTL_NAME("parent_station")> parent_station_;
};
{ // First pass: collect parents.
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_stop>(line);
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_stop>(header_permutation, line);
if (!row.parent_station_->empty() &&
stop_ids.contains(row.stop_id_->view())) {
stop_ids.emplace(row.parent_station_->view());
}
}
}
{ // Second pass: copy contents.
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_stop>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
if (filter_stops) {
auto const row = utl::read_row<csv_stop>(header_permutation, line);
if (stop_ids.contains(row.stop_id_->view())) {
out << line.view() << "\n";
++n_lines;
}
} else {
out << line.view() << "\n";
}
}
fmt::println(" stops.txt: lines written: {}", n_lines);
}
}
void copy_trips(hash_set<std::string> const& trip_ids,
std::string_view file_content,
hash_set<std::string>& route_ids,
hash_set<std::string>& service_ids,
std::ostream& out) {
struct csv_trip {
utl::csv_col<utl::cstr, UTL_NAME("trip_id")> trip_id_;
utl::csv_col<utl::cstr, UTL_NAME("route_id")> route_id_;
utl::csv_col<utl::cstr, UTL_NAME("service_id")> service_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_trip>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_trip>(header_permutation, line);
if (trip_ids.contains(row.trip_id_->view())) {
route_ids.insert(row.route_id_->view());
service_ids.insert(row.service_id_->view());
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" trips.txt: lines written: {}", n_lines);
}
void copy_calendar(hash_set<std::string> const& service_ids,
std::string_view file_content,
std::ostream& out) {
struct csv_service {
utl::csv_col<utl::cstr, UTL_NAME("service_id")> service_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_service>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_service>(header_permutation, line);
if (service_ids.contains(row.service_id_->view())) {
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" calendar.txt / calendar_dates.txt: lines written: {}",
n_lines);
}
void copy_routes(hash_set<std::string> const& route_ids,
std::string_view file_content,
hash_set<std::string>& agency_ids,
std::ostream& out) {
struct csv_service {
utl::csv_col<utl::cstr, UTL_NAME("route_id")> route_id_;
utl::csv_col<utl::cstr, UTL_NAME("agency_id")> agency_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_service>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_service>(header_permutation, line);
if (route_ids.contains(row.route_id_->view())) {
agency_ids.insert(row.agency_id_->view());
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" routes.txt: lines written: {}", n_lines);
}
void copy_agencies(hash_set<std::string> const& agency_ids,
std::string_view file_content,
std::ostream& out) {
struct csv_stop {
utl::csv_col<utl::cstr, UTL_NAME("agency_id")> agency_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_stop>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_stop>(header_permutation, line);
if (agency_ids.contains(row.agency_id_->view())) {
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" agencies.txt: lines written: {}", n_lines);
}
void copy_transfers(hash_set<std::string> const& stop_ids,
std::string_view file_content,
std::ostream& out) {
struct csv_stop {
utl::csv_col<utl::cstr, UTL_NAME("from_stop_id")> from_stop_id_;
utl::csv_col<utl::cstr, UTL_NAME("to_stop_id")> to_stop_id_;
};
auto n_lines = 0U;
auto reader = utl::make_buf_reader(file_content);
auto line = reader.read_line();
auto const header_permutation = utl::read_header<csv_stop>(line);
out << line.view() << "\n";
while ((line = reader.read_line())) {
auto const row = utl::read_row<csv_stop>(header_permutation, line);
if (stop_ids.contains(row.from_stop_id_->view()) &&
stop_ids.contains(row.to_stop_id_->view())) {
out << line.view() << "\n";
++n_lines;
}
}
fmt::println(" transfers.txt: lines written: {}", n_lines);
}
int extract(int ac, char** av) {
auto in = std::vector<fs::path>{"response.json"};
auto out = fs::path{"gtfs"};
auto reduce = false;
auto filter_stops = true;
auto desc = po::options_description{"Options"};
desc.add_options() //
("help", "Prints this help message") //
("reduce", po::value(&reduce)->default_value(reduce),
"Only extract first and last stop of legs for stop times") //
("filter_stops", po::value(&filter_stops)->default_value(filter_stops),
"Filter stops") //
("in,i", po::value(&in)->multitoken(),
"PlanResponse JSON input files") //
("out,o", po::value(&out), "output directory");
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}
auto important_stops = hash_set<std::string>{};
auto const add_important_stop = [&](api::Place const& p) {
if (!reduce || p.vertexType_ != api::VertexTypeEnum::TRANSIT) {
return;
}
auto const tag_end = p.stopId_.value().find('_');
utl::verify(tag_end != std::string::npos, "no tag found for stop id {}",
p.stopId_.value());
auto const [_, added] =
important_stops.insert(p.stopId_.value().substr(tag_end + 1U));
if (added) {
fmt::println("important stop {}", p.stopId_.value().substr(tag_end + 1U));
}
};
auto todos = hash_map<std::string, hash_set<std::string>>{};
auto source = std::string{};
auto from_line = std::string{};
auto to_line = std::string{};
auto path = std::string{};
for (auto const& x : in) {
auto const f =
cista::mmap{x.generic_string().c_str(), cista::mmap::protection::READ};
auto const res =
boost::json::value_to<api::plan_response>(boost::json::parse(f.view()));
fmt::println("found {} itineraries", res.itineraries_.size());
for (auto const& i : res.itineraries_) {
for (auto const& l : i.legs_) {
add_important_stop(l.from_);
add_important_stop(l.to_);
if (!l.source_.has_value() || !l.tripId_.has_value()) {
continue;
}
source.resize(l.source_->size());
std::reverse_copy(begin(*l.source_), end(*l.source_), begin(source));
auto const [to, from, p] =
utl::split<':', utl::cstr, utl::cstr, utl::cstr>(source);
from_line.resize(from.length());
std::reverse_copy(begin(from), end(from), begin(from_line));
to_line.resize(to.length());
std::reverse_copy(begin(to), end(to), begin(to_line));
path.resize(p.length());
std::reverse_copy(begin(p), end(p), begin(path));
auto const trip_id = split_trip_id(*l.tripId_);
auto const [_, added] = todos[path].emplace(trip_id.trip_id_);
if (added) {
fmt::println("added {}:{}:{}, trip_id={}", path, from_line, to_line,
trip_id.trip_id_);
}
}
}
}
auto stop_ids = hash_set<std::string>{};
auto route_ids = hash_set<std::string>{};
auto service_ids = hash_set<std::string>{};
auto agency_ids = hash_set<std::string>{};
for (auto const& [stop_times_str, trip_ids] : todos) {
auto const stop_times_path = fs::path{stop_times_str};
stop_ids.clear();
route_ids.clear();
service_ids.clear();
agency_ids.clear();
utl::verify(stop_times_path.filename() == "stop_times.txt",
"expected filename stop_times.txt, got \"{}\"",
stop_times_path);
auto const dataset_dir = stop_times_path.parent_path();
utl::verify(stop_times_path.has_parent_path() && fs::exists(dataset_dir),
"expected path \"{}\" to have existent parent path",
stop_times_path);
auto const dir = n::loader::make_dir(dataset_dir);
utl::verify(dir->exists("stop_times.txt"),
"no stop_times.txt file found in {}", dataset_dir);
auto ec = std::error_code{};
fs::create_directories(out / dataset_dir.filename(), ec);
{
fmt::println("writing {}/stop_times.txt, searching for trips={}",
out / dataset_dir.filename(), trip_ids);
auto of = std::ofstream{out / dataset_dir.filename() / "stop_times.txt"};
fmt::println("important stops: {}", important_stops);
copy_stop_times(trip_ids, important_stops,
dir->get_file("stop_times.txt").data(), stop_ids, of);
}
{
fmt::println("writing {}/stops.txt, searching for stops={}",
out / dataset_dir.filename(), stop_ids);
auto of = std::ofstream{out / dataset_dir.filename() / "stops.txt"};
copy_stops(stop_ids, dir->get_file("stops.txt").data(), of, filter_stops);
}
{
fmt::println("writing {}/trips.txt", out / dataset_dir.filename());
auto of = std::ofstream{out / dataset_dir.filename() / "trips.txt"};
copy_trips(trip_ids, dir->get_file("trips.txt").data(), route_ids,
service_ids, of);
}
{
fmt::println("writing {}/routes.txt, searching for routes={}",
out / dataset_dir.filename(), route_ids);
auto of = std::ofstream{out / dataset_dir.filename() / "routes.txt"};
copy_routes(route_ids, dir->get_file("routes.txt").data(), agency_ids,
of);
}
if (dir->exists("calendar.txt")) {
fmt::println("writing {}/calendar.txt, searching for service_ids={}",
out / dataset_dir.filename(), service_ids);
auto of = std::ofstream{out / dataset_dir.filename() / "calendar.txt"};
copy_calendar(service_ids, dir->get_file("calendar.txt").data(), of);
}
if (dir->exists("calendar_dates.txt")) {
fmt::println(
"writing {}/calendar_dates.txt, searching for service_ids={}",
out / dataset_dir.filename(), service_ids);
auto of =
std::ofstream{out / dataset_dir.filename() / "calendar_dates.txt"};
copy_calendar(service_ids, dir->get_file("calendar_dates.txt").data(),
of);
}
if (dir->exists("agency.txt")) {
fmt::println("writing {}/agency.txt, searching for agencies={}",
out / dataset_dir.filename(), agency_ids);
auto of = std::ofstream{out / dataset_dir.filename() / "agency.txt"};
copy_agencies(agency_ids, dir->get_file("agency.txt").data(), of);
}
if (dir->exists("transfers.txt")) {
fmt::println("writing {}/transfers.txt", out / dataset_dir.filename());
auto of = std::ofstream{out / dataset_dir.filename() / "transfers.txt"};
copy_transfers(stop_ids, dir->get_file("transfers.txt").data(), of);
}
if (dir->exists("feed_info.txt")) {
std::ofstream{out / dataset_dir.filename() / "feed_info.txt"}
<< dir->get_file("feed_info.txt").data();
}
}
return 0;
}
} // namespace motis
================================================
FILE: exe/flags.h
================================================
#pragma once
#include <filesystem>
#include <string>
#include <vector>
#include "boost/program_options.hpp"
namespace motis {
inline void add_help_opt(boost::program_options::options_description& desc) {
desc.add_options()("help,h", "print this help message");
}
inline void add_data_path_opt(boost::program_options::options_description& desc,
std::filesystem::path& p) {
desc.add_options() //
("data,d", boost::program_options::value(&p)->default_value(p),
"The data path contains all preprocessed data as well as a "
"`config.yml`. "
"It will be created by the `motis import` command. After the import has "
"finished, `motis server` only needs the `data` folder and can run "
"without the input files (such as OpenStreetMap file, GTFS datasets, "
"tiles-profiles, etc.)");
}
inline void add_config_path_opt(
boost::program_options::options_description& desc,
std::filesystem::path& p) {
desc.add_options() //
("config,c", boost::program_options::value(&p)->default_value(p),
"Configuration YAML file. Legacy INI files are still supported but this "
"support will be dropped in the future.");
}
inline void add_trip_id_opt(boost::program_options::options_description& desc) {
desc.add_options()(
"trip-id,t",
boost::program_options::value<std::vector<std::string>>()->composing(),
"Add trip-id to analyze.\n"
"If the trip-id is encoded, it will be decoded automatically.\n"
"This option can be used multiple times.\n"
"\n"
"Will search the shape corresponding to each trip-id. "
"If a shape is found, the index of the shape point, that is "
"matched with each stop, will be printed.\n"
"Notice that the first and last stop of a trip will always be "
"matched with the first and last shape point respectively.\n"
"If a shape contains less points than stops in the trip, this "
"segmentation is not possible.");
}
inline void add_log_level_opt(boost::program_options::options_description& desc,
std::string& log_lvl) {
desc.add_options()("log-level", boost::program_options::value(&log_lvl),
"Set the log level.\n"
"Supported log levels: error, info, debug");
}
inline boost::program_options::variables_map parse_opt(
int ac, char** av, boost::program_options::options_description& desc) {
namespace po = boost::program_options;
auto vm = po::variables_map{};
po::store(po::command_line_parser(ac, av).options(desc).run(), vm);
po::notify(vm);
return vm;
}
} // namespace motis
================================================
FILE: exe/generate.cc
================================================
#include <fstream>
#include <iostream>
#include <mutex>
#include "conf/configuration.h"
#include "boost/url/url.hpp"
#include "nigiri/common/interval.h"
#include "nigiri/routing/raptor/debug.h"
#include "nigiri/routing/search.h"
#include "nigiri/timetable.h"
#include "utl/progress_tracker.h"
#include "motis-api/motis-api.h"
#include "motis/config.h"
#include "motis/data.h"
#include "motis/endpoints/routing.h"
#include "motis/odm/bounds.h"
#include "motis/point_rtree.h"
#include "motis/tag_lookup.h"
#include "./flags.h"
namespace n = nigiri;
namespace fs = std::filesystem;
namespace po = boost::program_options;
namespace motis {
constexpr auto const kMinRank = 16UL;
static std::atomic_uint32_t seed{0U};
std::uint32_t rand_in(std::uint32_t const from, std::uint32_t const to) {
auto a = ++seed;
a = (a ^ 61U) ^ (a >> 16U);
a = a + (a << 3U);
a = a ^ (a >> 4U);
a = a * 0x27d4eb2d;
a = a ^ (a >> 15U);
return from + (a % (to - from));
}
template <typename It>
It rand_in(It const begin, It const end) {
return std::next(
begin,
rand_in(0U, static_cast<std::uint32_t>(std::distance(begin, end))));
}
template <typename Collection>
Collection::value_type rand_in(Collection const& c) {
using std::begin;
using std::end;
utl::verify(!c.empty(), "empty collection");
return *rand_in(begin(c), end(c));
}
n::location_idx_t random_stop(n::timetable const& tt,
std::vector<n::location_idx_t> const& stops) {
auto s = n::location_idx_t::invalid();
do {
s = rand_in(stops);
} while (tt.location_routes_[s].empty());
return s;
}
int generate(int ac, char** av) {
auto data_path = fs::path{"data"};
auto n = 100U;
auto first_day = std::optional<date::sys_days>{};
auto last_day = std::optional<date::sys_days>{};
auto time_of_day = std::optional<std::uint32_t>{};
auto modes = std::optional<std::vector<api::ModeEnum>>{};
auto max_dist = 800.0; // m
auto use_walk = false;
auto use_bike = false;
auto use_car = false;
auto use_odm = false;
auto lb_rank = true;
auto p = api::plan_params{};
auto const parse_date = [](std::string_view const s) {
std::stringstream in;
in.exceptions(std::ios::badbit | std::ios::failbit);
in << s;
auto d = date::sys_days{};
in >> date::parse("%Y-%m-%d", d);
return d;
};
auto const parse_first_day = [&](std::string_view const s) {
first_day = parse_date(s);
};
auto const parse_last_day = [&](std::string_view const s) {
last_day = parse_date(s);
};
auto const parse_modes = [&](std::string_view const s) {
modes = std::vector<api::ModeEnum>{};
if (s.contains("WALK")) {
modes->emplace_back(api::ModeEnum::WALK);
use_walk = true;
}
if (s.contains("BIKE")) {
modes->emplace_back(api::ModeEnum::BIKE);
use_bike = true;
}
if (s.contains("CAR")) {
modes->emplace_back(api::ModeEnum::CAR);
use_car = true;
}
if (s.contains("ODM")) {
modes->emplace_back(api::ModeEnum::ODM);
use_odm = true;
}
if (s.contains("RIDE_SHARING")) {
modes->emplace_back(api::ModeEnum::RIDE_SHARING);
use_odm = true;
}
};
auto const parse_time_of_day = [&](std::uint32_t const h) {
time_of_day = h % 24U;
};
auto desc = po::options_description{"Options"};
desc.add_options() //
("help", "Prints this help message") //
("n,n", po::value(&n)->default_value(n), "number of queries") //
("first_day", po::value<std::string>()->notifier(parse_first_day),
"first day of query generation, format: YYYY-MM-DD") //
("last_day", po::value<std::string>()->notifier(parse_last_day),
"last day of query generation, format: YYYY-MM-DD") //
("time_of_day", po::value<std::uint32_t>()->notifier(parse_time_of_day),
"fixes the time of day of all queries to the given number of hours "
"after midnight, i.e., 0 - 23") //
("modes,m", po::value<std::string>()->notifier(parse_modes),
"comma-separated list of modes for first/last mile and "
"direct (requires "
"street routing), supported: WALK, BIKE, CAR, ODM") //
("all,a",
"requires OSM nodes to be accessible by all specified modes, otherwise "
"OSM nodes accessible by at least one mode are eligible, only used for "
"intermodal queries") //
("max_dist", po::value(&max_dist)->default_value(max_dist),
"maximum distance from a public transit stop in meters, only used for "
"intermodal queries") //
("max_travel_time",
po::value<std::int64_t>()->notifier(
[&](auto const v) { p.maxTravelTime_ = v; }),
"sets maximum travel time of the queries") //
("max_matching_distance",
po::value(&p.maxMatchingDistance_)
->default_value(p.maxMatchingDistance_),
"sets the maximum matching distance of the queries") //
("fastest_direct_factor",
po::value(&p.fastestDirectFactor_)
->default_value(p.fastestDirectFactor_),
"sets fastest direct factor of the queries") //
("lb_rank", po::value(&lb_rank)->default_value(lb_rank),
"emit queries uniformly distributed over the lower bounds (lb) ranks, "
"lb rank n: 2^n-th stop when sorting all stops by their lb value from "
"the start (min. rank: 4, max. rank: derived from number of eligible "
"stops)");
add_data_path_opt(desc, data_path);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}
auto const c = config::read(data_path / "config.yml");
utl::verify(c.timetable_.has_value(), "timetable required");
utl::verify(!modes || c.use_street_routing(),
"intermodal requires street routing");
auto d = data{data_path, c};
utl::verify(d.tt_, "timetable required");
first_day = first_day
? d.tt_->date_range_.clamp(*first_day)
: std::chrono::time_point_cast<date::sys_days::duration>(
d.tt_->external_interval().from_);
last_day = last_day ? d.tt_->date_range_.clamp(
std::max(*first_day + date::days{1U}, *last_day))
: d.tt_->date_range_.clamp(*first_day + date::days{14U});
if (*first_day == *last_day) {
fmt::println(
"can not generate queries: date range [{}, {}] has zero length after "
"clamping",
*first_day, *last_day);
return 1;
}
fmt::println("date range: [{}, {}], tt={}", *first_day, *last_day,
d.tt_->external_interval());
auto const use_odm_bounds = modes && use_odm && d.odm_bounds_ != nullptr;
auto node_rtree = point_rtree<osr::node_idx_t>{};
if (modes) {
if (modes->empty()) {
fmt::println(
"can not generate queries: provided modes option without valid "
"mode");
return 1;
}
std::cout << "modes:";
for (auto const m : *modes) {
std::cout << " " << m;
}
std::cout << "\n";
p.directModes_ = *modes;
p.preTransitModes_ = *modes;
p.postTransitModes_ = *modes;
auto const mode_match = [&](auto const node) {
auto const can_walk = [&](auto const x) {
return utl::any_of(d.w_->r_->node_ways_[x], [&](auto const w) {
return d.w_->r_->way_properties_[w].is_foot_accessible();
});
};
auto const can_bike = [&](auto const x) {
return utl::any_of(d.w_->r_->node_ways_[x], [&](auto const w) {
return d.w_->r_->way_properties_[w].is_bike_accessible();
});
};
auto const can_car = [&](auto const x) {
return utl::any_of(d.w_->r_->node_ways_[x], [&](auto const w) {
return d.w_->r_->way_properties_[w].is_car_accessible();
});
};
return vm.count("all") ? ((!use_walk || can_walk(node)) &&
(!use_bike || can_bike(node)) &&
(!(use_car || use_odm) || can_car(node)))
: ((use_walk && can_walk(node)) ||
(use_bike && can_bike(node)) ||
((use_car || use_odm) && can_car(node)));
};
auto const in_bounds = [&](auto const& pos) {
return !use_odm_bounds || d.odm_bounds_->contains(pos);
};
for (auto i = osr::node_idx_t{0U}; i < d.w_->n_nodes(); ++i) {
if (mode_match(i) && in_bounds(d.w_->get_node_pos(i))) {
node_rtree.add(d.w_->get_node_pos(i), i);
}
}
} else {
fmt::println("station-to-station");
}
auto stops = std::vector<n::location_idx_t>{};
for (auto i = 0U; i != d.tt_->n_locations(); ++i) {
auto const l = n::location_idx_t{i};
if (use_odm_bounds &&
!d.odm_bounds_->contains(d.tt_->locations_.coordinates_[l])) {
continue;
}
stops.emplace_back(l);
}
auto ss = std::optional<n::routing::search_state>{};
auto rs = std::optional<n::routing::raptor_state>{};
if (lb_rank) {
ss = n::routing::search_state{};
rs = n::routing::raptor_state{};
fmt::println("from and to pairings by lower bounds rank");
} else {
fmt::println("from and to uniformly at random");
}
auto const get_place =
[&](n::location_idx_t const l) -> std::optional<std::string> {
if (!modes) {
return d.tags_->id(*d.tt_, l);
}
auto const nodes =
node_rtree.in_radius(d.tt_->locations_.coordinates_[l], max_dist);
if (nodes.empty()) {
return std::nullopt;
}
auto const pos = d.w_->get_node_pos(rand_in(nodes));
return fmt::format("{},{}", pos.lat(), pos.lng());
};
auto const random_from_to = [&](auto const r) {
auto from_place = std::optional<std::string>{};
auto to_place = std::optional<std::string>{};
for (auto x = 0U; x != 1000U; ++x) {
auto const from_stop = random_stop(*d.tt_, stops);
from_place = get_place(from_stop);
if (!from_place) {
continue;
}
if (lb_rank) {
auto const s = n::routing::search<
n::direction::kBackward,
n::routing::raptor<n::direction::kBackward, false, 0,
n::routing::search_mode::kOneToAll>>{
*d.tt_, nullptr, *ss, *rs,
nigiri::routing::query{
.start_time_ = d.tt_->date_range_.from_,
.destination_ = {{from_stop, n::duration_t{0U}, 0}}}};
utl::sort(stops, [&](auto const& a, auto const& b) {
return ss->travel_time_lower_bound_[to_idx(a)] <
ss->travel_time_lower_bound_[to_idx(b)];
});
to_place = get_place(stops[r]);
} else {
to_place = get_place(random_stop(*d.tt_, stops));
}
if (to_place) {
break;
}
}
p.fromPlace_ = *from_place;
p.toPlace_ = *to_place;
};
auto const random_time = [&]() {
using namespace std::chrono_literals;
p.time_ =
*first_day +
rand_in(0U,
static_cast<std::uint32_t>((*last_day - *first_day).count())) *
date::days{1U} +
(time_of_day ? *time_of_day : rand_in(6U, 18U)) * 1h;
};
{
auto out = std::ofstream{"queries.txt"};
auto const progress_tracker =
utl::activate_progress_tracker(fmt::format("generating {} queries", n));
progress_tracker->in_high(n);
auto const silencer = utl::global_progress_bars{false};
for (auto [i, r] = std::tuple{0U, kMinRank}; i != n;
++i, r = r * 2U < stops.size() ? r * 2U : kMinRank) {
random_from_to(r);
random_time();
out << p.to_url("/api/v1/plan") << "\n";
progress_tracker->increment();
}
}
return 0;
}
} // namespace motis
================================================
FILE: exe/main.cc
================================================
#include <cctype>
#include <filesystem>
#include <iostream>
#include <string>
#include <string_view>
#include "boost/program_options.hpp"
#include "boost/url/decode_view.hpp"
#include "google/protobuf/stubs/common.h"
#include "utl/progress_tracker.h"
#include "utl/to_vec.h"
#include "nigiri/rt/util.h"
#include "motis/analyze_shapes.h"
#include "motis/config.h"
#include "motis/data.h"
#include "motis/import.h"
#include "motis/logging.h"
#include "motis/server.h"
#include "./flags.h"
#if defined(USE_MIMALLOC) && defined(_WIN32)
#include "mimalloc-new-delete.h"
#endif
#if !defined(MOTIS_VERSION)
#define MOTIS_VERSION "unknown"
#endif
namespace po = boost::program_options;
using namespace std::string_view_literals;
namespace fs = std::filesystem;
namespace motis {
int generate(int, char**);
int batch(int, char**);
int compare(int, char**);
int extract(int, char**);
int params(int, char**);
} // namespace motis
using namespace motis;
int main(int ac, char** av) {
auto const motis_version = std::string_view{MOTIS_VERSION};
if (ac > 1 && av[1] == "--help"sv) {
fmt::println(
"MOTIS {}\n\n"
"Usage:\n"
" --help print this help message\n"
" --version print program version\n\n"
"Commands:\n"
" generate generate random queries and write them to a file\n"
" batch run queries from a file\n"
" params update query parameters for a batch file\n"
" compare compare results from different batch runs\n"
" config generate a config file from a list of input files\n"
" import prepare input data, creates the data directory\n"
" server starts a web server serving the API\n"
" extract trips from a Itinerary to GTFS timetable\n"
" pb2json convert GTFS-RT protobuf to JSON\n"
" json2pb convert JSON to GTFS-RT protobuf\n"
" shapes print shape segmentation for trips\n",
motis_version);
return 0;
} else if (ac <= 1 || (ac >= 2 && av[1] == "--version"sv)) {
fmt::println("{}", motis_version);
return 0;
}
// Skip program argument, quit if no command.
--ac;
++av;
auto return_value = 0;
// Execute command.
auto const cmd = std::string_view{av[0]};
switch (cista::hash(cmd)) {
case cista::hash("extract"): return_value = extract(ac, av); break;
case cista::hash("generate"): return_value = generate(ac, av); break;
case cista::hash("params"): return_value = params(ac, av); break;
case cista::hash("batch"): return_value = batch(ac, av); break;
case cista::hash("compare"): return_value = compare(ac, av); break;
case cista::hash("config"): {
auto paths = std::vector<std::string>{};
for (auto i = 1; i != ac; ++i) {
paths.push_back(std::string{av[i]});
}
if (paths.empty() || paths.front() == "--help") {
fmt::println(
"usage: motis config [PATHS...]\n\n"
"Generates a config.yml file in the current working "
"directory.\n\n"
"File type will be determined based on extension:\n"
" - \".osm.pbf\" will be used as OpenStreetMap file.\n"
" This enables street routing, geocoding and map tiles\n"
" - the rest will be interpreted as static timetables.\n"
" This enables transit routing."
"\n\n"
"Example: motis config germany-latest.osm.pbf "
"germany.gtfs.zip\n");
return_value = paths.empty() ? 1 : 0;
break;
}
std::ofstream{"config.yml"} << config::read_simple(paths) << "\n";
return_value = 0;
break;
}
case cista::hash("server"):
try {
auto data_path = fs::path{"data"};
auto log_lvl = std::string{};
auto desc = po::options_description{"Server Options"};
add_data_path_opt(desc, data_path);
add_log_level_opt(desc, log_lvl);
add_help_opt(desc);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return_value = 0;
break;
}
auto const c = config::read(data_path / "config.yml");
if ((return_value = set_log_level(c))) {
break;
}
if (vm.count("log-level") &&
(return_value = set_log_level(std::move(log_lvl)))) {
break;
}
return_value = server(data{data_path, c}, c, motis_version);
} catch (std::exception const& e) {
std::cerr << "unable to start server: " << e.what() << "\n";
return_value = 1;
}
break;
case cista::hash("import"): {
auto c = config{};
try {
auto data_path = fs::path{"data"};
auto config_path = fs::path{"config.yml"};
auto filter_tasks = std::vector<std::string>{};
auto desc = po::options_description{"Import Options"};
add_data_path_opt(desc, data_path);
add_config_path_opt(desc, config_path);
add_help_opt(desc);
desc.add_options() //
("filter",
boost::program_options::value<std::vector<std::string>>(
&filter_tasks)
->composing(),
"Filter tasks and only run selected import tasks. Tasks have to "
"be active based on the configuration. Available tasks are:\n"
" - osr (street_routing)\n"
" - adr (geocoding/reverse_geocoding)\n"
" - tt (timetable)\n"
" - tbd (timetable.tb)\n"
" - adr_extend (timetable+geocoding)\n"
" - osr_footpath\n"
" - matches (timetable+street_routing)\n"
" - route_shapes (timetable.route_shapes)\n"
" - tiles\n");
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return_value = 0;
break;
}
c = config::read(config_path);
if ((return_value = set_log_level(c))) {
break;
}
auto const bars = utl::global_progress_bars{false};
import(
c, std::move(data_path),
filter_tasks.empty() ? std::nullopt : std::optional{filter_tasks});
return_value = 0;
} catch (std::exception const& e) {
fmt::println("unable to import: {}", e.what());
fmt::println("config:\n{}", fmt::streamed(c));
return_value = 1;
}
break;
}
case cista::hash("pb2json"): {
try {
auto p = fs::path{};
auto desc = po::options_description{"GTFS-RT Protobuf to JSON"};
desc.add_options() //
("path,p", boost::program_options::value(&p)->default_value(p),
"Path to Protobuf GTFS-RT file");
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return_value = 0;
break;
}
auto const protobuf = cista::mmap{p.generic_string().c_str(),
cista::mmap::protection::READ};
fmt::println("{}", nigiri::rt::protobuf_to_json(protobuf.view()));
return_value = 0;
} catch (std::exception const& e) {
fmt::println("error: ", e.what());
return_value = 1;
}
break;
}
case cista::hash("json2pb"): {
try {
auto p = fs::path{};
auto desc = po::options_description{"GTFS-RT JSON to Protobuf"};
desc.add_options() //
("path,p", boost::program_options::value(&p)->default_value(p),
"Path to GTFS-RT JSON file");
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return_value = 0;
break;
}
auto const protobuf = cista::mmap{p.generic_string().c_str(),
cista::mmap::protection::READ};
fmt::println("{}", nigiri::rt::json_to_protobuf(protobuf.view()));
return_value = 0;
} catch (std::exception const& e) {
fmt::println("error: ", e.what());
return_value = 1;
}
break;
}
case cista::hash("shapes"): {
try {
auto data_path = fs::path{"data"};
auto desc = po::options_description{"Analyze Shapes Options"};
add_trip_id_opt(desc);
add_data_path_opt(desc, data_path);
add_help_opt(desc);
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return_value = 0;
break;
}
if (vm.count("trip-id") == 0) {
std::cerr << "missing trip-ids\n";
return_value = 2;
break;
}
auto const c = config::read(data_path / "config.yml");
auto const ids = utl::to_vec(
vm["trip-id"].as<std::vector<std::string>>(),
[](auto const& trip_id) {
// Set space_as_plus = true
auto const opts = boost::urls::encoding_opts{true};
auto const decoded = boost::urls::decode_view{trip_id, opts};
return std::string{decoded.begin(), decoded.end()};
});
return_value = analyze_shapes(data{data_path, c}, ids) ? 0 : 1;
} catch (std::exception const& e) {
std::cerr << "unable to analyse shapes: " << e.what() << "\n";
return_value = 1;
}
break;
}
default:
fmt::println(
"Invalid command. Type motis --help for a list of commands.");
return_value = 1;
break;
}
google::protobuf::ShutdownProtobufLibrary();
return return_value;
}
================================================
FILE: exe/params.cc
================================================
#include <fstream>
#include <iostream>
#include "boost/url/url.hpp"
#include "utl/file_utils.h"
#include "utl/parser/cstr.h"
#include "./flags.h"
namespace po = boost::program_options;
namespace motis {
int params(int ac, char** av) {
auto params = std::string{};
auto in = std::string{};
auto out = std::string{};
auto desc = po::options_description{"Options"};
desc.add_options() //
("help", "Prints this help message") //
("params,p", po::value(¶ms)->default_value(params)) //
("in,i", po::value(&in)->default_value(in)) //
("out,o", po::value(&out)->default_value(out));
auto vm = parse_opt(ac, av, desc);
if (vm.count("help")) {
std::cout << desc << "\n";
return 0;
}
auto const override = boost::urls::url{params};
auto out_file = std::ofstream{out};
auto in_file = utl::open_file(in);
auto line = std::optional<std::string>{};
while ((line = utl::read_line(in_file))) {
auto query = boost::urls::url{*line};
for (auto const& x : override.params()) {
query.params().set(x.key, x.value);
}
out_file << query << "\n";
}
return 0U;
}
} // namespace motis
================================================
FILE: include/motis/adr_extend_tt.h
================================================
#pragma once
#include "date/tz.h"
#include "nigiri/routing/clasz_mask.h"
#include "nigiri/types.h"
#include "motis/fwd.h"
#include "motis/types.h"
namespace motis {
// Starts counting timetable places at the last OSM place.
using adr_extra_place_idx_t =
cista::strong<std::uint32_t, struct adr_extra_place_idx_>;
using tz_map_t = vector_map<adr_extra_place_idx_t, date::time_zone const*>;
struct adr_ext {
vector_map<nigiri::location_idx_t, adr_extra_place_idx_t> location_place_;
vector_map<adr_extra_place_idx_t, nigiri::routing::clasz_mask_t> place_clasz_;
vector_map<adr_extra_place_idx_t, float> place_importance_;
};
date::time_zone const* get_tz(nigiri::timetable const&,
adr_ext const*,
tz_map_t const*,
nigiri::location_idx_t);
adr_ext adr_extend_tt(nigiri::timetable const&,
adr::area_database const*,
adr::typeahead&);
} // namespace motis
================================================
FILE: include/motis/analyze_shapes.h
================================================
#include <string>
#include <vector>
#include "motis/data.h"
namespace motis {
bool analyze_shapes(data const&, std::vector<std::string> const& trip_ids);
} // namespace motis
================================================
FILE: include/motis/box_rtree.h
================================================
#pragma once
#include <algorithm>
#include <array>
#include "cista/strong.h"
#include "rtree.h"
#include "geo/box.h"
#include "geo/latlng.h"
namespace motis {
template <typename T, typename Fn>
concept BoxRtreePosHandler = requires(geo::box const& b, T const x, Fn&& f) {
{ std::forward<Fn>(f)(b, x) };
};
template <typename T>
struct box_rtree {
box_rtree() : rtree_{rtree_new()} {}
~box_rtree() {
if (rtree_ != nullptr) {
rtree_free(rtree_);
}
}
box_rtree(box_rtree const& o) {
if (this != &o) {
if (rtree_ != nullptr) {
rtree_free(rtree_);
}
rtree_ = rtree_clone(o.rtree_);
}
}
box_rtree(box_rtree&& o) {
if (this != &o) {
rtree_ = o.rtree_;
o.rtree_ = nullptr;
}
}
box_rtree& operator=(box_rtree const& o) {
if (this != &o) {
if (rtree_ != nullptr) {
rtree_free(rtree_);
}
rtree_ = rtree_clone(o.rtree_);
}
return *this;
}
box_rtree& operator=(box_rtree&& o) {
if (this != &o) {
rtree_ = o.rtree_;
o.rtree_ = nullptr;
}
return *this;
}
void add(geo::box const& b, T const t) {
auto const min_corner = b.min_.lnglat();
auto const max_corner = b.max_.lnglat();
rtree_insert(
rtree_, min_corner.data(), max_corner.data(),
reinterpret_cast<void*>(static_cast<std::size_t>(cista::to_idx(t))));
}
void remove(geo::box const& b, T const t) {
auto const min_corner = b.min_.lnglat();
auto const max_corner = b.max_.lnglat();
rtree_delete(
rtree_, min_corner.data(), max_corner.data(),
reinterpret_cast<void*>(static_cast<std::size_t>(cista::to_idx(t))));
}
std::vector<T> in_radius(geo::latlng const& x, double distance) const {
auto ret = std::vector<T>{};
in_radius(x, distance, [&](auto&& item) { ret.emplace_back(item); });
return ret;
}
template <typename Fn>
void in_radius(geo::latlng const& x, double distance, Fn&& fn) const {
auto const rad_sq = distance * distance;
auto const approx_distance_lng_degrees =
geo::approx_distance_lng_degrees(x);
find(geo::box{x, distance}, [&](geo::box const& box, T const item) {
auto const closest =
geo::latlng{std::clamp(x.lat(), box.min_.lat(), box.max_.lat()),
std::clamp(x.lng(), box.min_.lng(), box.max_.lng())};
if (geo::approx_squared_distance(x, closest,
approx_distance_lng_degrees) < rad_sq) {
fn(item);
}
});
}
template <typename Fn>
void find(geo::box const& b, Fn&& fn) const {
auto const min = b.min_.lnglat();
auto const max = b.max_.lnglat();
rtree_search(
rtree_, min.data(), max.data(),
[](double const* min_corner, double const* max_corner, void const* item,
void* udata) {
if constexpr (BoxRtreePosHandler<T, Fn>) {
(*reinterpret_cast<Fn*>(udata))(
geo::box{geo::latlng{min_corner[1], min_corner[0]},
geo::latlng{max_corner[1], max_corner[0]}},
T{static_cast<cista::base_t<T>>(
reinterpret_cast<std::size_t>(item))});
} else {
(*reinterpret_cast<Fn*>(udata))(T{static_cast<cista::base_t<T>>(
reinterpret_cast<std::size_t>(item))});
}
return true;
},
&fn);
}
template <typename Fn>
void find(geo::latlng const& pos, Fn&& fn) const {
return find(geo::box{pos, pos}, std::forward<Fn>(fn));
}
rtree* rtree_{nullptr};
};
} // namespace motis
================================================
FILE: include/motis/clog_redirect.h
================================================
#pragma once
#include <fstream>
#include <memory>
#include <mutex>
#include <streambuf>
namespace motis {
struct clog_redirect {
explicit clog_redirect(char const* log_file_path);
clog_redirect(clog_redirect const&) = delete;
clog_redirect(clog_redirect&&) = delete;
clog_redirect& operator=(clog_redirect const&) = delete;
clog_redirect& operator=(clog_redirect&&) = delete;
~clog_redirect();
static void set_enabled(bool);
private:
std::ofstream sink_;
std::unique_ptr<std::streambuf> sink_buf_;
std::streambuf* backup_clog_{};
bool active_{};
std::mutex mutex_;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
static bool enabled_;
};
} // namespace motis
================================================
FILE: include/motis/compute_footpaths.h
================================================
#pragma once
#include "cista/memory_holder.h"
#include "osr/routing/profile.h"
#include "osr/types.h"
#include "motis/fwd.h"
#include "motis/types.h"
namespace motis {
using elevator_footpath_map_t = hash_map<
osr::node_idx_t,
hash_set<std::pair<nigiri::location_idx_t, nigiri::location_idx_t>>>;
struct routed_transfers_settings {
osr::search_profile profile_;
nigiri::profile_idx_t profile_idx_;
double max_matching_distance_;
bool extend_missing_{false};
std::chrono::seconds max_duration_;
std::function<bool(nigiri::location_idx_t)> is_candidate_{};
};
elevator_footpath_map_t compute_footpaths(
osr::ways const&,
osr::lookup const&,
osr::platforms const&,
nigiri::timetable&,
osr::elevation_storage const*,
bool update_coordinates,
std::vector<routed_transfers_settings> const& settings);
} // namespace motis
================================================
FILE: include/motis/config.h
================================================
#pragma once
#include <filesystem>
#include <functional>
#include <iosfwd>
#include <map>
#include <optional>
#include <set>
#include <thread>
#include <variant>
#include <vector>
#include "cista/hashing.h"
#include "utl/verify.h"
namespace motis {
using headers_t = std::map<std::string, std::string>;
struct config {
friend std::ostream& operator<<(std::ostream&, config const&);
static config read_simple(std::vector<std::string> const& args);
static config read(std::filesystem::path const&);
static config read(std::string const&);
void verify() const;
void verify_input_files_exist() const;
bool requires_rt_timetable_updates() const;
bool shapes_debug_api_enabled() const;
bool has_gbfs_feeds() const;
bool has_prima() const;
bool has_elevators() const;
bool use_street_routing() const;
bool operator==(config const&) const = default;
struct server {
bool operator==(server const&) const = default;
std::string host_{"0.0.0.0"};
std::string port_{"8080"};
std::string web_folder_{"ui"};
unsigned n_threads_{0U};
std::optional<std::string> data_attribution_link_{};
std::optional<std::vector<std::string>> lbs_{};
};
std::optional<server> server_{};
std::optional<std::filesystem::path> osm_{};
struct tiles {
bool operator==(tiles const&) const = default;
std::filesystem::path profile_;
std::optional<std::filesystem::path> coastline_{};
std::size_t db_size_{sizeof(void*) >= 8
? 256ULL * 1024ULL * 1024ULL * 1024ULL
: 256U * 1024U * 1024U};
std::size_t flush_threshold_{100'000};
};
std::optional<tiles> tiles_{};
struct timetable {
struct dataset {
struct rt {
bool operator==(rt const&) const = default;
cista::hash_t hash() const noexcept {
return cista::build_hash(url_, headers_);
}
std::string url_;
std::optional<headers_t> headers_{};
enum struct protocol { gtfsrt, auser, siri, siri_json };
protocol protocol_{protocol::gtfsrt};
};
bool operator==(dataset const&) const = default;
std::string path_;
std::optional<std::string> script_{};
bool default_bikes_allowed_{false};
bool default_cars_allowed_{false};
bool extend_calendar_{false};
std::optional<std::map<std::string, bool>> clasz_bikes_allowed_{};
std::optional<std::map<std::string, bool>> clasz_cars_allowed_{};
std::optional<std::vector<rt>> rt_{};
std::optional<std::string> default_timezone_{};
};
struct shapes_debug {
bool operator==(shapes_debug const&) const = default;
std::filesystem::path path_;
std::optional<std::vector<std::string>> trips_{};
std::optional<std::vector<std::string>> route_ids_{};
std::optional<std::vector<unsigned>> route_indices_{};
bool all_{false};
bool all_with_beelines_{false};
unsigned slow_{0U};
};
struct route_shapes {
enum class mode { all, missing };
bool operator==(route_shapes const&) const = default;
mode mode_{mode::all};
bool cache_reuse_old_osm_data_{false};
std::size_t cache_db_size_{sizeof(void*) >= 8
? 256ULL * 1024ULL * 1024ULL * 1024ULL
: 256U * 1024U * 1024U};
std::optional<std::map<std::string, bool>> clasz_{};
unsigned max_stops_{0U};
unsigned n_threads_{0U};
bool debug_api_{false};
std::optional<shapes_debug> debug_{};
};
bool operator==(timetable const&) const = default;
std::string first_day_{"TODAY"};
std::uint16_t num_days_{365U};
bool tb_{false};
bool railviz_{true};
bool with_shapes_{true};
bool adjust_footpaths_{true};
bool merge_dupes_intra_src_{false};
bool merge_dupes_inter_src_{false};
unsigned link_stop_distance_{100U};
unsigned update_interval_{60};
unsigned http_timeout_{30};
bool canned_rt_{false};
bool incremental_rt_update_{false};
bool use_osm_stop_coordinates_{false};
bool extend_missing_footpaths_{false};
std::uint16_t max_footpath_length_{15};
double max_matching_distance_{25.0};
double preprocess_max_matching_distance_{250.0};
std::optional<std::string> default_timezone_{};
std::map<std::string, dataset> datasets_{};
std::optional<std::filesystem::path> assistance_times_{};
std::optional<route_shapes> route_shapes_{};
};
std::optional<timetable> timetable_{};
struct gbfs {
bool operator==(gbfs const&) const = default;
struct ttl {
bool operator==(ttl const&) const = default;
std::optional<std::map<std::string, unsigned>> default_{};
std::optional<std::map<std::string, unsigned>> overwrite_{};
};
struct restrictions {
bool operator==(restrictions const&) const = default;
bool ride_start_allowed_{true};
bool ride_end_allowed_{true};
bool ride_through_allowed_{true};
std::optional<bool> station_parking_{};
std::optional<std::string> return_constraint_{};
};
struct oauth_settings {
bool operator==(oauth_settings const&) const = default;
std::string token_url_;
std::string client_id_;
std::string client_secret_;
std::optional<headers_t> headers_{};
std::optional<unsigned> expires_in_;
};
struct feed {
bool operator==(feed const&) const = default;
std::string url_;
std::optional<headers_t> headers_{};
std::optional<oauth_settings> oauth_{};
std::optional<
std::variant<std::string, std::map<std::string, std::string>>>
group_{};
std::optional<
std::variant<std::string, std::map<std::string, std::string>>>
color_{};
std::optional<ttl> ttl_{};
};
struct group {
bool operator==(group const&) const = default;
std::optional<std::string> name_{};
std::optional<std::string> color_{};
std::optional<std::string> url_{};
};
std::map<std::string, feed> feeds_{};
std::map<std::string, group> groups_{};
std::map<std::string, restrictions> default_restrictions_{};
unsigned update_interval_{60};
unsigned http_timeout_{30};
unsigned cache_size_{50};
std::optional<std::string> proxy_{};
std::optional<ttl> ttl_{};
};
std::optional<gbfs> gbfs_{};
struct prima {
bool operator==(prima const&) const = default;
std::string url_{};
std::optional<std::string> bounds_{};
std::optional<std::string> ride_sharing_bounds_{};
};
std::optional<prima> prima_{};
struct elevators {
bool operator==(elevators const&) const = default;
std::optional<std::string> url_{};
std::optional<std::string> init_{};
std::optional<std::string> osm_mapping_{};
unsigned http_timeout_{10};
std::optional<headers_t> headers_{};
};
unsigned n_threads() const;
std::optional<elevators> const& get_elevators() const;
std::variant<bool, std::optional<elevators>> elevators_{false};
struct street_routing {
bool operator==(street_routing const&) const = default;
std::optional<std::filesystem::path> elevation_data_dir_;
};
std::optional<street_routing> get_street_routing() const;
std::variant<bool, std::optional<street_routing>> street_routing_{false};
struct limits {
bool operator==(limits const&) const = default;
unsigned stoptimes_max_results_{256U};
unsigned plan_max_results_{256U};
unsigned plan_max_search_window_minutes_{5760U};
unsigned stops_max_results_{2048U};
unsigned onetomany_max_many_{128U};
unsigned onetoall_max_results_{65535U};
unsigned onetoall_max_travel_minutes_{90U};
unsigned routing_max_timeout_seconds_{90U};
unsigned gtfsrt_expose_max_trip_updates_{100U};
unsigned street_routing_max_prepost_transit_seconds_{3600U};
unsigned street_routing_max_direct_seconds_{21600U};
unsigned geocode_max_suggestions_{10U};
unsigned reverse_geocode_max_results_{5U};
};
limits get_limits() const { return limits_.value_or(limits{}); }
std::optional<limits> limits_{};
struct logging {
bool operator==(logging const&) const = default;
std::optional<std::string> log_level_{};
};
std::optional<logging> logging_{};
bool osr_footpath_{false};
bool geocoding_{false};
bool reverse_geocoding_{false};
};
} // namespace motis
================================================
FILE: include/motis/constants.h
================================================
#pragma once
namespace motis {
// search radius for neighbors to route to [meters]
constexpr auto const kMaxDistance = 2000;
// max distance from start/destination coordinate to way segment [meters]
constexpr auto const kMaxMatchingDistance = 25.0;
constexpr auto const kMaxWheelchairMatchingDistance = 8.0;
// max distance from gbfs vehicle/station to way segment [meters]
constexpr auto const kMaxGbfsMatchingDistance = 100.0;
// distance between location in timetable and OSM platform coordinate [meters]
constexpr auto const kMaxAdjust = 200;
// multiplier for transfer times
constexpr auto const kTransferTimeMultiplier = 1.5F;
// footpaths of public transport locations around this distance
// are updated on elevator status changes [meters]
constexpr auto const kElevatorUpdateRadius = 1000.;
} // namespace motis
================================================
FILE: include/motis/ctx_data.h
================================================
#pragma once
#include "ctx/op_id.h"
#include "ctx/operation.h"
namespace motis {
struct ctx_data {
void transition(ctx::transition, ctx::op_id, ctx::op_id) {}
};
} // namespace motis
================================================
FILE: include/motis/ctx_exec.h
================================================
#pragma once
#include <iostream>
#include "boost/asio/io_context.hpp"
#include "boost/asio/post.hpp"
#include "ctx/scheduler.h"
#include "motis/ctx_data.h"
namespace motis {
struct ctx_exec {
ctx_exec(boost::asio::io_context& io, ctx::scheduler<ctx_data>& sched)
: io_{io}, sched_{sched} {}
void exec(auto&& f, net::web_server::http_res_cb_t cb) {
sched_.post_void_io(
ctx_data{},
[&, f = std::move(f), cb = std::move(cb)]() mutable {
try {
auto res = std::make_shared<net::web_server::http_res_t>(f());
boost::asio::post(
io_, [cb = std::move(cb), res = std::move(res)]() mutable {
cb(std::move(*res));
});
} catch (...) {
std::cerr << "UNEXPECTED EXCEPTION\n";
auto str = net::web_server::string_res_t{
boost::beast::http::status::internal_server_error, 11};
str.body() = "error";
str.prepare_payload();
auto res = std::make_shared<net::web_server::http_res_t>(str);
boost::asio::post(
io_, [cb = std::move(cb), res = std::move(res)]() mutable {
cb(std::move(*res));
});
}
},
CTX_LOCATION);
}
boost::asio::io_context& io_;
ctx::scheduler<ctx_data>& sched_;
};
} // namespace motis
================================================
FILE: include/motis/data.h
================================================
#pragma once
#include <memory>
#include "cista/memory_holder.h"
#include "date/date.h"
#include "nigiri/rt/vdv_aus.h"
#include "nigiri/types.h"
#include "osr/types.h"
#include "motis-api/motis-api.h"
#include "motis/adr_extend_tt.h"
#include "motis/config.h"
#include "motis/elevators/parse_elevator_id_osm_mapping.h"
#include "motis/fwd.h"
#include "motis/gbfs/data.h"
#include "motis/match_platforms.h"
#include "motis/rt/auser.h"
#include "motis/types.h"
namespace motis {
struct elevators;
template <typename T>
struct point_rtree;
template <typename T>
using ptr = std::unique_ptr<T>;
struct rt {
rt();
rt(ptr<nigiri::rt_timetable>&&, ptr<elevators>&&, ptr<railviz_rt_index>&&);
~rt();
ptr<nigiri::rt_timetable> rtt_;
ptr<railviz_rt_index> railviz_rt_;
ptr<elevators> e_;
};
struct data {
data(std::filesystem::path);
data(std::filesystem::path, config const&);
~data();
data(data const&) = delete;
data& operator=(data const&) = delete;
data(data&&);
data& operator=(data&&);
friend std::ostream& operator<<(std::ostream&, data const&);
void load_osr();
void load_tt(std::filesystem::path const&);
void load_flex_areas();
void load_shapes();
void load_railviz();
void load_tbd();
void load_geocoder();
void load_matches();
void load_way_matches();
void load_reverse_geocoder();
void load_tiles();
void load_auser_updater(std::string_view, config::timetable::dataset const&);
void init_rtt(date::sys_days = std::chrono::time_point_cast<date::days>(
std::chrono::system_clock::now()));
auto cista_members() {
// !!! Remember to add all new members !!!
return std::tie(config_, motis_version_, initial_response_, t_, adr_ext_,
f_, tz_, r_, tc_, w_, pl_, l_, elevations_, tt_, tbd_,
tags_, location_rtree_, elevator_nodes_,
elevator_osm_mapping_, shapes_, railviz_static_, matches_,
way_matches_, rt_, gbfs_, odm_bounds_, ride_sharing_bounds_,
flex_areas_, metrics_, auser_);
}
std::filesystem::path path_;
config config_;
std::string_view motis_version_;
api::initial_response initial_response_;
cista::wrapped<adr::typeahead> t_;
cista::wrapped<adr_ext> adr_ext_;
ptr<adr::formatter> f_;
ptr<vector_map<adr_extra_place_idx_t, date::time_zone const*>> tz_;
ptr<adr::reverse> r_;
ptr<adr::cache> tc_;
ptr<osr::ways> w_;
ptr<osr::platforms> pl_;
ptr<osr::lookup> l_;
ptr<osr::elevation_storage> elevations_;
cista::wrapped<nigiri::timetable> tt_;
cista::wrapped<nigiri::routing::tb::tb_data> tbd_;
cista::wrapped<tag_lookup> tags_;
ptr<point_rtree<nigiri::location_idx_t>> location_rtree_;
ptr<hash_set<osr::node_idx_t>> elevator_nodes_;
ptr<elevator_id_osm_mapping_t> elevator_osm_mapping_;
ptr<nigiri::shapes_storage> shapes_;
ptr<railviz_static_index> railviz_static_;
cista::wrapped<vector_map<nigiri::location_idx_t, osr::platform_idx_t>>
matches_;
ptr<way_matches_storage> way_matches_;
ptr<tiles_data> tiles_;
std::shared_ptr<rt> rt_{std::make_shared<rt>()};
std::shared_ptr<gbfs::gbfs_data> gbfs_{};
ptr<odm::bounds> odm_bounds_;
ptr<odm::ride_sharing_bounds> ride_sharing_bounds_;
ptr<flex::flex_areas> flex_areas_;
ptr<metrics_registry> metrics_;
ptr<std::map<std::string, auser>> auser_;
};
} // namespace motis
================================================
FILE: include/motis/direct_filter.h
================================================
#pragma once
#include <vector>
#include "nigiri/routing/journey.h"
#include "motis-api/motis-api.h"
namespace motis {
void direct_filter(std::vector<api::Itinerary> const& direct,
std::vector<nigiri::routing::journey>&);
} // namespace motis
================================================
FILE: include/motis/elevators/elevators.h
================================================
#pragma once
#include "motis/elevators/match_elevator.h"
#include "motis/elevators/parse_elevator_id_osm_mapping.h"
#include "motis/fwd.h"
#include "motis/point_rtree.h"
namespace motis {
struct elevators {
elevators(osr::ways const&,
elevator_id_osm_mapping_t const*,
hash_set<osr::node_idx_t> const&,
vector_map<elevator_idx_t, elevator>&&);
vector_map<elevator_idx_t, elevator> elevators_;
point_rtree<elevator_idx_t> elevators_rtree_;
osr::bitvec<osr::node_idx_t> blocked_;
};
} // namespace motis
================================================
FILE: include/motis/elevators/get_state_changes.h
================================================
#pragma once
#include <ranges>
#include <vector>
#include "fmt/ranges.h"
#include "nigiri/common/interval.h"
#include "utl/enumerate.h"
#include "utl/generator.h"
#include "utl/to_vec.h"
#include "utl/verify.h"
namespace motis {
template <typename Time>
struct state_change {
friend bool operator==(state_change const&, state_change const&) = default;
Time valid_from_;
bool state_;
};
template <typename Time, bool Default = true>
std::vector<state_change<Time>> intervals_to_state_changes(
std::vector<nigiri::interval<Time>> const& iv, bool const status) {
using Duration = typename Time::duration;
auto ret = std::vector<state_change<Time>>{};
if (iv.empty()) {
ret.push_back({Time{Duration{0}}, status});
} else {
ret.push_back({Time{Duration{0}}, Default});
for (auto const& i : iv) {
ret.push_back({i.from_, !Default});
ret.push_back({i.to_, Default});
}
}
return ret;
}
template <typename Time>
static utl::generator<std::pair<Time, std::vector<bool>>> get_state_changes(
std::vector<std::vector<state_change<Time>>> const& c) {
using It = std::vector<state_change<Time>>::const_iterator;
struct range {
bool is_finished() const { return curr_ == end_; }
bool state_{false};
It curr_, end_;
};
auto its = utl::to_vec(c, [](auto&& v) {
utl::verify(!v.empty(), "empty state vecto
gitextract_8b0p7zjl/
├── .clang-format
├── .clang-tidy.in
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .pkg
├── CMakeLists.txt
├── CMakePresets.json
├── CODE_OF_CONDUCT.md
├── Dockerfile
├── LICENSE
├── README.md
├── cmake/
│ ├── buildcache.cmake
│ ├── clang-tidy.cmake
│ └── pkg.cmake
├── docs/
│ ├── STYLE.md
│ ├── dev-setup-server.md
│ ├── elevation-setup.md
│ ├── linux-dev-setup.md
│ ├── macos-dev-setup.md
│ ├── python-client.md
│ ├── scripting.md
│ ├── setup.md
│ └── windows-dev-setup.md
├── exe/
│ ├── batch.cc
│ ├── compare.cc
│ ├── extract.cc
│ ├── flags.h
│ ├── generate.cc
│ ├── main.cc
│ └── params.cc
├── include/
│ └── motis/
│ ├── adr_extend_tt.h
│ ├── analyze_shapes.h
│ ├── box_rtree.h
│ ├── clog_redirect.h
│ ├── compute_footpaths.h
│ ├── config.h
│ ├── constants.h
│ ├── ctx_data.h
│ ├── ctx_exec.h
│ ├── data.h
│ ├── direct_filter.h
│ ├── elevators/
│ │ ├── elevators.h
│ │ ├── get_state_changes.h
│ │ ├── match_elevator.h
│ │ ├── parse_elevator_id_osm_mapping.h
│ │ ├── parse_fasta.h
│ │ ├── parse_siri_fm.h
│ │ └── update_elevators.h
│ ├── endpoints/
│ │ ├── adr/
│ │ │ ├── filter_conv.h
│ │ │ ├── geocode.h
│ │ │ ├── reverse_geocode.h
│ │ │ └── suggestions_to_response.h
│ │ ├── elevators.h
│ │ ├── graph.h
│ │ ├── gtfsrt.h
│ │ ├── initial.h
│ │ ├── levels.h
│ │ ├── map/
│ │ │ ├── flex_locations.h
│ │ │ ├── rental.h
│ │ │ ├── route_details.h
│ │ │ ├── routes.h
│ │ │ ├── shapes_debug.h
│ │ │ ├── stops.h
│ │ │ └── trips.h
│ │ ├── matches.h
│ │ ├── metrics.h
│ │ ├── ojp.h
│ │ ├── one_to_all.h
│ │ ├── one_to_many.h
│ │ ├── one_to_many_post.h
│ │ ├── osr_routing.h
│ │ ├── platforms.h
│ │ ├── routing.h
│ │ ├── stop_times.h
│ │ ├── tiles.h
│ │ ├── transfers.h
│ │ ├── trip.h
│ │ └── update_elevator.h
│ ├── flex/
│ │ ├── flex.h
│ │ ├── flex_areas.h
│ │ ├── flex_output.h
│ │ ├── flex_routing_data.h
│ │ └── mode_id.h
│ ├── fwd.h
│ ├── gbfs/
│ │ ├── compression.h
│ │ ├── data.h
│ │ ├── gbfs_output.h
│ │ ├── geofencing.h
│ │ ├── lru_cache.h
│ │ ├── mode.h
│ │ ├── osr_mapping.h
│ │ ├── osr_profile.h
│ │ ├── parser.h
│ │ ├── partition.h
│ │ ├── routing_data.h
│ │ └── update.h
│ ├── get_loc.h
│ ├── get_stops_with_traffic.h
│ ├── hashes.h
│ ├── http_req.h
│ ├── import.h
│ ├── journey_to_response.h
│ ├── location_routes.h
│ ├── logging.h
│ ├── match_platforms.h
│ ├── metrics_registry.h
│ ├── motis_instance.h
│ ├── odm/
│ │ ├── bounds.h
│ │ ├── journeys.h
│ │ ├── meta_router.h
│ │ ├── odm.h
│ │ ├── prima.h
│ │ ├── query_factory.h
│ │ ├── shorten.h
│ │ └── td_offsets.h
│ ├── osr/
│ │ ├── max_distance.h
│ │ ├── mode_to_profile.h
│ │ ├── parameters.h
│ │ └── street_routing.h
│ ├── parse_location.h
│ ├── place.h
│ ├── point_rtree.h
│ ├── polyline.h
│ ├── railviz.h
│ ├── route_shapes.h
│ ├── rt/
│ │ ├── auser.h
│ │ └── rt_metrics.h
│ ├── rt_update.h
│ ├── server.h
│ ├── tag_lookup.h
│ ├── tiles_data.h
│ ├── timetable/
│ │ ├── clasz_to_mode.h
│ │ ├── modes_to_clasz_mask.h
│ │ └── time_conv.h
│ ├── transport_mode_ids.h
│ ├── tt_location_rtree.h
│ ├── types.h
│ └── update_rtt_td_footpaths.h
├── openapi.yaml
├── src/
│ ├── adr_extend_tt.cc
│ ├── analyze_shapes.cc
│ ├── clog_redirect.cc
│ ├── compute_footpaths.cc
│ ├── config.cc
│ ├── data.cc
│ ├── direct_filter.cc
│ ├── elevators/
│ │ ├── elevators.cc
│ │ ├── match_elevators.cc
│ │ ├── parse_elevator_id_osm_mapping.cc
│ │ ├── parse_fasta.cc
│ │ ├── parse_siri_fm.cc
│ │ └── update_elevators.cc
│ ├── endpoints/
│ │ ├── adr/
│ │ │ ├── filter_conv.cc
│ │ │ ├── geocode.cc
│ │ │ ├── reverse_geocode.cc
│ │ │ └── suggestions_to_response.cc
│ │ ├── elevators.cc
│ │ ├── graph.cc
│ │ ├── gtfsrt.cc
│ │ ├── initial.cc
│ │ ├── levels.cc
│ │ ├── map/
│ │ │ ├── flex.cc
│ │ │ ├── rental.cc
│ │ │ ├── route_details.cc
│ │ │ ├── routes.cc
│ │ │ ├── shapes_debug.cc
│ │ │ ├── stops.cc
│ │ │ └── trips.cc
│ │ ├── matches.cc
│ │ ├── metrics.cc
│ │ ├── ojp.cc
│ │ ├── one_to_all.cc
│ │ ├── one_to_many.cc
│ │ ├── one_to_many_post.cc
│ │ ├── osr_routing.cc
│ │ ├── platforms.cc
│ │ ├── routing.cc
│ │ ├── stop_times.cc
│ │ ├── tiles.cc
│ │ ├── transfers.cc
│ │ ├── trip.cc
│ │ └── update_elevator.cc
│ ├── flex/
│ │ ├── flex.cc
│ │ ├── flex_areas.cc
│ │ └── flex_output.cc
│ ├── gbfs/
│ │ ├── data.cc
│ │ ├── gbfs_output.cc
│ │ ├── geofencing.cc
│ │ ├── mode.cc
│ │ ├── osr_mapping.cc
│ │ ├── osr_profile.cc
│ │ ├── parser.cc
│ │ ├── routing_data.cc
│ │ └── update.cc
│ ├── get_stops_with_traffic.cc
│ ├── hashes.cc
│ ├── http_req.cc
│ ├── import.cc
│ ├── journey_to_response.cc
│ ├── logging.cc
│ ├── match_platforms.cc
│ ├── metrics_registry.cc
│ ├── odm/
│ │ ├── blacklist_taxi.cc
│ │ ├── bounds.cc
│ │ ├── journeys.cc
│ │ ├── meta_router.cc
│ │ ├── odm.cc
│ │ ├── prima.cc
│ │ ├── query_factory.cc
│ │ ├── shorten.cc
│ │ ├── td_offsets.cc
│ │ ├── whitelist_ridesharing.cc
│ │ └── whitelist_taxi.cc
│ ├── osr/
│ │ ├── max_distance.cc
│ │ ├── mode_to_profile.cc
│ │ ├── parameters.cc
│ │ └── street_routing.cc
│ ├── parse_location.cc
│ ├── place.cc
│ ├── polyline.cc
│ ├── railviz.cc
│ ├── route_shapes.cc
│ ├── rt/
│ │ └── auser.cc
│ ├── rt_update.cc
│ ├── server.cc
│ ├── tag_lookup.cc
│ ├── timetable/
│ │ ├── clasz_to_mode.cc
│ │ └── modes_to_clasz_mask.cc
│ └── update_rtt_td_footpaths.cc
├── test/
│ ├── combinations_test.cc
│ ├── config_test.cc
│ ├── elevators/
│ │ ├── parse_elevator_id_osm_mapping_test.cc
│ │ ├── parse_fasta_test.cc
│ │ ├── parse_siri_fm_test.cc
│ │ └── siri_fm_routing_test.cc
│ ├── endpoints/
│ │ ├── map_routes_test.cc
│ │ ├── ojp_test.cc
│ │ ├── one_to_many_test.cc
│ │ ├── siri_sx_test.cc
│ │ ├── stop_group_geocoding_test.cc
│ │ ├── stop_times_test.cc
│ │ └── trip_test.cc
│ ├── ffm_hbf.osm
│ ├── flex_mode_id_test.cc
│ ├── gbfs_partition_test.cc
│ ├── main.cc
│ ├── matching_test.cc
│ ├── odm/
│ │ ├── csv_journey_test.cc
│ │ ├── prima_test.cc
│ │ └── td_offsets_test.cc
│ ├── read_test.cc
│ ├── resources/
│ │ ├── gbfs/
│ │ │ ├── free_bike_status.json
│ │ │ ├── gbfs.json
│ │ │ ├── geofencing_zones.json
│ │ │ ├── station_information.json
│ │ │ ├── station_status.json
│ │ │ ├── system_information.json
│ │ │ └── vehicle_types.json
│ │ ├── ojp/
│ │ │ ├── geocoding_request.xml
│ │ │ ├── geocoding_response.xml
│ │ │ ├── intermodal_routing_request.xml
│ │ │ ├── intermodal_routing_response.xml
│ │ │ ├── map_stops_request.xml
│ │ │ ├── map_stops_response.xml
│ │ │ ├── routing_request.xml
│ │ │ ├── routing_response.xml
│ │ │ ├── stop_event_request.xml
│ │ │ ├── stop_event_response.xml
│ │ │ ├── trip_info_request.xml
│ │ │ └── trip_info_response.xml
│ │ └── test_case.geojson
│ ├── routing_shrink_results_test.cc
│ ├── routing_slow_direct_test.cc
│ ├── routing_test.cc
│ ├── tag_lookup_test.cc
│ ├── test_case/
│ │ └── .gitignore
│ ├── test_case.cc
│ ├── test_case.h
│ ├── test_dir.h.in
│ ├── util.cc
│ └── util.h
├── tools/
│ ├── buildcache-clang-tidy.lua
│ ├── suppress.txt
│ ├── try-reproduce.py
│ └── ubsan-suppress.txt
└── ui/
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc
├── README.md
├── api/
│ ├── LICENSE
│ ├── README.md
│ ├── openapi/
│ │ ├── index.ts
│ │ ├── schemas.gen.ts
│ │ ├── services.gen.ts
│ │ └── types.gen.ts
│ ├── package.json
│ └── tsconfig.json
├── components.json
├── eslint.config.js
├── package.json
├── playwright.config.ts
├── pnpm-workspace.yaml
├── postcss.config.js
├── src/
│ ├── app.css
│ ├── app.d.ts
│ ├── app.html
│ ├── index.test.ts
│ ├── lib/
│ │ ├── AddressTypeahead.svelte
│ │ ├── AdvancedOptions.svelte
│ │ ├── Alerts.svelte
│ │ ├── Color.ts
│ │ ├── ConnectionDetail.svelte
│ │ ├── DateInput.svelte
│ │ ├── Debug.svelte
│ │ ├── DeparturesMask.svelte
│ │ ├── DirectConnection.svelte
│ │ ├── ErrorMessage.svelte
│ │ ├── IsochronesInfo.svelte
│ │ ├── IsochronesMask.svelte
│ │ ├── ItineraryList.svelte
│ │ ├── LevelSelect.svelte
│ │ ├── Location.ts
│ │ ├── Modes.ts
│ │ ├── NumberSelect.svelte
│ │ ├── Precision.ts
│ │ ├── RailViz.svelte
│ │ ├── Route.svelte
│ │ ├── SearchMask.svelte
│ │ ├── StopTimes.svelte
│ │ ├── StreetModes.svelte
│ │ ├── Time.svelte
│ │ ├── TransitModeSelect.svelte
│ │ ├── ViaStopOptions.svelte
│ │ ├── components/
│ │ │ └── ui/
│ │ │ ├── button/
│ │ │ │ ├── button.svelte
│ │ │ │ └── index.ts
│ │ │ ├── card/
│ │ │ │ ├── card-content.svelte
│ │ │ │ ├── card-description.svelte
│ │ │ │ ├── card-footer.svelte
│ │ │ │ ├── card-header.svelte
│ │ │ │ ├── card-title.svelte
│ │ │ │ ├── card.svelte
│ │ │ │ └── index.ts
│ │ │ ├── dialog/
│ │ │ │ ├── dialog-content.svelte
│ │ │ │ ├── dialog-description.svelte
│ │ │ │ ├── dialog-footer.svelte
│ │ │ │ ├── dialog-header.svelte
│ │ │ │ ├── dialog-overlay.svelte
│ │ │ │ ├── dialog-title.svelte
│ │ │ │ └── index.ts
│ │ │ ├── label/
│ │ │ │ ├── index.ts
│ │ │ │ └── label.svelte
│ │ │ ├── radio-group/
│ │ │ │ ├── index.ts
│ │ │ │ ├── radio-group-item.svelte
│ │ │ │ └── radio-group.svelte
│ │ │ ├── select/
│ │ │ │ ├── index.ts
│ │ │ │ ├── select-content.svelte
│ │ │ │ ├── select-group-heading.svelte
│ │ │ │ ├── select-item.svelte
│ │ │ │ ├── select-scroll-down-button.svelte
│ │ │ │ ├── select-scroll-up-button.svelte
│ │ │ │ ├── select-separator.svelte
│ │ │ │ └── select-trigger.svelte
│ │ │ ├── separator/
│ │ │ │ ├── index.ts
│ │ │ │ └── separator.svelte
│ │ │ ├── switch/
│ │ │ │ ├── index.ts
│ │ │ │ └── switch.svelte
│ │ │ ├── table/
│ │ │ │ ├── index.ts
│ │ │ │ ├── table-body.svelte
│ │ │ │ ├── table-caption.svelte
│ │ │ │ ├── table-cell.svelte
│ │ │ │ ├── table-footer.svelte
│ │ │ │ ├── table-head.svelte
│ │ │ │ ├── table-header.svelte
│ │ │ │ ├── table-row.svelte
│ │ │ │ └── table.svelte
│ │ │ ├── tabs/
│ │ │ │ ├── index.ts
│ │ │ │ ├── tabs-content.svelte
│ │ │ │ ├── tabs-list.svelte
│ │ │ │ ├── tabs-trigger.svelte
│ │ │ │ └── tabs.svelte
│ │ │ └── toggle/
│ │ │ ├── index.ts
│ │ │ └── toggle.svelte
│ │ ├── constants.ts
│ │ ├── defaults.ts
│ │ ├── formatDuration.ts
│ │ ├── generateTimes.ts
│ │ ├── getModeName.ts
│ │ ├── i18n/
│ │ │ ├── bg.ts
│ │ │ ├── cs.ts
│ │ │ ├── de.ts
│ │ │ ├── en.ts
│ │ │ ├── fr.ts
│ │ │ ├── pl.ts
│ │ │ └── translation.ts
│ │ ├── lngLatToStr.ts
│ │ ├── map/
│ │ │ ├── Control.svelte
│ │ │ ├── Drawer.svelte
│ │ │ ├── GeoJSON.svelte
│ │ │ ├── Isochrones.svelte
│ │ │ ├── IsochronesShapeWorker.ts
│ │ │ ├── IsochronesShared.ts
│ │ │ ├── IsochronesWorker.ts
│ │ │ ├── Layer.svelte
│ │ │ ├── Map.svelte
│ │ │ ├── Marker.svelte
│ │ │ ├── Popup.svelte
│ │ │ ├── colors.ts
│ │ │ ├── createTripIcon.ts
│ │ │ ├── getModeLabel.ts
│ │ │ ├── handleScroll.ts
│ │ │ ├── itineraries/
│ │ │ │ ├── ItineraryGeoJSON.svelte
│ │ │ │ ├── itineraryLayers.ts
│ │ │ │ └── layerFilters.ts
│ │ │ ├── rentals/
│ │ │ │ ├── Rentals.svelte
│ │ │ │ ├── StationPopup.svelte
│ │ │ │ ├── VehiclePopup.svelte
│ │ │ │ ├── ZoneLayer.svelte
│ │ │ │ ├── ZonePopup.svelte
│ │ │ │ ├── assets.ts
│ │ │ │ ├── style.ts
│ │ │ │ ├── zone-fill-layer.ts
│ │ │ │ └── zone-types.ts
│ │ │ ├── routes/
│ │ │ │ └── Routes.svelte
│ │ │ ├── shield.ts
│ │ │ ├── stops/
│ │ │ │ └── StopsGeoJSON.svelte
│ │ │ └── style.ts
│ │ ├── modeStyle.ts
│ │ ├── preprocessItinerary.ts
│ │ ├── toDateTime.ts
│ │ ├── tripsWorker.ts
│ │ ├── types.ts
│ │ └── utils.ts
│ └── routes/
│ ├── +layout.svelte
│ ├── +layout.ts
│ └── +page.svelte
├── static/
│ ├── sprite_sdf.json
│ └── sprite_sdf@2x.json
├── svelte.config.js
├── tailwind.config.js
├── tests/
│ └── test.ts
├── tsconfig.json
└── vite.config.ts
SYMBOL INDEX (984 symbols across 258 files)
FILE: exe/batch.cc
type thousands_sep (line 20) | struct thousands_sep : std::numpunct<char> {
method char_type (line 21) | char_type do_thousands_sep() const override { return ','; }
method string_type (line 22) | string_type do_grouping() const override { return "\3"; }
type stats (line 25) | struct stats {
type entry (line 26) | struct entry {
method stats (line 31) | stats() = default;
method stats (line 32) | stats(std::string name, std::uint64_t count_so_far)
method add (line 35) | void add(uint64_t msg_id, std::uint64_t value) {
type category (line 45) | struct category {
method category (line 46) | category() = default;
method category (line 47) | explicit category(std::string name) : name_(std::move(name)) {}
function quantile (line 53) | stats::entry quantile(std::vector<stats::entry> const& sorted_values,
function print_category (line 64) | void print_category(category& cat,
type motis (line 126) | namespace motis {
function batch (line 128) | int batch(int ac, char** av) {
FILE: exe/compare.cc
type motis (line 34) | namespace motis {
function compare (line 36) | int compare(int ac, char** av) {
FILE: exe/extract.cc
type motis (line 30) | namespace motis {
function copy_stop_times (line 32) | void copy_stop_times(hash_set<std::string> const& trip_ids,
function copy_stops (line 61) | void copy_stops(hash_set<std::string>& stop_ids,
function copy_trips (line 104) | void copy_trips(hash_set<std::string> const& trip_ids,
function copy_calendar (line 133) | void copy_calendar(hash_set<std::string> const& service_ids,
function copy_routes (line 157) | void copy_routes(hash_set<std::string> const& route_ids,
function copy_agencies (line 183) | void copy_agencies(hash_set<std::string> const& agency_ids,
function copy_transfers (line 206) | void copy_transfers(hash_set<std::string> const& stop_ids,
function extract (line 231) | int extract(int ac, char** av) {
FILE: exe/flags.h
function namespace (line 9) | namespace motis {
FILE: exe/generate.cc
type motis (line 30) | namespace motis {
function rand_in (line 36) | std::uint32_t rand_in(std::uint32_t const from, std::uint32_t const to) {
function It (line 47) | It rand_in(It const begin, It const end) {
function rand_in (line 54) | Collection::value_type rand_in(Collection const& c) {
function random_stop (line 61) | n::location_idx_t random_stop(n::timetable const& tt,
function generate (line 70) | int generate(int ac, char** av) {
FILE: exe/main.cc
type motis (line 38) | namespace motis {
function main (line 48) | int main(int ac, char** av) {
FILE: exe/params.cc
type motis (line 13) | namespace motis {
function params (line 15) | int params(int ac, char** av) {
FILE: include/motis/adr_extend_tt.h
function namespace (line 11) | namespace motis {
FILE: include/motis/analyze_shapes.h
function namespace (line 6) | namespace motis {
FILE: include/motis/box_rtree.h
function add (line 64) | void add(geo::box const& b, T const t) {
function remove (line 72) | void remove(geo::box const& b, T const t) {
function ret (line 81) | auto ret = std::vector<T>{}
function closest (line 92) | auto const closest =
function rtree (line 130) | rtree* rtree_{nullptr};
FILE: include/motis/clog_redirect.h
function namespace (line 8) | namespace motis {
FILE: include/motis/compute_footpaths.h
function namespace (line 11) | namespace motis {
FILE: include/motis/config.h
function namespace (line 17) | namespace motis {
type timetable (line 63) | struct timetable {
function extend_calendar_ (line 83) | bool extend_calendar_{false};
type shapes_debug (line 90) | struct shapes_debug {
function slow_ (line 98) | unsigned slow_{0U};
type route_shapes (line 101) | struct route_shapes {
function debug_api_ (line 113) | bool debug_api_{false};
function max_matching_distance_ (line 135) | double max_matching_distance_{25.0};
type street_routing (line 227) | struct street_routing {
type limits (line 236) | struct limits {
function reverse_geocode_max_results_ (line 250) | unsigned reverse_geocode_max_results_{5U};
type logging (line 255) | struct logging {
function geocoding_ (line 262) | bool geocoding_{false};
FILE: include/motis/constants.h
function namespace (line 3) | namespace motis {
FILE: include/motis/ctx_data.h
type ctx_data (line 8) | struct ctx_data {
FILE: include/motis/ctx_exec.h
function namespace (line 12) | namespace motis {
function str (line 31) | auto str = net::web_server::string_res_t{
FILE: include/motis/data.h
function namespace (line 24) | namespace motis {
FILE: include/motis/direct_filter.h
function namespace (line 9) | namespace motis {
FILE: include/motis/elevators/elevators.h
function namespace (line 8) | namespace motis {
FILE: include/motis/elevators/get_state_changes.h
function namespace (line 15) | namespace motis {
function state_ (line 46) | struct range {
function its (line 52) | auto its = utl::to_vec(c, [](auto&& v) {
function next (line 61) | auto const next = [&]() -> range& {
function get_state (line 75) | auto const get_state = [&]() -> std::vector<bool> {
function state (line 90) | auto const state = std::pair{t, get_state()};
FILE: include/motis/elevators/match_elevator.h
function namespace (line 10) | namespace motis {
FILE: include/motis/elevators/parse_elevator_id_osm_mapping.h
function namespace (line 9) | namespace motis {
FILE: include/motis/elevators/parse_fasta.h
function namespace (line 10) | namespace motis {
FILE: include/motis/elevators/parse_siri_fm.h
function namespace (line 8) | namespace motis {
FILE: include/motis/elevators/update_elevators.h
function namespace (line 9) | namespace motis {
FILE: include/motis/endpoints/adr/filter_conv.h
function namespace (line 7) | namespace motis {
FILE: include/motis/endpoints/adr/geocode.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/adr/reverse_geocode.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/adr/suggestions_to_response.h
function namespace (line 11) | namespace motis {
FILE: include/motis/endpoints/elevators.h
function namespace (line 10) | namespace motis::ep {
FILE: include/motis/endpoints/graph.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/gtfsrt.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/initial.h
function namespace (line 8) | namespace motis::ep {
FILE: include/motis/endpoints/levels.h
function namespace (line 8) | namespace motis::ep {
FILE: include/motis/endpoints/map/flex_locations.h
function namespace (line 11) | namespace motis::ep {
FILE: include/motis/endpoints/map/rental.h
function namespace (line 10) | namespace motis::ep {
FILE: include/motis/endpoints/map/route_details.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/map/routes.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/map/shapes_debug.h
function namespace (line 8) | namespace motis::ep {
FILE: include/motis/endpoints/map/stops.h
function namespace (line 12) | namespace motis::ep {
FILE: include/motis/endpoints/map/trips.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/matches.h
function namespace (line 10) | namespace motis::ep {
FILE: include/motis/endpoints/metrics.h
function namespace (line 10) | namespace motis::ep {
FILE: include/motis/endpoints/ojp.h
function namespace (line 13) | namespace motis::ep {
FILE: include/motis/endpoints/one_to_all.h
function namespace (line 9) | namespace motis::ep {
FILE: include/motis/endpoints/one_to_many.h
function namespace (line 28) | namespace motis::ep {
FILE: include/motis/endpoints/one_to_many_post.h
function namespace (line 14) | namespace motis::ep {
FILE: include/motis/endpoints/osr_routing.h
function namespace (line 8) | namespace motis::ep {
FILE: include/motis/endpoints/platforms.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/routing.h
function namespace (line 23) | namespace motis::ep {
FILE: include/motis/endpoints/stop_times.h
function namespace (line 13) | namespace motis::ep {
FILE: include/motis/endpoints/tiles.h
function namespace (line 7) | namespace motis::ep {
FILE: include/motis/endpoints/transfers.h
function namespace (line 15) | namespace motis::ep {
FILE: include/motis/endpoints/trip.h
function namespace (line 10) | namespace motis::ep {
FILE: include/motis/endpoints/update_elevator.h
function namespace (line 16) | namespace motis::ep {
FILE: include/motis/flex/flex.h
function namespace (line 14) | namespace motis::flex {
FILE: include/motis/flex/flex_areas.h
function namespace (line 15) | namespace motis::flex {
FILE: include/motis/flex/flex_output.h
function namespace (line 7) | namespace motis::flex {
FILE: include/motis/flex/flex_routing_data.h
function namespace (line 12) | namespace motis::flex {
FILE: include/motis/flex/mode_id.h
function namespace (line 7) | namespace motis::flex {
function id (line 40) | auto id = nigiri::transport_mode_id_t{}
FILE: include/motis/fwd.h
function namespace (line 3) | namespace adr {
function namespace (line 11) | namespace osr {
function namespace (line 22) | namespace nigiri {
function namespace (line 45) | namespace motis {
FILE: include/motis/gbfs/compression.h
function cbv (line 26) | auto cbv = compressed_bitvec{
FILE: include/motis/gbfs/data.h
function namespace (line 39) | namespace motis::gbfs {
type compressed_bitvec (line 279) | struct compressed_bitvec {
function original_bytes_ (line 285) | int original_bytes_{}
function compressed_bytes_ (line 286) | int compressed_bytes_{}
type routing_data (line 290) | struct routing_data {
function station_parking_ (line 299) | bool station_parking_{}
type compressed_routing_data (line 302) | struct compressed_routing_data {
function compressed_bitvec (line 307) | compressed_bitvec start_allowed_{}
function compressed_bitvec (line 308) | compressed_bitvec end_allowed_{}
function compressed_bitvec (line 309) | compressed_bitvec through_allowed_{}
type provider_routing_data (line 312) | struct provider_routing_data
type products_routing_data (line 314) | struct products_routing_data {
function provider_routing_data (line 341) | struct provider_routing_data
function gbfs_products_idx_t (line 352) | struct provider_products {
type aggregated_feed (line 438) | struct aggregated_feed {
function headers_t (line 450) | headers_t headers_{}
type gbfs_data (line 458) | struct gbfs_data {
FILE: include/motis/gbfs/gbfs_output.h
function namespace (line 5) | namespace motis::gbfs {
FILE: include/motis/gbfs/geofencing.h
function namespace (line 12) | namespace motis::gbfs {
FILE: include/motis/gbfs/lru_cache.h
function max_size_ (line 20) | lru_cache(lru_cache const& o) : max_size_{o.max_size_}
function read_lock (line 21) | auto read_lock = std::shared_lock{o.mutex_};
function read_lock (line 43) | auto read_lock = std::shared_lock{mutex_};
function write_lock (line 51) | auto write_lock = std::unique_lock{mutex_};
function read_lock (line 96) | auto read_lock = std::shared_lock{mutex_};
function contains (line 103) | bool contains(Key const key) {
function remove (line 139) | void remove(Key const key) {
type cache_entry (line 168) | struct cache_entry {
function move_to_front (line 173) | void move_to_front(Key const key) {
FILE: include/motis/gbfs/mode.h
function namespace (line 10) | namespace motis::gbfs {
FILE: include/motis/gbfs/osr_mapping.h
function namespace (line 5) | namespace motis::gbfs {
FILE: include/motis/gbfs/osr_profile.h
function namespace (line 7) | namespace motis::gbfs {
FILE: include/motis/gbfs/parser.h
function namespace (line 10) | namespace motis::gbfs {
FILE: include/motis/gbfs/partition.h
function namespace (line 10) | namespace motis::gbfs {
FILE: include/motis/gbfs/update.h
function namespace (line 10) | namespace motis::gbfs {
FILE: include/motis/get_loc.h
function namespace (line 12) | namespace motis {
FILE: include/motis/get_stops_with_traffic.h
function namespace (line 8) | namespace motis {
FILE: include/motis/hashes.h
function namespace (line 8) | namespace motis {
FILE: include/motis/http_req.h
function namespace (line 12) | namespace motis {
FILE: include/motis/import.h
function namespace (line 7) | namespace motis {
FILE: include/motis/journey_to_response.h
function namespace (line 23) | namespace motis {
FILE: include/motis/location_routes.h
function namespace (line 5) | namespace motis {
FILE: include/motis/logging.h
function namespace (line 7) | namespace motis {
FILE: include/motis/match_platforms.h
function namespace (line 14) | namespace motis {
FILE: include/motis/metrics_registry.h
function namespace (line 9) | namespace motis {
FILE: include/motis/motis_instance.h
function namespace (line 42) | namespace motis {
function stop (line 58) | void stop() {
function join (line 65) | void join() {
function run (line 180) | void run(data& d, config const& c) {
function stop (line 194) | void stop() {
function join (line 199) | void join() {
FILE: include/motis/odm/bounds.h
type tg_geom (line 7) | struct tg_geom
function namespace (line 9) | namespace motis::odm {
FILE: include/motis/odm/journeys.h
function namespace (line 6) | namespace motis::odm {
FILE: include/motis/odm/meta_router.h
function namespace (line 19) | namespace nigiri {
function namespace (line 24) | namespace nigiri::routing {
function namespace (line 29) | namespace motis::odm {
FILE: include/motis/odm/odm.h
function namespace (line 9) | namespace motis::odm {
FILE: include/motis/odm/prima.h
function namespace (line 16) | namespace motis::ep {
function kODMOffsetMinImprovement (line 24) | constexpr auto kODMOffsetMinImprovement = std::chrono::seconds{60};
FILE: include/motis/odm/query_factory.h
function namespace (line 7) | namespace motis::odm {
FILE: include/motis/odm/shorten.h
function namespace (line 3) | namespace motis::odm {
FILE: include/motis/odm/td_offsets.h
function namespace (line 9) | namespace motis::odm {
FILE: include/motis/osr/max_distance.h
function namespace (line 7) | namespace motis {
FILE: include/motis/osr/mode_to_profile.h
function namespace (line 8) | namespace motis {
FILE: include/motis/osr/parameters.h
function namespace (line 8) | namespace motis {
FILE: include/motis/osr/street_routing.h
function namespace (line 15) | namespace motis {
FILE: include/motis/parse_location.h
function namespace (line 12) | namespace motis {
FILE: include/motis/place.h
function namespace (line 11) | namespace motis {
FILE: include/motis/point_rtree.h
function add (line 63) | void add(geo::latlng const& pos, T const t) {
FILE: include/motis/polyline.h
function namespace (line 7) | namespace motis {
FILE: include/motis/railviz.h
function namespace (line 9) | namespace motis {
FILE: include/motis/route_shapes.h
function namespace (line 23) | namespace motis {
FILE: include/motis/rt/auser.h
function namespace (line 7) | namespace motis {
FILE: include/motis/rt/rt_metrics.h
function namespace (line 9) | namespace motis {
type vdvaus_metrics (line 363) | struct vdvaus_metrics {
FILE: include/motis/rt_update.h
function namespace (line 10) | namespace motis {
FILE: include/motis/server.h
function namespace (line 7) | namespace motis {
FILE: include/motis/tag_lookup.h
function namespace (line 13) | namespace motis {
FILE: include/motis/tiles_data.h
function namespace (line 8) | namespace motis {
FILE: include/motis/timetable/clasz_to_mode.h
function namespace (line 8) | namespace motis {
FILE: include/motis/timetable/modes_to_clasz_mask.h
function namespace (line 7) | namespace motis {
FILE: include/motis/timetable/time_conv.h
function namespace (line 8) | namespace motis {
FILE: include/motis/transport_mode_ids.h
function namespace (line 7) | namespace motis {
FILE: include/motis/tt_location_rtree.h
function namespace (line 8) | namespace motis {
FILE: include/motis/types.h
function namespace (line 18) | namespace nigiri {
function namespace (line 22) | namespace motis {
FILE: include/motis/update_rtt_td_footpaths.h
function namespace (line 18) | namespace motis {
FILE: src/adr_extend_tt.cc
type motis (line 29) | namespace motis {
function normalize (line 50) | void normalize(std::string& x) {
function get_diff (line 83) | adr::score_t get_diff(std::string str1,
function adr_ext (line 159) | adr_ext adr_extend_tt(nigiri::timetable const& tt,
FILE: src/analyze_shapes.cc
type motis (line 13) | namespace motis {
function analyze_shape (line 15) | bool analyze_shape(nigiri::shapes_storage const& shapes,
function analyze_shapes (line 35) | bool analyze_shapes(data const& d, std::vector<std::string> const& tri...
FILE: src/clog_redirect.cc
type motis (line 6) | namespace motis {
type synchronized_streambuf (line 10) | struct synchronized_streambuf : std::streambuf {
method synchronized_streambuf (line 11) | synchronized_streambuf(std::streambuf* wrapped, std::mutex& mutex)
method int_type (line 14) | int_type overflow(int_type ch) override {
method xsputn (line 23) | std::streamsize xsputn(char const* s, std::streamsize count) override {
method sync (line 28) | int sync() override {
FILE: src/compute_footpaths.cc
type motis (line 27) | namespace motis {
function elevator_footpath_map_t (line 29) | elevator_footpath_map_t compute_footpaths(
FILE: src/config.cc
type motis (line 22) | namespace motis {
function drop_last (line 25) | consteval auto drop_last() {
type drop_trailing (line 31) | struct drop_trailing {
method process (line 34) | static auto process(auto&& named_tuple) {
method handle_one_field (line 48) | static auto handle_one_field(FieldType&& _f) {
function config (line 59) | config config::read_simple(std::vector<std::string> const& args) {
function config (line 85) | config config::read(std::filesystem::path const& p) {
function config (line 91) | config config::read(std::string const& s) {
FILE: src/data.cc
type motis (line 47) | namespace motis {
FILE: src/direct_filter.cc
type motis (line 8) | namespace motis {
function direct_filter (line 13) | void direct_filter(std::vector<api::Itinerary> const& direct,
FILE: src/elevators/elevators.cc
type motis (line 5) | namespace motis {
function update_elevator_coordinates (line 7) | vector_map<elevator_idx_t, elevator> update_elevator_coordinates(
FILE: src/elevators/match_elevators.cc
type motis (line 8) | namespace motis {
function create_elevator_rtree (line 10) | point_rtree<elevator_idx_t> create_elevator_rtree(
function get_elevator_nodes (line 19) | osr::hash_set<osr::node_idx_t> get_elevator_nodes(osr::ways const& w) {
function elevator_idx_t (line 31) | elevator_idx_t match_elevator(
function get_blocked_elevators (line 49) | osr::bitvec<osr::node_idx_t> get_blocked_elevators(
FILE: src/elevators/parse_elevator_id_osm_mapping.cc
type motis (line 5) | namespace motis {
function elevator_id_osm_mapping_t (line 7) | elevator_id_osm_mapping_t parse_elevator_id_osm_mapping(std::string_vi...
function elevator_id_osm_mapping_t (line 21) | elevator_id_osm_mapping_t parse_elevator_id_osm_mapping(
FILE: src/elevators/parse_fasta.cc
type motis (line 14) | namespace motis {
function parse_date_time (line 16) | n::unixtime_t parse_date_time(std::string_view s) {
function parse_out_of_service (line 25) | std::vector<n::interval<n::unixtime_t>> parse_out_of_service(
function parse_elevator (line 48) | std::optional<elevator> parse_elevator(json::value const& e) {
function parse_fasta (line 80) | vector_map<elevator_idx_t, elevator> parse_fasta(std::string_view s) {
function parse_fasta (line 90) | vector_map<elevator_idx_t, elevator> parse_fasta(
FILE: src/elevators/parse_siri_fm.cc
type motis (line 5) | namespace motis {
function parse_facility_condition (line 7) | std::optional<elevator> parse_facility_condition(pugi::xml_node const&...
function parse_siri_fm (line 28) | vector_map<elevator_idx_t, elevator> parse_siri_fm(std::string_view s) {
function parse_siri_fm (line 46) | vector_map<elevator_idx_t, elevator> parse_siri_fm(
FILE: src/elevators/update_elevators.cc
type motis (line 17) | namespace motis {
function elevator_map_t (line 21) | elevator_map_t to_map(vector_map<elevator_idx_t, elevator> const& elev...
function update_elevators (line 29) | ptr<elevators> update_elevators(config const& c,
FILE: src/endpoints/adr/filter_conv.cc
type motis (line 5) | namespace motis {
function to_filter_type (line 7) | adr::filter_type to_filter_type(
FILE: src/endpoints/adr/geocode.cc
type motis::ep (line 26) | namespace motis::ep {
FILE: src/endpoints/adr/reverse_geocode.cc
type motis::ep (line 15) | namespace motis::ep {
FILE: src/endpoints/adr/suggestions_to_response.cc
type motis (line 20) | namespace motis {
function get_area_lang_idx (line 22) | long get_area_lang_idx(a::typeahead const& t,
function suggestions_to_response (line 35) | api::geocode_response suggestions_to_response(
FILE: src/endpoints/elevators.cc
type std (line 18) | namespace std {
function tag_invoke (line 20) | n::unixtime_t tag_invoke(boost::json::value_to_tag<n::unixtime_t>,
function tag_invoke (line 28) | void tag_invoke(boost::json::value_from_tag,
type nigiri (line 38) | namespace nigiri {
function tag_invoke (line 41) | n::interval<T> tag_invoke(boost::json::value_to_tag<n::interval<T>>,
function tag_invoke (line 50) | void tag_invoke(boost::json::value_from_tag,
type motis::ep (line 60) | namespace motis::ep {
FILE: src/endpoints/graph.cc
type motis::ep (line 11) | namespace motis::ep {
FILE: src/endpoints/gtfsrt.cc
type motis::ep (line 28) | namespace motis::ep {
function add_trip_updates (line 30) | void add_trip_updates(n::timetable const& tt,
function add_rt_transports (line 133) | void add_rt_transports(n::timetable const& tt,
function add_cancelled_transports (line 144) | void add_cancelled_transports(n::timetable const& tt,
FILE: src/endpoints/initial.cc
type motis::ep (line 16) | namespace motis::ep {
function get_initial_response (line 18) | api::initial_response get_initial_response(data const& d) {
FILE: src/endpoints/levels.cc
type motis::ep (line 16) | namespace motis::ep {
FILE: src/endpoints/map/flex.cc
type motis::ep (line 18) | namespace motis::ep {
function to_geometry (line 20) | json::value to_geometry(n::timetable const& tt, n::flex_area_idx_t con...
FILE: src/endpoints/map/rental.cc
type motis::ep (line 29) | namespace motis::ep {
FILE: src/endpoints/map/route_details.cc
type motis::ep (line 9) | namespace motis::ep {
FILE: src/endpoints/map/routes.cc
type motis::ep (line 9) | namespace motis::ep {
FILE: src/endpoints/map/shapes_debug.cc
type motis::ep (line 25) | namespace motis::ep {
function parse_route_idx (line 29) | std::uint64_t parse_route_idx(std::string_view const path) {
function build_caller_data (line 44) | boost::json::object build_caller_data(nigiri::timetable const& tt,
FILE: src/endpoints/map/stops.cc
type motis::ep (line 15) | namespace motis::ep {
FILE: src/endpoints/map/trips.cc
type motis::ep (line 9) | namespace motis::ep {
FILE: src/endpoints/matches.cc
type motis::ep (line 14) | namespace motis::ep {
function get_names (line 18) | std::string get_names(osr::platforms const& pl, osr::platform_idx_t co...
FILE: src/endpoints/metrics.cc
type motis::ep (line 23) | namespace motis::ep {
function update_all_runs_metrics (line 25) | void update_all_runs_metrics(nigiri::timetable const& tt,
FILE: src/endpoints/ojp.cc
type motis::ep (line 25) | namespace motis::ep {
function T (line 28) | T* maybe_ref(T& x) {
function T (line 33) | T* maybe_ref(T* x) {
function T (line 38) | T& maybe_deref(T& x) {
function T (line 43) | T& maybe_deref(T* x) {
type transport_mode (line 50) | struct transport_mode {
function transport_mode (line 56) | transport_mode get_transport_mode(std::int64_t const route_type) {
function transport_mode (line 140) | transport_mode to_pt_mode(api::ModeEnum mode) {
function append (line 167) | void append(std::string_view lang,
function append (line 177) | void append(std::string_view lang,
function append (line 187) | void append(pugi::xml_node node, std::string_view name, T const& value) {
function append (line 192) | void append(pugi::xml_node node,
function append_stop_ref (line 204) | void append_stop_ref(pugi::xml_node node, api::Place const& p) {
function append_place_ref_or_geo (line 213) | void append_place_ref_or_geo(pugi::xml_node node, api::Place const& p) {
function append_position (line 221) | void append_position(pugi::xml_node node,
function get_place_ref (line 229) | std::string_view get_place_ref(pugi::xml_node ref) {
function get_place_ref_or_geo (line 245) | std::string get_place_ref_or_geo(pugi::xml_node ref) {
function append_mode (line 265) | pugi::xml_node append_mode(pugi::xml_node service, transport_mode cons...
function to_upper_ascii (line 275) | std::string to_upper_ascii(std::string_view input) {
function now_timestamp (line 283) | std::string now_timestamp() {
function format_coord_param (line 288) | std::string format_coord_param(double const lat, double const lon) {
function time_to_iso (line 295) | std::string time_to_iso(openapi::date_time_t const& t) {
function duration_to_iso (line 301) | std::string duration_to_iso(std::chrono::seconds const dur) {
function xml_to_str (line 313) | std::string xml_to_str(pugi::xml_document const& doc) {
function create_ojp_response (line 323) | std::pair<pugi::xml_document, pugi::xml_node> create_ojp_response() {
function build_geocode_response (line 344) | pugi::xml_document build_geocode_response(
function build_map_stops_response (line 387) | pugi::xml_document build_map_stops_response(
function add_place (line 433) | void add_place(auto const& t,
function append_leg_places (line 473) | void append_leg_places(auto const& t,
function build_trip_info_response (line 493) | pugi::xml_document build_trip_info_response(trip const& trip_ep,
function build_stop_event_response (line 609) | pugi::xml_document build_stop_event_response(
function build_trip_response (line 733) | pugi::xml_document build_trip_response(routing const& routing_ep,
FILE: src/endpoints/one_to_all.cc
type motis::ep (line 24) | namespace motis::ep {
FILE: src/endpoints/one_to_many.cc
type motis::ep (line 21) | namespace motis::ep {
function one_to_many_direct (line 27) | api::oneToMany_response one_to_many_direct(
function duration_to_seconds (line 82) | double duration_to_seconds(n::duration_t const d) { return 60 * d.coun...
function transit_durations (line 85) | std::vector<api::ParetoSet> transit_durations(
function run_one_to_many_intermodal (line 234) | api::OneToManyIntermodalResponse run_one_to_many_intermodal(
FILE: src/endpoints/one_to_many_post.cc
type motis::ep (line 10) | namespace motis::ep {
FILE: src/endpoints/osr_routing.cc
type motis::ep (line 13) | namespace motis::ep {
function parse_location (line 15) | osr::location parse_location(json::value const& v) {
FILE: src/endpoints/platforms.cc
type motis::ep (line 9) | namespace motis::ep {
FILE: src/endpoints/routing.cc
type motis::ep (line 66) | namespace motis::ep {
function osr_loaded (line 71) | bool osr_loaded(routing const& r) {
function is_intermodal (line 75) | bool is_intermodal(routing const& r, place_t const&) {
function get_match_mode (line 79) | n::routing::location_match_mode get_match_mode(routing const& r,
function station_start (line 85) | std::vector<n::routing::offset> station_start(n::location_idx_t const ...
function radius_offsets (line 89) | std::vector<n::routing::offset> radius_offsets(
function stop_to_osr_location (line 100) | osr::location stop_to_osr_location(routing const& r,
function get_td_offsets (line 106) | n::routing::td_offsets_t get_td_offsets(
function include_rental_provider (line 202) | bool include_rental_provider(
function get_offsets (line 220) | std::vector<n::routing::offset> get_offsets(
function shrink (line 374) | n::interval<n::unixtime_t> shrink(bool const keep_late,
function get_start_time (line 457) | std::pair<n::routing::query, std::optional<n::unixtime_t>> get_start_t...
function stats_map_t (line 596) | stats_map_t join(auto&&... maps) {
function remove_slower_than_fastest_direct (line 605) | void remove_slower_than_fastest_direct(n::routing::query& q) {
function get_via_stops (line 646) | std::vector<n::routing::via_stop> get_via_stops(
function deduplicate (line 668) | std::vector<api::ModeEnum> deduplicate(std::vector<api::ModeEnum> m) {
FILE: src/endpoints/stop_times.cc
type motis::ep (line 34) | namespace motis::ep {
type ev_iterator (line 36) | struct ev_iterator {
method ev_iterator (line 37) | ev_iterator() = default;
method ev_iterator (line 38) | ev_iterator(ev_iterator const&) = delete;
method ev_iterator (line 39) | ev_iterator(ev_iterator&&) = delete;
method ev_iterator (line 40) | ev_iterator& operator=(ev_iterator const&) = delete;
method ev_iterator (line 41) | ev_iterator& operator=(ev_iterator&&) = delete;
type static_ev_iterator (line 49) | struct static_ev_iterator : public ev_iterator {
method static_ev_iterator (line 50) | static_ev_iterator(n::timetable const& tt,
method static_ev_iterator (line 74) | static_ev_iterator(static_ev_iterator const&) = delete;
method static_ev_iterator (line 75) | static_ev_iterator(static_ev_iterator&&) = delete;
method static_ev_iterator (line 76) | static_ev_iterator& operator=(static_ev_iterator const&) = delete;
method static_ev_iterator (line 77) | static_ev_iterator& operator=(static_ev_iterator&&) = delete;
method seek_next (line 79) | void seek_next(std::optional<n::unixtime_t> const start = std::nullo...
method finished (line 96) | bool finished() const override { return day_ == end_day_; }
method time (line 98) | n::unixtime_t time() const override {
method get (line 102) | n::rt::run get() const override {
method increment (line 109) | void increment() override {
method is_active (line 115) | bool is_active() const {
method t (line 127) | n::transport t() const {
type rt_ev_iterator (line 146) | struct rt_ev_iterator : public ev_iterator {
method rt_ev_iterator (line 147) | rt_ev_iterator(n::rt_timetable const& rtt,
method rt_ev_iterator (line 169) | rt_ev_iterator(rt_ev_iterator const&) = delete;
method rt_ev_iterator (line 170) | rt_ev_iterator(rt_ev_iterator&&) = delete;
method rt_ev_iterator (line 171) | rt_ev_iterator& operator=(rt_ev_iterator const&) = delete;
method rt_ev_iterator (line 172) | rt_ev_iterator& operator=(rt_ev_iterator&&) = delete;
method finished (line 174) | bool finished() const override { return finished_; }
method time (line 176) | n::unixtime_t time() const override {
method get (line 180) | n::rt::run get() const override {
method increment (line 186) | void increment() override { finished_ = true; }
function get_events (line 195) | std::vector<n::rt::run> get_events(
function other_stops_impl (line 301) | std::vector<api::Place> other_stops_impl(n::rt::frun fr,
FILE: src/endpoints/tiles.cc
type motis::ep (line 17) | namespace motis::ep {
FILE: src/endpoints/transfers.cc
type motis::ep (line 21) | namespace motis::ep {
FILE: src/endpoints/trip.cc
type motis::ep (line 22) | namespace motis::ep {
FILE: src/endpoints/update_elevator.cc
type motis::ep (line 17) | namespace motis::ep {
FILE: src/flex/flex.cc
type motis::flex (line 23) | namespace motis::flex {
function prepare_sharing_data (line 25) | osr::sharing_data prepare_sharing_data(n::timetable const& tt,
function get_relevant_days (line 138) | n::interval<n::day_idx_t> get_relevant_days(
function flex_routings_t (line 156) | flex_routings_t get_flex_routings(
function is_in_flex_stop (line 241) | bool is_in_flex_stop(n::timetable const& tt,
function add_flex_td_offsets (line 262) | void add_flex_td_offsets(osr::ways const& w,
FILE: src/flex/flex_areas.cc
type motis::flex (line 12) | namespace motis::flex {
function tg_ring (line 14) | tg_ring* convert_ring(std::vector<tg_point>& ring_tmp, auto&& osm_ring) {
type tmp (line 31) | struct tmp {
FILE: src/flex/flex_output.cc
type motis::flex (line 14) | namespace motis::flex {
function get_flex_stop_name (line 16) | std::string_view get_flex_stop_name(n::timetable const& tt,
function get_flex_id (line 28) | std::string_view get_flex_id(n::timetable const& tt, n::flex_stop_t co...
function transport_mode_t (line 66) | transport_mode_t flex_output::get_cache_key() const { return mode_id_....
FILE: src/gbfs/data.cc
type motis::gbfs (line 9) | namespace motis::gbfs {
FILE: src/gbfs/gbfs_output.cc
type motis::gbfs (line 7) | namespace motis::gbfs {
function transport_mode_t (line 38) | transport_mode_t gbfs_output::get_cache_key() const {
FILE: src/gbfs/geofencing.cc
type motis::gbfs (line 7) | namespace motis::gbfs {
function applies (line 9) | bool applies(std::vector<vehicle_type_idx_t> const& rule_vehicle_type_...
function multipoly_contains_point (line 18) | bool multipoly_contains_point(tg_geom const* geom, geo::latlng const& ...
function geofencing_restrictions (line 30) | geofencing_restrictions geofencing_zones::get_restrictions(
FILE: src/gbfs/mode.cc
type motis::gbfs (line 10) | namespace motis::gbfs {
function to_api_form_factor (line 12) | api::RentalFormFactorEnum to_api_form_factor(vehicle_form_factor const...
function vehicle_form_factor (line 29) | vehicle_form_factor from_api_form_factor(api::RentalFormFactorEnum con...
function to_api_propulsion_type (line 46) | api::RentalPropulsionTypeEnum to_api_propulsion_type(propulsion_type c...
function propulsion_type (line 66) | propulsion_type from_api_propulsion_type(
function to_api_return_constraint (line 87) | api::RentalReturnConstraintEnum to_api_return_constraint(
function products_match (line 100) | bool products_match(
FILE: src/gbfs/osr_mapping.cc
type motis::gbfs (line 29) | namespace motis::gbfs {
type node_match (line 31) | struct node_match {
type osr_mapping (line 41) | struct osr_mapping {
method osr_mapping (line 42) | osr_mapping(osr::ways const& w,
method map_geofencing_zones (line 49) | void map_geofencing_zones() {
method get_node_matches (line 165) | std::vector<node_match> get_node_matches(osr::location const& loc) c...
method map_stations (line 225) | void map_stations() {
method map_vehicles (line 305) | void map_vehicles() {
method add_node (line 352) | osr::node_idx_t add_node(routing_data& rd,
function map_data (line 372) | void map_data(osr::ways const& w,
FILE: src/gbfs/osr_profile.cc
type motis::gbfs (line 3) | namespace motis::gbfs {
function get_osr_profile (line 5) | osr::search_profile get_osr_profile(vehicle_form_factor const& ff) {
FILE: src/gbfs/parser.cc
type motis::gbfs (line 15) | namespace motis::gbfs {
function gbfs_version (line 17) | gbfs_version get_version(json::value const& root) {
function get_localized_string (line 36) | std::string get_localized_string(json::value const& v) {
function get_as_string (line 51) | std::string get_as_string(json::object const& obj, std::string_view co...
function optional_str (line 64) | std::string optional_str(json::object const& obj, std::string_view key) {
function optional_localized_str (line 68) | std::string optional_localized_str(json::object const& obj,
function get_bool (line 73) | bool get_bool(json::object const& obj,
function tg_geom (line 89) | tg_geom* parse_multipolygon(json::object const& json) {
function parse_discovery (line 139) | hash_map<std::string, std::string> parse_discovery(json::value const& ...
function rental_uris (line 161) | rental_uris parse_rental_uris(json::object const& parent) {
function get_vehicle_type (line 174) | std::optional<vehicle_type_idx_t> get_vehicle_type(
function load_system_information (line 215) | void load_system_information(gbfs_provider& provider, json::value cons...
function load_station_information (line 234) | void load_station_information(gbfs_provider& provider,
function load_station_status (line 273) | void load_station_status(gbfs_provider& provider, json::value const& r...
function vehicle_form_factor (line 358) | vehicle_form_factor parse_form_factor(std::string_view const s) {
function propulsion_type (line 377) | propulsion_type parse_propulsion_type(std::string_view const s) {
function parse_return_constraint (line 394) | std::optional<return_constraint> parse_return_constraint(
function parse_return_constraint (line 406) | std::optional<return_constraint> parse_return_constraint(
function load_vehicle_types (line 414) | void load_vehicle_types(gbfs_provider& provider, json::value const& ro...
function load_vehicle_status (line 451) | void load_vehicle_status(gbfs_provider& provider, json::value const& r...
function rule (line 509) | rule parse_rule(gbfs_provider& provider,
function load_geofencing_zones (line 548) | void load_geofencing_zones(gbfs_provider& provider, json::value const&...
FILE: src/gbfs/routing_data.cc
type motis::gbfs (line 17) | namespace motis::gbfs {
function compute_provider_routing_data (line 19) | std::shared_ptr<provider_routing_data> compute_provider_routing_data(
function get_provider_routing_data (line 30) | std::shared_ptr<provider_routing_data> get_provider_routing_data(
function products_routing_data (line 45) | products_routing_data* gbfs_routing_data::get_products_routing_data(
function products_routing_data (line 54) | products_routing_data* gbfs_routing_data::get_products_routing_data(
function provider_products (line 60) | provider_products const& gbfs_routing_data::get_products(
function gbfs_products_ref (line 76) | gbfs_products_ref gbfs_routing_data::get_products_ref(
FILE: src/gbfs/update.cc
type motis::gbfs (line 57) | namespace motis::gbfs {
type gbfs_file (line 59) | struct gbfs_file {
function read_file (line 65) | std::string read_file(std::filesystem::path const& path) {
function needs_refresh (line 72) | bool needs_refresh(file_info const& fi) {
function hash_gbfs_data (line 78) | cista::hash_t hash_gbfs_data(std::string_view const json) {
function get_expiry (line 128) | std::chrono::system_clock::time_point get_expiry(
type gbfs_update (line 155) | struct gbfs_update {
method gbfs_update (line 156) | gbfs_update(config::gbfs const& c,
method run (line 177) | awaitable<void> run() {
method init_feed (line 263) | awaitable<void> init_feed(std::string const& id,
method update_provider_feed (line 331) | awaitable<void> update_provider_feed(
method gbfs_provider (line 355) | gbfs_provider& add_provider(provider_feed const& pf) {
method process_provider_feed (line 388) | awaitable<void> process_provider_feed(
method partition_provider (line 565) | void partition_provider(gbfs_provider& provider) {
method update_rtree (line 662) | void update_rtree(gbfs_provider const& provider,
method init_aggregated_feed (line 748) | awaitable<void> init_aggregated_feed(
method update_aggregated_feed (line 772) | awaitable<void> update_aggregated_feed(aggregated_feed& af) {
method process_aggregated_feed (line 783) | awaitable<void> process_aggregated_feed(aggregated_feed& af,
method update_aggregated_feed_provider_feeds (line 841) | awaitable<void> update_aggregated_feed_provider_feeds(aggregated_fee...
method fetch_file (line 856) | awaitable<gbfs_file> fetch_file(
method get_oauth_token (line 887) | awaitable<void> get_oauth_token(std::shared_ptr<oauth_state> const& ...
method refresh_oauth_token (line 898) | awaitable<void> refresh_oauth_token(
method refresh_oauth_tokens (line 966) | awaitable<void> refresh_oauth_tokens() {
method geofencing_restrictions (line 1001) | geofencing_restrictions lookup_default_restrictions(std::string cons...
method lookup_default_return_constraint (line 1022) | std::optional<return_constraint> lookup_default_return_constraint(
method lookup_mapping (line 1041) | std::optional<std::string> lookup_mapping(std::string const& af_id,
method lookup_group (line 1064) | std::optional<std::string> lookup_group(std::string const& af_id,
method lookup_color (line 1070) | std::optional<std::string> lookup_color(std::string const& af_id,
function update (line 1087) | awaitable<void> update(config const& c,
function run_gbfs_update (line 1114) | void run_gbfs_update(boost::asio::io_context& ioc,
FILE: src/get_stops_with_traffic.cc
type motis (line 10) | namespace motis {
function get_stops_with_traffic (line 12) | std::vector<n::location_idx_t> get_stops_with_traffic(
FILE: src/hashes.cc
type motis (line 12) | namespace motis {
function to_str (line 14) | std::string to_str(meta_t const& h) {
function meta_t (line 18) | meta_t read_hashes(fs::path const& data_path, std::string const& name) {
function write_hashes (line 28) | void write_hashes(fs::path const& data_path,
FILE: src/http_req.cc
type motis (line 20) | namespace motis {
function req_no_tls (line 34) | asio::awaitable<http_response> req_no_tls(
function req_tls (line 55) | asio::awaitable<http_response> req_tls(
function req (line 92) | asio::awaitable<http_response> req(
function http_GET (line 126) | asio::awaitable<http::response<http::dynamic_body>> http_GET(
function http_POST (line 153) | asio::awaitable<http::response<http::dynamic_body>> http_POST(
function get_http_body (line 181) | std::string get_http_body(http_response const& res) {
FILE: src/import.cc
type motis (line 65) | namespace motis {
type task (line 67) | struct task {
method ready_for_load (line 96) | bool ready_for_load(fs::path const& data_path) {
method run (line 106) | void run(fs::path const& data_path) {
function hash_file (line 133) | cista::hash_t hash_file(fs::path const& p) {
function import (line 163) | void import(config const& c,
type fmt::formatter<motis::task> (line 129) | struct fmt::formatter<motis::task> : fmt::ostream_formatter {}
type motis (line 131) | namespace motis {
type task (line 67) | struct task {
method ready_for_load (line 96) | bool ready_for_load(fs::path const& data_path) {
method run (line 106) | void run(fs::path const& data_path) {
function hash_file (line 133) | cista::hash_t hash_file(fs::path const& p) {
function import (line 163) | void import(config const& c,
FILE: src/journey_to_response.cc
type motis (line 40) | namespace motis {
function to_mode (line 42) | api::ModeEnum to_mode(osr::search_profile const m) {
function cleanup_intermodal (line 65) | void cleanup_intermodal(api::Itinerary& i) {
type fare_indices (line 74) | struct fare_indices {
function get_fare_indices (line 79) | std::optional<fare_indices> get_fare_indices(
function get_alerts (line 101) | std::optional<std::vector<api::Alert>> get_alerts(
type parent_name_hash (line 206) | struct parent_name_hash {
type parent_name_eq (line 213) | struct parent_name_eq {
function get_is_unique_stop_name (line 224) | void get_is_unique_stop_name(n::rt::frun const& fr,
function journey_to_response (line 236) | api::Itinerary journey_to_response(
FILE: src/logging.cc
type motis (line 13) | namespace motis {
function set_log_level (line 15) | int set_log_level(std::string_view log_lvl) {
function set_log_level (line 32) | int set_log_level(config const& c) {
function set_log_level (line 39) | int set_log_level(std::string&& log_lvl) {
FILE: src/match_platforms.cc
type motis (line 17) | namespace motis {
function is_number (line 19) | bool is_number(char const x) { return x >= '0' && x <= '9'; }
function for_each_number (line 22) | void for_each_number(std::string_view x, Fn&& fn) {
function has_number_match (line 40) | bool has_number_match(std::string_view a, std::string_view b) {
function has_number_match (line 49) | bool has_number_match(Collection&& a, std::string_view b) {
function has_exact_match (line 55) | bool has_exact_match(Collection&& a, std::string_view b) {
function has_contains_match (line 61) | bool has_contains_match(Collection&& a, std::string_view b) {
function get_track (line 66) | std::optional<std::string_view> get_track(std::string_view s) {
function get_routes_bonus (line 80) | double get_routes_bonus(n::timetable const& tt,
function get_match_bonus (line 102) | double get_match_bonus(Collection&& names,
function compare_platform_code (line 127) | int compare_platform_code(Collection&& names, std::string_view platfor...
type center (line 139) | struct center {
method add (line 141) | void add(T const& polyline) {
method add (line 147) | void add(geo::latlng const& pos) {
method get_center (line 153) | geo::latlng get_center() const { return {sum_.lat_ / n_, sum_.lng_ /...
function get_platform_center (line 159) | std::optional<geo::latlng> get_platform_center(osr::platforms const& pl,
function get_matches (line 208) | vector_map<n::location_idx_t, osr::platform_idx_t> get_matches(
function get_match (line 219) | osr::platform_idx_t get_match(n::timetable const& tt,
function get_reverse_platform_way_matches (line 304) | std::vector<osr::match_t> get_reverse_platform_way_matches(
FILE: src/metrics_registry.cc
type motis (line 4) | namespace motis {
FILE: src/odm/blacklist_taxi.cc
type motis::odm (line 18) | namespace motis::odm {
function to_json (line 20) | json::array to_json(std::vector<n::routing::offset> const& offsets,
function read_intvl (line 44) | n::interval<n::unixtime_t> read_intvl(json::value const& jv) {
FILE: src/odm/bounds.cc
type motis::odm (line 13) | namespace motis::odm {
FILE: src/odm/journeys.cc
type motis::odm (line 15) | namespace motis::odm {
type csv_journey (line 17) | struct csv_journey {
function read_transport_mode (line 29) | std::optional<nigiri::transport_mode_id_t> read_transport_mode(
function make_dummy (line 40) | nigiri::routing::journey make_dummy(
function from_csv (line 64) | std::vector<nigiri::routing::journey> from_csv(std::string_view const ...
function separate_pt (line 107) | nigiri::pareto_set<nigiri::routing::journey> separate_pt(
function to_csv (line 121) | std::string to_csv(nigiri::routing::journey const& j) {
function to_csv (line 161) | std::string to_csv(std::vector<nigiri::routing::journey> const& jv) {
function make_odm_direct (line 173) | nigiri::routing::journey make_odm_direct(nigiri::location_idx_t const ...
FILE: src/odm/meta_router.cc
type motis::odm (line 57) | namespace motis::odm {
function print_time (line 63) | void print_time(auto const& start,
function collect_odm_journeys (line 219) | std::vector<n::routing::journey> collect_odm_journeys(
function pareto_dominance (line 240) | void pareto_dominance(std::vector<n::routing::journey>& odm_journeys) {
FILE: src/odm/odm.cc
type motis::odm (line 9) | namespace motis::odm {
function by_stop (line 14) | bool by_stop(nr::start const& a, nr::start const& b) {
function is_odm_leg (line 19) | bool is_odm_leg(nr::journey::leg const& l,
function uses_odm (line 25) | bool uses_odm(nr::journey const& j, nigiri::transport_mode_id_t const ...
function is_pure_pt (line 30) | bool is_pure_pt(nr::journey const& j) {
function odm_time (line 35) | n::duration_t odm_time(nr::journey::leg const& l) {
function odm_time (line 42) | n::duration_t odm_time(nr::journey const& j) {
function pt_time (line 48) | n::duration_t pt_time(nr::journey const& j) {
function is_direct_odm (line 52) | bool is_direct_odm(nr::journey const& j) {
function duration (line 56) | n::duration_t duration(nr::start const& ride) {
function odm_label (line 60) | std::string odm_label(nr::journey const& j) {
FILE: src/odm/prima.cc
type motis::odm (line 27) | namespace motis::odm {
function init_direct (line 50) | n::duration_t init_direct(std::vector<direct_ride>& rides,
function init_pt (line 100) | void init_pt(std::vector<n::routing::offset>& offsets,
function to_millis (line 235) | std::int64_t to_millis(n::unixtime_t const t) {
function to_unix (line 241) | n::unixtime_t to_unix(std::int64_t const t) {
function to_json (line 246) | json::array to_json(std::vector<n::routing::start> const& rides,
function to_json (line 272) | json::array to_json(std::vector<direct_ride> const& v,
function tag_invoke (line 281) | void tag_invoke(json::value_from_tag const&,
function make_whitelist_request (line 290) | std::string make_whitelist_request(
function n_rides_in_response (line 314) | std::size_t n_rides_in_response(json::array const& ja) {
function fix_first_mile_duration (line 320) | void fix_first_mile_duration(std::vector<nr::journey>& journeys,
function fix_last_mile_duration (line 366) | void fix_last_mile_duration(std::vector<nr::journey>& journeys,
function add_direct_odm (line 410) | void add_direct_odm(std::vector<direct_ride> const& direct,
FILE: src/odm/query_factory.cc
type motis::odm (line 5) | namespace motis::odm {
FILE: src/odm/shorten.cc
type motis::odm (line 17) | namespace motis::odm {
function shorten (line 19) | void shorten(std::vector<nr::journey>& odm_journeys,
FILE: src/odm/td_offsets.cc
type motis::odm (line 9) | namespace motis::odm {
function get_td_offsets_split (line 11) | std::pair<nr::td_offsets_t, nr::td_offsets_t> get_td_offsets_split(
FILE: src/odm/whitelist_ridesharing.cc
type motis::odm (line 16) | namespace motis::odm {
FILE: src/odm/whitelist_taxi.cc
type motis::odm (line 19) | namespace motis::odm {
function extract_taxis (line 29) | void extract_taxis(std::vector<nr::journey> const& journeys,
FILE: src/osr/max_distance.cc
type motis (line 5) | namespace motis {
function get_max_distance (line 7) | double get_max_distance(osr::search_profile const profile,
FILE: src/osr/mode_to_profile.cc
type motis (line 5) | namespace motis {
function to_mode (line 7) | api::ModeEnum to_mode(osr::mode const m) {
function to_profile (line 19) | osr::search_profile to_profile(
FILE: src/osr/parameters.cc
type motis (line 15) | namespace motis {
function use_wheelchair (line 28) | bool use_wheelchair(T const&) {
function use_wheelchair (line 33) | bool use_wheelchair(T const& t)
function pedestrian_speed (line 40) | float pedestrian_speed(T const&) {
function pedestrian_speed (line 45) | float pedestrian_speed(api::PedestrianProfileEnum const& p) {
function pedestrian_speed (line 52) | float pedestrian_speed(T const& params)
function pedestrian_speed (line 59) | float pedestrian_speed(T const& params)
function cycling_speed (line 72) | float cycling_speed(T const&) {
function cycling_speed (line 77) | float cycling_speed(T const& params)
function osr_parameters (line 91) | osr_parameters to_osr_parameters(T const& params) {
function osr_parameters (line 99) | osr_parameters get_osr_parameters(api::plan_params const& params) {
function osr_parameters (line 103) | osr_parameters get_osr_parameters(api::oneToAll_params const& params) {
function osr_parameters (line 107) | osr_parameters get_osr_parameters(api::oneToMany_params const& params) {
function osr_parameters (line 111) | osr_parameters get_osr_parameters(api::OneToManyParams const& params) {
function osr_parameters (line 115) | osr_parameters get_osr_parameters(
function osr_parameters (line 120) | osr_parameters get_osr_parameters(
function to_profile_parameters (line 125) | osr::profile_parameters to_profile_parameters(osr::search_profile cons...
FILE: src/osr/street_routing.cc
type motis (line 23) | namespace motis {
function transport_mode_t (line 96) | transport_mode_t default_output::get_cache_key() const {
function get_step_instructions (line 109) | std::vector<api::StepInstruction> get_step_instructions(
function dummy_itinerary (line 178) | api::Itinerary dummy_itinerary(api::Place const& from,
function street_routing (line 210) | api::Itinerary street_routing(osr::ways const& w,
FILE: src/parse_location.cc
type motis (line 14) | namespace motis {
function parse_location (line 16) | std::optional<osr::location> parse_location(std::string_view s,
function parse_iso_date (line 47) | date::sys_days parse_iso_date(std::string_view s) {
function parse_cursor (line 53) | std::pair<n::direction, n::unixtime_t> parse_cursor(std::string_view s) {
function cursor_to_query (line 74) | n::routing::query cursor_to_query(std::string_view s) {
FILE: src/place.cc
type motis (line 20) | namespace motis {
function to_place (line 31) | api::Place to_place(osr::location const l,
function get_lvl (line 44) | osr::level_t get_lvl(osr::ways const* w,
function get_level (line 52) | double get_level(osr::ways const* w,
function get_location (line 59) | osr::location get_location(api::Place const& p) {
function get_location (line 63) | osr::location get_location(n::timetable const* tt,
function to_place (line 96) | api::Place to_place(n::timetable const* tt,
function to_place (line 178) | api::Place to_place(n::timetable const* tt,
function place_t (line 206) | place_t get_place(n::timetable const* tt,
FILE: src/polyline.cc
type motis (line 5) | namespace motis {
function to_polyline (line 8) | api::EncodedPolyline to_polyline(geo::polyline const& polyline) {
function empty_polyline (line 13) | api::EncodedPolyline empty_polyline() {
FILE: src/railviz.cc
type motis (line 59) | namespace motis {
type stop_pair (line 61) | struct stop_pair {
function min_zoom_level (line 66) | int min_zoom_level(n::clasz const clasz, float const distance) {
function should_display (line 110) | bool should_display(n::clasz const clasz,
type route_geo_index (line 116) | struct route_geo_index {
method route_geo_index (line 117) | route_geo_index() = default;
method route_geo_index (line 119) | route_geo_index(n::timetable const& tt,
method get_routes (line 148) | std::vector<n::route_idx_t> get_routes(geo::box const& b) const {
type rt_transport_geo_index (line 161) | struct rt_transport_geo_index {
method rt_transport_geo_index (line 162) | rt_transport_geo_index() = default;
method rt_transport_geo_index (line 164) | rt_transport_geo_index(
method get_rt_transports (line 189) | std::vector<n::rt_transport_idx_t> get_rt_transports(
type railviz_static_index::impl (line 205) | struct railviz_static_index::impl {
type railviz_rt_index::impl (line 222) | struct railviz_rt_index::impl {
function add_rt_transports (line 239) | void add_rt_transports(n::timetable const& tt,
function add_static_transports (line 266) | void add_static_transports(n::timetable const& tt,
function get_trains (line 331) | api::trips_response get_trains(tag_lookup const& tags,
type route_info (line 432) | struct route_info {
function Response (line 442) | Response build_routes_response(
function get_routes (line 632) | api::routes_response get_routes(tag_lookup const& tags,
function get_route_details (line 678) | api::routeDetails_response get_route_details(
FILE: src/route_shapes.cc
type motis (line 44) | namespace motis {
function to_string_view (line 46) | std::string_view to_string_view(cista::byte_buf const& data) {
type shape_cache_payload (line 50) | struct shape_cache_payload {
function get_profile (line 127) | std::optional<osr::search_profile> get_profile(n::clasz const clasz) {
type route_shape_result (line 146) | struct route_shape_result {
function route_shape_result (line 158) | route_shape_result route_shape(
function route_shape_debug (line 319) | boost::json::object route_shape_debug(osr::ways const& w,
function route_shapes (line 349) | void route_shapes(osr::ways const& w,
FILE: src/rt/auser.cc
type motis (line 12) | namespace motis {
FILE: src/rt_update.cc
type motis (line 33) | namespace motis {
function update_elevators (line 35) | asio::awaitable<ptr<elevators>> update_elevators(config const& c,
function get_dump_path (line 47) | std::string get_dump_path(auto&& ep) {
type gtfs_rt_endpoint (line 66) | struct gtfs_rt_endpoint {
type auser_endpoint (line 73) | struct auser_endpoint {
function run_rt_update (line 80) | void run_rt_update(boost::asio::io_context& ioc, config const& c, data...
FILE: src/server.cc
type motis (line 27) | namespace motis {
function server (line 29) | int server(data d, config const& c, std::string_view const motis_versi...
function get_api_version (line 81) | unsigned get_api_version(boost::urls::url_view const& url) {
FILE: src/tag_lookup.cc
type motis (line 23) | namespace motis {
function split_trip_id (line 25) | trip_id<std::string_view> split_trip_id(std::string_view id) {
function split_tag_id (line 54) | std::pair<std::string_view, std::string_view> split_tag_id(std::string...
FILE: src/timetable/clasz_to_mode.cc
type motis (line 7) | namespace motis {
function to_mode (line 9) | api::ModeEnum to_mode(n::clasz const c, unsigned const api_version) {
function to_modes (line 35) | std::vector<api::ModeEnum> to_modes(nigiri::routing::clasz_mask_t cons...
FILE: src/timetable/modes_to_clasz_mask.cc
type motis (line 5) | namespace motis {
function to_clasz_mask (line 7) | n::routing::clasz_mask_t to_clasz_mask(std::vector<api::ModeEnum> cons...
FILE: src/update_rtt_td_footpaths.cc
type motis (line 19) | namespace motis {
function node_states_t (line 24) | node_states_t get_node_states(osr::ways const& w,
function get_states_at (line 60) | std::optional<std::pair<nodes_t, states_t>> get_states_at(
function get_td_footpaths (line 79) | std::vector<n::td_footpath> get_td_footpaths(
function update_rtt_td_footpaths (line 142) | void update_rtt_td_footpaths(
function update_rtt_td_footpaths (line 208) | void update_rtt_td_footpaths(osr::ways const& w,
FILE: test/combinations_test.cc
function TEST (line 26) | TEST(motis, int_state_changes) {
FILE: test/config_test.cc
function TEST (line 8) | TEST(motis, config) {
FILE: test/elevators/parse_elevator_id_osm_mapping_test.cc
function TEST (line 18) | TEST(motis, parse_elevator_id_osm_mapping) {
FILE: test/elevators/parse_fasta_test.cc
function TEST (line 54) | TEST(motis, parse_fasta) {
FILE: test/elevators/parse_siri_fm_test.cc
function TEST (line 73) | TEST(motis, parse_siri_fm) {
FILE: test/elevators/siri_fm_routing_test.cc
function TEST (line 105) | TEST(motis, siri_fm_routing) {
FILE: test/endpoints/map_routes_test.cc
function TEST (line 65) | TEST(motis, map_routes) {
FILE: test/endpoints/ojp_test.cc
function TEST (line 76) | TEST(motis, ojp_requests) {
FILE: test/endpoints/one_to_many_test.cc
function test_case_params (line 109) | test_case_params const import_test_case<test_case::FFM_one_to_many>() {
function parse_time (line 121) | std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>
function one_to_many_get (line 127) | auto one_to_many_get(data& d) {
function one_to_many_post (line 131) | auto one_to_many_post(data& d) {
function TEST (line 135) | TEST(one_to_many, get_request_forward) {
function TEST (line 208) | TEST(one_to_many, post_request_backward) {
function TEST (line 286) | TEST(one_to_many,
function TEST (line 344) | TEST(one_to_many, get_request_backward_with_wheelchair_and_short_post_tr...
function TEST (line 391) | TEST(one_to_many, oneway_get_forward_for_pre_transit_and_direct_modes) {
function TEST (line 425) | TEST(one_to_many, oneway_post_backward_for_post_transit_and_direct_modes) {
function TEST (line 461) | TEST(one_to_many, oneway_post_forward_for_post_transit_modes) {
function TEST (line 482) | TEST(one_to_many, oneway_get_backward_for_pre_transit_modes) {
function TEST (line 509) | TEST(one_to_many, transfer_time_settings_min_transfer_time) {
function TEST (line 529) | TEST(one_to_many, transfer_time_settings_additional_transfer_time) {
function TEST (line 548) | TEST(one_to_many, bug_additional_footpath_for_first_last_mile) {
function TEST (line 635) | TEST(one_to_many, pareto_sets_with_routed_transfers_and_distances) {
function TEST (line 675) | TEST(one_to_many, pareto_sets_with_multiple_entries) {
FILE: test/endpoints/siri_sx_test.cc
function TEST (line 259) | TEST(motis, trip_siri_sx_alerts) {
FILE: test/endpoints/stop_group_geocoding_test.cc
function TEST (line 56) | TEST(motis, stop_group_geocoding) {
FILE: test/endpoints/stop_times_test.cc
function TEST (line 88) | TEST(motis, stop_times) {
FILE: test/endpoints/trip_test.cc
function TEST (line 85) | TEST(motis, trip_stop_naming) {
function TEST (line 384) | TEST(motis, trip_notice_translations) {
FILE: test/flex_mode_id_test.cc
function TEST (line 7) | TEST(motis, flex_mode_id_zero) {
function TEST (line 20) | TEST(motis, flex_mode_id) {
FILE: test/gbfs_partition_test.cc
function compare_partitions (line 14) | bool compare_partitions(std::vector<std::vector<T>> const& actual,
function TEST (line 36) | TEST(motis, gbfs_partition_test) {
function TEST (line 71) | TEST(motis, gbfs_partition_empty_refinement) {
function TEST (line 80) | TEST(motis, gbfs_partition_single_element) {
function TEST (line 89) | TEST(motis, gbfs_partition_disjoint_refinements) {
FILE: test/main.cc
function main (line 16) | int main(int argc, char** argv) {
FILE: test/matching_test.cc
function TEST (line 76) | TEST(motis, get_track) {
function TEST (line 88) | TEST(motis, get_way_candidates) {
FILE: test/odm/csv_journey_test.cc
function TEST (line 18) | TEST(odm, csv_journeys_in_out) { EXPECT_EQ(csv0, to_csv(from_csv(csv0))); }
function TEST (line 25) | TEST(odm, csv_journeys_direct) {
FILE: test/odm/prima_test.cc
function tt_files (line 22) | n::loader::mem_dir tt_files() {
function TEST (line 87) | TEST(odm, prima_update) {
FILE: test/odm/td_offsets_test.cc
type motis::odm (line 10) | namespace motis::odm {
function print (line 12) | void print(td_offsets_t const& tdos) {
function TEST (line 23) | TEST(odm, get_td_offsets_basic) {
function TEST (line 49) | TEST(odm, get_td_offsets_extension) {
function TEST (line 82) | TEST(odm, get_td_offsets_extension_reverse) {
function TEST (line 115) | TEST(odm, get_td_offsets_extension_fill_gap) {
function TEST (line 148) | TEST(odm, get_td_offsets_intermittent) {
function TEST (line 201) | TEST(odm, get_td_offsets_long_short_long) {
function TEST (line 246) | TEST(odm, get_td_offsets_late_improvement) {
function TEST (line 297) | TEST(odm, get_td_offsets_late_worse) {
FILE: test/read_test.cc
function TEST (line 11) | TEST(motis, parse_location_with_level) {
function TEST (line 17) | TEST(motis, parse_location_no_level) {
function TEST (line 23) | TEST(motis, parse_cursor_earlier) {
function TEST (line 34) | TEST(motis, parse_cursor_later) {
FILE: test/routing_shrink_results_test.cc
function TEST (line 11) | TEST(motis, shrink) {
FILE: test/routing_slow_direct_test.cc
function TEST (line 63) | TEST(motis, routing_slow_direct) {
FILE: test/routing_test.cc
function print_short (line 193) | void print_short(std::ostream& out, api::Itinerary const& j) {
function to_str (line 263) | std::string to_str(std::vector<api::Itinerary> const& x) {
function TEST (line 271) | TEST(motis, routing_osm_only_direct_walk) {
function TEST (line 297) | TEST(motis, routing) {
FILE: test/tag_lookup_test.cc
function TEST (line 61) | TEST(motis, tag_lookup) {
FILE: test/test_case.cc
function test_case_params (line 7) | test_case_params const import_test_case(config const&& c,
FILE: test/test_case.h
function test_case (line 21) | enum class test_case {
FILE: test/util.cc
type motis::test (line 5) | namespace motis::test {
function to_feed_msg (line 13) | transit_realtime::FeedMessage to_feed_msg(
FILE: test/util.h
function namespace (line 9) | namespace motis::test {
FILE: tools/try-reproduce.py
function update_timetable_config (line 23) | def update_timetable_config(path):
function cmd (line 34) | def cmd(cmd, cwd=None, verbose=False):
function get_directories (line 61) | def get_directories(path):
function try_reproduce (line 71) | def try_reproduce(id_value, verbose=False):
FILE: ui/api/openapi/types.gen.ts
type AlertCause (line 6) | type AlertCause = 'UNKNOWN_CAUSE' | 'OTHER_CAUSE' | 'TECHNICAL_PROBLEM' ...
type AlertEffect (line 11) | type AlertEffect = 'NO_SERVICE' | 'REDUCED_SERVICE' | 'SIGNIFICANT_DELAY...
type AlertSeverityLevel (line 16) | type AlertSeverityLevel = 'UNKNOWN_SEVERITY' | 'INFO' | 'WARNING' | 'SEV...
type TimeRange (line 23) | type TimeRange = {
type Alert (line 41) | type Alert = {
type Duration (line 128) | type Duration = {
type ParetoSetEntry (line 142) | type ParetoSetEntry = {
type ParetoSet (line 163) | type ParetoSet = Array<ParetoSetEntry>;
type OneToManyIntermodalResponse (line 168) | type OneToManyIntermodalResponse = {
type Area (line 188) | type Area = {
type Token (line 218) | type Token = [
type LocationType (line 226) | type LocationType = 'ADDRESS' | 'PLACE' | 'STOP';
type Mode (line 265) | type Mode = 'WALK' | 'BIKE' | 'RENTAL' | 'CAR' | 'CAR_PARKING' | 'CAR_DR...
type Match (line 270) | type Match = {
type ElevationCosts (line 353) | type ElevationCosts = 'NONE' | 'LOW' | 'HIGH';
type PedestrianProfile (line 358) | type PedestrianProfile = 'FOOT' | 'WHEELCHAIR';
type PedestrianSpeed (line 363) | type PedestrianSpeed = number;
type CyclingSpeed (line 368) | type CyclingSpeed = number;
type VertexType (line 376) | type VertexType = 'NORMAL' | 'BIKESHARE' | 'TRANSIT';
type PickupDropoffType (line 383) | type PickupDropoffType = 'NORMAL' | 'NOT_ALLOWED';
type Place (line 385) | type Place = {
type ReachablePlace (line 490) | type ReachablePlace = {
type Reachable (line 516) | type Reachable = {
type StopTime (line 530) | type StopTime = {
type TripInfo (line 606) | type TripInfo = {
type TripSegment (line 624) | type TripSegment = {
type Direction (line 663) | type Direction = 'DEPART' | 'HARD_LEFT' | 'LEFT' | 'SLIGHTLY_LEFT' | 'CO...
type EncodedPolyline (line 665) | type EncodedPolyline = {
type StepInstruction (line 682) | type StepInstruction = {
type RentalFormFactor (line 744) | type RentalFormFactor = 'BICYCLE' | 'CARGO_BICYCLE' | 'CAR' | 'MOPED' | ...
type RentalPropulsionType (line 746) | type RentalPropulsionType = 'HUMAN' | 'ELECTRIC_ASSIST' | 'ELECTRIC' | '...
type RentalReturnConstraint (line 748) | type RentalReturnConstraint = 'NONE' | 'ANY_STATION' | 'ROUNDTRIP_STATION';
type Rental (line 753) | type Rental = {
type MultiPolygon (line 817) | type MultiPolygon = Array<Array<EncodedPolyline>>;
type RentalZoneRestrictions (line 819) | type RentalZoneRestrictions = {
type RentalVehicleType (line 845) | type RentalVehicleType = {
type RentalProvider (line 863) | type RentalProvider = {
type RentalProviderGroup (line 914) | type RentalProviderGroup = {
type RentalStation (line 939) | type RentalStation = {
type RentalVehicle (line 1026) | type RentalVehicle = {
type RentalZone (line 1084) | type RentalZone = {
type Category (line 1121) | type Category = {
type Leg (line 1127) | type Leg = {
type RiderCategory (line 1272) | type RiderCategory = {
type FareMediaType (line 1295) | type FareMediaType = 'NONE' | 'PAPER_TICKET' | 'TRANSIT_CARD' | 'CONTACT...
type FareMedia (line 1297) | type FareMedia = {
type FareProduct (line 1308) | type FareProduct = {
type FareTransferRule (line 1325) | type FareTransferRule = 'A_AB' | 'A_AB_B' | 'AB';
type FareTransfer (line 1346) | type FareTransfer = {
type Itinerary (line 1361) | type Itinerary = {
type Transfer (line 1391) | type Transfer = {
type OneToManyParams (line 1437) | type OneToManyParams = {
type OneToManyIntermodalParams (line 1495) | type OneToManyIntermodalParams = {
type ServerConfig (line 1720) | type ServerConfig = {
type Error (line 1760) | type Error = {
type RouteSegment (line 1770) | type RouteSegment = {
type RoutePolyline (line 1788) | type RoutePolyline = {
type RouteColor (line 1800) | type RouteColor = {
type RoutePathSource (line 1805) | type RoutePathSource = 'NONE' | 'TIMETABLE' | 'ROUTED';
type TransitRouteInfo (line 1807) | type TransitRouteInfo = {
type RouteInfo (line 1815) | type RouteInfo = {
type PlanData (line 1833) | type PlanData = {
type PlanResponse (line 2379) | type PlanResponse = ({
type PlanError (line 2419) | type PlanError = (Error);
type OneToManyData (line 2421) | type OneToManyData = {
type OneToManyResponse (line 2482) | type OneToManyResponse = (Array<Duration>);
type OneToManyError (line 2484) | type OneToManyError = (Error);
type OneToManyPostData (line 2486) | type OneToManyPostData = {
type OneToManyPostResponse (line 2490) | type OneToManyPostResponse = (Array<Duration>);
type OneToManyPostError (line 2492) | type OneToManyPostError = (Error);
type OneToManyIntermodalData (line 2494) | type OneToManyIntermodalData = {
type OneToManyIntermodalResponse2 (line 2707) | type OneToManyIntermodalResponse2 = (OneToManyIntermodalResponse);
type OneToManyIntermodalError (line 2709) | type OneToManyIntermodalError = (Error);
type OneToManyIntermodalPostData (line 2711) | type OneToManyIntermodalPostData = {
type OneToManyIntermodalPostResponse (line 2715) | type OneToManyIntermodalPostResponse = (OneToManyIntermodalResponse);
type OneToManyIntermodalPostError (line 2717) | type OneToManyIntermodalPostError = (Error);
type OneToAllData (line 2719) | type OneToAllData = {
type OneToAllResponse (line 2905) | type OneToAllResponse = (Reachable);
type OneToAllError (line 2907) | type OneToAllError = (Error);
type ReverseGeocodeData (line 2909) | type ReverseGeocodeData = {
type ReverseGeocodeResponse (line 2926) | type ReverseGeocodeResponse = (Array<Match>);
type ReverseGeocodeError (line 2928) | type ReverseGeocodeError = (Error);
type GeocodeData (line 2930) | type GeocodeData = {
type GeocodeResponse (line 2971) | type GeocodeResponse = (Array<Match>);
type GeocodeError (line 2973) | type GeocodeError = (Error);
type TripData (line 2975) | type TripData = {
type TripResponse (line 3011) | type TripResponse = (Itinerary);
type TripError (line 3013) | type TripError = (Error);
type StoptimesData (line 3015) | type StoptimesData = {
type StoptimesResponse (line 3127) | type StoptimesResponse = ({
type StoptimesError (line 3150) | type StoptimesError = (Error);
type TripsData (line 3152) | type TripsData = {
type TripsResponse (line 3187) | type TripsResponse = (Array<TripSegment>);
type TripsError (line 3189) | type TripsError = (Error);
type InitialResponse (line 3191) | type InitialResponse = ({
type InitialError (line 3207) | type InitialError = (Error);
type StopsData (line 3209) | type StopsData = {
type StopsResponse (line 3228) | type StopsResponse = (Array<Place>);
type StopsError (line 3230) | type StopsError = (Error);
type LevelsData (line 3232) | type LevelsData = {
type LevelsResponse (line 3245) | type LevelsResponse = (Array<(number)>);
type LevelsError (line 3247) | type LevelsError = (Error);
type RoutesData (line 3249) | type RoutesData = {
type RoutesResponse (line 3272) | type RoutesResponse = ({
type RoutesError (line 3284) | type RoutesError = (Error);
type RouteDetailsData (line 3286) | type RouteDetailsData = {
type RouteDetailsResponse (line 3301) | type RouteDetailsResponse = ({
type RouteDetailsError (line 3311) | type RouteDetailsError = (Error);
type RentalsData (line 3313) | type RentalsData = {
type RentalsResponse (line 3376) | type RentalsResponse = ({
type RentalsError (line 3384) | type RentalsError = (Error);
type TransfersData (line 3386) | type TransfersData = {
type TransfersResponse (line 3395) | type TransfersResponse = ({
type TransfersError (line 3417) | type TransfersError = unknown;
FILE: ui/src/app.d.ts
type PageState (line 11) | interface PageState {
FILE: ui/src/lib/Color.ts
type RGBA (line 1) | type RGBA = [number, number, number, number];
function hexToRgb (line 2) | function hexToRgb(hex: string): RGBA {
function rgbToHex (line 10) | function rgbToHex(rgba: RGBA): string {
FILE: ui/src/lib/Location.ts
constant COORD_LVL_REGEX (line 4) | const COORD_LVL_REGEX = /^([+-]?\d+(\.\d+)?)\s*,\s*([+-]?\d+(\.\d+)?)\s*...
constant COORD_REGEX (line 5) | const COORD_REGEX = /^([+-]?\d+(\.\d+)?)\s*,\s*([+-]?\d+(\.\d+)?)$/;
type Location (line 7) | type Location = {
function posToLocation (line 32) | function posToLocation(pos: maplibregl.LngLatLike, level?: number): Loca...
FILE: ui/src/lib/Modes.ts
type PrePostDirectMode (line 21) | type PrePostDirectMode = (typeof prePostDirectModes)[number];
type TransitMode (line 63) | type TransitMode = (typeof possibleTransitModes)[number];
FILE: ui/src/lib/Precision.ts
constant GEOCODER_PRECISION (line 1) | const GEOCODER_PRECISION: number = 50;
constant ZOOM_LEVEL_PRECISION (line 2) | const ZOOM_LEVEL_PRECISION: Array<number> = [
FILE: ui/src/lib/constants.ts
constant LEVEL_MIN_ZOOM (line 1) | const LEVEL_MIN_ZOOM = 17;
FILE: ui/src/lib/i18n/translation.ts
type Translations (line 9) | type Translations = {
FILE: ui/src/lib/lngLatToStr.ts
function lngLatToStr (line 3) | function lngLatToStr(pos: maplibregl.LngLatLike) {
FILE: ui/src/lib/map/IsochronesShapeWorker.ts
type LngLat (line 11) | type LngLat = {
type LngLatBounds (line 15) | type LngLatBounds = {
type UpdateMessage (line 19) | type UpdateMessage =
type ShapeMessage (line 23) | type ShapeMessage = { method: 'update-shape'; index: number } & UpdateMe...
type RectType (line 24) | type RectType = { rect: LngLatBounds; distance: number; data: Isochrones...
type CircleType (line 25) | type CircleType = ReturnType<typeof circle>;
function resetState (line 55) | function resetState(index: number) {
function getMaxDistanceFunction (line 65) | function getMaxDistanceFunction(kilometersPerSecond: number, maxSeconds:...
function createShapes (line 69) | async function createShapes() {
function createRects (line 145) | async function createRects() {
function contains (line 168) | function contains(larger: RectType, smaller: RectType): boolean {
function filterNotContainedRects (line 179) | async function filterNotContainedRects(allRects: RectType[]) {
function createCircles (line 191) | async function createCircles() {
function createUnion (line 212) | async function createUnion() {
FILE: ui/src/lib/map/IsochronesShared.ts
type DisplayLevel (line 4) | type DisplayLevel = (typeof DisplayLevels)[number];
type StatusLevel (line 5) | type StatusLevel = 'WORKING' | 'DONE' | 'EMPTY' | 'FAILED';
type Geometry (line 6) | type Geometry = Feature<Polygon | MultiPolygon, GeoJsonProperties>;
type IsochronesOptions (line 8) | interface IsochronesOptions {
type IsochronesPos (line 16) | interface IsochronesPos {
FILE: ui/src/lib/map/IsochronesWorker.ts
type WorkerMessage (line 8) | type WorkerMessage = {
type CircleType (line 14) | type CircleType = ReturnType<typeof circle>;
function getTransformer (line 80) | function getTransformer(boundingBox: LngLatBounds, dimensions: [number, ...
function getIsVisible (line 92) | function getIsVisible(boundingBox: LngLatBounds) {
function drawRects (line 107) | function drawRects(ctx: OffscreenCanvasRenderingContext2D, transform: (p...
function drawCircles (line 124) | function drawCircles(
function createWorker (line 165) | function createWorker() {
FILE: ui/src/lib/map/colors.ts
function getDecorativeColors (line 3) | function getDecorativeColors(baseColor: string) {
FILE: ui/src/lib/map/createTripIcon.ts
function createTripIcon (line 3) | function createTripIcon(size: number): HTMLCanvasElement | undefined {
FILE: ui/src/lib/map/rentals/assets.ts
type FormFactorAssets (line 17) | type FormFactorAssets = {
type IconDimensions (line 25) | type IconDimensions = {
type MapLibreImageSource (line 30) | type MapLibreImageSource = ImageBitmap | HTMLImageElement;
constant DEFAULT_FORM_FACTOR (line 32) | const DEFAULT_FORM_FACTOR: RentalFormFactor = 'BICYCLE';
constant ICON_TYPES (line 34) | const ICON_TYPES = ['station', 'vehicle', 'cluster'] as const;
type IconType (line 35) | type IconType = (typeof ICON_TYPES)[number];
constant ICON_BASE_PATH (line 37) | const ICON_BASE_PATH = 'icons/rental/';
function colorizeIcon (line 128) | async function colorizeIcon(
FILE: ui/src/lib/map/rentals/style.ts
constant DEFAULT_COLOR (line 31) | const DEFAULT_COLOR = '#2563eb';
constant DEFAULT_CONTRAST_COLOR (line 32) | const DEFAULT_CONTRAST_COLOR = '#ffffff';
FILE: ui/src/lib/map/rentals/zone-fill-layer.ts
type GLContext (line 9) | type GLContext = WebGLRenderingContext | WebGL2RenderingContext;
constant DEFAULT_OPACITY (line 11) | const DEFAULT_OPACITY = 0.4;
constant STRIPE_WIDTH_PX (line 12) | const STRIPE_WIDTH_PX = 6.0;
constant STRIPE_OPACITY_VARIATION (line 13) | const STRIPE_OPACITY_VARIATION = 0.1;
constant POSITION_COMPONENTS (line 14) | const POSITION_COMPONENTS = 2;
constant POSITION_STRIDE_BYTES (line 15) | const POSITION_STRIDE_BYTES = POSITION_COMPONENTS * Float32Array.BYTES_P...
constant COLOR_COMPONENTS (line 16) | const COLOR_COMPONENTS = 4;
constant COLOR_STRIDE_BYTES (line 17) | const COLOR_STRIDE_BYTES = COLOR_COMPONENTS * Float32Array.BYTES_PER_ELE...
constant FILL_VERTEX_SHADER_SOURCE (line 19) | const FILL_VERTEX_SHADER_SOURCE = `#version 300 es
constant FILL_FRAGMENT_SHADER_SOURCE (line 33) | const FILL_FRAGMENT_SHADER_SOURCE = `#version 300 es
type ZoneGeometry (line 42) | type ZoneGeometry = {
type FillProgramState (line 50) | type FillProgramState = {
type ZoneFillLayerOptions (line 59) | type ZoneFillLayerOptions = {
constant QUAD_VERTICES (line 64) | const QUAD_VERTICES = new Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1...
constant SCREEN_VERTEX_SHADER_SOURCE (line 66) | const SCREEN_VERTEX_SHADER_SOURCE = `
constant SCREEN_FRAGMENT_SHADER_SOURCE (line 76) | const SCREEN_FRAGMENT_SHADER_SOURCE = `
constant ZONE_COLOR_ALLOWED (line 95) | const ZONE_COLOR_ALLOWED = new Float32Array([0.13333333, 0.77254902, 0.3...
constant ZONE_COLOR_FORBIDDEN (line 96) | const ZONE_COLOR_FORBIDDEN = new Float32Array([0.9372549, 0.26666667, 0....
constant ZONE_COLOR_RESTRICTED (line 97) | const ZONE_COLOR_RESTRICTED = new Float32Array([1, 0.84313725, 0, 1]);
constant ZONE_COLOR_STATION (line 98) | const ZONE_COLOR_STATION = new Float32Array([0.25882354, 0.52156866, 0.9...
type ZoneClipFrame (line 126) | type ZoneClipFrame = {
constant WEB_MERCATOR_MAX_LATITUDE (line 176) | const WEB_MERCATOR_MAX_LATITUDE = 85.051129;
class ZoneFillLayer (line 184) | class ZoneFillLayer implements maplibregl.CustomLayerInterface {
method constructor (line 221) | constructor(options: ZoneFillLayerOptions) {
method setOpacity (line 226) | setOpacity(opacity: number) {
method setFeatures (line 234) | setFeatures(features: RentalZoneFeature[]) {
method onAdd (line 241) | onAdd(map: MapLibreMap, gl: GLContext) {
method onRemove (line 248) | onRemove(_map: MapLibreMap, gl: GLContext) {
method cleanup (line 252) | cleanup(gl?: GLContext) {
method prerender (line 298) | prerender(gl: GLContext, _options: CustomRenderMethodInput) {
method render (line 419) | render(gl: GLContext, _options: CustomRenderMethodInput) {
method initialize (line 461) | private initialize(gl: GLContext) {
method ensureFramebuffer (line 494) | private ensureFramebuffer(gl: GLContext, width: number, height: number) {
method ensurePickingFramebuffer (line 531) | private ensurePickingFramebuffer(gl: GLContext, width: number, height:...
method ensureFillProgram (line 579) | private ensureFillProgram(gl: GLContext): FillProgramState | null {
method createProgram (line 602) | private createProgram(
method compileShader (line 629) | private compileShader(gl: GLContext, type: number, source: string): We...
method updateGeometry (line 644) | private updateGeometry() {
method deleteGeometryBuffers (line 752) | private deleteGeometryBuffers(gl: GLContext) {
method pickFeatureAt (line 770) | pickFeatureAt(pointLike: PointLike): RentalZoneFeature | null {
method buildZoneGeometry (line 809) | private buildZoneGeometry(feature: RentalZoneFeature): ZoneGeometry | ...
FILE: ui/src/lib/map/rentals/zone-types.ts
type RentalZoneFeatureProperties (line 3) | type RentalZoneFeatureProperties = {
type RentalZoneFeature (line 13) | type RentalZoneFeature = Feature<MultiPolygon, RentalZoneFeatureProperti...
type RentalZoneFeatureCollection (line 15) | type RentalZoneFeatureCollection = FeatureCollection<
FILE: ui/src/lib/map/shield.ts
class ShieldOptions (line 4) | class ShieldOptions {
function createShield (line 9) | function createShield(opt: ShieldOptions): [ImageData, Partial<StyleImag...
FILE: ui/src/lib/map/style.ts
function getUrlBase (line 127) | function getUrlBase(url: string): string {
function getAbsoluteUrl (line 133) | function getAbsoluteUrl(base: string, relative: string): string {
FILE: ui/src/lib/modeStyle.ts
type Colorable (line 3) | type Colorable = { routeColor?: string; routeTextColor?: string; mode: M...
type TripInfo (line 5) | type TripInfo = { tripId?: string; displayName?: string };
type RentalInfo (line 7) | type RentalInfo = { rental?: Rental };
type LegLike (line 9) | type LegLike = Colorable & TripInfo & RentalInfo;
FILE: ui/src/lib/tripsWorker.ts
constant TO_RAD (line 17) | const TO_RAD = Math.PI / 180;
constant TO_DEG (line 18) | const TO_DEG = 180 / Math.PI;
function updateState (line 215) | function updateState(data: TransferData, colorMode: string) {
FILE: ui/src/lib/types.ts
type Position (line 3) | type Position = [number, number];
type Trip (line 4) | type Trip = {
type TransferData (line 15) | type TransferData = {
type MetaData (line 21) | type MetaData = {
FILE: ui/src/lib/utils.ts
function cn (line 11) | function cn(...inputs: ClassValue[]) {
Condensed preview — 443 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,338K chars).
[
{
"path": ".clang-format",
"chars": 1965,
"preview": "BasedOnStyle: Google\nIndentWidth: 2\nLanguage: Cpp\nDerivePointerAlignment: false\nPointerAlignment: Left\nAccessModifierOff"
},
{
"path": ".clang-tidy.in",
"chars": 18116,
"preview": "Checks: \"*,\\\n-llvmlibc-*,\\\n-abseil-*,\\\n-readability-identifier-length,\\\n-altera-unroll-loops,\\\n-altera-id-dependent-back"
},
{
"path": ".github/workflows/ci.yml",
"chars": 14666,
"preview": "name: CI\n\non:\n push:\n branches: [ master ]\n pull_request:\n branches: [ master ]\n release:\n types:\n - pu"
},
{
"path": ".gitignore",
"chars": 232,
"preview": "/tiles-profiles\n/*build*\n/.pkg.mutex\n/.clang-tidy\n/.idea\n.vscode/\n.DS_Store\n/deps\n*.zip\n*.bin\n*.pbf\n*.csv\n/osr\n/delfi\n/t"
},
{
"path": ".pkg",
"chars": 2322,
"preview": "[nigiri]\n url=git@github.com:motis-project/nigiri.git\n branch=master\n commit=8b07193adf152f258ccfa207f922579d0a0e2195"
},
{
"path": "CMakeLists.txt",
"chars": 8211,
"preview": "cmake_minimum_required(VERSION 3.20)\n\nproject(motis LANGUAGES C CXX ASM)\n\nset(CMAKE_POLICY_DEFAULT_CMP0077 NEW)\n\noption("
},
{
"path": "CMakePresets.json",
"chars": 5608,
"preview": "{\n \"version\": 3,\n \"cmakeMinimumRequired\": {\n \"major\": 3,\n \"minor\": 21,\n \"patch\": 0\n },\n \"configurePresets\":"
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 5482,
"preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
},
{
"path": "Dockerfile",
"chars": 272,
"preview": "FROM alpine:3.20\nARG TARGETARCH\nADD motis-linux-$TARGETARCH/motis-linux-$TARGETARCH.tar.bz2 /\nRUN addgroup -S motis && a"
},
{
"path": "LICENSE",
"chars": 1070,
"preview": "MIT License\n\nCopyright (c) 2024 MOTIS Project\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
},
{
"path": "README.md",
"chars": 5200,
"preview": "<p align=\"center\"><img src=\"logo.svg\" width=\"196\" height=\"196\"></p>\n\n> [!TIP]\n> :sparkles: Join the international MOTIS "
},
{
"path": "cmake/buildcache.cmake",
"chars": 2801,
"preview": "option(NO_BUILDCACHE \"Disable build caching using buildcache\" Off)\n\n# PDB debug information is not supported by buildcac"
},
{
"path": "cmake/clang-tidy.cmake",
"chars": 780,
"preview": "if (CMake_SOURCE_DIR STREQUAL CMake_BINARY_DIR)\n message(FATAL_ERROR \"CMake_RUN_CLANG_TIDY requires an out-of-source "
},
{
"path": "cmake/pkg.cmake",
"chars": 2222,
"preview": "if (NOT DEFINED PROJECT_IS_TOP_LEVEL OR PROJECT_IS_TOP_LEVEL)\n find_program(pkg-bin pkg HINTS /opt/pkg)\n if (pkg-b"
},
{
"path": "docs/STYLE.md",
"chars": 11895,
"preview": "# MOTIS C++ Style\n\n# Preamble\n\nBeware that these rules only apply to MOTIS C++ and are very opinionated.\nC++ has a big d"
},
{
"path": "docs/dev-setup-server.md",
"chars": 1298,
"preview": "# Setting up a server from a development build\n\n1. Build `motis`. Refer to the respective documentation if necessary:\n "
},
{
"path": "docs/elevation-setup.md",
"chars": 3694,
"preview": "# Setting up elevation tiles\n\nThis page explains how to set up elevation tiles, that are required for elevation profiles"
},
{
"path": "docs/linux-dev-setup.md",
"chars": 1816,
"preview": "> [!NOTE] \n> Due to developer capacity constraints we cannot support newer or older compilers.\n> We also cannot support"
},
{
"path": "docs/macos-dev-setup.md",
"chars": 1023,
"preview": "Requirements:\n\n- macOS 10.15 or newer\n- Command Line Tools for Xcode or Xcode: `xcode-select --install` or [manual downl"
},
{
"path": "docs/python-client.md",
"chars": 527,
"preview": "# Python client for MOTIS\n\n## Install dependencies\n```sh\npip install openapi-python-client\n```\n\n## Generate Python code "
},
{
"path": "docs/scripting.md",
"chars": 9494,
"preview": "# User Scripts\n\nMOTIS can post-process GTFS static timetable data using [Lua](https://www.lua.org/) scripts. The main pu"
},
{
"path": "docs/setup.md",
"chars": 17723,
"preview": "# Advanced Configuration\n\nThis is an example of how to use multiple GTFS-static datasets with multiple real-time feeds, "
},
{
"path": "docs/windows-dev-setup.md",
"chars": 1542,
"preview": "In the following, we list requirements and a download link. There may be other sources (like package managers) to instal"
},
{
"path": "exe/batch.cc",
"chars": 7708,
"preview": "#include <fstream>\n#include <iostream>\n\n#include \"conf/configuration.h\"\n\n#include \"utl/init_from.h\"\n#include \"utl/parall"
},
{
"path": "exe/compare.cc",
"chars": 6416,
"preview": "#include <fstream>\n#include <iostream>\n#include <ranges>\n#include <string>\n#include <vector>\n\n#include \"conf/configurati"
},
{
"path": "exe/extract.cc",
"chars": 14325,
"preview": "#include <filesystem>\n#include <iterator>\n\n#include \"boost/json.hpp\"\n#include \"boost/program_options.hpp\"\n\n#include \"fmt"
},
{
"path": "exe/flags.h",
"chars": 2671,
"preview": "#pragma once\n\n#include <filesystem>\n#include <string>\n#include <vector>\n\n#include \"boost/program_options.hpp\"\n\nnamespace"
},
{
"path": "exe/generate.cc",
"chars": 11744,
"preview": "#include <fstream>\n#include <iostream>\n#include <mutex>\n\n#include \"conf/configuration.h\"\n\n#include \"boost/url/url.hpp\"\n\n"
},
{
"path": "exe/main.cc",
"chars": 9730,
"preview": "#include <cctype>\n#include <filesystem>\n#include <iostream>\n#include <string>\n#include <string_view>\n\n#include \"boost/pr"
},
{
"path": "exe/params.cc",
"chars": 1162,
"preview": "#include <fstream>\n#include <iostream>\n\n#include \"boost/url/url.hpp\"\n\n#include \"utl/file_utils.h\"\n#include \"utl/parser/c"
},
{
"path": "include/motis/adr_extend_tt.h",
"chars": 1005,
"preview": "#pragma once\n\n#include \"date/tz.h\"\n\n#include \"nigiri/routing/clasz_mask.h\"\n#include \"nigiri/types.h\"\n\n#include \"motis/fw"
},
{
"path": "include/motis/analyze_shapes.h",
"chars": 180,
"preview": "#include <string>\n#include <vector>\n\n#include \"motis/data.h\"\n\nnamespace motis {\n\nbool analyze_shapes(data const&, std::v"
},
{
"path": "include/motis/box_rtree.h",
"chars": 3611,
"preview": "#pragma once\n\n#include <algorithm>\n#include <array>\n\n#include \"cista/strong.h\"\n\n#include \"rtree.h\"\n\n#include \"geo/box.h\""
},
{
"path": "include/motis/clog_redirect.h",
"chars": 719,
"preview": "#pragma once\n\n#include <fstream>\n#include <memory>\n#include <mutex>\n#include <streambuf>\n\nnamespace motis {\n\nstruct clog"
},
{
"path": "include/motis/compute_footpaths.h",
"chars": 872,
"preview": "#pragma once\n\n#include \"cista/memory_holder.h\"\n\n#include \"osr/routing/profile.h\"\n#include \"osr/types.h\"\n\n#include \"motis"
},
{
"path": "include/motis/config.h",
"chars": 8459,
"preview": "#pragma once\n\n#include <filesystem>\n#include <functional>\n#include <iosfwd>\n#include <map>\n#include <optional>\n#include "
},
{
"path": "include/motis/constants.h",
"chars": 831,
"preview": "#pragma once\n\nnamespace motis {\n\n// search radius for neighbors to route to [meters]\nconstexpr auto const kMaxDistance ="
},
{
"path": "include/motis/ctx_data.h",
"chars": 189,
"preview": "#pragma once\n\n#include \"ctx/op_id.h\"\n#include \"ctx/operation.h\"\n\nnamespace motis {\n\nstruct ctx_data {\n void transition("
},
{
"path": "include/motis/ctx_exec.h",
"chars": 1388,
"preview": "#pragma once\n\n#include <iostream>\n\n#include \"boost/asio/io_context.hpp\"\n#include \"boost/asio/post.hpp\"\n\n#include \"ctx/sc"
},
{
"path": "include/motis/data.h",
"chars": 3402,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"cista/memory_holder.h\"\n\n#include \"date/date.h\"\n\n#include \"nigiri/rt/vdv_aus.h"
},
{
"path": "include/motis/direct_filter.h",
"chars": 267,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"nigiri/routing/journey.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnamespace motis "
},
{
"path": "include/motis/elevators/elevators.h",
"chars": 551,
"preview": "#pragma once\n\n#include \"motis/elevators/match_elevator.h\"\n#include \"motis/elevators/parse_elevator_id_osm_mapping.h\"\n#in"
},
{
"path": "include/motis/elevators/get_state_changes.h",
"chars": 2657,
"preview": "#pragma once\n\n#include <ranges>\n#include <vector>\n\n#include \"fmt/ranges.h\"\n\n#include \"nigiri/common/interval.h\"\n\n#includ"
},
{
"path": "include/motis/elevators/match_elevator.h",
"chars": 873,
"preview": "#pragma once\n\n#include \"osr/types.h\"\n\n#include \"motis/elevators/parse_elevator_id_osm_mapping.h\"\n#include \"motis/fwd.h\"\n"
},
{
"path": "include/motis/elevators/parse_elevator_id_osm_mapping.h",
"chars": 389,
"preview": "#pragma once\n\n#include <cinttypes>\n#include <filesystem>\n#include <string_view>\n\n#include \"motis/types.h\"\n\nnamespace mot"
},
{
"path": "include/motis/elevators/parse_fasta.h",
"chars": 414,
"preview": "#pragma once\n\n#include <filesystem>\n#include <string_view>\n\n#include \"boost/json/object.hpp\"\n\n#include \"motis/types.h\"\n\n"
},
{
"path": "include/motis/elevators/parse_siri_fm.h",
"chars": 285,
"preview": "#pragma once\n\n#include <filesystem>\n#include <string_view>\n\n#include \"motis/types.h\"\n\nnamespace motis {\n\nvector_map<elev"
},
{
"path": "include/motis/elevators/update_elevators.h",
"chars": 417,
"preview": "#pragma once\n\n#include <memory>\n#include <string_view>\n\n#include \"motis/elevators/elevators.h\"\n#include \"motis/fwd.h\"\n\nn"
},
{
"path": "include/motis/endpoints/adr/filter_conv.h",
"chars": 203,
"preview": "#pragma once\n\n#include \"adr/types.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnamespace motis {\n\nadr::filter_type to_filter_ty"
},
{
"path": "include/motis/endpoints/adr/geocode.h",
"chars": 526,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/adr/reverse_geocode.h",
"chars": 552,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/adr/suggestions_to_response.h",
"chars": 631,
"preview": "#pragma once\n\n#include \"adr/adr.h\"\n#include \"adr/types.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#incl"
},
{
"path": "include/motis/endpoints/elevators.h",
"chars": 357,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"nigiri/types.h\"\n\n#include \"motis/elevators/elevators.h\"\n#includ"
},
{
"path": "include/motis/endpoints/graph.h",
"chars": 253,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"motis/fwd.h\"\n\nnamespace motis::ep {\n\nstruct graph {\n boost::js"
},
{
"path": "include/motis/endpoints/gtfsrt.h",
"chars": 331,
"preview": "#pragma once\n\n#include \"net/web_server/query_router.h\"\n\n#include \"motis/fwd.h\"\n\nnamespace motis::ep {\n\nstruct gtfsrt {\n "
},
{
"path": "include/motis/endpoints/initial.h",
"chars": 344,
"preview": "#pragma once\n\n#include \"boost/url/url.hpp\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n\nnamespace motis::ep"
},
{
"path": "include/motis/endpoints/levels.h",
"chars": 294,
"preview": "#pragma once\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/map/flex_locations.h",
"chars": 425,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n#include \"boost/url/url_view.hpp\"\n\n#include \"nigiri/types.h\"\n\n#include \"mo"
},
{
"path": "include/motis/endpoints/map/rental.h",
"chars": 375,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd"
},
{
"path": "include/motis/endpoints/map/route_details.h",
"chars": 568,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/map/routes.h",
"chars": 555,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/map/shapes_debug.h",
"chars": 373,
"preview": "#pragma once\n\n#include \"net/web_server/query_router.h\"\n\n#include \"motis/config.h\"\n#include \"motis/fwd.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/map/stops.h",
"chars": 613,
"preview": "#pragma once\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"nigiri/types.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"m"
},
{
"path": "include/motis/endpoints/map/trips.h",
"chars": 552,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms.h\"\n\nnamespace moti"
},
{
"path": "include/motis/endpoints/matches.h",
"chars": 458,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"nigiri/types.h\"\n\n#include \"motis/fwd.h\"\n#include \"motis/point_r"
},
{
"path": "include/motis/endpoints/metrics.h",
"chars": 397,
"preview": "#pragma once\n\n#include <string_view>\n\n#include \"net/web_server/query_router.h\"\n\n#include \"motis/fwd.h\"\n#include \"motis/m"
},
{
"path": "include/motis/endpoints/ojp.h",
"chars": 587,
"preview": "#pragma once\n\n#include <optional>\n\n#include \"net/web_server/query_router.h\"\n\n#include \"motis/endpoints/adr/geocode.h\"\n#i"
},
{
"path": "include/motis/endpoints/one_to_all.h",
"chars": 801,
"preview": "#pragma once\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/data.h\"\n#include \"moti"
},
{
"path": "include/motis/endpoints/one_to_many.h",
"chars": 3237,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"utl/to_vec.h\"\n\n#include \"net/bad_request_e"
},
{
"path": "include/motis/endpoints/one_to_many_post.h",
"chars": 1155,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"nigiri/types.h\"\n\n#include \"motis-api/motis-api.h\"\n\n#include \"motis/data.h\"\n#i"
},
{
"path": "include/motis/endpoints/osr_routing.h",
"chars": 332,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"motis/elevators/elevators.h\"\n#include \"motis/fwd.h\"\n\nnamespace "
},
{
"path": "include/motis/endpoints/platforms.h",
"chars": 286,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"motis/fwd.h\"\n\nnamespace motis::ep {\n\nstruct platforms {\n boost"
},
{
"path": "include/motis/endpoints/routing.h",
"chars": 4732,
"preview": "#pragma once\n\n#include <chrono>\n#include <optional>\n#include <utility>\n#include <vector>\n\n#include \"boost/thread/tss.hpp"
},
{
"path": "include/motis/endpoints/stop_times.h",
"chars": 670,
"preview": "#pragma once\n\n#include \"nigiri/types.h\"\n\n#include \"osr/types.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\""
},
{
"path": "include/motis/endpoints/tiles.h",
"chars": 239,
"preview": "#pragma once\n\n#include \"net/web_server/query_router.h\"\n\n#include \"motis/fwd.h\"\n\nnamespace motis::ep {\n\nstruct tiles {\n "
},
{
"path": "include/motis/endpoints/transfers.h",
"chars": 672,
"preview": "#pragma once\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"nigiri/types.h\"\n\n#include \"osr/types.h\"\n\n#include \"motis-api/"
},
{
"path": "include/motis/endpoints/trip.h",
"chars": 687,
"preview": "#pragma once\n\n#include \"boost/url/url_view.hpp\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/elevators/elevators.h\""
},
{
"path": "include/motis/endpoints/update_elevator.h",
"chars": 739,
"preview": "#pragma once\n\n#include \"boost/json/value.hpp\"\n\n#include \"utl/init_from.h\"\n\n#include \"nigiri/types.h\"\n\n#include \"osr/type"
},
{
"path": "include/motis/flex/flex.h",
"chars": 2489,
"preview": "#pragma once\n\n#include \"osr/location.h\"\n#include \"osr/routing/profile.h\"\n#include \"osr/types.h\"\n\n#include \"nigiri/routin"
},
{
"path": "include/motis/flex/flex_areas.h",
"chars": 759,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"tg.h\"\n\n#include \"osr/types.h\"\n\n#include \"nigiri/types.h\"\n\n#include \"motis/fwd"
},
{
"path": "include/motis/flex/flex_output.h",
"chars": 1837,
"preview": "#pragma once\n\n#include \"motis/flex/flex_routing_data.h\"\n#include \"motis/flex/mode_id.h\"\n#include \"motis/osr/street_routi"
},
{
"path": "include/motis/flex/flex_routing_data.h",
"chars": 1196,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"osr/routing/additional_edge.h\"\n#include \"osr/routing/sharing_data.h\"\n#include"
},
{
"path": "include/motis/flex/mode_id.h",
"chars": 1382,
"preview": "#pragma once\n\n#include \"osr/types.h\"\n\n#include \"nigiri/types.h\"\n\nnamespace motis::flex {\n\nstruct mode_id {\n mode_id(nig"
},
{
"path": "include/motis/fwd.h",
"chars": 1079,
"preview": "#pragma once\n\nnamespace adr {\nstruct formatter;\nstruct reverse;\nstruct area_database;\nstruct typeahead;\nstruct cache;\n} "
},
{
"path": "include/motis/gbfs/compression.h",
"chars": 2214,
"preview": "#pragma once\n\n#include <cstdint>\n#include <cstdlib>\n#include <memory>\n\n#include \"cista/containers/bitvec.h\"\n\n#include \"u"
},
{
"path": "include/motis/gbfs/data.h",
"chars": 13781,
"preview": "#pragma once\n\n#include <algorithm>\n#include <chrono>\n#include <compare>\n#include <cstdint>\n#include <filesystem>\n#includ"
},
{
"path": "include/motis/gbfs/gbfs_output.h",
"chars": 1342,
"preview": "#pragma once\n\n#include \"motis/osr/street_routing.h\"\n\nnamespace motis::gbfs {\n\nstruct gbfs_output final : public output {"
},
{
"path": "include/motis/gbfs/geofencing.h",
"chars": 409,
"preview": "#pragma once\n\n#include <string>\n#include <vector>\n\n#include \"tg.h\"\n\n#include \"geo/latlng.h\"\n\n#include \"motis/gbfs/data.h"
},
{
"path": "include/motis/gbfs/lru_cache.h",
"chars": 5370,
"preview": "#pragma once\n\n#include <future>\n#include <memory>\n#include <mutex>\n#include <shared_mutex>\n#include <vector>\n\n#include \""
},
{
"path": "include/motis/gbfs/mode.h",
"chars": 762,
"preview": "#pragma once\n\n#include <optional>\n#include <vector>\n\n#include \"motis/gbfs/data.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnam"
},
{
"path": "include/motis/gbfs/osr_mapping.h",
"chars": 286,
"preview": "#pragma once\n\n#include \"motis/fwd.h\"\n\nnamespace motis::gbfs {\n\nstruct gbfs_provider;\nstruct provider_routing_data;\n\nvoid"
},
{
"path": "include/motis/gbfs/osr_profile.h",
"chars": 197,
"preview": "#pragma once\n\n#include \"osr/routing/profile.h\"\n\n#include \"motis/gbfs/data.h\"\n\nnamespace motis::gbfs {\n\nosr::search_profi"
},
{
"path": "include/motis/gbfs/parser.h",
"chars": 792,
"preview": "#pragma once\n\n#include <string>\n\n#include \"boost/json.hpp\"\n\n#include \"motis/gbfs/data.h\"\n#include \"motis/types.h\"\n\nnames"
},
{
"path": "include/motis/gbfs/partition.h",
"chars": 3545,
"preview": "#pragma once\n\n#include <cassert>\n#include <cstdint>\n#include <span>\n#include <vector>\n\n#include \"cista/strong.h\"\n\nnamesp"
},
{
"path": "include/motis/gbfs/routing_data.h",
"chars": 1578,
"preview": "#pragma once\n\n#include <cstdint>\n#include <memory>\n\n#include \"motis/fwd.h\"\n#include \"motis/gbfs/data.h\"\n#include \"motis/"
},
{
"path": "include/motis/gbfs/update.h",
"chars": 627,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"boost/asio/awaitable.hpp\"\n#include \"boost/asio/io_context.hpp\"\n\n#include \"mot"
},
{
"path": "include/motis/get_loc.h",
"chars": 917,
"preview": "#pragma once\n\n#include \"osr/platforms.h\"\n#include \"osr/routing/route.h\"\n\n#include \"nigiri/timetable.h\"\n\n#include \"motis/"
},
{
"path": "include/motis/get_stops_with_traffic.h",
"chars": 453,
"preview": "#pragma once\n\n#include \"nigiri/types.h\"\n\n#include \"motis/fwd.h\"\n#include \"motis/point_rtree.h\"\n\nnamespace motis {\n\nstd::"
},
{
"path": "include/motis/hashes.h",
"chars": 1366,
"preview": "#pragma once\n\n#include <filesystem>\n#include <map>\n#include <string>\n#include <utility>\n\nnamespace motis {\n\nusing meta_e"
},
{
"path": "include/motis/http_req.h",
"chars": 982,
"preview": "#pragma once\n\n#include <chrono>\n#include <map>\n#include <string>\n\n#include \"boost/asio/awaitable.hpp\"\n#include \"boost/be"
},
{
"path": "include/motis/import.h",
"chars": 263,
"preview": "#pragma once\n\n#include <filesystem>\n\n#include \"motis/config.h\"\n\nnamespace motis {\n\nvoid import(config const&,\n "
},
{
"path": "include/motis/journey_to_response.h",
"chars": 2040,
"preview": "#pragma once\n\n#include <string_view>\n#include <variant>\n\n#include \"nigiri/routing/journey.h\"\n#include \"nigiri/rt/frun.h\""
},
{
"path": "include/motis/location_routes.h",
"chars": 445,
"preview": "#pragma once\n\n#include \"nigiri/timetable.h\"\n\nnamespace motis {\n\ninline nigiri::hash_set<std::string_view> get_location_r"
},
{
"path": "include/motis/logging.h",
"chars": 179,
"preview": "#pragma once\n\n#include <string>\n\n#include \"motis/config.h\"\n\nnamespace motis {\n\nint set_log_level(config const&);\n\nint se"
},
{
"path": "include/motis/match_platforms.h",
"chars": 1876,
"preview": "#pragma once\n\n#include <map>\n#include <optional>\n\n#include \"osr/lookup.h\"\n#include \"osr/types.h\"\n\n#include \"nigiri/types"
},
{
"path": "include/motis/metrics_registry.h",
"chars": 2353,
"preview": "#pragma once\n\n#include \"prometheus/counter.h\"\n#include \"prometheus/family.h\"\n#include \"prometheus/gauge.h\"\n#include \"pro"
},
{
"path": "include/motis/motis_instance.h",
"chars": 6958,
"preview": "#include <memory>\n#include <thread>\n\n#include \"boost/asio/io_context.hpp\"\n\n#include \"net/web_server/query_router.h\"\n\n#in"
},
{
"path": "include/motis/odm/bounds.h",
"chars": 349,
"preview": "#pragma once\n\n#include <filesystem>\n\n#include \"geo/latlng.h\"\n\nstruct tg_geom;\n\nnamespace motis::odm {\n\nstruct bounds {\n "
},
{
"path": "include/motis/odm/journeys.h",
"chars": 712,
"preview": "#pragma once\n\n#include \"nigiri/routing/journey.h\"\n#include \"nigiri/routing/pareto_set.h\"\n\nnamespace motis::odm {\n\nstd::v"
},
{
"path": "include/motis/odm/meta_router.h",
"chars": 4114,
"preview": "#pragma once\n\n#include <optional>\n#include <variant>\n#include <vector>\n\n#include \"osr/location.h\"\n\n#include \"nigiri/type"
},
{
"path": "include/motis/odm/odm.h",
"chars": 1094,
"preview": "#pragma once\n\n#include \"nigiri/routing/journey.h\"\n#include \"nigiri/routing/start_times.h\"\n#include \"nigiri/types.h\"\n\n#in"
},
{
"path": "include/motis/odm/prima.h",
"chars": 6166,
"preview": "#pragma once\n\n#include <chrono>\n#include <vector>\n\n#include \"geo/latlng.h\"\n\n#include \"nigiri/routing/journey.h\"\n#include"
},
{
"path": "include/motis/odm/query_factory.h",
"chars": 1920,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"nigiri/routing/query.h\"\n\nnamespace motis::odm {\n\nstruct query_factory {\n sta"
},
{
"path": "include/motis/odm/shorten.h",
"chars": 541,
"preview": "#pragma once\n\nnamespace motis::odm {\n\nvoid shorten(std::vector<nigiri::routing::journey>& odm_journeys,\n std"
},
{
"path": "include/motis/odm/td_offsets.h",
"chars": 2497,
"preview": "#pragma once\n\n#include \"nigiri/routing/query.h\"\n#include \"nigiri/routing/start_times.h\"\n#include \"nigiri/types.h\"\n\n#incl"
},
{
"path": "include/motis/osr/max_distance.h",
"chars": 176,
"preview": "#pragma once\n\n#include <chrono>\n\n#include \"osr/routing/profile.h\"\n\nnamespace motis {\n\ndouble get_max_distance(osr::searc"
},
{
"path": "include/motis/osr/mode_to_profile.h",
"chars": 349,
"preview": "#pragma once\n\n#include \"osr/routing/mode.h\"\n#include \"osr/routing/profile.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnamespac"
},
{
"path": "include/motis/osr/parameters.h",
"chars": 1010,
"preview": "#pragma once\n\n#include \"osr/routing/parameters.h\"\n#include \"osr/routing/profile.h\"\n\n#include \"motis-api/motis-api.h\"\n\nna"
},
{
"path": "include/motis/osr/street_routing.h",
"chars": 3662,
"preview": "#pragma once\n\n#include <optional>\n\n#include \"osr/location.h\"\n#include \"osr/routing/profile.h\"\n#include \"osr/routing/rout"
},
{
"path": "include/motis/parse_location.h",
"chars": 530,
"preview": "#pragma once\n\n#include <optional>\n#include <string>\n#include <string_view>\n\n#include \"osr/routing/route.h\"\n\n#include \"ni"
},
{
"path": "include/motis/place.h",
"chars": 2603,
"preview": "#pragma once\n\n#include \"osr/location.h\"\n\n#include \"nigiri/types.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd"
},
{
"path": "include/motis/point_rtree.h",
"chars": 2910,
"preview": "#pragma once\n\n#include <array>\n\n#include \"cista/strong.h\"\n\n#include \"rtree.h\"\n\n#include \"geo/box.h\"\n#include \"geo/latlng"
},
{
"path": "include/motis/polyline.h",
"chars": 256,
"preview": "#pragma once\n\n#include \"geo/polyline.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnamespace motis {\n\ntemplate <std::int64_t Pre"
},
{
"path": "include/motis/railviz.h",
"chars": 2908,
"preview": "#pragma once\n\n#include <memory>\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/fwd.h\"\n#include \"motis/match_platforms"
},
{
"path": "include/motis/route_shapes.h",
"chars": 1939,
"preview": "#pragma once\n\n#include <chrono>\n#include <filesystem>\n#include <optional>\n\n#include \"boost/json/fwd.hpp\"\n\n#include \"cist"
},
{
"path": "include/motis/rt/auser.h",
"chars": 592,
"preview": "#pragma once\n\n#include <string>\n\n#include \"nigiri/rt/vdv_aus.h\"\n\nnamespace motis {\n\nstruct auser {\n auser(nigiri::timet"
},
{
"path": "include/motis/rt/rt_metrics.h",
"chars": 23764,
"preview": "#pragma once\n\n#include \"prometheus/counter.h\"\n#include \"prometheus/family.h\"\n#include \"prometheus/gauge.h\"\n\n#include \"mo"
},
{
"path": "include/motis/rt_update.h",
"chars": 202,
"preview": "#pragma once\n\n#include <chrono>\n#include <memory>\n\n#include \"boost/asio/io_context.hpp\"\n\n#include \"motis/fwd.h\"\n\nnamespa"
},
{
"path": "include/motis/server.h",
"chars": 255,
"preview": "#pragma once\n\n#include <string_view>\n\n#include \"boost/url/url_view.hpp\"\n\nnamespace motis {\n\nstruct data;\nstruct config;\n"
},
{
"path": "include/motis/tag_lookup.h",
"chars": 1822,
"preview": "#pragma once\n\n#include <filesystem>\n#include <string>\n#include <string_view>\n\n#include \"cista/memory_holder.h\"\n\n#include"
},
{
"path": "include/motis/tiles_data.h",
"chars": 554,
"preview": "#pragma once\n\n#include <string>\n\n#include \"tiles/db/tile_database.h\"\n#include \"tiles/get_tile.h\"\n\nnamespace motis {\n\nstr"
},
{
"path": "include/motis/timetable/clasz_to_mode.h",
"chars": 342,
"preview": "#pragma once\n\n#include \"nigiri/routing/clasz_mask.h\"\n#include \"nigiri/types.h\"\n\n#include \"motis-api/motis-api.h\"\n\nnamesp"
},
{
"path": "include/motis/timetable/modes_to_clasz_mask.h",
"chars": 189,
"preview": "#pragma once\n\n#include \"motis-api/motis-api.h\"\n\n#include \"nigiri/routing/clasz_mask.h\"\n\nnamespace motis {\n\nnigiri::routi"
},
{
"path": "include/motis/timetable/time_conv.h",
"chars": 551,
"preview": "#pragma once\n\n#include <chrono>\n#include <cinttypes>\n\n#include \"nigiri/types.h\"\n\nnamespace motis {\n\ninline std::int64_t "
},
{
"path": "include/motis/transport_mode_ids.h",
"chars": 564,
"preview": "#pragma once\n\n#include \"osr/routing/profile.h\"\n\n#include \"nigiri/types.h\"\n\nnamespace motis {\n\nconstexpr auto const kOdmT"
},
{
"path": "include/motis/tt_location_rtree.h",
"chars": 473,
"preview": "#pragma once\n\n#include \"nigiri/special_stations.h\"\n#include \"nigiri/timetable.h\"\n\n#include \"motis/point_rtree.h\"\n\nnamesp"
},
{
"path": "include/motis/types.h",
"chars": 1551,
"preview": "#pragma once\n\n#include <cinttypes>\n#include <memory>\n#include <optional>\n#include <vector>\n\n#include \"geo/latlng.h\"\n\n#in"
},
{
"path": "include/motis/update_rtt_td_footpaths.h",
"chars": 2548,
"preview": "#pragma once\n\n#include <vector>\n\n#include \"osr/lookup.h\"\n#include \"osr/routing/route.h\"\n\n#include \"nigiri/rt/rt_timetabl"
},
{
"path": "openapi.yaml",
"chars": 172889,
"preview": "openapi: 3.1.0\ninfo:\n title: MOTIS API\n description: |\n This is the MOTIS routing API.\n\n Overview of MOTIS API v"
},
{
"path": "src/adr_extend_tt.cc",
"chars": 16175,
"preview": "#include \"osr/geojson.h\"\n\n#include \"motis/adr_extend_tt.h\"\n\n#include \"nigiri/special_stations.h\"\n\n#include <string>\n#inc"
},
{
"path": "src/analyze_shapes.cc",
"chars": 1472,
"preview": "#include \"motis/analyze_shapes.h\"\n\n#include \"utl/verify.h\"\n\n#include \"fmt/base.h\"\n#include \"fmt/ranges.h\"\n\n#include \"nig"
},
{
"path": "src/clog_redirect.cc",
"chars": 1705,
"preview": "#include \"motis/clog_redirect.h\"\n\n#include <iostream>\n#include <mutex>\n\nnamespace motis {\n\nnamespace {\n\nstruct synchroni"
},
{
"path": "src/compute_footpaths.cc",
"chars": 8222,
"preview": "#include \"motis/compute_footpaths.h\"\n\n#include \"nigiri/loader/build_lb_graph.h\"\n\n#include \"cista/mmap.h\"\n#include \"cista"
},
{
"path": "src/config.cc",
"chars": 8779,
"preview": "#include \"motis/config.h\"\n\n#include <iostream>\n\n#include \"boost/url.hpp\"\n\n#include \"fmt/std.h\"\n\n#include \"utl/erase.h\"\n#"
},
{
"path": "src/data.cc",
"chars": 12856,
"preview": "#include \"motis/data.h\"\n\n#include <filesystem>\n#include <future>\n\n#include \"cista/io.h\"\n\n#include \"utl/get_or_create.h\"\n"
},
{
"path": "src/direct_filter.cc",
"chars": 1870,
"preview": "#include \"motis/direct_filter.h\"\n\n#include \"utl/erase_if.h\"\n#include \"utl/visit.h\"\n\n#include \"nigiri/types.h\"\n\nnamespace"
},
{
"path": "src/elevators/elevators.cc",
"chars": 1489,
"preview": "#include \"motis/elevators/elevators.h\"\n\n#include \"osr/ways.h\"\n\nnamespace motis {\n\nvector_map<elevator_idx_t, elevator> u"
},
{
"path": "src/elevators/match_elevators.cc",
"chars": 2928,
"preview": "#include \"motis/elevators/match_elevator.h\"\n\n#include \"utl/enumerate.h\"\n#include \"utl/parallel_for.h\"\n\n#include \"osr/way"
},
{
"path": "src/elevators/parse_elevator_id_osm_mapping.cc",
"chars": 869,
"preview": "#include \"motis/elevators/parse_elevator_id_osm_mapping.h\"\n\n#include \"utl/parser/csv_range.h\"\n\nnamespace motis {\n\nelevat"
},
{
"path": "src/elevators/parse_fasta.cc",
"chars": 2838,
"preview": "#include \"motis/elevators/parse_fasta.h\"\n\n#include <iostream>\n\n#include \"boost/json.hpp\"\n\n#include \"date/date.h\"\n\n#inclu"
},
{
"path": "src/elevators/parse_siri_fm.cc",
"chars": 1430,
"preview": "#include \"motis/elevators/parse_siri_fm.h\"\n\n#include \"pugixml.hpp\"\n\nnamespace motis {\n\nstd::optional<elevator> parse_fac"
},
{
"path": "src/elevators/update_elevators.cc",
"chars": 2986,
"preview": "#include \"motis/elevators/update_elevators.h\"\n\n#include \"utl/verify.h\"\n\n#include \"nigiri/logging.h\"\n\n#include \"motis/con"
},
{
"path": "src/endpoints/adr/filter_conv.cc",
"chars": 504,
"preview": "#include \"motis/endpoints/adr/filter_conv.h\"\n\nnamespace a = adr;\n\nnamespace motis {\n\nadr::filter_type to_filter_type(\n "
},
{
"path": "src/endpoints/adr/geocode.cc",
"chars": 3705,
"preview": "#include \"motis/endpoints/adr/geocode.h\"\n\n#include \"boost/thread/tss.hpp\"\n\n#include \"utl/for_each_bit_set.h\"\n#include \"u"
},
{
"path": "src/endpoints/adr/reverse_geocode.cc",
"chars": 1292,
"preview": "#include \"motis/endpoints/adr/reverse_geocode.h\"\n\n#include \"net/bad_request_exception.h\"\n\n#include \"adr/guess_context.h\""
},
{
"path": "src/endpoints/adr/suggestions_to_response.cc",
"chars": 6271,
"preview": "#include \"motis/endpoints/adr/suggestions_to_response.h\"\n\n#include \"utl/for_each_bit_set.h\"\n#include \"utl/helpers/algori"
},
{
"path": "src/endpoints/elevators.cc",
"chars": 3590,
"preview": "#include \"motis/endpoints/elevators.h\"\n\n#include \"net/too_many_exception.h\"\n\n#include \"osr/geojson.h\"\n\n#include \"boost/j"
},
{
"path": "src/endpoints/graph.cc",
"chars": 1946,
"preview": "#include \"motis/endpoints/graph.h\"\n\n#include \"net/too_many_exception.h\"\n\n#include \"osr/geojson.h\"\n#include \"osr/routing/"
},
{
"path": "src/endpoints/gtfsrt.cc",
"chars": 7957,
"preview": "#include \"motis/endpoints/gtfsrt.h\"\n\n#include <functional>\n\n#ifdef NO_DATA\n#undef NO_DATA\n#endif\n#include \"gtfsrt/gtfs-r"
},
{
"path": "src/endpoints/initial.cc",
"chars": 3191,
"preview": "#include \"motis/endpoints/initial.h\"\n#include \"motis/config.h\"\n\n#include \"utl/erase_if.h\"\n#include \"utl/to_vec.h\"\n\n#incl"
},
{
"path": "src/endpoints/levels.cc",
"chars": 1214,
"preview": "#include \"motis/endpoints/levels.h\"\n\n#include \"net/bad_request_exception.h\"\n\n#include \"utl/pipes/all.h\"\n#include \"utl/pi"
},
{
"path": "src/endpoints/map/flex.cc",
"chars": 3229,
"preview": "#include \"motis/endpoints/map/flex_locations.h\"\n\n#include \"utl/to_vec.h\"\n\n#include \"net/bad_request_exception.h\"\n\n#inclu"
},
{
"path": "src/endpoints/map/rental.cc",
"chars": 17990,
"preview": "#include \"motis/endpoints/map/rental.h\"\n\n#include <algorithm>\n#include <array>\n#include <cassert>\n#include <set>\n#includ"
},
{
"path": "src/endpoints/map/route_details.cc",
"chars": 675,
"preview": "#include \"motis/endpoints/map/route_details.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/data.h\"\n#include \"motis"
},
{
"path": "src/endpoints/map/routes.cc",
"chars": 601,
"preview": "#include \"motis/endpoints/map/routes.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/data.h\"\n#include \"motis/fwd.h\""
},
{
"path": "src/endpoints/map/shapes_debug.cc",
"chars": 4656,
"preview": "#include \"motis/endpoints/map/shapes_debug.h\"\n\n#include <charconv>\n#include <set>\n#include <string>\n#include <string_vie"
},
{
"path": "src/endpoints/map/stops.cc",
"chars": 1274,
"preview": "#include \"motis/endpoints/map/stops.h\"\n\n#include \"net/bad_request_exception.h\"\n#include \"net/too_many_exception.h\"\n\n#inc"
},
{
"path": "src/endpoints/map/trips.cc",
"chars": 611,
"preview": "#include \"motis/endpoints/map/trips.h\"\n\n#include \"motis-api/motis-api.h\"\n#include \"motis/data.h\"\n#include \"motis/fwd.h\"\n"
},
{
"path": "src/endpoints/matches.cc",
"chars": 4431,
"preview": "#include \"motis/endpoints/matches.h\"\n\n#include \"net/too_many_exception.h\"\n\n#include \"osr/geojson.h\"\n\n#include \"motis/loc"
},
{
"path": "src/endpoints/metrics.cc",
"chars": 6396,
"preview": "#include \"motis/endpoints/metrics.h\"\n\n#include <chrono>\n#include <functional>\n#include <iostream>\n\n#include \"prometheus/"
},
{
"path": "src/endpoints/ojp.cc",
"chars": 45507,
"preview": "#include \"motis/endpoints/ojp.h\"\n\n#include \"pugixml.hpp\"\n\n#include <unordered_set>\n\n#include \"fmt/format.h\"\n\n#include \"d"
},
{
"path": "src/endpoints/one_to_all.cc",
"chars": 6925,
"preview": "#include \"motis/endpoints/one_to_all.h\"\n\n#include <chrono>\n#include <vector>\n\n#include \"utl/verify.h\"\n\n#include \"net/bad"
},
{
"path": "src/endpoints/one_to_many.cc",
"chars": 13141,
"preview": "#include \"motis/endpoints/one_to_many.h\"\n\n#include <chrono>\n#include <limits>\n#include <optional>\n\n#include \"utl/enumera"
},
{
"path": "src/endpoints/one_to_many_post.cc",
"chars": 841,
"preview": "#include \"motis/endpoints/one_to_many_post.h\"\n\n#include <string_view>\n\n#include \"utl/to_vec.h\"\n\n#include \"motis/endpoint"
},
{
"path": "src/endpoints/osr_routing.cc",
"chars": 3094,
"preview": "#include \"motis/endpoints/osr_routing.h\"\n\n#include \"utl/pipes.h\"\n\n#include \"osr/geojson.h\"\n#include \"osr/routing/route.h"
},
{
"path": "src/endpoints/platforms.cc",
"chars": 1141,
"preview": "#include \"motis/endpoints/platforms.h\"\n\n#include \"net/too_many_exception.h\"\n\n#include \"osr/geojson.h\"\n\nnamespace json = "
},
{
"path": "src/endpoints/routing.cc",
"chars": 44987,
"preview": "#include \"motis/endpoints/routing.h\"\n\n#include <algorithm>\n#include <cmath>\n\n#include \"boost/thread/tss.hpp\"\n\n#include \""
},
{
"path": "src/endpoints/stop_times.cc",
"chars": 23361,
"preview": "#include \"motis/endpoints/stop_times.h\"\n\n#include <algorithm>\n#include <memory>\n\n#include \"utl/concat.h\"\n#include \"utl/e"
},
{
"path": "src/endpoints/tiles.cc",
"chars": 2329,
"preview": "#include \"motis/endpoints/tiles.h\"\n\n#include <string>\n\n#include \"net/web_server/url_decode.h\"\n\n#include \"tiles/get_tile."
},
{
"path": "src/endpoints/transfers.cc",
"chars": 4211,
"preview": "#include \"motis/endpoints/transfers.h\"\n\n#include \"osr/geojson.h\"\n#include \"osr/routing/route.h\"\n\n#include \"utl/pipes/all"
},
{
"path": "src/endpoints/trip.cc",
"chars": 2609,
"preview": "#include \"motis/endpoints/trip.h\"\n\n#include <chrono>\n\n#include \"net/not_found_exception.h\"\n\n#include \"nigiri/routing/jou"
},
{
"path": "src/endpoints/update_elevator.cc",
"chars": 2383,
"preview": "#include \"motis/endpoints/update_elevator.h\"\n\n#include \"net/not_found_exception.h\"\n\n#include \"nigiri/rt/create_rt_timeta"
},
{
"path": "src/flex/flex.cc",
"chars": 15697,
"preview": "#include \"motis/flex/flex.h\"\n\n#include <ranges>\n\n#include \"utl/concat.h\"\n\n#include \"osr/lookup.h\"\n#include \"osr/routing/"
},
{
"path": "src/flex/flex_areas.cc",
"chars": 3295,
"preview": "#include \"motis/flex/flex_areas.h\"\n\n#include \"osr/lookup.h\"\n\n#include \"utl/concat.h\"\n#include \"utl/parallel_for.h\"\n\n#inc"
},
{
"path": "src/flex/flex_output.cc",
"chars": 6116,
"preview": "#include \"motis/flex/flex_output.h\"\n\n#include \"nigiri/flex.h\"\n#include \"nigiri/timetable.h\"\n\n#include \"motis/flex/flex.h"
},
{
"path": "src/gbfs/data.cc",
"chars": 1285,
"preview": "#include \"motis/gbfs/data.h\"\n\n#include \"osr/lookup.h\"\n#include \"osr/ways.h\"\n\n#include \"motis/gbfs/compression.h\"\n#includ"
},
{
"path": "src/gbfs/gbfs_output.cc",
"chars": 6431,
"preview": "#include \"motis/gbfs/gbfs_output.h\"\n\n#include \"motis/gbfs/mode.h\"\n#include \"motis/gbfs/osr_profile.h\"\n#include \"motis/gb"
},
{
"path": "src/gbfs/geofencing.cc",
"chars": 1861,
"preview": "#include \"motis/gbfs/data.h\"\n\n#include \"utl/helpers/algorithm.h\"\n\n#include \"tg.h\"\n\nnamespace motis::gbfs {\n\nbool applies"
},
{
"path": "src/gbfs/mode.cc",
"chars": 4604,
"preview": "#include \"motis/gbfs/mode.h\"\n\n#include <utility>\n\n#include \"utl/helpers/algorithm.h\"\n#include \"utl/verify.h\"\n\n#include \""
},
{
"path": "src/gbfs/osr_mapping.cc",
"chars": 14410,
"preview": "#include \"motis/gbfs/osr_mapping.h\"\n\n#include <optional>\n#include <utility>\n#include <vector>\n\n#include \"tg.h\"\n\n#include"
},
{
"path": "src/gbfs/osr_profile.cc",
"chars": 316,
"preview": "#include \"motis/gbfs/osr_profile.h\"\n\nnamespace motis::gbfs {\n\nosr::search_profile get_osr_profile(vehicle_form_factor co"
},
{
"path": "src/gbfs/parser.cc",
"chars": 22057,
"preview": "#include <optional>\n#include <string_view>\n#include <vector>\n\n#include \"motis/gbfs/parser.h\"\n\n#include \"cista/hash.h\"\n\n#"
},
{
"path": "src/gbfs/routing_data.cc",
"chars": 2616,
"preview": "#include \"motis/gbfs/routing_data.h\"\n\n#include \"osr/lookup.h\"\n#include \"osr/types.h\"\n#include \"osr/ways.h\"\n\n#include \"fm"
},
{
"path": "src/gbfs/update.cc",
"chars": 43662,
"preview": "#include \"motis/gbfs/update.h\"\n\n#include <algorithm>\n#include <cassert>\n#include <chrono>\n#include <filesystem>\n#include"
},
{
"path": "src/get_stops_with_traffic.cc",
"chars": 813,
"preview": "#include \"motis/get_stops_with_traffic.h\"\n\n#include \"osr/location.h\"\n\n#include \"nigiri/rt/rt_timetable.h\"\n#include \"nigi"
},
{
"path": "src/hashes.cc",
"chars": 856,
"preview": "#include \"motis/hashes.h\"\n\n#include <fstream>\n#include <ostream>\n\n#include \"boost/json.hpp\"\n\n#include \"cista/mmap.h\"\n\nna"
},
{
"path": "src/http_req.cc",
"chars": 6706,
"preview": "#include \"motis/http_req.h\"\n\n#include \"boost/asio/awaitable.hpp\"\n#include \"boost/asio/co_spawn.hpp\"\n#include \"boost/asio"
},
{
"path": "src/import.cc",
"chars": 25241,
"preview": "#include \"motis/import.h\"\n\n#include <fstream>\n#include <map>\n#include <ostream>\n#include <tuple>\n#include <vector>\n\n#inc"
},
{
"path": "src/journey_to_response.cc",
"chars": 30350,
"preview": "#include \"motis/journey_to_response.h\"\n\n#include <cmath>\n#include <iostream>\n#include <span>\n#include <variant>\n\n#includ"
},
{
"path": "src/logging.cc",
"chars": 1183,
"preview": "#include \"motis/logging.h\"\n\n#include <algorithm>\n#include <iostream>\n#include <string_view>\n\n#include \"fmt/ostream.h\"\n\n#"
}
]
// ... and 243 more files (download for full content)
About this extraction
This page contains the full source code of the motis-project/motis GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 443 files (18.0 MB), approximately 568.0k tokens, and a symbol index with 984 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.