diff --git a/.clang-tidy.in b/.clang-tidy.in index 9cdf69a6c..82d7cf885 100644 --- a/.clang-tidy.in +++ b/.clang-tidy.in @@ -78,7 +78,8 @@ Checks: "*,\ -cert-dcl37-c,\ -bugprone-reserved-identifier,\ -cert-dcl51-cpp,\ --misc-confusable-identifiers" +-misc-confusable-identifiers,\ +-misc-include-cleaner" WarningsAsErrors: '*' HeaderFilterRegex: '^${RELATIVE_SOURCE_DIR}(base|modules|test)/' AnalyzeTemporaryDtors: false diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index 3e47d7188..5a0cb509a 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -24,7 +24,7 @@ jobs: run: | find base libs modules test \ -type f -a \( -name "*.cc" -o -name "*.h" -o -name ".cuh" -o -name ".cu" \) \ - -print0 | xargs -0 clang-format-16 -i + -print0 | xargs -0 clang-format-17 -i - name: Check for differences run: | @@ -32,38 +32,6 @@ jobs: git status --porcelain git status --porcelain | xargs -I {} -0 test -z \"{}\" - rsl-ui-checks: - runs-on: ubuntu-latest - defaults: - run: - working-directory: ui/rsl - steps: - - uses: actions/checkout@v4 - - - name: pnpm Cache - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: pnpm-${{ runner.os }}-${{ hashFiles('ui/rsl/pnpm-lock.yaml') }} - restore-keys: | - pnpm-${{ runner.os }}- - - - name: Install RSL Web Interface Dependencies - uses: pnpm/action-setup@v3 - with: - version: ^8.15.4 - run_install: | - - cwd: ui/rsl - - - name: Formatting - run: pnpm run format-check - - - name: ESLint - run: pnpm run lint - - - name: TypeScript - run: pnpm run ts-check - api-docs: runs-on: ubuntu-latest defaults: @@ -88,7 +56,7 @@ jobs: - cwd: tools/protocol - name: Run Protocol Tool - run: pnpm start --skip rsl-ui + run: pnpm start - name: Upload API Docs uses: actions/upload-artifact@v4 @@ -164,12 +132,10 @@ jobs: if: matrix.config.tests == 'On' run: | ./build/motis --mode test \ - --import.paths schedule:base/loader/test_resources/hrd_schedules/single-ice \ - --dataset.begin 20151004 \ - --dataset.write_serialized false \ + --import.paths schedule-x:base/loader/test_resources/hrd_schedules/single-ice \ + --nigiri.first_day 2015-10-04 \ --nigiri.no_cache true \ - --ris.db_max_size 1048576 \ - --exclude_modules address osrm parking path ppr tiles tripbased gbfs transfers valhalla osr adr + --modules nigiri - name: Run Tests if: matrix.config.tests == 'On' @@ -183,25 +149,6 @@ jobs: - name: Compile Web Interface run: cmake --build build --target motis-web-ui || (sleep 10 && cmake --build build --target motis-web-ui) - - name: pnpm Cache - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: pnpm-${{ runner.os }}-${{ hashFiles('ui/rsl/pnpm-lock.yaml') }} - restore-keys: | - pnpm-${{ runner.os }}- - - - name: Install RSL Web Interface Dependencies - uses: pnpm/action-setup@v3 - with: - version: ^8.15.4 - run_install: | - - cwd: ./ui/rsl - - - name: Compile RSL Web Interface - run: pnpm run build - working-directory: ./ui/rsl - - name: Download API Docs uses: actions/download-artifact@v4 with: @@ -216,7 +163,6 @@ jobs: mv ui/web/{external_lib,img,js,style} motis/web/ mv ui/web/{*.html,*.js,*.ico} motis/web/ mv ui/web/openapi motis/web/ - mv ui/rsl/dist motis/web/rsl mv build/motis motis/ cp -r deps/osrm-backend/profiles motis/osrm-profiles cp -r deps/ppr/profiles motis/ppr-profiles @@ -316,12 +262,10 @@ jobs: if: ${{ !matrix.config.skiptests }} run: | ${{ matrix.config.emulator }} ./build/motis --mode test \ - --import.paths schedule:base/loader/test_resources/hrd_schedules/single-ice \ - --dataset.begin 20151004 \ - --dataset.write_serialized false \ + --import.paths schedule-x:base/loader/test_resources/hrd_schedules/single-ice \ + --nigiri.first_day 2015-10-04 \ --nigiri.no_cache true \ - --ris.db_max_size 1048576 \ - --exclude_modules address osrm parking path ppr tiles tripbased gbfs transfers valhalla osr adr + --modules nigiri - name: Run Tests if: ${{ !matrix.config.skiptests }} @@ -338,19 +282,6 @@ jobs: ln -s /elm ui/web/elm-stuff cmake --build build --target motis-web-ui || (sleep 10 && cmake --build build --target motis-web-ui) - - name: Install RSL Web Interface Dependencies - uses: pnpm/action-setup@v3 - if: ${{ !matrix.config.skipui }} - with: - version: ^8.15.4 - run_install: | - - cwd: ./ui/rsl - - - name: Compile RSL Web Interface - if: ${{ !matrix.config.skipui }} - run: pnpm run build - working-directory: ./ui/rsl - - name: Download API Docs if: matrix.config.artifact uses: actions/download-artifact@v4 @@ -371,7 +302,6 @@ jobs: mv ui/web/*.js motis/web/ mv ui/web/*.ico motis/web/ mv ui/web/openapi motis/web/ - mv ui/rsl/dist motis/web/rsl mv build/motis motis/motis cp -r deps/osrm-backend/profiles motis/osrm-profiles cp -r deps/ppr/profiles motis/ppr-profiles @@ -447,11 +377,12 @@ jobs: run: | ${{ matrix.config.emulator }} ./motis/motis \ --mode test \ - --modules routing lookup guesser ppr address intermodal osrm railviz tiles \ + --modules nigiri osr adr tiles intermodal \ --server.static_path motis/web \ --import.data_dir data \ - --import.paths schedule:data/hrd osm:data/aachen.osm.pbf \ - --dataset.begin 20210809 \ + --import.paths schedule-x:data/hrd osm:data/aachen.osm.pbf \ + --nigiri.first_day 2015-10-04 \ + --nigiri.no_cache true \ --osrm.profiles motis/osrm-profiles/car.lua \ --osrm.profiles motis/osrm-profiles/bike.lua \ --ppr.profile motis/ppr-profiles/default.json \ diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 901fe6852..530de428e 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -80,11 +80,10 @@ jobs: run: > .\build\motis.exe --mode test - --import.paths schedule:base/loader/test_resources/hrd_schedules/single-ice - --dataset.begin 20151004 - --dataset.write_serialized false + --import.paths schedule-x:base/loader/test_resources/hrd_schedules/single-ice + --nigiri.first_day 2015-10-04 --nigiri.no_cache true - --exclude_modules address osrm parking path ppr tiles tripbased gbfs transfers valhalla osr adr + --modules nigiri - name: Run Tests if: matrix.config.webui == 'Off' @@ -102,19 +101,6 @@ jobs: rm -r ui/web/elm-stuff rm -r ui/web/src - - name: Install RSL Web Interface Dependencies - uses: pnpm/action-setup@v3 - if: matrix.config.webui == 'On' - with: - version: ^8.15.4 - run_install: | - - cwd: ./ui/rsl - - - name: Compile RSL Web Interface - if: matrix.config.webui == 'On' - run: pnpm run build - working-directory: ./ui/rsl - # ==== API DOCS ==== - name: Install Protocol Tool Dependencies if: matrix.config.mode == 'Release' @@ -126,7 +112,7 @@ jobs: - name: Run Protocol Tool if: matrix.config.mode == 'Release' - run: pnpm start --skip rsl-ui + run: pnpm start working-directory: tools/protocol # ==== DISTRIBUTION ==== @@ -144,7 +130,6 @@ jobs: Copy-Item .\ui\web\external_lib,.\ui\web\img,.\ui\web\js,.\ui\web\style .\web\ -Recurse Copy-Item .\ui\web\*.html,.\ui\web\*.js,.\ui\web\*.ico .\web\ Copy-Item .\ui\web\openapi .\web\ -Recurse - Copy-Item .\ui\rsl\dist .\web\rsl -Recurse - name: Move API Docs if: matrix.config.mode == 'Release' diff --git a/.pkg b/.pkg index 1a75a8101..2441b05a0 100644 --- a/.pkg +++ b/.pkg @@ -1,7 +1,3 @@ -[address-typeahead] - url=git@github.com:motis-project/address-typeahead.git - branch=master - commit=b6b5e60faac2921f1c0b3813da9c11731a3ca31d [cista] url=git@github.com:felixguendling/cista.git branch=master @@ -9,7 +5,7 @@ [conf] url=git@github.com:motis-project/conf.git branch=master - commit=3aca4248da3f67d2a31ccce358ad9ee6102ab539 + commit=f9bf4bd83bf55a2170725707e526cbacc45dcc66 [ctx] url=git@github.com:motis-project/ctx.git branch=master @@ -54,30 +50,14 @@ url=git@github.com:motis-project/ppr.git branch=master commit=217585f424f6865693dd4aaa1a16f85daa574863 -[protobuf] - url=git@github.com:motis-project/protobuf.git - branch=main - commit=690e03babf0963d3da9615a2dae0891777842719 -[pugixml] - url=git@github.com:motis-project/pugixml.git - branch=master - commit=60175e80e2f5e97e027ac78f7e14c5acc009ce50 [rapidjson] url=git@github.com:motis-project/rapidjson.git branch=master commit=e7a1ac95c7840c6f4351abead02b1f7a02874197 -[tar] - url=git@github.com:motis-project/tar.git - branch=master - commit=3a08b6575eb6a04e6b3d0977e6da3b61a91d62f2 [tiles] url=git@github.com:motis-project/tiles.git branch=master commit=64f297ea0f782d04c89e82c6d478a1dd453e5f70 -[transfers] - url=git@github.com:motis-project/transfers.git - branch=main - commit=e66556443bad898ba98d418d53c96f5f03304833 [utl] url=git@github.com:motis-project/utl.git branch=master @@ -85,7 +65,7 @@ [guess] url=git@github.com:motis-project/guess.git branch=master - commit=cd2700556d69de939ea67af976cc982c9c05ee3a + commit=cecba85dbd6796c92a7f9c4e274849bb6ef03494 [boost] url=git@github.com:motis-project/boost.git branch=master @@ -94,22 +74,10 @@ url=git@github.com:motis-project/mimalloc.git branch=master commit=0087f000848de31b0090cb6f282348bd2fd3a9b8 -[rabbitmq-c] - url=git@github.com:motis-project/rabbitmq-c.git - branch=master - commit=5c57cc7ebbfba2d77c4fd6adfe6644586c87b3bb [nigiri] url=git@github.com:motis-project/nigiri.git branch=master - commit=7f0c17b2d363a400cfad191795fb543d7b28b68f -[osmium] - url=git@github.com:motis-project/libosmium.git - branch=master - commit=6e6d6b3081cc8bdf25dda89730e25c36eb995516 -[valhalla] - url=git@github.com:motis-project/valhalla.git - branch=master - commit=bcc77cb2746e3d234a34c73bd13880c32a96e6cc + commit=5def8503fa8baf36cf5fc5fd69bef4e6c59e8456 [osr] url=git@github.com:motis-project/osr.git branch=master @@ -117,4 +85,4 @@ [adr] url=git@github.com:triptix-tech/adr.git branch=master - commit=f044654571cfe5dd4cdd5260b16d9907dc270644 + commit=bef3f11a8c1642939e7047bcebf3d2f3528b23a3 diff --git a/.pkg.lock b/.pkg.lock index 2f4f3ed6d..a5430eb73 100644 --- a/.pkg.lock +++ b/.pkg.lock @@ -1,34 +1,33 @@ -4466310106395246297 -cista ebd5eb5cc7f82c414d3e060a3937d497189a103f +3742374743462604182 +cista ed9ea61e4d3e287546f778729fafb5caca574658 zlib fe8e13ffca867612951bc6baf114e5ac8b00f305 boost 1c3f21c1fa8b149da89e2f6bcb48b28fff30fa5e -cereal 5afa46f98d1c22627777c3f9d048fffe3f9763dc -expat b8c26c40f1900899b95c795705e0252fc0c1350c -googletest 34a46558609e05865c197f0260ab36daa7cbbb6e -guess 5acaeaacca154bd20987806f9626be5e3b87e1c5 -libosmium d5cc2a02d997c2b464d37d37c3a75cd9efa23dc4 -protozero 8c9f3fa97c2cfdceef86d0b61818ae98e9328f29 -fmt 3503709ac2ba2a938676e6b2071f1362294e278b -utl 4c1503afe58e209977d9a1e3db6a6b271a50c521 -address-typeahead b6b5e60faac2921f1c0b3813da9c11731a3ca31d -conf a32d491bd54800310a53ccba13f4ee9f6736ff3e +conf f9bf4bd83bf55a2170725707e526cbacc45dcc66 context 797dd16e2b5e959997ddcd5bdeac4f80931169b6 +fmt 3503709ac2ba2a938676e6b2071f1362294e278b +googletest 34a46558609e05865c197f0260ab36daa7cbbb6e +utl fd7425b1a57a4b887318ba8c41a3184f8c4a50c5 ctx d514aa0b0001596b0317abaa17a5a689dc601a55 res 7d97784ba785ce8a2677ea77164040fde484fb04 date 2d2c46a39bbf582dc663be1af926b4d58b2e0c9a flatbuffers a2028f13ae6aafe855010b43a0c93f86e04d9717 doctest 70e8f76437b76dd5e9c0a2eb9b907df190ab71a0 geo ee76668f0f0454e4acd3c769e00c6868620e3490 +utf8proc 779b780da3b99d123133eb99707b65c7e4324cc8 +guess cecba85dbd6796c92a7f9c4e274849bb6ef03494 lmdb 9bd01f14f549d8202413c4cd5f49b066b0a22b66 mimalloc 2a557cafb2e9e7c872358a83a63c62a7e14330b3 miniz 1edbdece9d71dc65c6ff405572ee37cbdcef7af4 libressl 39c1bf084d5c179d7bbce7ba902fffbebff0ee15 net 785b39c08212732e510305f0eef18de70f19b15e -abseil-cpp f2b3825f36e37fddd47c5c395096e9b1e99eca12 -protobuf 690e03babf0963d3da9615a2dae0891777842719 +abseil-cpp ba5240842d352b4b67a32092453a2fe5fe53a62e +protobuf d8136b9c6a62db6ce09900ecdeb82bb793096cbd unordered_dense c11595a7743d20622637584bddf77243d72ae152 wyhash 1e012b57fc2227a9e583a57e2eacb3da99816d99 -nigiri 7f0c17b2d363a400cfad191795fb543d7b28b68f +nigiri 5def8503fa8baf36cf5fc5fd69bef4e6c59e8456 +expat b8c26c40f1900899b95c795705e0252fc0c1350c +libosmium d5cc2a02d997c2b464d37d37c3a75cd9efa23dc4 +protozero 8c9f3fa97c2cfdceef86d0b61818ae98e9328f29 rapidjson 9ece673b648b19d0f1995b82d402c9a6fc0eb277 LuaJIT babeae2c3311bed245ee86f3e35a1f244e3da60b clipper 904f0e6644c7f01c176443613be8f7788d59c658 @@ -44,22 +43,6 @@ tbb b3011be5060ec1be43c76d4a8cc80d5550adb31d osrm-backend a7fe58cf3b6a54968d1248e0b4299d49db02ff2e cpptoml 2133029ec819e8398e96fa679993b269f21ff9f2 ppr 217585f424f6865693dd4aaa1a16f85daa574863 -pugixml 60175e80e2f5e97e027ac78f7e14c5acc009ce50 -rabbitmq-c 5c57cc7ebbfba2d77c4fd6adfe6644586c87b3bb -zstd bce26304a57dd504ae7ae51f384bf9292d7e3acb -tar 3a08b6575eb6a04e6b3d0977e6da3b61a91d62f2 -transfers e66556443bad898ba98d418d53c96f5f03304833 -OSM-binary 0be467dc07f2ee5271fb1e61c7c364dd20f29be0 -cpp-statsd-client b60bc7bb930df664b4ab9573ad8bee80d29dc72d -cxxopts a68479e98d6694d4bcfc7af9fc09527888a740b6 -dirent 11a4d8ab1bf5b0123f039127bc75b52b6702779e -just_gtfs 94b35eea71c09aefccf994c28ee7d373de4460e6 -lz4 c4765545ebb14b0a56c663e21923166923f8280e -microtar c71afe40887ae1a187ec24cedd85c765058d9978 -robin-hood-hashing bd632059ea0bb5cf444b33bdfb4eba2118300c62 -spatialite 7b8cd6447ac8632bd2c6c8ff9fbc10151742ef18 -valhalla bcc77cb2746e3d234a34c73bd13880c32a96e6cc FTXUI dd6a5d371fd7a3e2937bb579955003c54b727233 -utf8proc 1cb28a66ca79a0845e99433fd1056257456cef8b tg 20c0f298b8ce58de29a790290f44dca7c4ecc364 -adr f044654571cfe5dd4cdd5260b16d9907dc270644 +adr bef3f11a8c1642939e7047bcebf3d2f3528b23a3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b46bb1c3..6e209daaa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,8 +123,6 @@ if (MOTIS_MIMALLOC) target_compile_definitions(boost INTERFACE BOOST_ASIO_DISABLE_STD_ALIGNED_ALLOC=1) endif() -add_subdirectory(modules/ris/gtfsrtpb) - ################################ # Basic Compiler Flags @@ -198,7 +196,6 @@ endif() ################################ add_subdirectory(base/data EXCLUDE_FROM_ALL) add_subdirectory(base/core EXCLUDE_FROM_ALL) -add_subdirectory(base/loader EXCLUDE_FROM_ALL) add_subdirectory(base/module EXCLUDE_FROM_ALL) file(GLOB all-modules RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/modules ${CMAKE_CURRENT_SOURCE_DIR}/modules/*) @@ -289,8 +286,6 @@ configure_file ( file(GLOB_RECURSE motis-test-files test/src/*.cc) file(GLOB_RECURSE motis-modules-test-files ${module-test-files}) file(GLOB_RECURSE motis-base-test-files base/*_test.cc) -file(GLOB_RECURSE motis-loader-test-files base/loader/*_test.cc) -set_source_files_properties(${motis-loader-test-files} PROPERTIES COMPILE_DEFINITIONS FLATBUFFERS_64=1) add_executable(motis-test EXCLUDE_FROM_ALL ${motis-test-files} ${motis-modules-test-files} @@ -312,7 +307,6 @@ target_link_libraries(motis-test ${motis-test-extra-dependencies} motis-bootstrap motis-core - motis-loader motis-module conf ianatzdb-res @@ -344,7 +338,6 @@ target_link_libraries(motis-itest ${module-targets} motis-bootstrap motis-core - motis-loader motis-module conf ianatzdb-res diff --git a/CMakePresets.json b/CMakePresets.json index 1baa1fc77..69c36a1f3 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -145,8 +145,8 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build/sanitizer", "cacheVariables": { - "CMAKE_C_COMPILER": "clang-16", - "CMAKE_CXX_COMPILER": "clang++-16", + "CMAKE_C_COMPILER": "clang-17", + "CMAKE_CXX_COMPILER": "clang++-17", "CMAKE_EXE_LINKER_FLAGS": "-lc++abi -B/opt/mold", "CMAKE_BUILD_TYPE": "Debug", "CMAKE_C_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer", @@ -169,8 +169,8 @@ }, "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++-12", - "CC": "/usr/bin/gcc-12" + "CXX": "/usr/bin/g++-13", + "CC": "/usr/bin/gcc-13" } }, { @@ -184,8 +184,8 @@ }, "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++-12", - "CC": "/usr/bin/gcc-12" + "CXX": "/usr/bin/g++-13", + "CC": "/usr/bin/gcc-13" } }, { @@ -194,8 +194,8 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build/clang-tidy", "cacheVariables": { - "CMAKE_C_COMPILER": "clang-16", - "CMAKE_CXX_COMPILER": "clang++-16", + "CMAKE_C_COMPILER": "clang-17", + "CMAKE_CXX_COMPILER": "clang++-17", "CMAKE_CXX_FLAGS": "-stdlib=libc++", "CMAKE_EXE_LINKER_FLAGS": "-lc++abi", "MOTIS_LINT": "ON", diff --git a/base/bootstrap/CMakeLists.txt b/base/bootstrap/CMakeLists.txt index ab810493c..6eeb00155 100644 --- a/base/bootstrap/CMakeLists.txt +++ b/base/bootstrap/CMakeLists.txt @@ -26,4 +26,4 @@ add_library(motis-bootstrap STATIC ${motis-bootstrap-files}) target_include_directories(motis-bootstrap PUBLIC include) target_compile_features(motis-bootstrap PUBLIC cxx_std_17) target_compile_options(motis-bootstrap PRIVATE ${MOTIS_CXX_FLAGS}) -target_link_libraries(motis-bootstrap conf utl motis-loader motis-module ${module-targets}) +target_link_libraries(motis-bootstrap conf utl motis-module ${module-targets}) diff --git a/base/bootstrap/include/motis/bootstrap/dataset_settings.h b/base/bootstrap/include/motis/bootstrap/dataset_settings.h deleted file mode 100644 index afd337407..000000000 --- a/base/bootstrap/include/motis/bootstrap/dataset_settings.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "boost/program_options.hpp" - -#include "conf/configuration.h" - -#include "motis/loader/loader_options.h" - -namespace motis::bootstrap { - -struct dataset_settings : public conf::configuration, - public motis::loader::loader_options { - dataset_settings() : configuration("Dataset Settings", "dataset") { - param(dataset_, "path", "MOTIS Dataset root"); - param(no_schedule_, "no_schedule", "skip loading schedule"); - param(dataset_prefix_, "prefix", - "station id prefixes (one per path or empty)."); - param(graph_path_, "graph_path", - "path to read&write the serialized graph from/to " - "(\"default\": generated from settings)"); - param(write_serialized_, "write_serialized", "Ignore serialized dataset"); - param(write_graph_, "write_graph", "Write bianry schedule graph"); - param(read_graph_, "read_graph", "Read binary schedule graph"); - param(read_graph_mmap_, "read_graph_mmap", "Read using memory mapped file"); - param(cache_graph_, "cache_graph", "Cache binary schedule graph"); - param(apply_rules_, "apply_rules", - "Apply special rules (through-services, merge-split-services)"); - param(adjust_footpaths_, "adjust_footpaths", - "Remove footpaths if they do not fit an assumed average speed"); - param(expand_footpaths_, "expand_footpaths", - "Calculate expanded footpaths"); - param(use_platforms_, "use_platforms", - "Use separate interchange times for trips stopping at the same " - "platform"); - param(schedule_begin_, "begin", - "schedule interval begin (TODAY or YYYYMMDD)"); - param(num_days_, "num_days", "number of days"); - param(planned_transfer_delta_, "planned_transfer_delta", - "Max. difference between feeder arrival and connector departure for " - "waiting time rules (minutes)"); - param(wzr_classes_path_, "wzr_classes_path", - "waiting time rules class mapping"); - param(wzr_matrix_path_, "wzr_matrix_path", "waiting time matrix"); - param(no_local_transport_, "no_local_transport", - "don't load local transport"); - param(debug_broken_trips_, "debug_broken_trips", - "print debug information for broken trips"); - param(link_stop_distance_, "link_stop_distance", - "GTFS only: radius to connect stations, 0=skip"); - } -}; - -} // namespace motis::bootstrap diff --git a/base/bootstrap/include/motis/bootstrap/import_schedule.h b/base/bootstrap/include/motis/bootstrap/import_schedule.h deleted file mode 100644 index f266a53b5..000000000 --- a/base/bootstrap/include/motis/bootstrap/import_schedule.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "motis/bootstrap/motis_instance.h" -#include "motis/loader/loader_options.h" - -namespace motis::bootstrap { - -void register_import_schedule(motis_instance&, - motis::module::import_dispatcher&, - loader::loader_options const&, - std::string const& data_dir); - -} // namespace motis::bootstrap diff --git a/base/bootstrap/include/motis/bootstrap/motis_instance.h b/base/bootstrap/include/motis/bootstrap/motis_instance.h index f8641111a..c6d8db2d6 100644 --- a/base/bootstrap/include/motis/bootstrap/motis_instance.h +++ b/base/bootstrap/include/motis/bootstrap/motis_instance.h @@ -8,14 +8,12 @@ #include "boost/asio/io_service.hpp" -#include "motis/core/schedule/schedule.h" #include "motis/module/controller.h" #include "motis/module/message.h" #include "motis/module/module.h" #include "motis/module/remote.h" #include "motis/bootstrap/import_settings.h" #include "motis/bootstrap/module_settings.h" -#include "motis/loader/loader_options.h" namespace motis::bootstrap { @@ -43,8 +41,8 @@ struct motis_instance : public motis::module::controller { std::vector module_names() const; schedule const& sched() const; - void import(module_settings const&, loader::loader_options const&, - import_settings const&, bool silent = false); + void import(module_settings const&, import_settings const&, + bool silent = false); void init_modules(module_settings const&, unsigned num_threads = std::thread::hardware_concurrency()); void init_remotes( diff --git a/base/bootstrap/src/import_schedule.cc b/base/bootstrap/src/import_schedule.cc deleted file mode 100644 index a403277a9..000000000 --- a/base/bootstrap/src/import_schedule.cc +++ /dev/null @@ -1,126 +0,0 @@ -#include "motis/bootstrap/import_schedule.h" - -#include "utl/pipes.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/station_lookup.h" -#include "motis/module/clog_redirect.h" -#include "motis/module/context/motis_publish.h" -#include "motis/module/event_collector.h" -#include "motis/module/message.h" -#include "motis/bootstrap/import_settings.h" -#include "motis/loader/loader.h" - -namespace mm = motis::module; - -namespace motis::bootstrap { - -void register_import_schedule(motis_instance& instance, - mm::import_dispatcher& reg, - loader::loader_options const& dataset_opt, - std::string const& data_dir) { - if (dataset_opt.no_schedule_) { - return; - } - - std::make_shared( - data_dir, "schedule", reg, - [&, dataset_opt]( - mm::event_collector::dependencies_map_t const& dependencies, - mm::event_collector::publish_fn_t const& publish) { - auto const& msg = dependencies.at("SCHEDULE"); - - auto const parsers = loader::parsers(); - using import::FileEvent; - auto dataset_opt_cpy = dataset_opt; - dataset_opt_cpy.dataset_.clear(); - dataset_opt_cpy.dataset_prefix_.clear(); - - for (auto const* p : *motis_content(FileEvent, msg)->paths()) { - if (p->tag()->str() == "schedule" && - std::any_of(begin(parsers), end(parsers), - [&](auto const& parser) { - return parser->applicable(p->path()->str()); - })) { - dataset_opt_cpy.dataset_.emplace_back(p->path()->str()); - dataset_opt_cpy.dataset_prefix_.emplace_back(p->options()->str()); - } - } - - utl::verify(!dataset_opt_cpy.dataset_.empty(), - "import_schedule: dataset_opt.dataset_.empty()"); - - cista::memory_holder memory; - auto sched = loader::load_schedule(dataset_opt_cpy, memory, data_dir); - std::shared_ptr station_lookup = - std::make_shared(*sched); - instance.emplace_data(motis::module::to_res_id( - motis::module::global_res_id::STATION_LOOKUP), - std::move(station_lookup)); - instance.emplace_data( - motis::module::to_res_id(motis::module::global_res_id::SCHEDULE), - schedule_data{std::move(memory), std::move(sched)}); - { - mm::message_creator fbb; - fbb.create_and_finish( - MsgContent_ScheduleEvent, - import::CreateScheduleEvent( - fbb, - fbb.CreateVector(utl::to_vec( - dataset_opt_cpy.dataset_, - [&, i = 0](auto const&) mutable { - return fbb.CreateString( - dataset_opt_cpy.fbs_schedule_path(data_dir, i++)); - })), - fbb.CreateVector(utl::to_vec(dataset_opt_cpy.dataset_prefix_, - [&](auto const& prefix) { - return fbb.CreateString( - prefix); - })), - instance.sched().hash_) - .Union(), - "/import", DestinationType_Topic); - publish(make_msg(fbb)); - } - { - mm::message_creator fbb; - fbb.create_and_finish(MsgContent_StationsEvent, - motis::import::CreateStationsEvent(fbb).Union(), - "/import", DestinationType_Topic); - publish(make_msg(fbb)); - } - return nullptr; - }) - ->require("SCHEDULE", [](mm::msg_ptr const& msg) { - if (msg->get()->content_type() != MsgContent_FileEvent) { - return false; - } - - auto any_applicable = false; - using import::FileEvent; - auto const parsers = loader::parsers(); - for (auto const* p : *motis_content(FileEvent, msg)->paths()) { - if (p->tag()->str() != "schedule") { - continue; - } - auto const& path = p->path()->str(); - auto const applicable = std::any_of( - begin(parsers), end(parsers), - [&](auto const& parser) { return parser->applicable(path); }); - - if (!applicable) { - std::clog << "import_schedule: no parser for " << path << "\n"; - for (auto const& parser : parsers) { - std::clog << "missing files:\n"; - for (auto const& file : parser->missing_files(path)) { - std::clog << " " << file << "\n"; - } - } - } - any_applicable = any_applicable || applicable; - } - return any_applicable; - }); -} - -} // namespace motis::bootstrap diff --git a/base/bootstrap/src/motis_instance.cc b/base/bootstrap/src/motis_instance.cc index 11f35c4f3..a7c5c3b52 100644 --- a/base/bootstrap/src/motis_instance.cc +++ b/base/bootstrap/src/motis_instance.cc @@ -16,8 +16,6 @@ #include "motis/module/context/motis_call.h" #include "motis/module/context/motis_publish.h" #include "motis/bootstrap/import_files.h" -#include "motis/bootstrap/import_schedule.h" -#include "motis/loader/loader.h" #include "modules.h" @@ -63,12 +61,7 @@ std::vector motis_instance::module_names() const { return s; } -schedule const& motis_instance::sched() const { - return *get(to_res_id(global_res_id::SCHEDULE)).schedule_; -} - void motis_instance::import(module_settings const& module_opt, - loader::loader_options const& dataset_opt, import_settings const& import_opt, bool const silent) { auto bars = utl::global_progress_bars{silent}; @@ -76,8 +69,6 @@ void motis_instance::import(module_settings const& module_opt, auto dispatcher = import_dispatcher{}; register_import_files(dispatcher); - register_import_schedule(*this, dispatcher, dataset_opt, - import_opt.data_directory_); for (auto const& module : modules_) { if (module_opt.is_module_active(module->module_name())) { @@ -96,10 +87,6 @@ void motis_instance::import(module_settings const& module_opt, registry_.reset(); - utl::verify( - dataset_opt.no_schedule_ || includes(to_res_id(global_res_id::SCHEDULE)), - "schedule not loaded"); - if (import_opt.require_successful_) { auto const unsuccessful_imports = utl::all(modules_) // diff --git a/base/core/CMakeLists.txt b/base/core/CMakeLists.txt index 95241d344..54916cdf5 100644 --- a/base/core/CMakeLists.txt +++ b/base/core/CMakeLists.txt @@ -10,7 +10,7 @@ target_compile_options(motis-core PRIVATE ${MOTIS_CXX_FLAGS}) target_link_libraries(motis-core utl date + geo motis-data - motis-loader motis-module ) diff --git a/base/core/include/motis/core/access/bfs.h b/base/core/include/motis/core/access/bfs.h deleted file mode 100644 index d8ebe5cce..000000000 --- a/base/core/include/motis/core/access/bfs.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/event.h" - -namespace motis { - -enum class bfs_direction { FORWARD, BACKWARD, BOTH }; - -std::set route_bfs(ev_key const&, bfs_direction, - bool with_through_edges = false); -std::set trip_bfs(ev_key const&, bfs_direction); - -} // namespace motis diff --git a/base/core/include/motis/core/access/connection_access.h b/base/core/include/motis/core/access/connection_access.h deleted file mode 100644 index a4140d146..000000000 --- a/base/core/include/motis/core/access/connection_access.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "motis/core/schedule/schedule.h" - -namespace motis::access { - -connection_info const& get_connection_info(schedule const&, - light_connection const&, - trip const*); - -} // namespace motis::access diff --git a/base/core/include/motis/core/access/edge_access.h b/base/core/include/motis/core/access/edge_access.h deleted file mode 100644 index 5ebb7903a..000000000 --- a/base/core/include/motis/core/access/edge_access.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "motis/core/schedule/connection.h" -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/nodes.h" - -namespace motis { - -template -void foreach_departure_in(edge const& edge, time begin, time end, F fun) { - if (edge.type() != edge::ROUTE_EDGE) { - return; - } - - auto const& conns = edge.m_.route_edge_.conns_; - auto it = std::lower_bound(std::begin(conns), std::end(conns), - light_connection(begin)); - for (; it != std::end(conns) && it->d_time_ < end; ++it) { - fun(it); - } -} - -template -void foreach_arrival_in(edge const& edge, time begin, time end, F fun) { - if (edge.type() != edge::ROUTE_EDGE) { - return; - } - - auto const& conns = edge.m_.route_edge_.conns_; - auto it = std::lower_bound(std::begin(conns), std::end(conns), begin, - [](light_connection const& lcon, time const& t) { - return lcon.a_time_ < t; - }); - for (; it != std::end(conns) && it->a_time_ < end; ++it) { - fun(it); - } -} - -edge const* get_route_edge(node const* route_node, light_connection const*, - event_type); - -node const* get_route_node(edge const&, event_type); - -light_connection const& get_lcon(edge const* route_edge, size_t lcon_index); - -time get_time(light_connection const*, event_type); - -time get_time(edge const* route_edge, std::size_t lcon_index, event_type); - -lcon_idx_t get_lcon_index(edge const* route_edge, light_connection const*); - -} // namespace motis diff --git a/base/core/include/motis/core/access/event_access.h b/base/core/include/motis/core/access/event_access.h deleted file mode 100644 index 2f6f1dbae..000000000 --- a/base/core/include/motis/core/access/event_access.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "motis/core/schedule/event.h" - -namespace motis { - -template -void for_each_departure(ev_key const& arr, Fn fn) { - for (auto const& e : arr.route_edge_->to_->edges_) { - if (!e.empty()) { - fn(ev_key{&e, arr.lcon_idx_, event_type::DEP}); - } else if (e.type() == edge::THROUGH_EDGE) { - for (auto const& ne : e.to_->edges_) { - if (!ne.empty()) { - fn(ev_key{&ne, arr.lcon_idx_, event_type::DEP}); - } - } - } - } -} - -template -void for_each_arrival(ev_key const& dep, Fn fn) { - for (auto const& e : dep.route_edge_->from_->incoming_edges_) { - if (!e->empty()) { - fn(ev_key{trip::route_edge{e}, dep.lcon_idx_, event_type::ARR}); - } else if (e->type() == edge::THROUGH_EDGE) { - for (auto const& pe : e->from_->incoming_edges_) { - if (!pe->empty()) { - fn(ev_key{trip::route_edge{pe}, dep.lcon_idx_, event_type::ARR}); - } - } - } - } -} - -} // namespace motis diff --git a/base/core/include/motis/core/access/realtime_access.h b/base/core/include/motis/core/access/realtime_access.h deleted file mode 100644 index 7193b994e..000000000 --- a/base/core/include/motis/core/access/realtime_access.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "motis/core/schedule/schedule.h" - -namespace motis { - -time get_schedule_time(schedule const&, ev_key const&); - -time get_schedule_time(schedule const&, edge const* route_edge, lcon_idx_t, - event_type); - -time get_schedule_time(schedule const&, edge const* route_edge, - light_connection const*, event_type); - -time get_delay(schedule const&, ev_key const&); - -delay_info get_delay_info(schedule const&, node const* route_node, - light_connection const*, event_type); - -delay_info get_delay_info(schedule const&, edge const* route_edge, - light_connection const*, event_type); - -delay_info get_delay_info(schedule const&, ev_key const&); - -ev_key const& get_current_ev_key(schedule const&, ev_key const&); - -ev_key const& get_orig_ev_key(schedule const&, ev_key const&); - -uint16_t get_schedule_track(schedule const&, ev_key const&); - -int get_schedule_track(schedule const&, edge const* route_edge, - light_connection const*, event_type); - -int get_schedule_track(schedule const&, node const* route_node, - light_connection const*, event_type); - -} // namespace motis diff --git a/base/core/include/motis/core/access/service_access.h b/base/core/include/motis/core/access/service_access.h deleted file mode 100644 index e2cd5f8ed..000000000 --- a/base/core/include/motis/core/access/service_access.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/error.h" - -namespace motis { - -uint32_t output_train_nr(uint32_t train_nr, uint32_t original_train_nr); - -std::string get_service_name(schedule const& sched, - connection_info const* info); - -} // namespace motis diff --git a/base/core/include/motis/core/access/station_access.h b/base/core/include/motis/core/access/station_access.h deleted file mode 100644 index ccd2519b8..000000000 --- a/base/core/include/motis/core/access/station_access.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/schedule.h" - -namespace motis { - -station* find_station(schedule const&, std::string_view eva_nr); -station* get_station(schedule const&, std::string_view eva_nr); -station_node* get_station_node(schedule const&, std::string_view eva_nr); -station_node* find_station_node(schedule const&, std::string_view eva_nr); - -} // namespace motis diff --git a/base/core/include/motis/core/access/time_access.h b/base/core/include/motis/core/access/time_access.h index 7e221e654..0aa39a607 100644 --- a/base/core/include/motis/core/access/time_access.h +++ b/base/core/include/motis/core/access/time_access.h @@ -3,7 +3,6 @@ #include "motis/core/common/date_time_util.h" #include "motis/core/common/logging.h" #include "motis/core/common/unixtime.h" -#include "motis/core/schedule/schedule.h" #include "motis/core/schedule/time.h" #include "motis/core/access/error.h" @@ -11,22 +10,7 @@ namespace motis { constexpr auto const DEFAULT_TIMEZONE_OFFSET = 60; -unixtime external_schedule_begin(schedule const&); - -unixtime external_schedule_end(schedule const&); - -void verify_timestamp(schedule const&, time_t); - -void verify_external_timestamp(schedule const&, time_t); - -unixtime motis_to_unixtime(schedule const&, time); - -time unix_to_motistime(schedule const&, unixtime); - time motis_time(int hhmm, int day_idx = 0, int timezone_offset = DEFAULT_TIMEZONE_OFFSET); -unixtime unix_time(schedule const&, int hhmm, int day_idx = 0, - int timezone_offset = DEFAULT_TIMEZONE_OFFSET); - } // namespace motis diff --git a/base/core/include/motis/core/access/track_access.h b/base/core/include/motis/core/access/track_access.h deleted file mode 100644 index e09cb08b2..000000000 --- a/base/core/include/motis/core/access/track_access.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/core/schedule/schedule.h" - -namespace motis { - -std::optional get_track_index(schedule const&, - std::string_view track_name); - -} // namespace motis diff --git a/base/core/include/motis/core/access/transfer_time.h b/base/core/include/motis/core/access/transfer_time.h deleted file mode 100644 index 24e1b53fd..000000000 --- a/base/core/include/motis/core/access/transfer_time.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/station.h" -#include "motis/core/schedule/time.h" - -namespace motis { - -std::optional get_transfer_time_between_platforms( - station const& from_station, std::optional from_platform, - station const& to_station, std::optional to_platform); - -} // namespace motis diff --git a/base/core/include/motis/core/access/trip_access.h b/base/core/include/motis/core/access/trip_access.h deleted file mode 100644 index 928ad18ea..000000000 --- a/base/core/include/motis/core/access/trip_access.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/schedule.h" -#include "motis/core/journey/extern_trip.h" - -namespace motis { - -trip const* get_gtfs_trip(schedule const&, gtfs_trip_id const&); - -trip const* get_trip(schedule const&, std::string_view eva_nr, - uint32_t train_nr, unixtime timestamp, - std::string_view target_eva_nr, unixtime target_timestamp, - std::string_view line_id, bool fuzzy = false); - -trip const* get_trip(schedule const&, extern_trip const&); - -trip const* get_trip(schedule const&, trip_idx_t); - -trip const* find_trip(schedule const&, primary_trip_id); - -trip const* find_trip(schedule const&, full_trip_id); - -unsigned stop_seq_to_stop_idx(trip const&, unsigned stop_seq); - -} // namespace motis diff --git a/base/core/include/motis/core/access/trip_iterator.h b/base/core/include/motis/core/access/trip_iterator.h deleted file mode 100644 index cbd282640..000000000 --- a/base/core/include/motis/core/access/trip_iterator.h +++ /dev/null @@ -1,138 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/core/schedule/trip.h" -#include "motis/core/access/trip_section.h" -#include "motis/core/access/trip_stop.h" - -namespace motis::access { - -template -struct trip_iterator { - using iterator_category = std::random_access_iterator_tag; - using value_type = T; // crap - using difference_type = int; - using pointer = T*; - using reference = T&; - - trip_iterator(trip const* t, int const i) : trip_(t), index_(i) {} - - trip_iterator& operator+=(int rhs) { - index_ += rhs; - return *this; - } - trip_iterator& operator-=(int rhs) { - index_ -= rhs; - return *this; - } - - T operator*() const { return {trip_, index_}; } - T operator[](int rhs) const { return {trip_, rhs}; } - - trip_iterator& operator++() { - ++index_; - return *this; - } - trip_iterator& operator--() { - --index_; - return *this; - } - trip_iterator operator++(int) { - trip_iterator tmp(*this); - ++index_; - return tmp; - } - trip_iterator operator--(int) { - trip_iterator tmp(*this); - --index_; - return tmp; - } - int operator-(const trip_iterator& rhs) const { - return index_ - rhs.index_; - } - trip_iterator operator+(int rhs) const { - return trip_iterator(trip_, index_ + rhs); - } - trip_iterator operator-(int rhs) const { - return trip_iterator(trip_, index_ - rhs); - } - friend trip_iterator operator+(int lhs, trip_iterator const& rhs) { - return trip_iterator(rhs.trip_, lhs + rhs.index_); - } - friend trip_iterator operator-(int lhs, trip_iterator const& rhs) { - return trip_iterator(rhs.trip_, lhs - rhs.index_); - } - - bool operator==(trip_iterator const& rhs) const { - return std::tie(trip_, index_) == std::tie(rhs.trip_, rhs.index_); - } - bool operator!=(trip_iterator const& rhs) const { - return std::tie(trip_, index_) != std::tie(rhs.trip_, rhs.index_); - } - bool operator>(trip_iterator const& rhs) const { - return std::tie(trip_, index_) > std::tie(rhs.trip_, rhs.index_); - } - bool operator<(trip_iterator const& rhs) const { - return std::tie(trip_, index_) < std::tie(rhs.trip_, rhs.index_); - } - bool operator>=(trip_iterator const& rhs) const { - return std::tie(trip_, index_) >= std::tie(rhs.trip_, rhs.index_); - } - bool operator<=(trip_iterator const& rhs) const { - return std::tie(trip_, index_) <= std::tie(rhs.trip_, rhs.index_); - } - -protected: - trip const* trip_; - int index_; -}; - -struct sections { - using iterator = trip_iterator; - - explicit sections(trip const* t) : t_(t) {} - - iterator begin() const { return begin(t_); } - iterator end() const { return end(t_); } - - friend iterator begin(sections const& s) { return begin(s.t_); } - friend iterator end(sections const& s) { return end(s.t_); } - - static iterator begin(trip const* t) { return {t, 0}; } - static iterator end(trip const* t) { - return {t, static_cast(t->edges_->size())}; - } - - std::uint32_t size() const { - return static_cast(t_->edges_->size()); - } - - trip const* t_; -}; - -struct stops { - using iterator = trip_iterator; - - explicit stops(trip const* t) : t_(t) {} - - iterator begin() const { return begin(t_); } - iterator end() const { return end(t_); } - - friend iterator begin(stops const& s) { return begin(s.t_); } - friend iterator end(stops const& s) { return end(s.t_); } - - static iterator begin(trip const* t) { return {t, 0}; } - static iterator end(trip const* t) { - return {t, - t->edges_->empty() ? 0 : static_cast(t->edges_->size()) + 1}; - } - - size_t size() const { return t_->edges_->size() + 1; } - - trip const* t_; -}; - -} // namespace motis::access diff --git a/base/core/include/motis/core/access/trip_section.h b/base/core/include/motis/core/access/trip_section.h deleted file mode 100644 index b9cd90698..000000000 --- a/base/core/include/motis/core/access/trip_section.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "motis/core/schedule/schedule.h" - -namespace motis::access { - -struct trip_section { - trip_section(trip const* t, int index); - - int index() const; - - light_connection const& lcon() const; - - connection const& fcon() const; - connection_info const& info(schedule const& sched) const; - - class edge const* edge() const; - - station const& from_station(schedule const& sched) const; - station const& to_station(schedule const& sched) const; - - uint32_t from_station_id() const; - uint32_t to_station_id() const; - - ev_key ev_key_from() const; - ev_key ev_key_to() const; - - class edge const* get_route_edge() const; - - node* from_node() const; - node* to_node() const; - - trip const* trip_; - int index_; - class edge const* edge_; -}; - -} // namespace motis::access diff --git a/base/core/include/motis/core/access/trip_stop.h b/base/core/include/motis/core/access/trip_stop.h deleted file mode 100644 index e047ddd7e..000000000 --- a/base/core/include/motis/core/access/trip_stop.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "motis/core/schedule/schedule.h" - -namespace motis::access { - -class trip_stop { -public: - trip_stop(trip const* t, int index); - - int index() const; - - bool has_arrival() const; - bool has_departure() const; - - light_connection const& arr_lcon() const; - light_connection const& dep_lcon() const; - - ev_key arr() const; - ev_key dep() const; - - connection_info const& arr_info(schedule const& sched) const; - connection_info const& dep_info(schedule const& sched) const; - station const& get_station(schedule const& sched) const; - - uint32_t get_station_id() const; - node const* get_route_node() const; - - bool is_first() const; - bool is_last() const; - -private: - trip const* trip_; - int index_; - node const* node_; -}; - -} // namespace motis::access diff --git a/base/core/include/motis/core/access/uuids.h b/base/core/include/motis/core/access/uuids.h deleted file mode 100644 index 00372e68b..000000000 --- a/base/core/include/motis/core/access/uuids.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#include "boost/uuid/uuid.hpp" - -#include "motis/core/schedule/schedule.h" - -namespace motis::access { - -inline std::optional get_event_uuid(schedule const& sched, - trip const* trp, - ev_key const evk) { - if (auto const it = - sched.event_to_uuid_.find(mcd::pair{ptr{trp}, evk}); - it != end(sched.event_to_uuid_)) { - return {it->second}; - } else { - return {}; - } -} - -} // namespace motis::access diff --git a/base/core/include/motis/core/conv/trip_conv.h b/base/core/include/motis/core/conv/trip_conv.h index 600bd1e13..a7b7ce812 100644 --- a/base/core/include/motis/core/conv/trip_conv.h +++ b/base/core/include/motis/core/conv/trip_conv.h @@ -1,33 +1,11 @@ #pragma once -#include "motis/core/access/time_access.h" -#include "motis/core/access/trip_access.h" #include "motis/core/conv/event_type_conv.h" #include "motis/core/journey/extern_trip.h" #include "motis/protocol/TripId_generated.h" namespace motis { -inline trip const* from_fbs(schedule const& sched, TripId const* t, - bool const fuzzy = false) { - return get_trip(sched, t->station_id()->str(), t->train_nr(), t->time(), - t->target_station_id()->str(), t->target_time(), - t->line_id()->str(), fuzzy); -} - -inline flatbuffers::Offset to_fbs(schedule const& sched, - flatbuffers::FlatBufferBuilder& fbb, - trip const* trp) { - auto const& p = trp->id_.primary_; - auto const& s = trp->id_.secondary_; - return CreateTripId( - fbb, fbb.CreateString(trp->gtfs_trip_id_.str()), - fbb.CreateString(sched.stations_.at(p.station_id_)->eva_nr_), p.train_nr_, - motis_to_unixtime(sched, p.time_), - fbb.CreateString(sched.stations_.at(s.target_station_id_)->eva_nr_), - motis_to_unixtime(sched, s.target_time_), fbb.CreateString(s.line_id_)); -} - inline flatbuffers::Offset to_fbs(flatbuffers::FlatBufferBuilder& fbb, extern_trip const& t) { return CreateTripId(fbb, fbb.CreateString(t.id_), @@ -36,23 +14,6 @@ inline flatbuffers::Offset to_fbs(flatbuffers::FlatBufferBuilder& fbb, fbb.CreateString(t.line_id_)); } -inline trip const* from_extern_trip(schedule const& sched, - extern_trip const* t) { - return get_trip(sched, t->station_id_, t->train_nr_, t->time_, - t->target_station_id_, t->target_time_, t->line_id_); -} - -inline extern_trip to_extern_trip(schedule const& sched, trip const* t) { - return extern_trip{ - t->gtfs_trip_id_, - sched.stations_.at(t->id_.primary_.station_id_)->eva_nr_, - t->id_.primary_.get_train_nr(), - motis_to_unixtime(sched, t->id_.primary_.time_), - sched.stations_.at(t->id_.secondary_.target_station_id_)->eva_nr_, - motis_to_unixtime(sched, t->id_.secondary_.target_time_), - t->id_.secondary_.line_id_}; -} - inline extern_trip to_extern_trip(TripId const* trp) { return extern_trip{trp->id() == nullptr ? "" : trp->id()->str(), trp->station_id()->str(), diff --git a/base/core/include/motis/core/journey/extern_trip.h b/base/core/include/motis/core/journey/extern_trip.h index d78f197d4..88b6967e8 100644 --- a/base/core/include/motis/core/journey/extern_trip.h +++ b/base/core/include/motis/core/journey/extern_trip.h @@ -3,6 +3,8 @@ #include #include +#include "cista/reflection/comparable.h" + #include "motis/string.h" #include "motis/core/common/date_time_util.h" diff --git a/base/core/include/motis/core/journey/generate_journey_transport.h b/base/core/include/motis/core/journey/generate_journey_transport.h deleted file mode 100644 index 6d95d4c53..000000000 --- a/base/core/include/motis/core/journey/generate_journey_transport.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "motis/core/schedule/connection.h" -#include "motis/core/schedule/schedule.h" -#include "motis/core/journey/journey.h" - -namespace motis { - -journey::transport generate_journey_transport( - unsigned int from, unsigned int to, connection_info const* con_info, - schedule const& sched, duration duration = 0, int mumo_id = -1, - unsigned mumo_price = 0, unsigned mumo_accessibility = 0); - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/build_platform_node.h b/base/core/include/motis/core/schedule/build_platform_node.h deleted file mode 100644 index 35143a30b..000000000 --- a/base/core/include/motis/core/schedule/build_platform_node.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "motis/core/schedule/nodes.h" -#include "motis/core/schedule/schedule.h" - -namespace motis { - -node* get_or_add_platform_node(schedule& sched, station_node* station_node, - uint16_t platform); - -node* add_platform_enter_edge(schedule& sched, node* route_node, - station_node* station_node, - int32_t platform_transfer_time, - uint16_t platform); - -node* add_platform_exit_edge(schedule& sched, node* route_node, - station_node* station_node, - int32_t platform_transfer_time, uint16_t platform); - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/build_route_node.h b/base/core/include/motis/core/schedule/build_route_node.h deleted file mode 100644 index b067f821d..000000000 --- a/base/core/include/motis/core/schedule/build_route_node.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include "motis/core/schedule/nodes.h" - -namespace motis { - -node* build_route_node(int route_index, int node_id, station_node* station_node, - int transfer_time, bool in_allowed, bool out_allowed); - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/category.h b/base/core/include/motis/core/schedule/category.h deleted file mode 100644 index 3502b4219..000000000 --- a/base/core/include/motis/core/schedule/category.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "motis/string.h" - -namespace motis { - -struct category { - mcd::string name_; - uint8_t output_rule_; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/connection.h b/base/core/include/motis/core/schedule/connection.h deleted file mode 100644 index d6532c829..000000000 --- a/base/core/include/motis/core/schedule/connection.h +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/string.h" -#include "motis/vector.h" - -#include "cista/reflection/comparable.h" - -#include "motis/core/common/hash_helper.h" -#include "motis/core/schedule/attribute.h" -#include "motis/core/schedule/event_type.h" -#include "motis/core/schedule/provider.h" -#include "motis/core/schedule/time.h" -#include "motis/core/schedule/trip_idx.h" - -namespace motis { - -constexpr auto kMaxValidTrainNr = 99999; - -using service_class_t = uint8_t; - -enum class service_class : service_class_t { - AIR = 0, - ICE = 1, - IC = 2, - COACH = 3, - N = 4, - RE = 5, - RB = 6, - S = 7, - U = 8, - STR = 9, - BUS = 10, - SHIP = 11, - OTHER = 12, - NUM_CLASSES -}; - -inline std::string_view to_str(service_class const clasz) { - constexpr std::string_view const names[] = {"Air", - "High Speed Rail", - "Long Distance Trains", - "Coach", - "Sleeper Rail", - "Cross-Country Rail", - "Regional Rail", - "Metro", - "Subway", - "Tram", - "Bus", - "Ferry", - "Other"}; - return names[static_cast>(clasz)]; -} - -inline service_class& operator++(service_class& c) { - return c = static_cast(static_cast(c) + 1); -} - -struct connection_info { - CISTA_COMPARABLE(); - - mcd::vector> attributes_; - mcd::string line_identifier_; - ptr dir_{nullptr}; - ptr provider_{nullptr}; - uint32_t family_{0U}; - uint32_t train_nr_{0U}; - uint32_t original_train_nr_{0U}; - ptr merged_with_{nullptr}; -}; - -struct connection { - ptr con_info_{nullptr}; - uint16_t price_{0U}; - uint16_t d_track_{0U}, a_track_{0U}; - service_class clasz_{service_class::AIR}; // service_class 0 -}; - -struct light_connection { - light_connection() - : full_con_{nullptr}, - d_time_{INVALID_TIME}, - a_time_{INVALID_TIME}, - trips_{0U}, - valid_{0U} {} - - explicit light_connection(time d_time) : d_time_{d_time} {} // NOLINT - - light_connection(time const d_time, time const a_time, - connection const* full_con = nullptr, - merged_trips_idx const trips = 0) - : full_con_{full_con}, - d_time_{d_time}, - a_time_{a_time}, - trips_{trips}, - valid_{1U} {} - - time event_time(event_type const t) const { - return t == event_type::DEP ? d_time_ : a_time_; - } - - unsigned travel_time() const { return a_time_ - d_time_; } - - inline bool operator<(light_connection const& o) const { - return d_time_ < o.d_time_; - } - - ptr full_con_; - time d_time_, a_time_; - uint32_t trips_ : 31; - uint32_t valid_ : 1; -}; - -// Index of a light_connection in a route edge. -using lcon_idx_t = uint32_t; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/constant_graph.h b/base/core/include/motis/core/schedule/constant_graph.h deleted file mode 100644 index b3a99f152..000000000 --- a/base/core/include/motis/core/schedule/constant_graph.h +++ /dev/null @@ -1,227 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/hash_map.h" -#include "motis/vector.h" - -#include "motis/core/common/dial.h" -#include "motis/core/schedule/nodes.h" - -namespace motis { - -//============================================================================= -// GRAPH DEFINITION -//----------------------------------------------------------------------------- -struct simple_edge { - uint32_t to_; - uint16_t cost_; -}; - -using constant_graph = mcd::vector>; - -//============================================================================= -// STATION GRAPH -//----------------------------------------------------------------------------- -struct map_station_graph_node { - uint32_t operator()(node const* n) const { return n->get_station()->id_; } -}; - -inline constant_graph build_station_graph( - mcd::vector const& station_nodes, search_dir const dir) { - constant_graph g(station_nodes.size()); - - auto add_edges = [&g, dir](station_node const& sn) { - // Stores the minimum distance to each neighboring station. - mcd::hash_map min; - - auto update_min = [&min](uint32_t const from, edge_cost const& ec) { - if (!ec.is_valid()) { - return; - } - - auto const it = min.find(from); - if (it == end(min) || ec.time_ < it->second) { - min[from] = ec.time_; - } - }; - - for (auto const& inner_station_edge : sn.edges_) { - if (inner_station_edge.to_->get_station() == &sn) { - for (auto const& e : inner_station_edge.to_->edges_) { - if (e.to_->get_station() != &sn) { - update_min(e.to_->get_station()->id_, e.get_minimum_cost()); - } - } - } - } - - for (const auto& e : min) { - auto const s = (dir == search_dir::FWD) ? e.first : sn.id_; - auto const t = (dir == search_dir::FWD) ? sn.id_ : e.first; - g[s].emplace_back(t, e.second); - } - }; - - for (auto const& station_node : station_nodes) { - add_edges(*station_node); - } - - return g; -} - -//============================================================================= -// INTERCHANGE GRAPH -//----------------------------------------------------------------------------- -struct map_interchange_graph_node { - explicit map_interchange_graph_node(uint32_t route_offset) - : route_offset_(route_offset) {} - uint32_t operator()(node const* n) const { - return n->is_route_node() ? route_offset_ + n->route_ - : n->get_station()->id_; - } - uint32_t route_offset_; -}; - -inline bool is_connected(node const* from, node const* to) { - return std::find_if(begin(from->edges_), end(from->edges_), - [&to](edge const& e) { - return e.to_ == to && e.type() != edge::INVALID_EDGE; - }) != end(from->edges_); -} - -inline constant_graph build_interchange_graph( - mcd::vector const& station_nodes, uint32_t route_offset, - unsigned route_count, search_dir const dir) { - constant_graph g(route_offset + route_count); - - auto is_new = [&g, dir](uint32_t from, uint32_t to) { - auto const s = (dir == search_dir::FWD) ? to : from; - auto const t = (dir == search_dir::FWD) ? from : to; - return std::find_if(begin(g[s]), end(g[s]), [&t](simple_edge const& e) { - return e.to_ == t; - }) == end(g[s]); - }; - - auto add_edge = [&g, is_new, dir](uint32_t from, uint32_t to, bool is_exit) { - if (is_new(from, to)) { - auto const s = (dir == search_dir::FWD) ? to : from; - auto const t = (dir == search_dir::FWD) ? from : to; - g[s].emplace_back(t, dir == search_dir::FWD ? is_exit : !is_exit); - } - }; - - auto add_station_edges = [&g, route_offset, add_edge, dir, - is_new](station_node const* sn) { - for (auto const& e : sn->edges_) { - if (e.to_->is_foot_node() && e.to_->get_station() == sn) { - for (auto const& fe : e.to_->edges_) { - if (fe.to_->is_station_node() && is_new(sn->id_, fe.to_->id_)) { - auto const s = (dir == search_dir::FWD) ? fe.to_->id_ : sn->id_; - auto const t = (dir == search_dir::FWD) ? sn->id_ : fe.to_->id_; - g[s].emplace_back(t, false); - } - } - } else if (e.to_->is_route_node()) { - auto const route_lb_node_id = e.to_->route_ + route_offset; - - if (is_connected(sn, e.to_)) { - add_edge(sn->id_, route_lb_node_id, false); - } - - if (is_connected(e.to_, sn)) { - add_edge(route_lb_node_id, sn->id_, true); - } - } - } - }; - - for (auto const& sn : station_nodes) { - add_station_edges(sn.get()); - } - - return g; -} - -//============================================================================= -// DIJKSTRA -//----------------------------------------------------------------------------- -template -class constant_graph_dijkstra { -public: - using dist_t = uint32_t; - - struct label { - label(uint32_t node, uint32_t dist) : node_(node), dist_(dist) {} - - friend bool operator>(label const& a, label const& b) { - return a.dist_ > b.dist_; - } - - uint32_t node_; - dist_t dist_; - }; - - struct get_bucket { - std::size_t operator()(label const& l) const { return l.dist_; } - }; - - enum : dist_t { UNREACHABLE = std::numeric_limits::max() }; - - constant_graph_dijkstra( - constant_graph const& g, std::vector const& goals, - mcd::hash_map> const& additional_edges, - MapNodeFn map_node = MapNodeFn()) - : graph_(g), - additional_edges_(additional_edges), - map_node_(std::forward(map_node)) { - dists_.resize(graph_.size(), UNREACHABLE); - for (auto const& goal : goals) { - dists_[goal] = 0; - pq_.push(label(goal, 0)); - } - } - - inline dist_t operator[](node const* n) const { - auto const idx = map_node_(n); - assert(idx < dists_.size()); - return dists_[idx]; - } - - void run() { - while (!pq_.empty()) { - auto label = pq_.top(); - pq_.pop(); - - for (auto const& edge : graph_[label.node_]) { - expand_edge(label.dist_, edge); - } - - auto additional_edges_it = additional_edges_.find(label.node_); - if (additional_edges_it != std::end(additional_edges_)) { - for (auto const& edge : additional_edges_it->second) { - expand_edge(label.dist_, edge); - } - } - } - } - - inline void expand_edge(uint32_t dist, simple_edge const& edge) { - uint32_t new_dist = dist + edge.cost_; // NOLINT - if (new_dist < dists_[edge.to_] && new_dist <= MaxValue) { - dists_[edge.to_] = new_dist; - pq_.push(label(edge.to_, new_dist)); - } - } - - inline bool is_reachable(dist_t val) const { return val != UNREACHABLE; } - - constant_graph const& graph_; - dial pq_; - mcd::vector dists_; - mcd::hash_map> const& additional_edges_; - MapNodeFn map_node_; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/delay_info.h b/base/core/include/motis/core/schedule/delay_info.h deleted file mode 100644 index ef608cf7e..000000000 --- a/base/core/include/motis/core/schedule/delay_info.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/event.h" -#include "motis/core/schedule/time.h" -#include "motis/core/schedule/timestamp_reason.h" - -namespace motis { - -struct delay_info { - inline time get_schedule_time() const { return schedule_time_; } - inline time get_is_time() const { return is_time_; } - inline time get_repair_time() const { return repair_time_; } - inline time get_forecast_time() const { return forecast_time_; } - inline time get_propagation_time() const { return propagation_time_; } - - inline void update(delay_info const& d) { - if (schedule_time_ == 0) { - *this = d; - } else { - if (d.forecast_time_ != 0) { - forecast_time_ = d.forecast_time_; - } - if (d.propagation_time_ != 0) { - propagation_time_ = d.propagation_time_; - } - if (is_time_ != 0) { - is_time_ = d.is_time_; - } - } - } - - inline bool set(timestamp_reason const r, time const t) { - auto const before = get_current_time(); - - switch (r) { - case timestamp_reason::REPAIR: repair_time_ = t; break; - case timestamp_reason::SCHEDULE: schedule_time_ = t; break; - case timestamp_reason::IS: is_time_ = t; break; - case timestamp_reason::FORECAST: forecast_time_ = t; break; - case timestamp_reason::PROPAGATION: propagation_time_ = t; break; - } - - if (r != timestamp_reason::REPAIR) { - repair_time_ = 0; - } - - return get_current_time() != before; - } - - inline time get(timestamp_reason const r) const { - switch (r) { - case timestamp_reason::REPAIR: return repair_time_; - case timestamp_reason::IS: return is_time_; - case timestamp_reason::SCHEDULE: return schedule_time_; - case timestamp_reason::PROPAGATION: return propagation_time_; - case timestamp_reason::FORECAST: return forecast_time_; - default: return schedule_time_; - } - } - - inline time get_current_time() const { return get(get_reason()); } - - inline time get_original_time() const { return get(get_original_reason()); } - - inline timestamp_reason get_reason() const { - if (repair_time_ != 0) { - return timestamp_reason::REPAIR; - } - return get_original_reason(); - } - - inline timestamp_reason get_original_reason() const { - if (is_time_ != 0) { - return timestamp_reason::IS; - } else { - auto const times = { - std::make_pair(schedule_time_, timestamp_reason::SCHEDULE), - std::make_pair(forecast_time_, timestamp_reason::FORECAST), - std::make_pair(propagation_time_, timestamp_reason::PROPAGATION)}; - return std::max_element(begin(times), end(times))->second; - } - } - - inline ev_key const& get_ev_key() const { return ev_; } - inline ev_key const& get_orig_ev_key() const { return orig_ev_; } - - inline void set_ev_key(ev_key const& k) { ev_ = k; } - - ev_key ev_, orig_ev_{ev_}; - time repair_time_{0U}, is_time_{0U}; - time schedule_time_{ev_.get_time()}, forecast_time_{0U}, - propagation_time_{0U}; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/edges.h b/base/core/include/motis/core/schedule/edges.h deleted file mode 100644 index 69edae71d..000000000 --- a/base/core/include/motis/core/schedule/edges.h +++ /dev/null @@ -1,614 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/vector.h" - -#include "motis/core/common/constants.h" -#include "motis/core/schedule/connection.h" -#include "motis/core/schedule/time.h" - -namespace motis { - -struct node; - -struct edge_cost { - edge_cost() - : connection_(nullptr), - time_(INVALID_TIME), - price_(0), - transfer_(false), - accessibility_(0) {} - - edge_cost(duration time, light_connection const* c) - : connection_(c), - time_(time), - price_(0), - transfer_(false), - accessibility_(0) {} - - explicit edge_cost(duration time, bool transfer = false, uint16_t price = 0, - uint16_t accessibility = 0) - : connection_(nullptr), - time_(time), - price_(price), - transfer_(transfer), - accessibility_(accessibility) {} - - bool is_valid() const { return time_ != INVALID_TIME; } - - light_connection const* connection_; - duration time_; - uint16_t price_; - bool transfer_; - uint16_t accessibility_; -}; - -const edge_cost NO_EDGE = edge_cost(); - -enum class search_dir { FWD, BWD }; - -class edge { -public: - enum type { - INVALID_EDGE, - ROUTE_EDGE, - FOOT_EDGE, - AFTER_TRAIN_FWD_EDGE, - AFTER_TRAIN_BWD_EDGE, - MUMO_EDGE, - PERIODIC_MUMO_EDGE, - TIME_DEPENDENT_MUMO_EDGE, - HOTEL_EDGE, - THROUGH_EDGE, - ENTER_EDGE, - EXIT_EDGE, - FWD_EDGE, - BWD_EDGE - }; - - edge() : from_{nullptr}, to_{nullptr} {} - - /** route edge constructor. */ - edge(node* from, node* to, mcd::vector const& connections) - : from_(from), to_(to) { - m_.type_ = ROUTE_EDGE; - if (!connections.empty()) { - m_.route_edge_.init_empty(); - m_.route_edge_.conns_.set(std::begin(connections), std::end(connections)); - std::sort(std::begin(m_.route_edge_.conns_), - std::end(m_.route_edge_.conns_)); - } - } - - /** foot edge constructor. */ - edge(node* from, node* to, uint8_t type, uint16_t time_cost, uint16_t price, - bool transfer, int mumo_id = 0, uint16_t interval_begin = 0, - uint16_t interval_end = 0, uint16_t accessibility = 0) - : from_(from), to_(to) { - m_.type_ = type; - m_.foot_edge_.time_cost_ = time_cost; - m_.foot_edge_.price_ = price; - m_.foot_edge_.transfer_ = transfer; - m_.foot_edge_.mumo_id_ = mumo_id; - m_.foot_edge_.interval_begin_ = interval_begin; - m_.foot_edge_.interval_end_ = interval_end; - m_.foot_edge_.accessibility_ = accessibility; - - assert(m_.type_ != ROUTE_EDGE); - } - - /** hotel edge constructor. */ - edge(node* station_node, uint16_t checkout_time, uint16_t min_stay_duration, - uint16_t price, int mumo_id) - : from_(station_node), to_(station_node) { - m_.type_ = HOTEL_EDGE; - m_.hotel_edge_.checkout_time_ = checkout_time; - m_.hotel_edge_.min_stay_duration_ = min_stay_duration; - m_.hotel_edge_.price_ = price; - m_.hotel_edge_.mumo_id_ = mumo_id; - } - - template - edge_cost get_edge_cost(time start_time, - light_connection const* last_con) const { - switch (m_.type_) { - case ROUTE_EDGE: return get_route_edge_cost(start_time); - - case ENTER_EDGE: - if (Dir == search_dir::FWD) { - return get_foot_edge_no_cost(); - } else { - return last_con == nullptr ? NO_EDGE : get_foot_edge_cost(); - } - - case EXIT_EDGE: - if (Dir == search_dir::FWD) { - return last_con == nullptr ? NO_EDGE : get_foot_edge_cost(); - } else { - return get_foot_edge_no_cost(); - } - - case AFTER_TRAIN_FWD_EDGE: - if (Dir == search_dir::FWD) { - return last_con == nullptr ? NO_EDGE : get_foot_edge_cost(); - } else { - return NO_EDGE; - } - - case AFTER_TRAIN_BWD_EDGE: - if (Dir == search_dir::BWD) { - return last_con == nullptr ? NO_EDGE : get_foot_edge_cost(); - } else { - return NO_EDGE; - } - - case FWD_EDGE: - if (Dir == search_dir::FWD) { - return get_foot_edge_cost(); - } else { - return NO_EDGE; - } - - case BWD_EDGE: - if (Dir == search_dir::BWD) { - return get_foot_edge_cost(); - } else { - return NO_EDGE; - } - - case MUMO_EDGE: - case FOOT_EDGE: return get_foot_edge_cost(); - - case PERIODIC_MUMO_EDGE: - return edge_cost(calc_time_off(m_.foot_edge_.interval_begin_, - m_.foot_edge_.interval_end_, - start_time % MINUTES_A_DAY) + - m_.foot_edge_.time_cost_, - m_.foot_edge_.transfer_, m_.foot_edge_.price_); - - case TIME_DEPENDENT_MUMO_EDGE: - return calc_cost_time_dependent_edge(start_time); - - case HOTEL_EDGE: return calc_cost_hotel_edge(start_time); - - case THROUGH_EDGE: - return last_con == nullptr ? NO_EDGE : edge_cost(0, false, 0); - - default: return NO_EDGE; - } - } - - inline edge_cost get_foot_edge_cost() const { - return edge_cost(m_.foot_edge_.time_cost_, m_.foot_edge_.transfer_, - m_.foot_edge_.price_, m_.foot_edge_.accessibility_); - } - - static inline edge_cost get_foot_edge_no_cost() { - return edge_cost(0, false, 0, 0); - } - - edge_cost get_minimum_cost() const { - if (m_.type_ == INVALID_EDGE) { - return NO_EDGE; - } else if (m_.type_ == ROUTE_EDGE) { - if (m_.route_edge_.conns_.empty()) { - return NO_EDGE; - } else { - return edge_cost( - std::min_element( - std::begin(m_.route_edge_.conns_), - std::end(m_.route_edge_.conns_), - [](light_connection const& c1, light_connection const& c2) { - return c1.travel_time() < c2.travel_time(); - }) - ->travel_time(), - false, std::begin(m_.route_edge_.conns_)->full_con_->price_); - } - } else if (m_.type_ == FOOT_EDGE || m_.type_ == AFTER_TRAIN_FWD_EDGE || - m_.type_ == AFTER_TRAIN_BWD_EDGE || m_.type_ == ENTER_EDGE || - m_.type_ == EXIT_EDGE || m_.type_ == BWD_EDGE) { - return edge_cost(0, m_.foot_edge_.transfer_); - } else if (m_.type_ == HOTEL_EDGE) { - return edge_cost(0, false, m_.hotel_edge_.price_); - } else if (m_.type_ == MUMO_EDGE || m_.type_ == TIME_DEPENDENT_MUMO_EDGE) { - return edge_cost(0, false, m_.foot_edge_.price_, - m_.foot_edge_.accessibility_); - } else { - return edge_cost(0); - } - } - - inline light_connection const* get_next_valid_lcon(light_connection const* lc, - unsigned skip = 0) const { - assert(type() == ROUTE_EDGE); - assert(lc); - - auto it = lc; - while (it != end(m_.route_edge_.conns_)) { - if (skip == 0 && (it->valid_ != 0U)) { - return it; - } - ++it; - if (skip != 0) { - --skip; - } - } - return nullptr; - } - - inline light_connection const* get_prev_valid_lcon(light_connection const* lc, - unsigned skip = 0) const { - assert(type() == ROUTE_EDGE); - assert(lc); - - auto it = std::reverse_iterator(lc); - --it; - while (it != m_.route_edge_.conns_.rend()) { - if (skip == 0 && (it->valid_ != 0U)) { - return &*it; - } - ++it; - if (skip != 0) { - --skip; - } - } - return nullptr; - } - - template - light_connection const* get_connection(time const start_time) const { - assert(type() == ROUTE_EDGE); - - if (m_.route_edge_.conns_.empty()) { - return nullptr; - } - - if (Dir == search_dir::FWD) { - auto it = std::lower_bound(std::begin(m_.route_edge_.conns_), - std::end(m_.route_edge_.conns_), - light_connection(start_time)); - - if (it == std::end(m_.route_edge_.conns_)) { - return nullptr; - } else { - return get_next_valid_lcon(&*it); - } - } else { - auto it = std::lower_bound( - m_.route_edge_.conns_.rbegin(), m_.route_edge_.conns_.rend(), - light_connection(0, start_time, nullptr), - [](light_connection const& lhs, light_connection const& rhs) { - return lhs.a_time_ > rhs.a_time_; - }); - - if (it == m_.route_edge_.conns_.rend()) { - return nullptr; - } else { - return get_prev_valid_lcon(&*it); - } - } - } - - template - edge_cost get_route_edge_cost(time const start_time) const { - assert(type() == ROUTE_EDGE); - - light_connection const* c = get_connection(start_time); - return (c == nullptr) - ? NO_EDGE - : edge_cost((Dir == search_dir::FWD) ? c->a_time_ - start_time - : start_time - c->d_time_, - c); - } - - template - inline node const* get_destination() const { - return (Dir == search_dir::FWD) ? to_ : from_; - } - - template - inline node const* get_source() const { - return (Dir == search_dir::FWD) ? from_ : to_; - } - - inline node const* get_destination(search_dir dir = search_dir::FWD) const { - return (dir == search_dir::FWD) ? to_ : from_; - } - - inline node const* get_source(search_dir dir = search_dir::FWD) const { - return (dir == search_dir::FWD) ? from_ : to_; - } - - inline bool valid() const { return type() != INVALID_EDGE; } - - inline uint8_t type() const { return m_.type_; } - - inline char const* type_str() const { - switch (type()) { - case ROUTE_EDGE: return "ROUTE_EDGE"; - case FOOT_EDGE: return "FOOT_EDGE"; - case AFTER_TRAIN_FWD_EDGE: return "AFTER_TRAIN_FWD_EDGE"; - case AFTER_TRAIN_BWD_EDGE: return "AFTER_TRAIN_BWD_EDGE"; - case MUMO_EDGE: return "MUMO_EDGE"; - case TIME_DEPENDENT_MUMO_EDGE: return "TIME_DEPENDENT_MUMO_EDGE"; - case PERIODIC_MUMO_EDGE: return "PERIODIC_MUMO_EDGE"; - case HOTEL_EDGE: return "HOTEL_EDGE"; - case THROUGH_EDGE: return "THROUGH_EDGE"; - case ENTER_EDGE: return "ENTER_EDGE"; - case EXIT_EDGE: return "EXIT_EDGE"; - case FWD_EDGE: return "FWD_EDGE"; - case BWD_EDGE: return "BWD_EDGE"; - default: return "INVALID"; - } - } - - int get_mumo_id() const { - switch (type()) { - case TIME_DEPENDENT_MUMO_EDGE: - case PERIODIC_MUMO_EDGE: - case AFTER_TRAIN_FWD_EDGE: - case AFTER_TRAIN_BWD_EDGE: [[fallthrough]]; - case MUMO_EDGE: return m_.foot_edge_.mumo_id_; - case HOTEL_EDGE: return m_.hotel_edge_.mumo_id_; - default: return -1; - } - } - - inline bool empty() const { - return type() != ROUTE_EDGE || m_.route_edge_.conns_.empty(); - } - - static time calc_time_off(time const period_begin, time const period_end, - time const timestamp) { - assert(period_begin < MINUTES_A_DAY); - assert(period_end < MINUTES_A_DAY); - assert(timestamp < MINUTES_A_DAY); - - /* validity-period begins and ends at the same day */ - if (period_begin <= period_end) { - if (timestamp < period_begin) { - return period_begin - timestamp; - } else if (timestamp > period_end) { - return (MINUTES_A_DAY - timestamp) + period_begin; - } - } - /* validity-period is over midnight */ - else if (timestamp > period_end && timestamp < period_begin) { - return period_begin - timestamp; - } - - return 0; - } - - ptr from_; - ptr to_; - - union edge_details { - edge_details() { // NOLINT - std::memset(static_cast(this), 0, sizeof(*this)); // NOLINT - } - - edge_details(edge_details&& other) noexcept { // NOLINT - type_ = other.type_; - if (type_ == ROUTE_EDGE) { - route_edge_.init_empty(); - route_edge_ = std::move(other.route_edge_); - } else if (type_ == HOTEL_EDGE) { - hotel_edge_ = other.hotel_edge_; - } else { - foot_edge_ = other.foot_edge_; - } - } - - edge_details(edge_details const& other) { // NOLINT - type_ = other.type_; - if (type_ == ROUTE_EDGE) { - route_edge_.init_empty(); - route_edge_ = other.route_edge_; - } else if (type_ == HOTEL_EDGE) { - hotel_edge_ = other.hotel_edge_; - } else { - foot_edge_.init_empty(); - foot_edge_ = other.foot_edge_; - } - } - - edge_details& operator=(edge_details&& other) noexcept { - type_ = other.type_; - if (type_ == ROUTE_EDGE) { - route_edge_.init_empty(); - route_edge_ = std::move(other.route_edge_); - } else if (type_ == HOTEL_EDGE) { - hotel_edge_ = other.hotel_edge_; - } else { - foot_edge_.init_empty(); - foot_edge_ = other.foot_edge_; - } - - return *this; - } - - edge_details& operator=(edge_details const& other) { - if (this == &other) { - return *this; - } - - type_ = other.type_; - if (type_ == ROUTE_EDGE) { - route_edge_.init_empty(); - route_edge_ = other.route_edge_; - } else if (type_ == HOTEL_EDGE) { - hotel_edge_ = other.hotel_edge_; - } else { - foot_edge_.init_empty(); - foot_edge_ = other.foot_edge_; - } - - return *this; - } - - ~edge_details() { - if (type_ == ROUTE_EDGE) { - using Type = decltype(route_edge_.conns_); - route_edge_.conns_.~Type(); - } - } - - // placeholder - uint8_t type_; - - // TYPE = ROUTE_EDGE - struct re { - uint8_t type_padding_; - mcd::vector conns_; - - void init_empty() { new (&conns_) mcd::vector(); } - } route_edge_; - - // TYPE = FOOT_EDGE & CO - struct fe { - uint8_t type_padding_; - - // edge weight - uint16_t time_cost_; - uint16_t price_; - bool transfer_; - - // id for mumo edge - int32_t mumo_id_; - - // interval: time-dependent/periodic mumo edge - uint16_t interval_begin_; - uint16_t interval_end_; - - uint16_t accessibility_; - - void init_empty() { - time_cost_ = 0; - price_ = 0; - transfer_ = false; - mumo_id_ = -1; - accessibility_ = 0; - } - } foot_edge_; - - // TYPE = HOTEL_EDGE - struct he { - uint8_t type_padding_; - uint16_t checkout_time_; - uint16_t min_stay_duration_; - uint16_t price_; - uint32_t mumo_id_; - } hotel_edge_; - } m_; - -private: - edge_cost calc_cost_time_dependent_edge(time const start_time) const { - if (start_time > m_.foot_edge_.interval_end_) { - return NO_EDGE; - } - auto const time_off = - std::max(0, m_.foot_edge_.interval_begin_ - start_time); - return edge_cost(time_off + m_.foot_edge_.time_cost_, - m_.foot_edge_.transfer_, m_.foot_edge_.price_); - } - - edge_cost calc_cost_hotel_edge(time const start_time) const { - uint16_t const offset = - start_time % MINUTES_A_DAY < m_.hotel_edge_.checkout_time_ - ? 0 - : MINUTES_A_DAY; - auto const duration = std::max( - m_.hotel_edge_.min_stay_duration_, - static_cast((m_.hotel_edge_.checkout_time_ + offset) - - (start_time % MINUTES_A_DAY))); - return edge_cost(duration, false, m_.hotel_edge_.price_); - } -}; - -/* convenience helper functions to generate the right edge type */ - -inline edge make_route_edge(node* from, node* to, - mcd::vector const& connections) { - return edge(from, to, connections); -} - -inline edge make_foot_edge(node* from, node* to, uint16_t time_cost = 0, - bool transfer = false) { - return edge(from, to, edge::FOOT_EDGE, time_cost, 0, transfer); -} - -inline edge make_after_train_fwd_edge(node* from, node* to, - uint16_t time_cost = 0, - bool transfer = false, int mumo_id = 0) { - return edge(from, to, edge::AFTER_TRAIN_FWD_EDGE, time_cost, 0, transfer, - mumo_id); -} - -inline edge make_after_train_bwd_edge(node* from, node* to, - uint16_t time_cost = 0, - bool transfer = false, int mumo_id = 0) { - return edge(from, to, edge::AFTER_TRAIN_BWD_EDGE, time_cost, 0, transfer, - mumo_id); -} - -inline edge make_mumo_edge(node* from, node* to, uint16_t time_cost = 0, - uint16_t price = 0, uint16_t accessibility = 0, - int mumo_id = 0) { - return edge(from, to, edge::MUMO_EDGE, time_cost, price, false, mumo_id, 0, 0, - accessibility); -} - -inline edge make_time_dependent_mumo_edge(node* from, node* to, - uint16_t time_cost, uint16_t price, - int mumo_id, uint16_t interval_begin, - uint16_t interval_end) { - return edge(from, to, edge::TIME_DEPENDENT_MUMO_EDGE, time_cost, price, false, - mumo_id, interval_begin, interval_end); -} - -inline edge make_periodic_mumo_edge(node* from, node* to, uint16_t time_cost, - uint16_t price, int mumo_id, - uint16_t interval_begin, - uint16_t interval_end) { - return edge(from, to, edge::PERIODIC_MUMO_EDGE, time_cost, price, false, - mumo_id, interval_begin, interval_end); -} - -inline edge make_hotel_edge(node* station_node, uint16_t checkout_time, - uint16_t min_stay_duration, uint16_t price, - int mumo_id) { - return edge(station_node, checkout_time, min_stay_duration, price, mumo_id); -} - -inline edge make_invalid_edge(node* from, node* to) { - return edge(from, to, edge::INVALID_EDGE, 0, 0, false, 0); -} - -inline edge make_through_edge(node* from, node* to) { - return edge(from, to, edge::THROUGH_EDGE, 0, 0, false, 0); -} - -inline edge make_enter_edge(node* from, node* to, uint16_t time_cost = 0, - bool transfer = false) { - return edge(from, to, edge::ENTER_EDGE, time_cost, 0, transfer); -} - -inline edge make_exit_edge(node* from, node* to, uint16_t time_cost = 0, - bool transfer = false) { - return edge(from, to, edge::EXIT_EDGE, time_cost, 0, transfer); -} - -inline edge make_fwd_edge(node* from, node* to, uint16_t time_cost = 0, - bool transfer = false) { - return edge(from, to, edge::FWD_EDGE, time_cost, 0, transfer); -} - -inline edge make_bwd_edge(node* from, node* to, uint16_t time_cost = 0, - bool transfer = false) { - return edge(from, to, edge::BWD_EDGE, time_cost, 0, transfer); -} - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/event.h b/base/core/include/motis/core/schedule/event.h deleted file mode 100644 index 8a89b7843..000000000 --- a/base/core/include/motis/core/schedule/event.h +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "cista/reflection/comparable.h" - -#include "motis/core/common/hash_helper.h" -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/event_type.h" -#include "motis/core/schedule/time.h" -#include "motis/core/schedule/trip.h" - -namespace motis { - -struct node; - -struct ev_key { - CISTA_COMPARABLE() - - bool is_not_null() const { return route_edge_.is_not_null(); } - - bool is_arrival() const { return ev_type_ == event_type::ARR; } - bool is_departure() const { return ev_type_ == event_type::DEP; } - - bool lcon_is_valid() const { return is_not_null() && lcon()->valid_ != 0U; } - - explicit operator bool() const { return is_not_null(); } - - ev_key get_opposite() const { - auto const ev_type = - ev_type_ == event_type::ARR ? event_type::DEP : event_type::ARR; - return {route_edge_, lcon_idx_, ev_type}; - } - - light_connection const* lcon() const { - return &route_edge_->m_.route_edge_.conns_[lcon_idx_]; - } - - time get_time() const { - return is_not_null() - ? ev_type_ == event_type::DEP ? lcon()->d_time_ : lcon()->a_time_ - : INVALID_TIME; - } - - bool is_canceled() const { return lcon()->valid_ == 0U; } - - int get_track() const { - auto const full_con = lcon()->full_con_; - return is_arrival() ? full_con->a_track_ : full_con->d_track_; - } - - node* get_node() const { - return ev_type_ == event_type::DEP ? route_edge_->from_ : route_edge_->to_; - } - - uint32_t get_station_idx() const { return get_node()->get_station()->id_; } - - cista::hash_t hash() const { - return cista::build_hash(route_edge_, lcon_idx_, ev_type_); - } - - trip::route_edge route_edge_{nullptr}; - lcon_idx_t lcon_idx_{0}; - event_type ev_type_{event_type::DEP}; -}; - -} // namespace motis \ No newline at end of file diff --git a/base/core/include/motis/core/schedule/interval.h b/base/core/include/motis/core/schedule/interval.h deleted file mode 100644 index dd0367f70..000000000 --- a/base/core/include/motis/core/schedule/interval.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "motis/core/schedule/time.h" - -namespace motis { - -struct interval { - motis::time begin_{INVALID_TIME}; - motis::time end_{INVALID_TIME}; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/nodes.h b/base/core/include/motis/core/schedule/nodes.h deleted file mode 100644 index ed03a3f55..000000000 --- a/base/core/include/motis/core/schedule/nodes.h +++ /dev/null @@ -1,137 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "motis/memory.h" -#include "motis/vector.h" - -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/time.h" - -namespace motis { - -enum class node_type : uint8_t { - STATION_NODE, - ROUTE_NODE, - FOOT_NODE, - PLATFORM_NODE -}; - -struct node; - -using station_node = node; - -using node_id_t = uint32_t; - -struct node { - inline bool is_station_node() const { - return type_ == node_type::STATION_NODE; - } - inline bool is_route_node() const { return type_ == node_type::ROUTE_NODE; } - inline bool is_foot_node() const { return type_ == node_type::FOOT_NODE; } - inline bool is_platform_node() const { - return type_ == node_type::PLATFORM_NODE; - } - - inline node_type type() const { return type_; } - - char const* type_str() const { - switch (type_) { - case node_type::STATION_NODE: return "STATION_NODE"; - case node_type::ROUTE_NODE: return "ROUTE_NODE"; - case node_type::FOOT_NODE: return "FOOT_NODE"; - case node_type::PLATFORM_NODE: return "PLATFORM_NODE"; - default: return "UNKNOWN_NODE"; - } - } - - station_node* as_station_node() { - if (station_node_ == nullptr) { - return reinterpret_cast(this); - } else { - return nullptr; - } - } - - station_node const* as_station_node() const { - if (station_node_ == nullptr) { - return reinterpret_cast(this); - } else { - return nullptr; - } - } - - station_node* get_station() { - if (station_node_ == nullptr) { - return reinterpret_cast(this); - } else { - return station_node_; - } - } - - station_node const* get_station() const { - if (station_node_ == nullptr) { - return reinterpret_cast(this); - } else { - return station_node_; - } - } - - template - void for_each_route_node(Fn&& f) const { - for (auto& edge : edges_) { - if (edge.to_->is_route_node()) { - f(edge.to_); - } - } - } - - bool is_in_allowed() const { - assert(is_route_node()); - return std::any_of( - begin(incoming_edges_), end(incoming_edges_), [&](auto const& e) { - return e->from_ == station_node_ && e->type() != edge::INVALID_EDGE; - }); - } - - bool is_out_allowed() const { - assert(is_route_node()); - return std::any_of(begin(edges_), end(edges_), [&](auto const& e) { - return e.to_ == station_node_ && e.type() != edge::INVALID_EDGE; - }); - } - - mcd::indexed_vector edges_; - mcd::vector> incoming_edges_; - ptr station_node_{nullptr}; - int32_t route_{-1}; - node_id_t id_{0}; - node_type type_{node_type::STATION_NODE}; - - // Station Node Properties - mcd::unique_ptr foot_node_; - mcd::vector> child_nodes_; - mcd::vector platform_nodes_; -}; - -inline node make_node(node_type const type, node* station_node, - node_id_t const node_id, int32_t const route = -1) { - node n; - n.type_ = type; - n.station_node_ = station_node; - n.id_ = node_id; - n.route_ = route; - return n; -} - -inline station_node make_station_node(node_id_t const id) { - return make_node(node_type::STATION_NODE, nullptr, id); -} - -using station_node_ptr = mcd::unique_ptr; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/price.h b/base/core/include/motis/core/schedule/price.h deleted file mode 100644 index 43a696675..000000000 --- a/base/core/include/motis/core/schedule/price.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "utl/verify.h" - -#include "motis/core/schedule/connection.h" -#include "motis/core/schedule/station.h" - -#ifndef M_PI -#define M_PI (3.14159265359) -#endif - -#define d2r (M_PI / 180.0) - -namespace motis { - -inline int get_price_per_km(service_class const clasz) { - switch (clasz) { - case service_class::AIR: return 25; - - case service_class::ICE: return 22; - - case service_class::N: - case service_class::IC: - case service_class::SHIP: - case service_class::OTHER: return 18; - - case service_class::RE: - case service_class::RB: - case service_class::S: - case service_class::U: - case service_class::STR: - case service_class::BUS: return 15; - - case service_class::COACH: return 12; - - default: throw utl::fail("unknown service class: {} ", to_str(clasz)); - } -} - -inline double get_distance(const station& s1, const station& s2) { - double lat1 = s1.width_, long1 = s1.length_; - double lat2 = s2.width_, long2 = s2.length_; - double dlong = (long2 - long1) * d2r; - double dlat = (lat2 - lat1) * d2r; - double a = pow(sin(dlat / 2.0), 2) + - cos(lat1 * d2r) * cos(lat2 * d2r) * pow(sin(dlong / 2.0), 2); - double c = 2 * atan2(sqrt(a), sqrt(1 - a)); - double d = 6367 * c; - return d; -} - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/print.h b/base/core/include/motis/core/schedule/print.h deleted file mode 100644 index 1fa556d49..000000000 --- a/base/core/include/motis/core/schedule/print.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include - -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/nodes.h" -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/service_access.h" - -namespace motis { - -void print_edge(edge const& edge, std::ostream& out, int indent); -void print_node(node const& node, std::ostream& out, int indent, - bool print_recursive); - -struct indentation { - explicit indentation(unsigned indent) : indent_(indent) {} - - friend std::ostream& operator<<(std::ostream& out, indentation const& ind) { - for (unsigned i = 0; i < ind.indent_; ++i) out << " "; - return out; - } - - unsigned indent_; -}; - -inline std::ostream& operator<<(std::ostream& out, - light_connection const& con) { - return out << "dep=" << con.d_time_ << ", " - << "arr=" << con.a_time_ << ", " - << "train_nr=" << con.full_con_->con_info_->train_nr_ << ", " - << (con.valid_ ? "" : "valid=false"); -} - -inline void print_node(node const& node, std::ostream& out, int indent, - bool print_recursive) { - out << "node_id=" << node.id_ << " [" << node.type_str() << "]"; - if (node.is_route_node()) { - out << " [route=" << node.route_ << "]"; - } - out << " [#edges=" << node.edges_.size() << "]:\n"; - for (unsigned i = 0; i < node.edges_.size(); ++i) { - out << indentation(indent + 1) << "edge[" << i << "]: "; - print_edge(node.edges_.el_[i], out, indent + 1); - - if (print_recursive) { - out << indentation(indent + 2); - print_node(*node.edges_.el_[i].to_, out, indent + 2, false); - } - } -} - -inline void print_edge(edge const& edge, std::ostream& out, int indent) { - out << "to=" << edge.to_->id_ << " [" << edge.to_->type_str() << "], "; - switch (edge.m_.type_) { - case edge::ROUTE_EDGE: { - out << "type=route_edge, " - << "[#connections=" << edge.m_.route_edge_.conns_.size() << "]:\n"; - for (unsigned i = 0; i < edge.m_.route_edge_.conns_.size(); ++i) { - out << indentation(indent + 1) << "connection[" << i - << "]: " << edge.m_.route_edge_.conns_.el_[i] << "\n"; - } - break; - } - - case edge::FOOT_EDGE: - out << "type=foot_edge, " - << "duration=" << edge.m_.foot_edge_.time_cost_ << ", " - << "transfer=" << std::boolalpha << edge.m_.foot_edge_.transfer_ - << ", " - << (edge.m_.foot_edge_.mumo_id_ == 0 - ? "" - : "mumo_id=" + std::to_string(static_cast( - edge.m_.foot_edge_.mumo_id_))) - << "\n"; - break; - - case edge::THROUGH_EDGE: out << "THROUGH\n"; break; - case edge::AFTER_TRAIN_FWD_EDGE: out << "AFTER_TRAIN_FWD\n"; break; - case edge::AFTER_TRAIN_BWD_EDGE: out << "AFTER_TRAIN_BWD\n"; break; - case edge::ENTER_EDGE: out << "ENTER\n"; break; - case edge::EXIT_EDGE: out << "EXIT\n"; break; - case edge::FWD_EDGE: out << "FWD\n"; break; - case edge::BWD_EDGE: out << "BWD\n"; break; - case edge::INVALID_EDGE: out << "NO_EDGE\n"; break; - - default: - out << "UNKNOWN [type=" << static_cast(edge.m_.type_) << "]\n"; - } -} - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/provider.h b/base/core/include/motis/core/schedule/provider.h deleted file mode 100644 index 0f3865dcb..000000000 --- a/base/core/include/motis/core/schedule/provider.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "motis/string.h" - -namespace motis { - -struct provider { - mcd::string short_name_; - mcd::string long_name_; - mcd::string full_name_; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/schedule.h b/base/core/include/motis/core/schedule/schedule.h deleted file mode 100644 index d19378fe5..000000000 --- a/base/core/include/motis/core/schedule/schedule.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include - -#include "boost/uuid/uuid.hpp" - -#include "cista/hash.h" -#include "cista/memory_holder.h" - -#include "motis/hash_map.h" -#include "motis/hash_set.h" -#include "motis/memory.h" -#include "motis/pair.h" -#include "motis/vector.h" - -#include "motis/core/common/dynamic_fws_multimap.h" -#include "motis/core/common/fws_multimap.h" -#include "motis/core/common/unixtime.h" -#include "motis/core/schedule/attribute.h" -#include "motis/core/schedule/category.h" -#include "motis/core/schedule/constant_graph.h" -#include "motis/core/schedule/delay_info.h" -#include "motis/core/schedule/event.h" -#include "motis/core/schedule/free_text.h" -#include "motis/core/schedule/nodes.h" -#include "motis/core/schedule/provider.h" -#include "motis/core/schedule/station.h" -#include "motis/core/schedule/trip.h" -#include "motis/core/schedule/waiting_time_rules.h" - -namespace motis { - -struct schedule { - unixtime first_event_schedule_time_{std::numeric_limits::max()}; - unixtime last_event_schedule_time_{std::numeric_limits::min()}; - unixtime schedule_begin_{0}, schedule_end_{0}; - mcd::vector prefixes_; - mcd::vector names_; - cista::hash_t hash_{0U}; - - mcd::vector stations_; - mcd::hash_map> eva_to_station_; - mcd::hash_map> ds100_to_station_; - mcd::hash_map classes_; - mcd::vector tracks_; - constant_graph travel_time_lower_bounds_fwd_; - constant_graph travel_time_lower_bounds_bwd_; - constant_graph transfers_lower_bounds_fwd_; - constant_graph transfers_lower_bounds_bwd_; - node_id_t next_node_id_{0U}; - node_id_t non_station_node_offset_{1'000'000U}; - uint32_t route_count_{0U}; - mcd::vector station_nodes_; - mcd::vector> route_index_to_first_route_node_; - mcd::hash_map> train_nr_to_routes_; - waiting_time_rules waiting_time_rules_; - - mcd::vector> full_connections_; - mcd::vector> connection_infos_; - mcd::vector> attributes_; - mcd::vector> categories_; - mcd::vector> providers_; - mcd::hash_map> provider_by_full_name_; - mcd::vector> directions_; - mcd::vector> timezones_; - - mcd::hash_map< - mcd::string, - mcd::vector>>> - gtfs_trip_ids_; - mcd::vector>> trips_; - mcd::vector> trip_mem_; - mcd::vector>> trip_edges_; - mcd::vector>>> merged_trips_; - mcd::vector> filenames_; - mcd::hash_map> uuid_to_trip_; - - unixtime system_time_{0U}, last_update_timestamp_{0U}; - mcd::vector> delay_mem_; - mcd::hash_map> graph_to_delay_info_; - mcd::hash_map graph_to_schedule_track_index_; - mcd::hash_map> graph_to_free_texts_; - mcd::hash_map> waits_for_trains_; - mcd::hash_map> trains_wait_for_; - - mcd::hash_map, ev_key>> - uuid_to_event_; - mcd::hash_map, ev_key>, boost::uuids::uuid> - event_to_uuid_; - - dynamic_fws_multimap> expanded_trips_; - dynamic_fws_multimap route_to_expanded_routes_; -}; - -using schedule_ptr = mcd::unique_ptr; - -struct schedule_data { - schedule_data(cista::memory_holder&& buf, schedule_ptr&& sched) - : schedule_buf_{std::move(buf)}, schedule_{std::move(sched)} {} - cista::memory_holder schedule_buf_; - schedule_ptr schedule_; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/serialization.h b/base/core/include/motis/core/schedule/serialization.h deleted file mode 100644 index f3cde7183..000000000 --- a/base/core/include/motis/core/schedule/serialization.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "cista/memory_holder.h" - -#include "motis/core/schedule/schedule.h" - -namespace motis { - -schedule_ptr read_graph(std::string const& path, cista::memory_holder&, - bool read_mmap); - -void write_graph(std::string const& path, schedule const&); - -schedule_data copy_graph(schedule const& sched); - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/station.h b/base/core/include/motis/core/schedule/station.h index c1d86da57..eb0d8c24d 100644 --- a/base/core/include/motis/core/schedule/station.h +++ b/base/core/include/motis/core/schedule/station.h @@ -13,7 +13,6 @@ #include "motis/string.h" #include "motis/vector.h" -#include "motis/core/schedule/connection.h" #include "motis/core/schedule/footpath.h" #include "motis/core/schedule/timezone.h" diff --git a/base/core/include/motis/core/schedule/station_lookup.h b/base/core/include/motis/core/schedule/station_lookup.h index d6b322ab4..b7d0848d7 100644 --- a/base/core/include/motis/core/schedule/station_lookup.h +++ b/base/core/include/motis/core/schedule/station_lookup.h @@ -60,20 +60,4 @@ struct station_lookup { std::unique_ptr rtree_; }; -struct schedule_station_lookup : public station_lookup { - schedule_station_lookup(schedule const&); - - schedule_station_lookup(schedule_station_lookup const&) = delete; - schedule_station_lookup(schedule_station_lookup&&) = delete; - schedule_station_lookup& operator=(schedule_station_lookup const&) = delete; - schedule_station_lookup& operator=(schedule_station_lookup&&) = delete; - virtual ~schedule_station_lookup() noexcept; - - lookup_station get(std::size_t idx) const override; - lookup_station get(std::string_view id) const override; - -private: - schedule const& sched_; -}; - } // namespace motis \ No newline at end of file diff --git a/base/core/include/motis/core/schedule/trip.h b/base/core/include/motis/core/schedule/trip.h deleted file mode 100644 index 384c9a0df..000000000 --- a/base/core/include/motis/core/schedule/trip.h +++ /dev/null @@ -1,184 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "boost/uuid/uuid.hpp" - -#include "cista/hashing.h" -#include "cista/offset_t.h" -#include "cista/reflection/comparable.h" - -#include "utl/to_vec.h" - -#include "motis/string.h" -#include "motis/vector.h" - -#include "motis/core/common/hash_helper.h" -#include "motis/core/common/unixtime.h" -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/nodes.h" - -namespace motis { - -struct primary_trip_id { - primary_trip_id() : station_id_{0}, time_{INVALID_TIME}, train_nr_{0} {} - primary_trip_id(uint32_t station_id, uint32_t train_nr, motis::time time) - : station_id_(station_id), time_(time), train_nr_(train_nr) {} - - friend bool operator<(primary_trip_id const& lhs, - primary_trip_id const& rhs) { - uint64_t a = 0, b = 0; - std::memcpy(&a, &lhs, sizeof(a)); - std::memcpy(&b, &rhs, sizeof(b)); - return a < b; - } - - friend bool operator==(primary_trip_id const& lhs, - primary_trip_id const& rhs) { - uint64_t a = 0, b = 0; - std::memcpy(&a, &lhs, sizeof(a)); - std::memcpy(&b, &rhs, sizeof(b)); - return a == b; - } - - uint32_t get_station_id() const { return static_cast(station_id_); } - motis::time get_time() const { return static_cast(time_); } - uint32_t get_train_nr() const { return static_cast(train_nr_); } - - cista::hash_t hash() const { - return cista::build_hash(station_id_, time_, train_nr_); - } - - uint64_t station_id_ : 31; - uint64_t time_ : 16; - uint64_t train_nr_ : 17; -}; - -struct secondary_trip_id { - CISTA_COMPARABLE(); - uint32_t target_station_id_{0U}; - motis::time target_time_{INVALID_TIME}; - mcd::string line_id_; -}; - -struct trip_debug { - trip_debug() = default; - - trip_debug(mcd::string* file, int line_from, int line_to) - : file_{file}, line_from_{line_from}, line_to_{line_to} {} - - friend std::ostream& operator<<(std::ostream& out, trip_debug const& dbg) { - return out << dbg.str(); - } - - std::string str() const { - return file_ == nullptr ? "" - : static_cast(*file_) + ":" + - std::to_string(line_from_) + ":" + - std::to_string(line_to_); - } - - ptr file_{nullptr}; - int line_from_{0}, line_to_{0}; -}; - -struct full_trip_id { - friend bool operator<(full_trip_id const& lhs, full_trip_id const& rhs) { - return std::tie(lhs.primary_, lhs.secondary_) < - std::tie(rhs.primary_, rhs.secondary_); - } - - friend bool operator==(full_trip_id const& lhs, full_trip_id const& rhs) { - return std::tie(lhs.primary_, lhs.secondary_) == - std::tie(rhs.primary_, rhs.secondary_); - } - - primary_trip_id primary_; - secondary_trip_id secondary_; -}; - -struct gtfs_trip_id { - gtfs_trip_id() = default; - gtfs_trip_id(std::string const& dataset_prefix, std::string const& trip_id, - std::optional start_date) - : trip_id_{dataset_prefix + trip_id}, start_date_{start_date} {} - friend std::ostream& operator<<(std::ostream& out, gtfs_trip_id const&); - bool operator<(gtfs_trip_id const& o) const { - return std::tie(trip_id_, start_date_) < - std::tie(o.trip_id_, o.start_date_); - } - bool operator==(gtfs_trip_id const& o) const { - return std::tie(trip_id_, start_date_) == - std::tie(o.trip_id_, o.start_date_); - } - bool operator!=(gtfs_trip_id const& o) const { - return std::tie(trip_id_, start_date_) != - std::tie(o.trip_id_, o.start_date_); - } - mcd::string trip_id_; - std::optional start_date_; -}; - -using trip_idx_t = uint32_t; - -struct trip { - struct route_edge { - route_edge() = default; - - route_edge(edge const* e) { // NOLINT - if (e != nullptr) { - route_node_ = e->from_; - outgoing_edge_idx_ = route_node_->edges_.index_of(e); - } - } - -#if defined(MOTIS_SCHEDULE_MODE_OFFSET) - route_edge(ptr e) : route_edge(e.get()) {} // NOLINT -#endif - - friend bool operator==(route_edge const& a, route_edge const& b) { - return std::tie(a.route_node_, a.outgoing_edge_idx_) == - std::tie(b.route_node_, b.outgoing_edge_idx_); - } - - friend bool operator<(route_edge const& a, route_edge const& b) { - return std::tie(a.route_node_, a.outgoing_edge_idx_) < - std::tie(b.route_node_, b.outgoing_edge_idx_); - } - - bool is_not_null() const { return route_node_ != nullptr; } - - edge* get_edge() const { - assert(outgoing_edge_idx_ < route_node_->edges_.size()); - return &route_node_->edges_[outgoing_edge_idx_]; - } - - edge* operator->() const { return get_edge(); } - - operator edge*() const { return get_edge(); } // NOLINT - - cista::hash_t hash() const { - return cista::build_hash(route_node_ != nullptr ? route_node_->id_ : 0U, - outgoing_edge_idx_); - } - - ptr route_node_{nullptr}; - uint32_t outgoing_edge_idx_{0}; - }; - - full_trip_id id_; - mcd::string gtfs_trip_id_; - ptr const> edges_{nullptr}; - lcon_idx_t lcon_idx_{0U}; - trip_idx_t trip_idx_{0U}; // position in schedule.trip_mem_ - trip_debug dbg_; - mcd::vector stop_seq_numbers_; - boost::uuids::uuid uuid_{}; - bool unscheduled_{false}; - ptr original_first_connection_info_{}; - service_class original_first_clasz_{service_class::OTHER}; -}; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/trip_idx.h b/base/core/include/motis/core/schedule/trip_idx.h deleted file mode 100644 index 6b4d96978..000000000 --- a/base/core/include/motis/core/schedule/trip_idx.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -namespace motis { - -using merged_trips_idx = uint32_t; - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/validate_graph.h b/base/core/include/motis/core/schedule/validate_graph.h deleted file mode 100644 index 9b08bafdc..000000000 --- a/base/core/include/motis/core/schedule/validate_graph.h +++ /dev/null @@ -1,210 +0,0 @@ -#pragma once - -#include - -#include "utl/verify.h" - -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/service_access.h" -#include "motis/core/access/trip_iterator.h" -#include "motis/core/debug/trip.h" - -namespace motis { - -inline bool incoming_edges_correct_2(schedule const& sched) { - auto const check_edges = [](node const* n) { - return std::all_of( - begin(n->incoming_edges_), end(n->incoming_edges_), [n](edge* const e) { - auto const& out = e->from_->edges_; - return e->to_ == n && e >= out.begin() && e < out.end(); - }); - }; - - return std::all_of( - begin(sched.station_nodes_), end(sched.station_nodes_), [&](auto&& sn) { - return check_edges(sn.get()) && - std::all_of( - begin(sn->incoming_edges_), end(sn->incoming_edges_), - [&](auto const& e) { return check_edges(e->from_); }); - }); -} - -inline void validate_graph(schedule const& sched) { - utl::verify( - [&] { - for (auto const& sn : sched.station_nodes_) { - for (auto const& se : sn->edges_) { - if (se.to_->type() != node_type::ROUTE_NODE) { - continue; - } - - for (auto const& re : se.to_->edges_) { - if (re.empty()) { - continue; - } - - auto const& lcons = re.m_.route_edge_.conns_; - auto const is_sorted_dep = std::is_sorted( - begin(lcons), end(lcons), - [](light_connection const& a, light_connection const& b) { - return a.d_time_ < b.d_time_; - }); - auto const is_sorted_arr = std::is_sorted( - begin(lcons), end(lcons), - [](light_connection const& a, light_connection const& b) { - return a.a_time_ < b.a_time_; - }); - if (!is_sorted_dep || !is_sorted_arr) { - return false; - } - } - } - } - return true; - }(), - "all light connections sorted after rt update"); - - utl::verify( - [&] { - auto const check_edges = [](node const* n) { - return std::all_of( - begin(n->edges_), end(n->edges_), [n](edge const& e) { - auto const in = e.to_->incoming_edges_; - return e.from_ == n && - std::find(begin(in), end(in), &e) != end(in); - }); - }; - - return std::all_of( - begin(sched.station_nodes_), end(sched.station_nodes_), - [&](mcd::unique_ptr const& sn) { - return check_edges(sn.get()) && - std::all_of( - begin(sn->edges_), end(sn->edges_), - [&](auto const& e) { return check_edges(e.to_); }); - }); - }(), - "incoming edges correct 1"); - - utl::verify(incoming_edges_correct_2(sched), "incoming edges correct 2"); - - auto const check_edges = [](node const* n) { - return std::all_of(begin(n->edges_), end(n->edges_), - [&](edge const& e) { return e.from_ == n; }) && - std::all_of(begin(n->incoming_edges_), end(n->incoming_edges_), - [&](edge const* e) { return e->to_ == n; }); - }; - - utl::verify( - [&]() { - return std::all_of( - begin(sched.station_nodes_), end(sched.station_nodes_), - [&](auto&& sn) { - return check_edges(sn.get()) && - std::all_of(begin(sn->child_nodes_), end(sn->child_nodes_), - [&](auto&& n) { - return n->get_station() == sn.get() && - check_edges(n.get()); - }) && - (sn->foot_node_.get() == nullptr || - (sn->foot_node_->get_station() == sn.get() && - check_edges(sn->foot_node_.get()))); - }); - }(), - "edge from pointer correct"); - - utl::verify( - [&] { - for (auto const route : sched.expanded_trips_) { - auto const route_idx = route.index(); - auto route_trip_idx = 0U; - for (auto const& tp : route) { - time last_time = 0; - for (auto const sec : access::sections{tp}) { - auto const& lc = sec.lcon(); - auto const section_times_ok = lc.d_time_ <= lc.a_time_; - auto const stop_times_ok = last_time <= lc.d_time_; - last_time = lc.a_time_; - if (!section_times_ok || !stop_times_ok) { - std::cout << "\nvalidate_graph: expanded trip times " - "inconsistent (expanded route " - << route_idx << ", expanded trip " - << route.data_index(route_trip_idx) << ", " - << route_trip_idx << "/" << route.size() - << " in route):\n" - << debug::trip_with_sections{sched, tp} << "\n"; - return false; - } - } - ++route_trip_idx; - } - } - return true; - }(), - "expanded trip times consistent"); -} - -inline void print_graph(schedule const& sched) { - auto const indent_line = [](size_t const indent) { - for (auto i = 0U; i != indent; ++i) { - std::cerr << " "; - } - }; - - auto const station_name = [&](node const* n) { - return sched.stations_.at(n->get_station()->id_)->name_; - }; - - std::cerr << "\n\nGraph:\n"; - auto const print_edge = [&](edge const* e, size_t const indent) { - indent_line(indent); - std::cerr << e->type_str() << ": " << station_name(e->from_) << " -> " - << station_name(e->to_) << "[" << e->to_->id_ << "]\n"; - if (!e->empty()) { - for (auto const& lcon : e->m_.route_edge_.conns_) { - indent_line(indent + 1); - - auto con_info = lcon.full_con_->con_info_; - while (con_info != nullptr) { - std::cerr << get_service_name(sched, con_info); - con_info = con_info->merged_with_; - if (con_info != nullptr) { - std::cerr << "|"; - } - } - - std::cerr << ", dep=" << format_time(lcon.d_time_) - << ", arr=" << format_time(lcon.a_time_); - std::cerr << "}\n"; - } - } - }; - - auto const print_node = [&](node const* n, size_t const indent) { - indent_line(indent); - std::cerr << "id=" << n->id_ << ", " << n->type_str() << " at " - << station_name(n) << ":" << std::endl; - - indent_line(indent + 1); - std::cerr << n->edges_.size() << " outgoing edges:" << std::endl; - for (auto const& e : n->edges_) { - print_edge(&e, indent + 2); - } - - indent_line(indent + 1); - std::cerr << n->incoming_edges_.size() << " incoming edges:" << std::endl; - for (auto const& e : n->incoming_edges_) { - print_edge(e, indent + 2); - } - }; - - for (auto const& sn : sched.station_nodes_) { - print_node(sn.get(), 0); - for (auto const& e : sn->edges_) { - print_node(e.to_, 1); - } - } - std::cerr << "\n\n"; -} - -} // namespace motis diff --git a/base/core/include/motis/core/schedule/waiting_time_rules.h b/base/core/include/motis/core/schedule/waiting_time_rules.h deleted file mode 100644 index 096bf64c2..000000000 --- a/base/core/include/motis/core/schedule/waiting_time_rules.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include - -#include "motis/hash_map.h" -#include "motis/string.h" -#include "motis/vector.h" - -#include "motis/core/common/flat_matrix.h" -#include "motis/core/schedule/time.h" - -namespace motis { - -struct waiting_time_rules { - int waiting_time_category(mcd::string const& train_category) const { - auto it = category_map_.find(train_category); - if (it == end(category_map_)) { - return default_group_; - } else { - return it->second; - } - } - - inline int waiting_time_category(int family) const { - if (static_cast(family) < family_to_wtr_category_.size()) { - return family_to_wtr_category_[family]; - } else { - return default_group_; - } - } - - inline int waiting_time(int connecting_category, int feeder_category) const { - return waiting_time_matrix_[connecting_category][feeder_category]; - } - - inline int waiting_time_family(int connecting_family, - int feeder_family) const { - return waiting_time_matrix_[waiting_time_category(connecting_family)] - [waiting_time_category(feeder_family)]; - } - - inline bool waits_for_other_trains(int connecting_category) const { - return waits_for_other_trains_[connecting_category]; - } - - inline bool other_trains_wait_for(int feeder_category) const { - return other_trains_wait_for_[feeder_category]; - } - - int default_group_{0}; - mcd::hash_map category_map_; - mcd::vector family_to_wtr_category_; - flat_matrix> waiting_time_matrix_; - mcd::vector waits_for_other_trains_; - mcd::vector other_trains_wait_for_; -}; - -} // namespace motis diff --git a/base/core/src/access/connection_access.cc b/base/core/src/access/connection_access.cc deleted file mode 100644 index 151bfbea1..000000000 --- a/base/core/src/access/connection_access.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "motis/core/access/connection_access.h" - -#include -#include - -namespace motis::access { - -connection_info const& get_connection_info(schedule const& sched, - light_connection const& lcon, - trip const* trp) { - auto const& trips = *sched.merged_trips_[lcon.trips_]; - if (trips.size() == 1) { - return *lcon.full_con_->con_info_; - } - - auto const it = std::find(begin(trips), end(trips), trp); - assert(it != end(trips)); - auto const pos = std::distance(begin(trips), it); - - auto info = lcon.full_con_->con_info_; - for (int i = 0; i < pos; ++i) { - info = info->merged_with_; - } - return *info; -} - -} // namespace motis::access diff --git a/base/core/src/access/edge_access.cc b/base/core/src/access/edge_access.cc deleted file mode 100644 index 6abf1857a..000000000 --- a/base/core/src/access/edge_access.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include "motis/core/access/edge_access.h" - -#include -#include - -namespace motis { - -edge const* get_route_edge(node const* route_node, light_connection const* lcon, - event_type const ev_type) { - if (ev_type == event_type::DEP) { - for (auto const& e : route_node->edges_) { - if (e.type() == edge::ROUTE_EDGE && - e.m_.route_edge_.conns_.contains(lcon)) { - return &e; - } - } - } else { - for (auto const& e : route_node->incoming_edges_) { - if (e->type() == edge::ROUTE_EDGE && - e->m_.route_edge_.conns_.contains(lcon)) { - return e; - } - } - } - throw std::runtime_error("get_route_edge(): light connection not found"); -} - -node const* get_route_node(edge const& e, event_type const ev_type) { - return ev_type == event_type::DEP ? e.from_ : e.to_; -} - -light_connection const& get_lcon(edge const* route_edge, size_t const index) { - assert(route_edge->type() == edge::ROUTE_EDGE); - assert(index < route_edge->m_.route_edge_.conns_.size()); - return route_edge->m_.route_edge_.conns_[index]; -} - -time get_time(light_connection const* lcon, event_type const ev_type) { - return ev_type == event_type::DEP ? lcon->d_time_ : lcon->a_time_; -} - -time get_time(edge const* route_edge, std::size_t const lcon_index, - event_type const ev_type) { - return get_time(&get_lcon(route_edge, lcon_index), ev_type); -} - -lcon_idx_t get_lcon_index(edge const* route_edge, - light_connection const* lcon) { - auto const& lcons = route_edge->m_.route_edge_.conns_; - if (lcon < begin(lcons) || lcon >= end(lcons)) { - throw std::runtime_error("get_lcon_index(): light connection not found"); - } - return static_cast(std::distance(begin(lcons), lcon)); -} - -} // namespace motis diff --git a/base/core/src/access/realtime_access.cc b/base/core/src/access/realtime_access.cc deleted file mode 100644 index b27e94e45..000000000 --- a/base/core/src/access/realtime_access.cc +++ /dev/null @@ -1,118 +0,0 @@ -#include "motis/core/access/realtime_access.h" - -#include - -#include "motis/core/access/edge_access.h" - -namespace motis { - -time get_schedule_time(schedule const& sched, ev_key const& k) { - auto it = sched.graph_to_delay_info_.find(k); - if (it == end(sched.graph_to_delay_info_)) { - return get_time(k.route_edge_, k.lcon_idx_, k.ev_type_); - } else { - return it->second->get_schedule_time(); - } -} - -time get_schedule_time(schedule const& sched, edge const* route_edge, - lcon_idx_t const lcon_index, event_type const ev_type) { - auto it = sched.graph_to_delay_info_.find({route_edge, lcon_index, ev_type}); - if (it == end(sched.graph_to_delay_info_)) { - return get_time(route_edge, lcon_index, ev_type); - } else { - return it->second->get_schedule_time(); - } -} - -time get_schedule_time(schedule const& sched, edge const* route_edge, - light_connection const* lcon, event_type const ev_type) { - auto it = sched.graph_to_delay_info_.find( - {route_edge, get_lcon_index(route_edge, lcon), ev_type}); - if (it == end(sched.graph_to_delay_info_)) { - return ev_type == event_type::DEP ? lcon->d_time_ : lcon->a_time_; - } else { - return it->second->get_schedule_time(); - } -} - -time get_delay(schedule const& sched, ev_key const& k) { - return get_time(k.lcon(), k.ev_type_) - get_schedule_time(sched, k); -} - -delay_info get_delay_info(schedule const& sched, node const* route_node, - light_connection const* lcon, - event_type const ev_type) { - auto route_edge = get_route_edge(route_node, lcon, ev_type); - auto lcon_idx = get_lcon_index(route_edge, lcon); - auto it = sched.graph_to_delay_info_.find({route_edge, lcon_idx, ev_type}); - if (it == end(sched.graph_to_delay_info_)) { - return delay_info{ev_key{route_edge, lcon_idx, ev_type}}; - } else { - return *it->second; - } -} - -delay_info get_delay_info(schedule const& sched, edge const* route_edge, - light_connection const* lcon, - event_type const ev_type) { - auto lcon_idx = get_lcon_index(route_edge, lcon); - auto it = sched.graph_to_delay_info_.find({route_edge, lcon_idx, ev_type}); - if (it == end(sched.graph_to_delay_info_)) { - return delay_info{ev_key{route_edge, lcon_idx, ev_type}}; - } else { - return *it->second; - } -} - -delay_info get_delay_info(schedule const& sched, ev_key const& k) { - auto it = sched.graph_to_delay_info_.find(k); - if (it == end(sched.graph_to_delay_info_)) { - return delay_info{k}; - } else { - return *it->second; - } -} - -ev_key const& get_current_ev_key(schedule const& sched, ev_key const& k) { - auto const it = sched.graph_to_delay_info_.find(k); - if (it != end(sched.graph_to_delay_info_)) { - return it->second->get_ev_key(); - } else { - return k; - } -} - -ev_key const& get_orig_ev_key(schedule const& sched, ev_key const& k) { - auto const it = sched.graph_to_delay_info_.find(k); - if (it != end(sched.graph_to_delay_info_)) { - return it->second->get_orig_ev_key(); - } else { - return k; - } -} - -uint16_t get_schedule_track(schedule const& sched, ev_key const& k) { - auto it = sched.graph_to_schedule_track_index_.find(k); - if (it == end(sched.graph_to_schedule_track_index_)) { - auto const full_con = k.lcon()->full_con_; - return k.is_arrival() ? full_con->a_track_ : full_con->d_track_; - } else { - return it->second; - } -} - -int get_schedule_track(schedule const& sched, edge const* route_edge, - light_connection const* lcon, event_type const ev_type) { - return get_schedule_track( - sched, {route_edge, get_lcon_index(route_edge, lcon), ev_type}); -} - -int get_schedule_track(schedule const& sched, node const* route_node, - light_connection const* lcon, event_type const ev_type) { - auto route_edge = get_route_edge(route_node, lcon, ev_type); - auto lcon_idx = get_lcon_index(route_edge, lcon); - return get_schedule_track(sched, {route_edge, lcon_idx, ev_type}); -} - -} // namespace motis diff --git a/base/core/src/access/service_access.cc b/base/core/src/access/service_access.cc deleted file mode 100644 index 6da8eb09d..000000000 --- a/base/core/src/access/service_access.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include "motis/core/access/service_access.h" - -#include - -#include "boost/algorithm/string/trim.hpp" - -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/error.h" - -namespace motis { - -uint32_t output_train_nr(uint32_t train_nr, uint32_t original_train_nr) { - return train_nr <= kMaxValidTrainNr ? train_nr : original_train_nr; -} - -std::string get_service_name(schedule const& sched, - connection_info const* info) { - constexpr auto const kOnlyCategory = std::uint8_t{0b0001}; - constexpr auto const kOnlyTrainNr = std::uint8_t{0b0010}; - constexpr auto const kNoOutput = std::uint8_t{0b0011}; - constexpr auto const kUseProvider = std::uint8_t{0b1000}; - - auto const rule = sched.categories_[info->family_]->output_rule_; - auto const is = [&](auto const flag) { return (rule & flag) == flag; }; - - if (is(kNoOutput)) { - return ""; - } else { - auto const& cat_name = sched.categories_[info->family_]->name_; - auto const& line_id = info->line_identifier_; - auto const clasz_it = sched.classes_.find(cat_name); - auto const clasz = clasz_it == end(sched.classes_) ? service_class::OTHER - : clasz_it->second; - auto const provider = - info->provider_ == nullptr ? "" : info->provider_->long_name_; - if (!line_id.empty() && clasz != service_class::BUS && - clasz != service_class::STR && - (line_id.view().front() > '9' || line_id.view().front() < '0') && - (line_id.view().back() >= '0' && line_id.view().back() <= '9')) { - // Line ID starts with letter and ends with number, seems to be complete. - return is(kUseProvider) ? (provider.str() + " " + line_id.str()) - : line_id.str(); - } - - auto const train_nr = - output_train_nr(info->train_nr_, info->original_train_nr_); - - auto const second = - is(kOnlyCategory) ? "" - : (train_nr == 0U || ((clasz == service_class::BUS || - clasz == service_class::STR || - clasz == service_class::S) && - !line_id.empty()) - ? line_id - : fmt::to_string(train_nr)); - auto const omit_s = - (!second.empty() && second[0] == 'S' && clasz == service_class::S); - auto const first = is(kOnlyTrainNr) || omit_s - ? "" - : (is(kUseProvider) ? provider : cat_name); - return fmt::format("{}{}{}", first, first.empty() ? "" : " ", second); - } -} - -} // namespace motis diff --git a/base/core/src/access/station_access.cc b/base/core/src/access/station_access.cc deleted file mode 100644 index 15efd945f..000000000 --- a/base/core/src/access/station_access.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "motis/core/access/station_access.h" - -#include "motis/core/access/error.h" - -namespace motis { - -station* find_station(schedule const& sched, std::string_view eva_nr) { - auto it = sched.eva_to_station_.find(eva_nr); - if (it == end(sched.eva_to_station_)) { - return nullptr; - } - return it->second; -} - -station* get_station(schedule const& sched, std::string_view eva_nr) { - auto it = sched.eva_to_station_.find(eva_nr); - if (it == end(sched.eva_to_station_)) { - throw std::system_error(access::error::station_not_found); - } - return it->second; -} - -station_node* get_station_node(schedule const& sched, std::string_view eva_nr) { - auto index = get_station(sched, eva_nr)->index_; - return sched.station_nodes_[index].get(); -} - -station_node* find_station_node(schedule const& sched, - std::string_view eva_nr) { - auto const s = find_station(sched, eva_nr); - return s == nullptr ? nullptr : sched.station_nodes_.at(s->index_).get(); -} - -} // namespace motis diff --git a/base/core/src/access/time_access.cc b/base/core/src/access/time_access.cc deleted file mode 100644 index 58bfcacd9..000000000 --- a/base/core/src/access/time_access.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include "motis/core/access/time_access.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/core/common/logging.h" -#include "motis/core/access/error.h" - -namespace motis { - -unixtime external_schedule_begin(schedule const& sched) { - return sched.schedule_begin_ + SCHEDULE_OFFSET_MINUTES * 60; -} - -unixtime external_schedule_end(schedule const& sched) { - return sched.schedule_end_; -} - -void verify_timestamp(schedule const& sched, time_t t) { - if (t < sched.schedule_begin_ || t >= external_schedule_end(sched)) { - auto const schedule_begin = external_schedule_begin(sched); - auto const schedule_end = external_schedule_end(sched); - LOG(logging::error) << "timestamp not in schedule: " << format_unix_time(t) - << " [" << format_unix_time(schedule_begin) << ", " - << format_unix_time(schedule_end) << "]"; - throw std::system_error(motis::access::error::timestamp_not_in_schedule); - } -} - -void verify_external_timestamp(schedule const& sched, time_t t) { - if (t < std::min(sched.first_event_schedule_time_, - external_schedule_begin(sched)) || - t >= std::max(sched.last_event_schedule_time_, - external_schedule_end(sched))) { - auto const schedule_begin = external_schedule_begin(sched); - auto const schedule_end = external_schedule_end(sched); - LOG(logging::error) << "timestamp not in schedule: " << format_unix_time(t) - << " [" << format_unix_time(schedule_begin) << ", " - << format_unix_time(schedule_end) << "]"; - throw std::system_error(motis::access::error::timestamp_not_in_schedule); - } -} - -unixtime motis_to_unixtime(schedule const& sched, time t) { - return motis_to_unixtime(sched.schedule_begin_, t); -} - -time unix_to_motistime(schedule const& sched, unixtime t) { - auto const mt = unix_to_motistime(sched.schedule_begin_, t); - if (mt == INVALID_TIME) { - throw std::system_error(motis::access::error::timestamp_not_in_schedule); - } - return mt; -} - -time motis_time(int const hhmm, int const day_idx, int const timezone_offset) { - return SCHEDULE_OFFSET_MINUTES + day_idx * MINUTES_A_DAY + hhmm_to_min(hhmm) - - timezone_offset; -} - -unixtime unix_time(schedule const& sched, int const hhmm, int const day_idx, - int const timezone_offset) { - return motis_to_unixtime(sched, motis_time(hhmm, day_idx, timezone_offset)); -} - -} // namespace motis diff --git a/base/core/src/access/track_access.cc b/base/core/src/access/track_access.cc deleted file mode 100644 index 71a63b565..000000000 --- a/base/core/src/access/track_access.cc +++ /dev/null @@ -1,20 +0,0 @@ -#include "motis/core/access/track_access.h" - -#include -#include - -namespace motis { - -std::optional get_track_index(schedule const& sched, - std::string_view const track_name) { - auto const it = - std::find_if(begin(sched.tracks_), end(sched.tracks_), - [&track_name](auto const& t) { return t == track_name; }); - if (it != end(sched.tracks_)) { - return static_cast(std::distance(begin(sched.tracks_), it)); - } else { - return {}; - } -} - -} // namespace motis diff --git a/base/core/src/access/transfer_time.cc b/base/core/src/access/transfer_time.cc deleted file mode 100644 index 26474bf38..000000000 --- a/base/core/src/access/transfer_time.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "motis/core/access/transfer_time.h" - -namespace motis { - -std::optional get_transfer_time_between_platforms( - station const& from_station, std::optional const from_platform, - station const& to_station, std::optional const to_platform) { - if (from_station.index_ == to_station.index_) { - return from_station.get_transfer_time_between_platforms(from_platform, - to_platform); - } else { - for (auto const& fp : from_station.outgoing_footpaths_) { - if (fp.to_station_ == to_station.index_) { - return fp.duration_; - } - } - return {}; - } -} - -} // namespace motis diff --git a/base/core/src/access/trip_access.cc b/base/core/src/access/trip_access.cc deleted file mode 100644 index 6988d2a04..000000000 --- a/base/core/src/access/trip_access.cc +++ /dev/null @@ -1,126 +0,0 @@ -#include "motis/core/access/trip_access.h" - -#include - -#include "fmt/ranges.h" - -#include "utl/verify.h" - -#include "motis/string.h" - -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/error.h" -#include "motis/core/access/station_access.h" -#include "motis/core/access/time_access.h" -#include "motis/core/journey/extern_trip.h" - -namespace motis { - -trip const* get_gtfs_trip(schedule const& sched, gtfs_trip_id const& trip_id) { - auto const it = sched.gtfs_trip_ids_.find(trip_id.trip_id_); - utl::verify(it != end(sched.gtfs_trip_ids_), "unable to find GTFS trip {}", - fmt::streamed(trip_id)); - - auto const& trips = it->second; - if (trip_id.start_date_.has_value()) { - auto const trip_it = - std::find_if(begin(trips), end(trips), - [&](mcd::pair> const& trp) { - return trp.first == *trip_id.start_date_; - }); - utl::verify(trip_it != end(trips), - "unable to find GTFS trip {} with at date {}", - fmt::streamed(trip_id), format_unix_time(*trip_id.start_date_)); - return trip_it->second; - } else if (it->second.size() > 1) { - auto const n = now(); - auto const closest_to_now = - std::min_element(begin(it->second), end(it->second), - [&](mcd::pair> const& a, - mcd::pair> const& b) { - return (a.first - n) < (b.first - n); - }); - LOG(logging::warn) << "ambiguous trip id " << trip_id << " w/o date, using " - << format_unix_time(closest_to_now->first, "%F"); - return closest_to_now->second; - } else { - return it->second.front().second; - } -} - -trip const* get_trip(schedule const& sched, std::string_view eva_nr, - uint32_t const train_nr, unixtime const timestamp, - std::string_view target_eva_nr, - unixtime const target_timestamp, std::string_view line_id, - bool const fuzzy) { - auto const station_id = get_station(sched, eva_nr)->index_; - auto const motis_time = unix_to_motistime(sched, timestamp); - auto const primary_id = primary_trip_id(station_id, train_nr, motis_time); - - auto it = - std::lower_bound(begin(sched.trips_), end(sched.trips_), - std::make_pair(primary_id, static_cast(nullptr))); - if (it == end(sched.trips_) || !(it->first == primary_id)) { - throw std::system_error(access::error::service_not_found); - } - - auto const target_station_id = get_station(sched, target_eva_nr)->index_; - auto const target_motis_time = - unix_to_motistime(sched.schedule_begin_, target_timestamp); - for (; it != end(sched.trips_) && it->first == primary_id; ++it) { - auto const& s = it->second->id_.secondary_; - if ((fuzzy || line_id == s.line_id_) && - target_station_id == s.target_station_id_ && - target_motis_time == s.target_time_) { - return it->second; - } - } - - throw std::system_error(access::error::service_not_found); -} - -trip const* get_trip(schedule const& sched, extern_trip const& e_trp) { - return get_trip(sched, e_trp.station_id_, e_trp.train_nr_, e_trp.time_, - e_trp.target_station_id_, e_trp.target_time_, e_trp.line_id_); -} - -trip const* get_trip(schedule const& sched, trip_idx_t const idx) { - return sched.trip_mem_.at(idx).get(); -} - -trip const* find_trip(schedule const& sched, primary_trip_id id) { - auto it = std::lower_bound(begin(sched.trips_), end(sched.trips_), - std::make_pair(id, static_cast(nullptr))); - if (it != end(sched.trips_) && it->first == id) { - return it->second; - } - return nullptr; -} - -trip const* find_trip(schedule const& sched, full_trip_id id) { - for (auto it = std::lower_bound( - begin(sched.trips_), end(sched.trips_), - std::make_pair(id.primary_, static_cast(nullptr))); - it != end(sched.trips_) && it->first == id.primary_; ++it) { - if (it->second->id_.secondary_ == id.secondary_) { - return it->second; - } - } - return nullptr; -} - -unsigned stop_seq_to_stop_idx(trip const& trp, unsigned stop_seq) { - if (trp.stop_seq_numbers_.empty() || stop_seq == 0U) { - return stop_seq; - } else { - auto const it = std::lower_bound(begin(trp.stop_seq_numbers_), - end(trp.stop_seq_numbers_), stop_seq); - utl::verify(it != end(trp.stop_seq_numbers_) && *it == stop_seq, - "stop sequence {} for trip {} not found, sequence: {}", - stop_seq, trp.dbg_.str(), trp.stop_seq_numbers_); - return static_cast( - std::distance(begin(trp.stop_seq_numbers_), it)); - } -} - -} // namespace motis diff --git a/base/core/src/access/trip_section.cc b/base/core/src/access/trip_section.cc deleted file mode 100644 index 38244281d..000000000 --- a/base/core/src/access/trip_section.cc +++ /dev/null @@ -1,59 +0,0 @@ -#include "motis/core/access/trip_section.h" - -#include "motis/core/access/connection_access.h" -#include "motis/core/access/edge_access.h" - -namespace motis::access { - -station const& get_station(schedule const& sched, node const* n) { - return *sched.stations_[n->get_station()->id_]; -} - -trip_section::trip_section(trip const* t, int const index) - : trip_(t), index_(index), edge_(t->edges_->at(index).get_edge()) {} - -int trip_section::index() const { return index_; } - -light_connection const& trip_section::lcon() const { - return get_lcon(edge_, trip_->lcon_idx_); -} - -connection const& trip_section::fcon() const { return *lcon().full_con_; } - -connection_info const& trip_section::info(schedule const& sched) const { - return get_connection_info(sched, lcon(), trip_); -} - -class edge const* trip_section::edge() const { return edge_; } - -station const& trip_section::from_station(schedule const& sched) const { - return get_station(sched, edge_->from_); -} - -station const& trip_section::to_station(schedule const& sched) const { - return get_station(sched, edge_->to_); -} - -uint32_t trip_section::from_station_id() const { - return edge_->from_->get_station()->id_; -} - -uint32_t trip_section::to_station_id() const { - return edge_->to_->get_station()->id_; -} - -ev_key trip_section::ev_key_from() const { - return ev_key{trip_->edges_->at(index_), trip_->lcon_idx_, event_type::DEP}; -} - -ev_key trip_section::ev_key_to() const { - return ev_key{trip_->edges_->at(index_), trip_->lcon_idx_, event_type::ARR}; -} - -edge const* trip_section::get_route_edge() const { return edge_; } - -node* trip_section::from_node() const { return edge_->from_; } - -node* trip_section::to_node() const { return edge_->to_; } - -} // namespace motis::access diff --git a/base/core/src/access/trip_stop.cc b/base/core/src/access/trip_stop.cc deleted file mode 100644 index 6a5441052..000000000 --- a/base/core/src/access/trip_stop.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "motis/core/access/trip_stop.h" - -#include "motis/core/access/connection_access.h" -#include "motis/core/access/edge_access.h" - -namespace motis::access { - -trip_stop::trip_stop(trip const* t, int const index) : trip_(t), index_(index) { - assert(!trip_->edges_->empty()); - if (index == static_cast(trip_->edges_->size())) { - node_ = trip_->edges_->back().get_edge()->to_; - } else { - node_ = trip_->edges_->at(index).get_edge()->from_; - } - assert(node_->is_route_node()); -} - -int trip_stop::index() const { return index_; } - -bool trip_stop::has_arrival() const { return index_ > 0; } -bool trip_stop::has_departure() const { - return index_ < static_cast(trip_->edges_->size()); -} - -light_connection const& trip_stop::arr_lcon() const { - return get_lcon(trip_->edges_->at(index_ - 1).get_edge(), trip_->lcon_idx_); -} - -light_connection const& trip_stop::dep_lcon() const { - return get_lcon(trip_->edges_->at(index_).get_edge(), trip_->lcon_idx_); -} - -ev_key trip_stop::arr() const { - return ev_key{trip_->edges_->at(index_ - 1).get_edge(), trip_->lcon_idx_, - event_type::ARR}; -} - -ev_key trip_stop::dep() const { - return ev_key{trip_->edges_->at(index_).get_edge(), trip_->lcon_idx_, - event_type::DEP}; -} - -connection_info const& trip_stop::arr_info(schedule const& sched) const { - return get_connection_info(sched, arr_lcon(), trip_); -} - -connection_info const& trip_stop::dep_info(schedule const& sched) const { - return get_connection_info(sched, dep_lcon(), trip_); -} - -station const& trip_stop::get_station(schedule const& sched) const { - return *sched.stations_[node_->get_station()->id_]; -} - -uint32_t trip_stop::get_station_id() const { return node_->get_station()->id_; } - -node const* trip_stop::get_route_node() const { return node_; } - -bool trip_stop::is_first() const { return index_ == 0; } -bool trip_stop::is_last() const { return index_ == trip_->edges_->size(); } - -} // namespace motis::access diff --git a/base/core/src/bfs.cc b/base/core/src/bfs.cc deleted file mode 100644 index a774fe230..000000000 --- a/base/core/src/bfs.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "motis/core/access/bfs.h" - -#include - -namespace motis { - -std::set route_bfs(ev_key const& k, bfs_direction const dir, - bool with_through_edges) { - std::set visited; - std::queue q; - - visited.insert(k.route_edge_); - q.push(k.route_edge_); - - while (!q.empty()) { - auto const e = q.front().get_edge(); - q.pop(); - - if (dir == bfs_direction::BOTH || dir == bfs_direction::BACKWARD) { - for (auto const& in : e->from_->incoming_edges_) { - if (in->type() != edge::THROUGH_EDGE && - in->type() != edge::ROUTE_EDGE) { - continue; - } - - if (visited.emplace(in).second) { - q.emplace(in); - } - } - } - - if (dir == bfs_direction::BOTH || dir == bfs_direction::FORWARD) { - for (auto const& out : e->to_->edges_) { - if (out.type() != edge::THROUGH_EDGE && - out.type() != edge::ROUTE_EDGE) { - continue; - } - - if (visited.insert(&out).second) { - q.emplace(&out); - } - } - } - } - - if (!with_through_edges) { - for (auto it = begin(visited); it != end(visited);) { - if ((*it)->type() == edge::THROUGH_EDGE) { - it = visited.erase(it); - } else { - ++it; - } - } - } - - return visited; -} - -std::set trip_bfs(ev_key const& k, bfs_direction const dir) { - std::set ev_keys; - for (auto const& e : route_bfs(k, dir)) { - auto const arr = ev_key{e, k.lcon_idx_, event_type::ARR}; - auto const dep = ev_key{e, k.lcon_idx_, event_type::DEP}; - - auto const bad_arr = dir == bfs_direction::BACKWARD && k.is_departure() && - arr == k.get_opposite(); - if (!bad_arr) { - ev_keys.insert(arr); - } - - auto const bad_dep = dir == bfs_direction::FORWARD && k.is_arrival() && - dep == k.get_opposite(); - if (!bad_dep) { - ev_keys.insert(dep); - } - } - return ev_keys; -} - -} // namespace motis diff --git a/base/core/src/build_platform_node.cc b/base/core/src/build_platform_node.cc deleted file mode 100644 index dd9c39022..000000000 --- a/base/core/src/build_platform_node.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "motis/core/schedule/build_platform_node.h" - -namespace motis { - -node* get_or_add_platform_node(schedule& sched, station_node* station_node, - uint16_t platform) { - if (platform >= station_node->platform_nodes_.size()) { - station_node->platform_nodes_.resize(platform + 1); - } - - auto platform_node = station_node->platform_nodes_[platform]; - if (platform_node == nullptr) { - platform_node = - station_node->child_nodes_ - .emplace_back(mcd::make_unique(make_node( - node_type::PLATFORM_NODE, station_node, sched.next_node_id_++))) - .get(); - station_node->platform_nodes_[platform] = platform_node; - } - return platform_node; -} - -node* add_platform_enter_edge(schedule& sched, node* route_node, - station_node* station_node, - int32_t platform_transfer_time, - uint16_t platform) { - auto const pn = get_or_add_platform_node(sched, station_node, platform); - pn->edges_.push_back( - make_enter_edge(pn, route_node, platform_transfer_time, true)); - return pn; -} - -node* add_platform_exit_edge(schedule& sched, node* route_node, - station_node* station_node, - int32_t platform_transfer_time, - uint16_t platform) { - auto const pn = get_or_add_platform_node(sched, station_node, platform); - route_node->edges_.push_back( - make_exit_edge(route_node, pn, platform_transfer_time, true)); - return pn; -} - -} // namespace motis diff --git a/base/core/src/build_route_node.cc b/base/core/src/build_route_node.cc deleted file mode 100644 index 96403b943..000000000 --- a/base/core/src/build_route_node.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "motis/core/schedule/build_route_node.h" - -#include "motis/core/schedule/nodes.h" - -namespace motis { - -node* build_route_node(int route_index, int node_id, station_node* station_node, - int transfer_time, bool in_allowed, bool out_allowed) { - auto route_node = - station_node->child_nodes_ - .emplace_back(mcd::make_unique(make_node( - node_type::ROUTE_NODE, station_node, node_id, route_index))) - .get(); - - if (!in_allowed) { - station_node->edges_.push_back(make_invalid_edge(station_node, route_node)); - } else { - station_node->edges_.push_back( - make_enter_edge(station_node, route_node, transfer_time, true)); - } - - if (!out_allowed) { - route_node->edges_.push_back(make_invalid_edge(route_node, station_node)); - } else { - route_node->edges_.push_back( - make_exit_edge(route_node, station_node, transfer_time, true)); - } - - if (station_node->foot_node_) { - if (out_allowed) { - route_node->edges_.push_back(make_after_train_fwd_edge( - route_node, station_node->foot_node_.get(), 0, true)); - } - if (in_allowed) { - station_node->foot_node_->edges_.emplace_back(make_after_train_bwd_edge( - station_node->foot_node_.get(), route_node, 0, true)); - } - } - - return route_node; -} - -} // namespace motis diff --git a/base/core/src/check_journey.cc b/base/core/src/check_journey.cc index c22887f84..b0d75d037 100644 --- a/base/core/src/check_journey.cc +++ b/base/core/src/check_journey.cc @@ -17,7 +17,7 @@ bool check_journey(journey const& j, auto const& t = j.transports_[i]; if (t.to_ <= t.from_) { raise_error() << " Transport " << i << " broken: " << t.from_ << " -> " - << t.to_ << std::endl; + << t.to_ << '\n'; } for (auto s = t.from_; s < t.to_; ++s) { ++segment_transports[s]; @@ -26,18 +26,18 @@ bool check_journey(journey const& j, for (auto i = 0UL; i < j.stops_.size() - 1; ++i) { if (segment_transports[i] < 1) { raise_error() << " No transport for segment between stops " << i - << " -> " << (i + 1) << std::endl; + << " -> " << (i + 1) << '\n'; } } } else if (j.stops_.size() == 1) { - raise_error() << " Connection only has one stop" << std::endl; + raise_error() << " Connection only has one stop" << '\n'; } for (auto i = 1UL; i < j.stops_.size(); ++i) { if (j.stops_[i].arrival_.timestamp_ < j.stops_[i - 1].departure_.timestamp_) { raise_error() << " Stops broken: " << (i - 1) << "/" << i - << ": Arrival before departure" << std::endl; + << ": Arrival before departure" << '\n'; } } @@ -45,7 +45,7 @@ bool check_journey(journey const& j, if (stop.arrival_.valid_ && stop.departure_.valid_) { if (stop.departure_.timestamp_ < stop.arrival_.timestamp_) { raise_error() << " Stop broken: " << stop.name_ - << ": Departure before arrival" << std::endl; + << ": Departure before arrival" << '\n'; } } } diff --git a/base/core/src/debug/fbs.cc b/base/core/src/debug/fbs.cc deleted file mode 100644 index 7c80d5bd6..000000000 --- a/base/core/src/debug/fbs.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "motis/core/debug/fbs.h" - -#include "flatbuffers/flatbuffers.h" - -#include "motis/core/conv/trip_conv.h" - -#include "motis/module/message.h" - -namespace motis::debug { - -std::string to_fbs_json(schedule const& sched, motis::trip const* trp, - motis::module::json_format const jf) { - flatbuffers::FlatBufferBuilder fbb; - fbb.Finish(to_fbs(sched, fbb, trp)); - return motis::module::fbs_table_to_json( - flatbuffers::GetRoot(fbb.GetBufferPointer()), "motis.TripId", jf); -} - -} // namespace motis::debug diff --git a/base/core/src/generate_journey_transport.cc b/base/core/src/generate_journey_transport.cc deleted file mode 100644 index a94198424..000000000 --- a/base/core/src/generate_journey_transport.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include "motis/core/journey/generate_journey_transport.h" - -#include "motis/core/access/service_access.h" - -namespace motis { - -journey::transport generate_journey_transport( - unsigned int from, unsigned int to, connection_info const* con_info, - schedule const& sched, duration duration, int mumo_id, unsigned mumo_price, - unsigned mumo_accessibility) { - bool is_walk = true; - mcd::string name; - mcd::string cat_name; - unsigned clasz = 0; - mcd::string line_identifier; - mcd::string direction; - mcd::string provider; - - if (con_info != nullptr) { - is_walk = false; - - cat_name = sched.categories_[con_info->family_]->name_; - - auto clasz_it = sched.classes_.find(cat_name); - clasz = static_cast(clasz_it == end(sched.classes_) - ? service_class::OTHER - : clasz_it->second); - - line_identifier = con_info->line_identifier_; - - if (con_info->dir_ != nullptr) { - direction = *con_info->dir_; - } - - if (con_info->provider_ != nullptr) { - provider = con_info->provider_->full_name_; - } - - name = get_service_name(sched, con_info); - } - - return {from, - to, - is_walk, - name.str(), - clasz, - line_identifier.str(), - duration, - mumo_id, - direction.str(), - provider.str(), - mumo_price, - mumo_accessibility, - ""}; -} - -} // namespace motis diff --git a/base/core/src/print_journey.cc b/base/core/src/print_journey.cc index d32c1d870..e3e5b8a88 100644 --- a/base/core/src/print_journey.cc +++ b/base/core/src/print_journey.cc @@ -113,12 +113,12 @@ bool print_journey(journey const& j, std::ostream& out, bool local_time, out << " --> "; print_event(out, arrival_event(j), local_time, rt_format); if (local_time) { - out << " (local)" << std::endl; + out << " (local)" << '\n'; } else { - out << " (UTC)" << std::endl; + out << " (UTC)" << '\n'; } - out << "\nStops:" << std::endl; + out << "\nStops:" << '\n'; for (auto i = 0UL; i < j.stops_.size(); ++i) { auto const& stop = j.stops_[i]; auto stop_name = is_virtual_station(stop) @@ -141,7 +141,7 @@ bool print_journey(journey const& j, std::ostream& out, bool local_time, out << "\n"; } - out << "\nTransports:" << std::endl; + out << "\nTransports:" << '\n'; for (auto i = 0UL; i < j.transports_.size(); ++i) { auto const& trans = j.transports_[i]; out << std::right << std::setw(2) << i << ": " << std::left << std::setw(2) @@ -152,7 +152,7 @@ bool print_journey(journey const& j, std::ostream& out, bool local_time, << " id=" << std::left << std::setw(7) << trans.mumo_id_ << " duration=" << std::left << std::setw(3) << trans.duration_ << " accessibility=" << std::left << trans.mumo_accessibility_ - << std::endl; + << '\n'; } else { out << std::left << std::setw(10) << trans.name_ << " duration=" << trans.duration_ << ", provider=\"" @@ -163,7 +163,7 @@ bool print_journey(journey const& j, std::ostream& out, bool local_time, } } - out << "\nTrips:" << std::endl; + out << "\nTrips:" << '\n'; for (auto i = 0UL; i < j.trips_.size(); ++i) { auto const& trp = j.trips_[i].extern_trip_; out << std::right << std::setw(2) << i << ": " << std::left << std::setw(2) @@ -175,21 +175,21 @@ bool print_journey(journey const& j, std::ostream& out, bool local_time, << "}, line_id=" << trp.line_id_ << ", id=" << trp.id_ << "\n #/trip/" << trp.station_id_ << "/" << trp.train_nr_ << "/" << trp.time_ << "/" << trp.target_station_id_ << "/" << trp.target_time_ - << "/" << trp.line_id_ << " " << j.trips_[i].debug_ << std::endl; + << "/" << trp.line_id_ << " " << j.trips_[i].debug_ << '\n'; } - out << "\nAttributes:" << std::endl; + out << "\nAttributes:" << '\n'; for (auto i = 0UL; i < j.attributes_.size(); ++i) { auto const& attribute = j.attributes_[i]; out << std::right << std::setw(2) << i << ": " << std::left << std::setw(2) << attribute.from_ << " -> " << std::left << std::setw(2) << attribute.to_ << " {" << attribute.attr_.code_ << " " - << attribute.attr_.text_ << "}" << std::endl; + << attribute.attr_.text_ << "}" << '\n'; } auto const report_error = [&](bool first_error) -> std::ostream& { if (first_error) { - out << "\nWARNING: Journey is broken:" << std::endl; + out << "\nWARNING: Journey is broken:" << '\n'; } return out; }; diff --git a/base/core/src/print_trip.cc b/base/core/src/print_trip.cc deleted file mode 100644 index e96d143dd..000000000 --- a/base/core/src/print_trip.cc +++ /dev/null @@ -1,84 +0,0 @@ -#include "motis/core/journey/print_trip.h" - -#include "fmt/core.h" -#include "fmt/ostream.h" - -#include "motis/core/schedule/schedule.h" -#include "motis/core/access/realtime_access.h" -#include "motis/core/access/trip_iterator.h" -#include "motis/core/conv/trip_conv.h" -#include "motis/core/journey/print_journey.h" - -namespace motis { - -std::ostream& operator<<(std::ostream& out, extern_trip const& ext_trp) { - return out << "#/trip/" << ext_trp.station_id_ << "/" << ext_trp.train_nr_ - << "/" << ext_trp.time_ << "/" << ext_trp.target_station_id_ << "/" - << ext_trp.target_time_ << "/" << ext_trp.line_id_; -} - -std::ostream& print_time(std::ostream& out, std::time_t t, bool local_time) { - struct tm time {}; -#ifdef _MSC_VER - if (local_time) { - localtime_s(&time, &t); - } else { - gmtime_s(&time, &t); - } -#else - if (local_time) { - localtime_r(&t, &time); - } else { - gmtime_r(&t, &time); - } -#endif - return out << std::put_time(&time, "%d.%m. %H:%M"); -} - -std::ostream& print_time(std::ostream& out, schedule const& sched, - motis::time const t, bool local_time) { - return print_time(out, motis_to_unixtime(sched, t), local_time); -} - -void print_trip(std::ostream& out, schedule const& sched, trip const* trp, - bool const local_time) { - auto i = 0U; - out << to_extern_trip(sched, trp) << "\n"; - if (!trp->gtfs_trip_id_.empty()) { - out << trp->gtfs_trip_id_ << "\n"; - } - for (auto const& stop : motis::access::stops{trp}) { - auto const& s = stop.get_station(sched); - fmt::print(out, "{:2}: {:7} {:.<48} a: ", i, s.eva_nr_, s.name_); - - if (!stop.is_first()) { - auto const di = get_delay_info(sched, stop.arr()); - out << di.get_reason() << "="; - print_time(out, motis_to_unixtime(sched, stop.arr_lcon().a_time_), - local_time); - out << " (S="; - print_time(out, motis_to_unixtime(sched, di.get_schedule_time()), - local_time); - out << ")"; - } else { - out << " "; - out << " "; - } - out << " d: "; - if (!stop.is_last()) { - auto const di = get_delay_info(sched, stop.dep()); - out << di.get_reason() << "="; - print_time(out, motis_to_unixtime(sched, stop.dep_lcon().d_time_), - local_time); - out << " (S="; - print_time(out, motis_to_unixtime(sched, di.get_schedule_time()), - local_time); - out << ")"; - } - out << "\n"; - - ++i; - } -} - -} // namespace motis diff --git a/base/core/src/schedule/station_lookup.cc b/base/core/src/schedule/station_lookup.cc index 8860bdedb..7ad7e5867 100644 --- a/base/core/src/schedule/station_lookup.cc +++ b/base/core/src/schedule/station_lookup.cc @@ -4,7 +4,8 @@ #include "geo/point_rtree.h" -#include "motis/core/schedule/schedule.h" +#include "cista/hashing.h" + #include "motis/core/conv/position_conv.h" namespace motis { @@ -71,22 +72,4 @@ std::vector station_lookup::in_radius( return rtree_->in_radius(center, min_radius, max_radius); } -schedule_station_lookup::schedule_station_lookup(motis::schedule const& sched) - : station_lookup{utl::to_vec(sched.stations_, - [](auto const& s) { - return geo::latlng{s->lat(), s->lng()}; - })}, - sched_{sched} {} - -schedule_station_lookup::~schedule_station_lookup() noexcept = default; - -lookup_station schedule_station_lookup::get(std::size_t const idx) const { - auto const& station = *sched_.stations_.at(idx); - return {"", station.eva_nr_, station.name_, {station.lat(), station.lng()}}; -} - -lookup_station schedule_station_lookup::get(std::string_view id) const { - return get(sched_.eva_to_station_.at(id)->index_); -} - } // namespace motis \ No newline at end of file diff --git a/base/core/src/schedule/trip.cc b/base/core/src/schedule/trip.cc deleted file mode 100644 index a47adecf3..000000000 --- a/base/core/src/schedule/trip.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include "motis/core/schedule/trip.h" - -#include "motis/core/common/date_time_util.h" - -namespace motis { - -std::ostream& operator<<(std::ostream& out, gtfs_trip_id const& id) { - return out << "{GTFS-TRIP trip_id=" << id.trip_id_ << ", start_date=" - << (id.start_date_.has_value() ? format_unix_time(*id.start_date_) - : "NO VALUE") - << "}"; -} - -} // namespace motis \ No newline at end of file diff --git a/base/core/src/serialization.cc b/base/core/src/serialization.cc deleted file mode 100644 index c77196fab..000000000 --- a/base/core/src/serialization.cc +++ /dev/null @@ -1,214 +0,0 @@ -#include "motis/core/schedule/serialization.h" - -#include - -#include "cista/serialization.h" - -#include "motis/core/common/dynamic_fws_multimap.h" -#include "motis/core/common/logging.h" - -namespace cista { - -cista::hash_t type_hash(boost::uuids::uuid const& el, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.data, h, done)); -} - -template -inline void serialize(Ctx&, boost::uuids::uuid const*, cista::offset_t const) {} - -template -inline void deserialize(Ctx const&, boost::uuids::uuid*) {} - -template <> -inline auto to_tuple(boost::uuids::uuid const& t) { - return std::tie(t.data); -} - -} // namespace cista - -namespace motis { - -constexpr auto const MODE = - cista::mode::WITH_INTEGRITY | cista::mode::WITH_VERSION; - -template -inline void serialize(Ctx& c, trip_debug const* origin, - cista::offset_t const offset) { - cista::serialize(c, &origin->file_, offset + offsetof(trip_debug, file_)); -} - -template -inline void deserialize(Ctx const& c, trip_debug* el) { - cista::deserialize(c, &el->file_); -} - -cista::hash_t type_hash(trip_debug const& el, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.file_, h, done), - cista::type_hash(el.line_from_, h, done), - cista::type_hash(el.line_to_, h, done)); -} - -template -inline void serialize(Ctx& c, light_connection const* origin, - cista::offset_t const offset) { - serialize(c, &origin->full_con_, - offset + offsetof(light_connection, full_con_)); -} - -template -inline void deserialize(Ctx const& c, light_connection* el) { - deserialize(c, &el->full_con_); -} - -cista::hash_t type_hash(light_connection const& el, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.full_con_, h, done), - cista::type_hash(el.d_time_, h, done), - cista::type_hash(el.a_time_, h, done), - cista::type_hash(el.trips_, h, done), 31, - cista::type_hash(el.valid_, h, done), 1); -} - -template -inline void serialize(Ctx&, primary_trip_id const*, cista::offset_t const) {} - -template -inline void deserialize(Ctx const&, primary_trip_id*) {} - -cista::hash_t type_hash(primary_trip_id const&, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(uint64_t{}, h, done), 31, 16, 17); -} - -template -inline void serialize(Ctx& c, trip::route_edge const* origin, - cista::offset_t const offset) { - cista::serialize(c, &origin->route_node_, - offset + offsetof(trip::route_edge, route_node_)); -} - -template -inline void deserialize(Ctx const& c, trip::route_edge* el) { - cista::deserialize(c, &el->route_node_); -} - -cista::hash_t type_hash(trip::route_edge const& el, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.route_node_, h, done), - cista::type_hash(el.outgoing_edge_idx_, h, done)); -} - -template -inline void serialize(Ctx& c, edge const* origin, - cista::offset_t const offset) { - cista::serialize(c, &origin->from_, offset + offsetof(edge, from_)); - cista::serialize(c, &origin->to_, offset + offsetof(edge, to_)); - if (origin->type() == edge::ROUTE_EDGE) { - cista::serialize(c, &origin->m_.route_edge_.conns_, - offset + offsetof(edge, m_) + - offsetof(decltype(origin->m_), route_edge_) + - offsetof(decltype(origin->m_.route_edge_), conns_)); - } -} - -template -inline void deserialize(Ctx const& c, edge* el) { - cista::deserialize(c, &el->from_); - cista::deserialize(c, &el->to_); - if (el->type() == edge::ROUTE_EDGE) { - cista::deserialize(c, &el->m_.route_edge_.conns_); - } -} - -cista::hash_t type_hash(edge const& el, cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.m_.route_edge_, h, done), - cista::type_hash(el.m_.foot_edge_, h, done), - cista::type_hash(el.m_.hotel_edge_, h, done)); -} - -template -inline void serialize(Ctx& c, dynamic_fws_multimap const* origin, - cista::offset_t const offset) { - using Type = dynamic_fws_multimap; - cista::serialize(c, &origin->index_, offset + offsetof(Type, index_)); - cista::serialize(c, &origin->data_, offset + offsetof(Type, data_)); - cista::serialize(c, &origin->free_buckets_, - offset + offsetof(Type, free_buckets_)); - cista::serialize(c, &origin->element_count_, - offset + offsetof(Type, element_count_)); -} - -template -inline void deserialize(Ctx const& c, dynamic_fws_multimap* el) { - cista::deserialize(c, &el->index_); - cista::deserialize(c, &el->data_); - cista::deserialize(c, &el->free_buckets_); - cista::deserialize(c, &el->element_count_); -} - -template -cista::hash_t type_hash(dynamic_fws_multimap const& el, - cista::hash_t const h, - std::map& done) { - return cista::hash_combine(cista::type_hash(el.index_, h, done), - cista::type_hash(el.data_, h, done), - cista::type_hash(el.free_buckets_, h, done), - cista::type_hash(el.element_count_, h, done)); -} - -template -struct overloaded : Ts... { - using Ts::operator()...; -}; -template -overloaded(Ts...) -> overloaded; - -schedule_ptr read_graph(std::string const& path, cista::memory_holder& mem, - bool const read_mmap) { - if (read_mmap) { - auto mmap = cista::mmap{path.c_str(), cista::mmap::protection::READ}; - mem = cista::buf(std::move(mmap)); - } else { - mem = cista::file(path.c_str(), "r").content(); - } - - auto ptr = schedule_ptr{}; - ptr.self_allocated_ = false; - ptr.el_ = - std::visit(overloaded{[&](cista::buf& b) { - return reinterpret_cast( - &b[cista::data_start(MODE)]); - }, - [&](cista::buffer& b) { - return cista::deserialize(b); - }, - [&](cista::byte_buf& b) { - return cista::deserialize(b); - }}, - mem); - return ptr; -} - -void write_graph(std::string const& path, schedule const& sched) { - auto mmap = cista::mmap{path.c_str(), cista::mmap::protection::WRITE}; - auto writer = cista::buf(std::move(mmap)); - - { - logging::scoped_timer const t{"writing graph"}; - cista::serialize(writer, sched); - } -} - -schedule_data copy_graph(schedule const& sched) { - logging::scoped_timer const timer{"clone schedule"}; - auto buf = cista::serialize(sched); - auto ptr = schedule_ptr{}; - ptr.self_allocated_ = false; - ptr.el_ = cista::deserialize(buf); - return schedule_data{cista::memory_holder{std::move(buf)}, std::move(ptr)}; -} - -} // namespace motis diff --git a/base/core/test/fws_multimap_test.cc b/base/core/test/fws_multimap_test.cc index b0f485908..76281cb6e 100644 --- a/base/core/test/fws_multimap_test.cc +++ b/base/core/test/fws_multimap_test.cc @@ -18,7 +18,7 @@ void check_result(std::vector const& ref, std::cout << "\n Result: "; std::copy(begin(result), end(result), std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; + std::cout << '\n'; } ASSERT_EQ(ref.size(), result.size()); for (auto i = 0UL; i < ref.size(); ++i) { diff --git a/base/core/test/route_edge_test.cc b/base/core/test/route_edge_test.cc deleted file mode 100644 index b6978d9e7..000000000 --- a/base/core/test/route_edge_test.cc +++ /dev/null @@ -1,93 +0,0 @@ -#include "gtest/gtest.h" - -#include "motis/core/schedule/edges.h" - -using namespace motis; - -auto const e = make_route_edge( - nullptr, nullptr, - {light_connection(0, 10, nullptr), light_connection(1, 11, nullptr), - light_connection(2, 12, nullptr)}); - -TEST(core_route_edge, get_connection_test_valid) { - auto c = e.get_connection(1); - ASSERT_TRUE(c); - ASSERT_EQ(1, c->d_time_); - ASSERT_EQ(11, c->a_time_); -} - -TEST(core_route_edge, get_connection_test_valid_last) { - EXPECT_FALSE(e.get_connection(3)); -} - -TEST(core_route_edge, get_connection_invalid_next_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[1].valid_ = 0U; - - auto c = e1.get_connection(1); - ASSERT_TRUE(c); - ASSERT_EQ(2, c->d_time_); - ASSERT_EQ(12, c->a_time_); -} - -TEST(core_route_edge, get_connection_2_invalid_next_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[0].valid_ = 0U; - e1.m_.route_edge_.conns_[1].valid_ = 0U; - - auto c = e1.get_connection(0); - ASSERT_TRUE(c); - ASSERT_EQ(2, c->d_time_); - ASSERT_EQ(12, c->a_time_); -} - -TEST(core_route_edge, get_connection_end_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[1].valid_ = 0U; - e1.m_.route_edge_.conns_[2].valid_ = 0U; - - EXPECT_FALSE(e1.get_connection(1)); -} - -TEST(core_route_edge, get_connection_reverse_valid_1_test) { - auto c = e.get_connection(20); - ASSERT_TRUE(c); - EXPECT_EQ(2, c->d_time_); - EXPECT_EQ(12, c->a_time_); -} - -TEST(core_route_edge, get_connection_reverse_valid_2_test) { - auto c = e.get_connection(11); - ASSERT_TRUE(c); - EXPECT_EQ(1, c->d_time_); - EXPECT_EQ(11, c->a_time_); -} - -TEST(core_route_edge, get_connection_reverse_invalid_next_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[2].valid_ = 0U; - - auto c = e1.get_connection(20); - ASSERT_TRUE(c); - EXPECT_EQ(1, c->d_time_); - EXPECT_EQ(11, c->a_time_); -} - -TEST(core_route_edge, get_connection_reverse_2_invalid_next_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[1].valid_ = 0U; - e1.m_.route_edge_.conns_[2].valid_ = 0U; - - auto c = e1.get_connection(20); - ASSERT_TRUE(c); - EXPECT_EQ(0, c->d_time_); - EXPECT_EQ(10, c->a_time_); -} - -TEST(core_route_edge, get_connection_reverse_end_test) { - auto e1 = e; - e1.m_.route_edge_.conns_[0].valid_ = 0U; - e1.m_.route_edge_.conns_[1].valid_ = 0U; - - EXPECT_FALSE(e1.get_connection(11)); -} diff --git a/base/core/test/waiting_time_test.cc b/base/core/test/waiting_time_test.cc deleted file mode 100644 index 476ac71ad..000000000 --- a/base/core/test/waiting_time_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -// #include "gtest/gtest.h" -// -// #include "motis/loader/loader.h" -// #include "motis/core/schedule/waiting_time_rules.h" - -// TODO(Mohammad Keyhani) new schedule required -// auto schedule = motis::load_schedule("../schedule/test", 0, 0); -// -// TEST(matrix, wzr) { -// auto const& waiting_time_rules = schedule->waiting_time_rules_; -// -// ASSERT_TRUE(waiting_time_rules.waiting_time(1, 1) == 3); -// ASSERT_TRUE(waiting_time_rules.waiting_time(1, 2) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(1, 3) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(1, 4) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(1, 5) == 0); -// -// ASSERT_TRUE(waiting_time_rules.waiting_time(2, 1) == 10); -// ASSERT_TRUE(waiting_time_rules.waiting_time(2, 2) == 10); -// ASSERT_TRUE(waiting_time_rules.waiting_time(2, 3) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(2, 4) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(2, 5) == 5); -// -// ASSERT_TRUE(waiting_time_rules.waiting_time(3, 1) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(3, 2) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(3, 3) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(3, 4) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(3, 5) == 0); -// -// ASSERT_TRUE(waiting_time_rules.waiting_time(4, 1) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(4, 2) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(4, 3) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(4, 4) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(4, 5) == 0); -// -// ASSERT_TRUE(waiting_time_rules.waiting_time(5, 1) == 5); -// ASSERT_TRUE(waiting_time_rules.waiting_time(5, 2) == 5); -// ASSERT_TRUE(waiting_time_rules.waiting_time(5, 3) == 0); -// ASSERT_TRUE(waiting_time_rules.waiting_time(5, 4) == 5); -// ASSERT_TRUE(waiting_time_rules.waiting_time(5, 5) == 5); -//} -// -// TEST(family_to_category_assignment, wzr) { -// auto const& waiting_time_rules = schedule->waiting_time_rules_; -// -// auto it = std::find(begin(schedule->category_names), -// end(schedule->category_names), "IC"); -// ASSERT_TRUE(it != end(schedule->category_names)); -// -// int family = std::distance(begin(schedule->category_names), it); -// ASSERT_TRUE(waiting_time_rules.waiting_time_category(family) == 1); -//} -// -// TEST(train_class_waits_for_other_trains, wzr) { -// auto const& waiting_time_rules = schedule->waiting_time_rules_; -// -// ASSERT_TRUE(waiting_time_rules.waits_for_other_trains(1)); -// ASSERT_TRUE(!waiting_time_rules.waits_for_other_trains(3)); -//} -// -// TEST(other_trains_wait_for_train_class, wzr) { -// auto const& waiting_time_rules = schedule->waiting_time_rules_; -// -// ASSERT_TRUE(waiting_time_rules.other_trains_wait_for(1)); -// ASSERT_TRUE(!waiting_time_rules.other_trains_wait_for(3)); -//} diff --git a/base/launcher/src/batch_mode.cc b/base/launcher/src/batch_mode.cc index 0b9c78f0b..46b1d795d 100644 --- a/base/launcher/src/batch_mode.cc +++ b/base/launcher/src/batch_mode.cc @@ -1,16 +1,19 @@ #include "motis/launcher/batch_mode.h" -#include +#include +#include #include -#include -#include #include #include +#include +#include -#include "utl/erase.h" +#include "boost/asio/io_service.hpp" #include "motis/core/common/logging.h" +#include "motis/module/json_format.h" #include "motis/module/message.h" +#include "motis/module/receiver.h" using namespace motis::module; diff --git a/base/launcher/src/load_server_certificate.cc b/base/launcher/src/load_server_certificate.cc index b4cca2d30..8e43379a4 100644 --- a/base/launcher/src/load_server_certificate.cc +++ b/base/launcher/src/load_server_certificate.cc @@ -1,6 +1,12 @@ #include "motis/launcher/load_server_certificate.h" #include +#include +#include +#include + +#include "boost/asio/buffer.hpp" +#include "boost/asio/ssl/context.hpp" namespace motis::launcher { diff --git a/base/launcher/src/main.cc b/base/launcher/src/main.cc index 802546a28..fbd6ac069 100644 --- a/base/launcher/src/main.cc +++ b/base/launcher/src/main.cc @@ -13,7 +13,6 @@ #include "utl/erase_if.h" #include "utl/parser/cstr.h" -#include "utl/to_vec.h" #include "net/stop_handler.h" @@ -24,7 +23,6 @@ #endif #include "motis/core/common/logging.h" -#include "motis/bootstrap/dataset_settings.h" #include "motis/bootstrap/import_settings.h" #include "motis/bootstrap/module_settings.h" #include "motis/bootstrap/motis_instance.h" @@ -56,25 +54,19 @@ int main(int argc, char const** argv) { web_server server(instance.runner_.ios(), instance); server_settings server_opt; - dataset_settings dataset_opt; import_settings import_opt; - dataset_opt.write_serialized_ = true; - dataset_opt.adjust_footpaths_ = true; module_settings module_opt(instance.module_names()); remote_settings remote_opt; launcher_settings launcher_opt; - std::set disabled_by_default{ - "cc", "csa", "gbfs", "nigiri", "paxforecast", "paxmon", - "raptor", "revise", "ris", "rt", "tiles", "tripbased"}; + std::set disabled_by_default{"ppr", "gbfs", "parking"}; utl::erase_if(module_opt.modules_, [&](std::string const& m) { return disabled_by_default.contains(m); }); - std::vector confs = {&server_opt, &import_opt, - &dataset_opt, &module_opt, - &remote_opt, &launcher_opt}; + std::vector confs = { + &server_opt, &import_opt, &module_opt, &remote_opt, &launcher_opt}; for (auto const& module : instance.modules()) { confs.push_back(module); } @@ -113,7 +105,7 @@ int main(int argc, char const** argv) { } try { - instance.import(module_opt, dataset_opt, import_opt); + instance.import(module_opt, import_opt); instance.init_modules(module_opt, launcher_opt.num_threads_); instance.init_remotes(remote_opt.get_remotes()); @@ -126,7 +118,7 @@ int main(int argc, char const** argv) { std::getline(in, json); auto const res = instance.call(make_msg(json), launcher_opt.num_threads_); - std::cout << res->to_json() << std::endl; + std::cout << res->to_json() << '\n'; } } else { instance.call(launcher_opt.init_, launcher_opt.num_threads_); diff --git a/base/launcher/src/web_server.cc b/base/launcher/src/web_server.cc index ee9af5160..ee11a5174 100644 --- a/base/launcher/src/web_server.cc +++ b/base/launcher/src/web_server.cc @@ -191,13 +191,12 @@ struct web_server::impl { serve_static_files_ = true; } } catch (fs::filesystem_error const& e) { - std::cerr << "Static file directory not found: " << e.what() << std::endl; + std::cerr << "Static file directory not found: " << e.what() << '\n'; } if (serve_static_files_) { - std::cout << "Serving static files from " << static_file_path_ - << std::endl; + std::cout << "Serving static files from " << static_file_path_ << '\n'; } else { - std::cout << "Not serving static files" << std::endl; + std::cout << "Not serving static files" << '\n'; } if (!ec) { server_.run(); @@ -409,7 +408,7 @@ struct web_server::impl { try { log_file_ << "[" << motis::logging::time() << "] " - << msg->to_json(json_format::SINGLE_LINE) << std::endl; + << msg->to_json(json_format::SINGLE_LINE) << '\n'; } catch (std::ios_base::failure const& e) { LOG(logging::error) << "could not log request: " << e.what(); reset_logging(false); diff --git a/base/loader/CMakeLists.txt b/base/loader/CMakeLists.txt deleted file mode 100644 index 93bcd9209..000000000 --- a/base/loader/CMakeLists.txt +++ /dev/null @@ -1,34 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(motis) - -set(schedule-dir ${CMAKE_CURRENT_SOURCE_DIR}/schedule-format) -set(generated-headers-dir "${CMAKE_BINARY_DIR}/generated/motis/schedule-format") -file(GLOB_RECURSE schedule-format-files ${schedule-dir}/*.fbs) -build_flatbuffers( - 64 # num_bits - "" # commandline_options - "${schedule-format-files}" # flatbuffers_schemas - "${schedule-dir}" # schema_include_dirs - generated-schedule-headers # custom_target_name - "" # additional_dependencies - "${generated-headers-dir}" # generated_includes_dir - "" # binary_schemas_dir - "" # copy_text_schemas_dir -) - -file(GLOB_RECURSE motis-loader-files src/*.cc) -add_library(motis-loader STATIC ${motis-loader-files}) -target_include_directories(motis-loader PUBLIC include) -target_compile_features(motis-loader PUBLIC cxx_std_17) -add_dependencies(motis-loader generated-schedule-headers) -target_link_libraries(motis-loader - boost-system - boost-filesystem - flatbuffers64 - motis-core - date - geo - date-tz -) -target_compile_options(motis-loader PRIVATE ${MOTIS_CXX_FLAGS}) -target_compile_definitions(motis-loader PRIVATE FLATBUFFERS_64=1) diff --git a/base/loader/include/motis/loader/bitfield.h b/base/loader/include/motis/loader/bitfield.h deleted file mode 100644 index 7e80423e0..000000000 --- a/base/loader/include/motis/loader/bitfield.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "utl/parser/cstr.h" - -namespace motis::loader { - -constexpr int BIT_COUNT = 2048; -using bitfield = std::bitset; - -template -struct bitset_comparator { - bool operator()(std::bitset const& lhs, - std::bitset const& rhs) const { - for (std::size_t i = 0; i < BitSetSize; ++i) { - int lhs_bit = lhs.test(i) ? 1 : 0; - int rhs_bit = rhs.test(i) ? 1 : 0; - if (lhs_bit != rhs_bit) { - return lhs_bit < rhs_bit; - } - } - return false; - } -}; - -template -std::bitset create_uniform_bitfield(char val) { - assert(val == '1' || val == '0'); - - std::string all_days_bit_str; - all_days_bit_str.resize(BitSetSize); - std::fill(begin(all_days_bit_str), end(all_days_bit_str), val); - - return std::bitset(all_days_bit_str); -} - -template -inline std::string serialize_bitset(std::bitset const& bitset) { - return bitset.to_string(); -} - -template -inline std::bitset deserialize_bitset(utl::cstr str) { - return std::bitset(std::string(str.str, str.len)); -} - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/build_footpaths.h b/base/loader/include/motis/loader/build_footpaths.h deleted file mode 100644 index 109a3a927..000000000 --- a/base/loader/include/motis/loader/build_footpaths.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -#include "motis/hash_map.h" - -#include "motis/core/schedule/schedule.h" - -#include "motis/loader/loader_options.h" - -namespace motis::loader { - -struct Schedule; // NOLINT -struct Station; // NOLINT - -void build_footpaths(schedule&, loader_options const&, - mcd::hash_map const&, - std::vector const&); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/build_graph.h b/base/loader/include/motis/loader/build_graph.h deleted file mode 100644 index 94e165278..000000000 --- a/base/loader/include/motis/loader/build_graph.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/core/schedule/schedule.h" -#include "motis/loader/loader_options.h" - -namespace motis::loader { - -struct Schedule; // NOLINT - -schedule_ptr build_graph(std::vector const&, - loader_options const&); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/build_stations.h b/base/loader/include/motis/loader/build_stations.h deleted file mode 100644 index a12d79676..000000000 --- a/base/loader/include/motis/loader/build_stations.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/hash_map.h" - -#include "motis/core/schedule/schedule.h" - -namespace motis::loader { - -struct Station; // NOLINT -struct Schedule; // NOLINT - -mcd::hash_map build_stations( - schedule&, std::vector const&, - std::map& tracks, bool use_platforms, - bool no_local_stations); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/classes.h b/base/loader/include/motis/loader/classes.h deleted file mode 100644 index 95acd0cc8..000000000 --- a/base/loader/include/motis/loader/classes.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "motis/hash_map.h" -#include "motis/string.h" - -#include "motis/core/schedule/connection.h" - -namespace motis::loader { - -mcd::hash_map const& class_mapping(); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/filter/local_stations.h b/base/loader/include/motis/loader/filter/local_stations.h deleted file mode 100644 index 5b2fb1ee0..000000000 --- a/base/loader/include/motis/loader/filter/local_stations.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "motis/schedule-format/Schedule_generated.h" - -namespace motis::loader { - -inline bool is_local_station(Station const* station) { - return station->id()->c_str()[0] == '0'; -} - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/graph_builder.h b/base/loader/include/motis/loader/graph_builder.h deleted file mode 100644 index 82cb63441..000000000 --- a/base/loader/include/motis/loader/graph_builder.h +++ /dev/null @@ -1,255 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "flatbuffers/flatbuffers.h" - -#include "cista/hashing.h" - -#include "motis/hash_map.h" -#include "motis/hash_set.h" -#include "motis/string.h" -#include "motis/vector.h" - -#include "motis/core/common/hash_helper.h" -#include "motis/core/schedule/connection.h" -#include "motis/core/schedule/edges.h" -#include "motis/core/schedule/nodes.h" -#include "motis/core/schedule/provider.h" -#include "motis/core/schedule/schedule.h" -#include "motis/core/schedule/timezone.h" - -#include "motis/loader/bitfield.h" -#include "motis/loader/loader_options.h" -#include "motis/loader/timezone_util.h" - -#include "motis/schedule-format/Schedule_generated.h" - -namespace motis::loader { - -struct route_section { - route_section() - : from_route_node_(nullptr), - to_route_node_(nullptr), - outgoing_route_edge_index_(-1) {} - - route_section(node* from, node* to, int edge_idx) - : from_route_node_(from), - to_route_node_(to), - outgoing_route_edge_index_(edge_idx) { - assert(from_route_node_ == nullptr || from_route_node_->is_route_node()); - assert(to_route_node_ == nullptr || to_route_node_->is_route_node()); - } - - bool is_valid() const { - return from_route_node_ != nullptr && to_route_node_ != nullptr && - outgoing_route_edge_index_ != -1; - } - - edge* get_route_edge() const { - if (outgoing_route_edge_index_ == -1) { - return nullptr; - } - - assert(outgoing_route_edge_index_ >= 0); - assert(static_cast(outgoing_route_edge_index_) < - from_route_node_->edges_.size()); - assert(from_route_node_->edges_[outgoing_route_edge_index_].type() == - edge::ROUTE_EDGE); - return &from_route_node_->edges_[outgoing_route_edge_index_]; - } - - node* from_route_node_; - node* to_route_node_; - int outgoing_route_edge_index_; -}; - -struct participant { - participant() : service_(nullptr), section_idx_(0) {} - - participant(Service const* service, unsigned section_idx) - : service_(service), section_idx_(section_idx) {} - - friend bool operator<(participant const& lhs, participant const& rhs) { - return lhs.service_ > rhs.service_; - } - - friend bool operator>(participant const& lhs, participant const& rhs) { - return lhs.service_ < rhs.service_; - } - - friend bool operator==(participant const& lhs, participant const& rhs) { - return lhs.service_ == rhs.service_; - } - - Service const* service_; - unsigned section_idx_; -}; - -struct service_with_day_offset { - CISTA_COMPARABLE() - - Service const* service_{nullptr}; - int day_offset_{0}; -}; - -struct services_key { - services_key() = default; - - services_key(Service const* service, int day_idx) - : services_({{service, 0}}), day_idx_(day_idx) {} - - services_key(std::set services, int day_idx) - : services_(std::move(services)), day_idx_(day_idx) {} - - friend bool operator<(services_key const& lhs, services_key const& rhs) { - return std::tie(lhs.services_, lhs.day_idx_) < - std::tie(rhs.services_, rhs.day_idx_); - } - - friend bool operator==(services_key const& lhs, services_key const& rhs) { - return std::tie(lhs.services_, lhs.day_idx_) == - std::tie(rhs.services_, rhs.day_idx_); - } - - std::set services_; - int day_idx_{0}; -}; - -template -inline std::size_t push_mem(mcd::vector>& elements, - Args... args) { - auto idx = elements.size(); - elements.emplace_back(new T{args...}); - return idx; -} - -using route = mcd::vector; -using route_lcs = mcd::vector>; - -struct graph_builder { - graph_builder(schedule&, loader_options const&); - - full_trip_id get_full_trip_id(Service const* s, int day, int section_idx = 0); - - std::optional create_merged_trips( - Service const* s, int day_idx, light_connection const* first_lcon); - - trip* register_service(Service const* s, int day_idx, bool allow_duplicates); - - void add_services( - flatbuffers64::Vector> const* services); - - bool has_duplicate(Service const*, mcd::vector const&); - - bool are_duplicates(Service const*, mcd::vector const&, - trip const*); - - void index_first_route_node(route const& r); - - void add_route_services( - mcd::vector> const& services); - - void add_expanded_trips(route const& r); - - static int get_index( - mcd::vector> const& alt_route, - mcd::vector const& sections, - mcd::vector const& stations); - - static void add_to_route(mcd::vector>& route, - mcd::vector const& sections, - int index); - - static void add_to_routes( - mcd::vector>>& alt_routes, - mcd::vector const& sections, - mcd::vector const& stations); - - connection_info* get_or_create_connection_info(Section const* section, - int dep_day_index, - connection_info* merged_with); - - connection_info* get_or_create_connection_info( - std::array const& services, int dep_day_index); - - light_connection section_to_connection( - merged_trips_idx trips, std::array const& services, - int day, time prev_arr, bool& adjusted); - - void connect_reverse(); - - void sort_connections(); - void sort_trips(); - - bitfield const& get_or_create_bitfield( - flatbuffers64::String const* serialized_bitfield); - - void read_attributes( - int day, - flatbuffers64::Vector> const* attributes, - mcd::vector>& active_attributes); - - mcd::string const* get_or_create_direction(Direction const* dir); - - provider const* get_or_create_provider(Provider const* p); - - int get_or_create_category_index(Category const* c); - - int get_or_create_track( - int day, - flatbuffers64::Vector> const* tracks); - - void write_trip_info(route const&); - - mcd::unique_ptr create_route(Route const* r, route_lcs const& lcons, - unsigned route_index); - - route_section add_route_section( - int route_index, mcd::vector const& connections, - Station const* from_stop, bool from_in_allowed, bool from_out_allowed, - Station const* to_stop, bool to_in_allowed, bool to_out_allowed, - node* from_route_node, node* to_route_node); - - bool check_trip(trip const* trp); - - bool skip_station(Station const* station) const; - bool skip_route(Route const* route) const; - - std::string dataset_prefix_; - unsigned lcon_count_{0U}; - unsigned next_route_index_{0U}; - tz_cache tz_cache_; - std::map categories_; - std::map tracks_; - std::map attributes_; - std::map directions_; - std::map providers_; - mcd::hash_map stations_; - mcd::hash_map bitfields_; - mcd::hash_set, connection_info>, - deep_ptr_eq> - con_infos_; - mcd::hash_set, connection>, - deep_ptr_eq> - connections_; - mcd::hash_map filenames_; - mcd::hash_map added_full_trip_ids_; - schedule& sched_; - int first_day_{0}, last_day_{0}; - bool apply_rules_{false}; - bool no_local_transport_{false}; - bool debug_broken_trips_{false}; - - connection_info con_info_; - connection con_; - std::size_t broken_trips_{0U}; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/gtfs/agency.h b/base/loader/include/motis/loader/gtfs/agency.h deleted file mode 100644 index 30b2cb200..000000000 --- a/base/loader/include/motis/loader/gtfs/agency.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct agency { - agency(std::string id, std::string name, std::string timezone) - : id_(std::move(id)), - name_(std::move(name)), - timezone_(std::move(timezone)) {} - - std::string id_; - std::string name_; - std::string timezone_; -}; - -using agency_map = std::map>; - -agency_map read_agencies(loaded_file); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/calendar.h b/base/loader/include/motis/loader/gtfs/calendar.h deleted file mode 100644 index f4e8f7571..000000000 --- a/base/loader/include/motis/loader/gtfs/calendar.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "date/date.h" - -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct calendar { - std::bitset<7> week_days_; - date::sys_days first_day_, last_day_; -}; - -std::map read_calendar(loaded_file); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/calendar_date.h b/base/loader/include/motis/loader/gtfs/calendar_date.h deleted file mode 100644 index 8312b4af4..000000000 --- a/base/loader/include/motis/loader/gtfs/calendar_date.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "cista/reflection/comparable.h" - -#include "date/date.h" - -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct calendar_date { - CISTA_COMPARABLE() - enum { ADD, REMOVE } type_{ADD}; - date::sys_days day_; -}; - -std::map> read_calendar_date( - loaded_file); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/feed_info.h b/base/loader/include/motis/loader/gtfs/feed_info.h deleted file mode 100644 index e0ddd07eb..000000000 --- a/base/loader/include/motis/loader/gtfs/feed_info.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/loaded_file.h" - -namespace motis { -namespace loader { -namespace gtfs { - -struct feed { - feed(std::string publisher_name, std::string version) - : publisher_name_(std::move(publisher_name)), - version_(std::move(version)) {} - - std::string publisher_name_; - std::string version_; -}; - -using feed_map = std::map; - -feed_map read_feed_publisher(loaded_file); - -} // namespace gtfs -} // namespace loader -} // namespace motis \ No newline at end of file diff --git a/base/loader/include/motis/loader/gtfs/files.h b/base/loader/include/motis/loader/gtfs/files.h deleted file mode 100644 index c285693a4..000000000 --- a/base/loader/include/motis/loader/gtfs/files.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -namespace motis::loader::gtfs { - -constexpr char const* AGENCY_FILE = "agency.txt"; -constexpr char const* STOPS_FILE = "stops.txt"; -constexpr char const* ROUTES_FILE = "routes.txt"; -constexpr char const* TRIPS_FILE = "trips.txt"; -constexpr char const* STOP_TIMES_FILE = "stop_times.txt"; -constexpr char const* CALENDAR_FILE = "calendar.txt"; -constexpr char const* CALENDAR_DATES_FILE = "calendar_dates.txt"; -constexpr char const* TRANSFERS_FILE = "transfers.txt"; -constexpr char const* FEED_INFO_FILE = "feed_info.txt"; -constexpr char const* FREQUENCIES_FILE = "frequencies.txt"; - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/flat_map.h b/base/loader/include/motis/loader/gtfs/flat_map.h deleted file mode 100644 index 0303e5238..000000000 --- a/base/loader/include/motis/loader/gtfs/flat_map.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "utl/to_vec.h" - -namespace motis::loader::gtfs { - -template -struct flat_map { - using index_t = std::size_t; - using entry_t = std::pair; - using iterator = typename std::vector::iterator; - using const_iterator = typename std::vector::const_iterator; - using reverse_iterator = typename std::vector::reverse_iterator; - using const_reverse_iterator = - typename std::vector::const_reverse_iterator; - - struct cmp { - bool operator()(entry_t const& lhs, entry_t const& rhs) { - return lhs.first < rhs.first; - } - }; - - size_t size() const { return elements_.size(); } - bool empty() const { return elements_.empty(); } - - std::vector to_vector() { - return utl::to_vec(elements_, [](entry_t const& el) { return el.second; }); - } - - template - void emplace(index_t idx, Args... args) { - auto s = std::make_pair(idx, T(std::forward(args)...)); - auto it = std::lower_bound(elements_.begin(), elements_.end(), s, cmp()); - elements_.emplace(it, std::move(s)); - } - - T& operator[](index_t idx) { - auto s = std::make_pair(idx, T()); - auto it = std::lower_bound(elements_.begin(), elements_.end(), s, cmp()); - if (it == elements_.end() || it->first != idx) { - it = elements_.emplace(it, s); - } - return it->second; - } - - iterator erase(const_iterator first, const_iterator last) { - return elements_.erase(first, last); - } - - T& front() { return elements_[0].second; } - T& back() { return elements_[elements_.size() - 1].second; } - T const& front() const { return elements_[0].second; } - T const& back() const { return elements_[elements_.size() - 1].second; } - - iterator begin() { return elements_.begin(); } - iterator end() { return elements_.end(); } - const_iterator begin() const { return elements_.begin(); } - const_iterator end() const { return elements_.end(); } - const_reverse_iterator rbegin() const { return elements_.rcbegin(); } - const_reverse_iterator rend() const { return elements_.rcend(); } - reverse_iterator rbegin() { return elements_.rbegin(); } - reverse_iterator rend() { return elements_.rend(); } - friend const_iterator begin(flat_map const& m) { return m.begin(); } - friend const_iterator end(flat_map const& m) { return m.end(); } - friend iterator begin(flat_map& m) { return m.begin(); } - friend iterator end(flat_map& m) { return m.end(); } - -private: - std::vector elements_; -}; - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/gtfs_parser.h b/base/loader/include/motis/loader/gtfs/gtfs_parser.h deleted file mode 100644 index 934758519..000000000 --- a/base/loader/include/motis/loader/gtfs/gtfs_parser.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "motis/loader/parser.h" - -namespace motis::loader::gtfs { - -struct gtfs_parser : public format_parser { - bool applicable(std::filesystem::path const&) override; - std::vector missing_files( - std::filesystem::path const&) const override; - void parse(parser_options const&, std::filesystem::path const& root, - flatbuffers64::FlatBufferBuilder&) override; -}; - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/parse_time.h b/base/loader/include/motis/loader/gtfs/parse_time.h deleted file mode 100644 index 5e1231c9c..000000000 --- a/base/loader/include/motis/loader/gtfs/parse_time.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "utl/parser/cstr.h" - -namespace motis::loader::gtfs { - -constexpr auto const kInterpolate = -1; - -int hhmm_to_min(utl::cstr s); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/route.h b/base/loader/include/motis/loader/gtfs/route.h deleted file mode 100644 index 823454441..000000000 --- a/base/loader/include/motis/loader/gtfs/route.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "cista/reflection/comparable.h" - -#include "motis/core/schedule/connection.h" -#include "motis/loader/gtfs/agency.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct category { - enum output { - PRINT_CATEGORY_AND_ID = 0b0000U, - PRINT_CATEGORY = 0b0001U, - PRINT_ID = 0b0010U, - FORCE_PROVIDER_INSTEAD_OF_CATEGORY = 0b1000U, - FORCE_TRAIN_NUMBER_INSTEAD_OF_LINE_ID = 0b0010U, - ROUTE_NAME_SHORT_INSTEAD_OF_CATEGORY = 0b10000U, - BASIC_ROUTE_TYPE = 0b100000U, - BASE = 0b1111U, - }; - - CISTA_COMPARABLE() - std::string name_; - unsigned output_rule_{PRINT_CATEGORY_AND_ID}; -}; - -struct route { - route(agency const* agency, std::string id, std::string short_name, - std::string long_name, std::string route_desc, int type) - : agency_(agency), - id_(std::move(id)), - short_name_(std::move(short_name)), - long_name_(std::move(long_name)), - desc_{std::move(route_desc)}, - type_(type) {} - - static std::map const s_types; - static std::map const s_clasz; - - std::optional get_category() const; - - agency const* agency_; - std::string id_; - std::string short_name_; - std::string long_name_; - std::string desc_; - int type_; -}; - -using route_map = std::map>; - -route_map read_routes(loaded_file, agency_map const&); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/services.h b/base/loader/include/motis/loader/gtfs/services.h deleted file mode 100644 index f4fa5e9c1..000000000 --- a/base/loader/include/motis/loader/gtfs/services.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "boost/date_time/gregorian/gregorian.hpp" - -#include "motis/loader/bitfield.h" -#include "motis/loader/gtfs/calendar.h" -#include "motis/loader/gtfs/calendar_date.h" - -namespace motis::loader::gtfs { - -struct traffic_days { - date::sys_days first_day_, last_day_; - std::map> traffic_days_; -}; - -traffic_days merge_traffic_days( - std::map const&, - std::map> const&); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/stop.h b/base/loader/include/motis/loader/gtfs/stop.h deleted file mode 100644 index 8839c23c3..000000000 --- a/base/loader/include/motis/loader/gtfs/stop.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "geo/latlng.h" -#include "geo/point_rtree.h" - -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct stop { - void compute_close_stations(geo::point_rtree const& stop_rtree, - unsigned const max_meters); - std::set get_metas(std::vector const& stops); - - std::string id_; - std::string name_; - geo::latlng coord_; - std::string timezone_; - std::set same_name_, parents_, children_; - std::vector close_; -}; - -using stop_map = std::map>; - -stop_map read_stops(loaded_file); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/stop_time.h b/base/loader/include/motis/loader/gtfs/stop_time.h deleted file mode 100644 index 5a324422f..000000000 --- a/base/loader/include/motis/loader/gtfs/stop_time.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/gtfs/trip.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -void read_stop_times(loaded_file const&, trip_map&, stop_map const&); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/transfers.h b/base/loader/include/motis/loader/gtfs/transfers.h deleted file mode 100644 index e43a9903f..000000000 --- a/base/loader/include/motis/loader/gtfs/transfers.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include -#include - -#include "utl/parser/cstr.h" - -#include "motis/loader/gtfs/stop.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::gtfs { - -struct transfer { - enum { - RECOMMENDED_TRANSFER, - TIMED_TRANSFER, - MIN_TRANSFER_TIME, - NOT_POSSIBLE, - GENERATED - }; - - transfer() = default; - transfer(int minutes, int type) : minutes_(minutes), type_(type) {} - - int minutes_; - int type_; -}; - -using stop_pair = std::pair; -std::map read_transfers(loaded_file, stop_map const&); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/gtfs/trip.h b/base/loader/include/motis/loader/gtfs/trip.h deleted file mode 100644 index 9b8b00e91..000000000 --- a/base/loader/include/motis/loader/gtfs/trip.h +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "cista/reflection/comparable.h" - -#include "motis/loader/gtfs/flat_map.h" -#include "motis/loader/gtfs/parse_time.h" -#include "motis/loader/gtfs/route.h" -#include "motis/loader/gtfs/services.h" -#include "motis/loader/gtfs/stop.h" -#include "motis/loader/loaded_file.h" -#include "motis/schedule-format/Service_generated.h" - -namespace motis::loader::gtfs { - -struct trip; - -struct block { - std::vector, bitfield>> rule_services(); - std::vector trips_; -}; - -using block_map = std::map>; - -struct stop_time { - stop_time(); - stop_time(stop*, std::string headsign, int arr_time, bool out_allowed, - int dep_time, bool in_allowed); - - struct ev { - int time_{kInterpolate}; - bool in_out_allowed_{false}; - }; - - stop* stop_{nullptr}; - std::string headsign_; - ev arr_, dep_; -}; - -struct frequency { - int start_time_; // minutes since midnight - int end_time_; // minutes since midnight on start day - int headway_; // minutes between trip starts - ScheduleRelationship schedule_relationship_; -}; - -struct trip { - struct stop_identity { - CISTA_COMPARABLE() - stop* stop_{nullptr}; - bool out_allowed_{false}; - bool in_allowed_{false}; - }; - using stop_seq = std::vector; - using stop_seq_numbers = std::vector; - - trip(route const*, bitfield const*, block*, std::string id, - std::string headsign, std::string short_name); - - void interpolate(); - - stop_seq stops() const; - stop_seq_numbers seq_numbers() const; - - int avg_speed() const; - int distance() const; - - void expand_frequencies( - std::function const&) const; - - void print_stop_times(std::ostream&, unsigned indent = 0) const; - - route const* route_; - bitfield const* service_; - block* block_; - std::string id_; - std::string headsign_; - std::string short_name_; - flat_map stop_times_; - std::size_t from_line_{0U}, to_line_{0U}; - std::optional> frequency_; -}; - -using trip_map = std::map>; - -std::pair read_trips(loaded_file, route_map const&, - traffic_days const&); - -void read_frequencies(loaded_file, trip_map&); - -} // namespace motis::loader::gtfs diff --git a/base/loader/include/motis/loader/hrd/builder/attribute_builder.h b/base/loader/include/motis/loader/hrd/builder/attribute_builder.h deleted file mode 100644 index 06690c044..000000000 --- a/base/loader/include/motis/loader/hrd/builder/attribute_builder.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/model/hrd_service.h" - -#include "motis/loader/hrd/builder/bitfield_builder.h" - -#include "motis/schedule-format/Attribute_generated.h" - -namespace motis::loader::hrd { - -struct attribute_builder { - explicit attribute_builder(std::map hrd_attributes); - - flatbuffers64::Offset>> - create_attributes(std::vector const&, - bitfield_builder&, flatbuffers64::FlatBufferBuilder&); - - flatbuffers64::Offset get_or_create_attribute( - hrd_service::attribute const&, bitfield_builder&, - flatbuffers64::FlatBufferBuilder&); - - std::map hrd_attributes_; - std::map> fbs_attribute_infos_; - std::map, flatbuffers64::Offset> - fbs_attributes_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/bitfield_builder.h b/base/loader/include/motis/loader/hrd/builder/bitfield_builder.h deleted file mode 100644 index 1179f675c..000000000 --- a/base/loader/include/motis/loader/hrd/builder/bitfield_builder.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include - -#include "flatbuffers/flatbuffers.h" - -#include "motis/hash_map.h" - -#include "motis/loader/bitfield.h" - -namespace motis::loader::hrd { - -struct bitfield_builder { - static constexpr int kNoBitfield = -1; - - explicit bitfield_builder(std::map); - - flatbuffers64::Offset get_or_create_bitfield( - int bitfield_num, flatbuffers64::FlatBufferBuilder&); - - flatbuffers64::Offset get_or_create_bitfield( - bitfield const&, flatbuffers64::FlatBufferBuilder&, int = kNoBitfield); - - std::map hrd_bitfields_; - mcd::hash_map, - std::hash, std::equal_to<>> - fbs_bitfields_; - std::map> fbs_bf_lookup_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/category_builder.h b/base/loader/include/motis/loader/hrd/builder/category_builder.h deleted file mode 100644 index e8ead384d..000000000 --- a/base/loader/include/motis/loader/hrd/builder/category_builder.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include - -#include "utl/parser/cstr.h" - -#include "motis/loader/hrd/parser/categories_parser.h" - -#include "motis/schedule-format/Category_generated.h" - -namespace motis::loader::hrd { - -struct category_builder { - explicit category_builder(std::map hrd_categories); - - flatbuffers64::Offset get_or_create_category( - utl::cstr, flatbuffers64::FlatBufferBuilder&); - - std::map hrd_categories_; - std::map> fbs_categories_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/direction_builder.h b/base/loader/include/motis/loader/hrd/builder/direction_builder.h deleted file mode 100644 index 9cddd767a..000000000 --- a/base/loader/include/motis/loader/hrd/builder/direction_builder.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/schedule-format/Direction_generated.h" - -#include "motis/loader/hrd/builder/station_builder.h" - -namespace motis::loader::hrd { - -struct direction_builder { - explicit direction_builder(std::map); - - flatbuffers64::Offset get_or_create_direction( - std::vector> const&, station_builder&, - flatbuffers64::FlatBufferBuilder&); - - std::map hrd_directions_; - std::map> fbs_directions_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/footpath_builder.h b/base/loader/include/motis/loader/hrd/builder/footpath_builder.h deleted file mode 100644 index 1f51983d8..000000000 --- a/base/loader/include/motis/loader/hrd/builder/footpath_builder.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/parser/station_meta_data_parser.h" - -#include "motis/schedule-format/Footpath_generated.h" - -namespace motis::loader::hrd { - -flatbuffers64::Offset>> -create_footpaths(std::set const&, station_builder&, - flatbuffers64::FlatBufferBuilder&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/line_builder.h b/base/loader/include/motis/loader/hrd/builder/line_builder.h deleted file mode 100644 index ea33d5a6b..000000000 --- a/base/loader/include/motis/loader/hrd/builder/line_builder.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include "flatbuffers/flatbuffers.h" - -#include "utl/parser/cstr.h" - -namespace motis::loader::hrd { - -struct line_builder { - flatbuffers64::Offset get_or_create_line( - std::vector const&, flatbuffers64::FlatBufferBuilder&); - - std::map> fbs_lines_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/meta_station_builder.h b/base/loader/include/motis/loader/hrd/builder/meta_station_builder.h deleted file mode 100644 index 3d7d43478..000000000 --- a/base/loader/include/motis/loader/hrd/builder/meta_station_builder.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/parser/station_meta_data_parser.h" - -#include "motis/schedule-format/MetaStation_generated.h" - -namespace motis::loader::hrd { - -flatbuffers64::Offset>> -create_meta_stations(std::set const&, - station_builder& sb, flatbuffers64::FlatBufferBuilder&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/provider_builder.h b/base/loader/include/motis/loader/hrd/builder/provider_builder.h deleted file mode 100644 index 2e5fcd602..000000000 --- a/base/loader/include/motis/loader/hrd/builder/provider_builder.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/parser/providers_parser.h" -#include "motis/schedule-format/Provider_generated.h" - -namespace motis::loader::hrd { - -struct provider_builder { - explicit provider_builder(std::map); - - flatbuffers64::Offset get_or_create_provider( - uint64_t, flatbuffers64::FlatBufferBuilder&); - - std::map hrd_providers_; - std::map> fbs_providers_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/route_builder.h b/base/loader/include/motis/loader/hrd/builder/route_builder.h deleted file mode 100644 index 0b3b43319..000000000 --- a/base/loader/include/motis/loader/hrd/builder/route_builder.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "utl/parser/cstr.h" - -#include "motis/schedule-format/Schedule_generated.h" - -#include "motis/loader/hrd/builder/bitfield_builder.h" -#include "motis/loader/hrd/builder/provider_builder.h" -#include "motis/loader/hrd/builder/rule_service_builder.h" -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/model/hrd_service.h" - -namespace motis::loader::hrd { - -struct stop_restrictions { - friend bool operator<(stop_restrictions const& lhs, - stop_restrictions const& rhs) { - if (rhs.eva_num_ < lhs.eva_num_) { - return true; - } else if (rhs.eva_num_ > lhs.eva_num_) { - return false; - } - if (static_cast(rhs.entering_allowed_) < - static_cast(lhs.entering_allowed_)) { - return true; - } else if (static_cast(rhs.entering_allowed_) > - static_cast(lhs.entering_allowed_)) { - return false; - } - if (static_cast(rhs.leaving_allowed_) < - static_cast(lhs.leaving_allowed_)) { - return true; - } else if (static_cast(rhs.entering_allowed_) > - static_cast(lhs.entering_allowed_)) { - return false; - } - return false; - } - - friend bool operator==(stop_restrictions const& lhs, - stop_restrictions const& rhs) { - return lhs.eva_num_ == rhs.eva_num_ && - lhs.entering_allowed_ == rhs.entering_allowed_ && - lhs.leaving_allowed_ == rhs.leaving_allowed_; - } - - int eva_num_; - bool entering_allowed_; - bool leaving_allowed_; -}; - -struct route_builder { - flatbuffers64::Offset get_or_create_route( - std::vector const&, station_builder&, - flatbuffers64::FlatBufferBuilder&); - - std::map, flatbuffers64::Offset> - routes_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/rule_service_builder.h b/base/loader/include/motis/loader/hrd/builder/rule_service_builder.h deleted file mode 100644 index dbefb33eb..000000000 --- a/base/loader/include/motis/loader/hrd/builder/rule_service_builder.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/model/rule_service.h" -#include "motis/loader/hrd/model/service_rule.h" -#include "motis/loader/util.h" -#include "motis/schedule-format/RuleService_generated.h" - -namespace motis::loader::hrd { - -struct rule_service_builder { - using service_builder_fun = std::function( - hrd_service const&, bool, flatbuffers64::FlatBufferBuilder&)>; - - rule_service_builder() = default; - explicit rule_service_builder(service_rules rs) - : input_rules_(std::move(rs)) {} - - bool add_service(hrd_service const&); - void resolve_rule_services(); - void create_rule_services(service_builder_fun const&, station_builder&, - flatbuffers64::FlatBufferBuilder&); - - std::vector> origin_services_; - std::vector rule_services_; - std::vector> fbs_rule_services_; - -private: - service_rules input_rules_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/service_builder.h b/base/loader/include/motis/loader/hrd/builder/service_builder.h deleted file mode 100644 index 8cf43ebed..000000000 --- a/base/loader/include/motis/loader/hrd/builder/service_builder.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/schedule-format/Service_generated.h" - -#include "motis/loader/hrd/builder/attribute_builder.h" -#include "motis/loader/hrd/builder/bitfield_builder.h" -#include "motis/loader/hrd/builder/category_builder.h" -#include "motis/loader/hrd/builder/direction_builder.h" -#include "motis/loader/hrd/builder/line_builder.h" -#include "motis/loader/hrd/builder/provider_builder.h" -#include "motis/loader/hrd/builder/route_builder.h" -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/parser/track_rules_parser.h" - -namespace motis::loader::hrd { - -struct service_builder { - explicit service_builder(track_rules); - - flatbuffers64::Offset create_service( - hrd_service const&, route_builder&, station_builder&, category_builder&, - provider_builder&, line_builder&, attribute_builder&, bitfield_builder&, - direction_builder&, flatbuffers64::FlatBufferBuilder&, - bool is_rule_participant); - - track_rules track_rules_; - std::vector> fbs_services_; - std::map> - filenames_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/builder/station_builder.h b/base/loader/include/motis/loader/hrd/builder/station_builder.h deleted file mode 100644 index 76ca78794..000000000 --- a/base/loader/include/motis/loader/hrd/builder/station_builder.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -#include "motis/loader/hrd/model/timezones.h" -#include "motis/loader/hrd/parser/stations_parser.h" - -#include "motis/schedule-format/Station_generated.h" - -namespace motis::loader::hrd { - -struct station_builder { - station_builder(std::map, timezones); - - flatbuffers64::Offset get_or_create_station( - int, flatbuffers64::FlatBufferBuilder&); - - std::map hrd_stations_; - timezones timezones_; - std::map> fbs_stations_; - std::map> - fbs_timezones_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/hrd_parser.h b/base/loader/include/motis/loader/hrd/hrd_parser.h deleted file mode 100644 index dc5691339..000000000 --- a/base/loader/include/motis/loader/hrd/hrd_parser.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/parser.h" - -namespace motis::loader::hrd { - -struct hrd_parser : public format_parser { - bool applicable(std::filesystem::path const& path) override; - static bool applicable(std::filesystem::path const& path, config const& c); - - std::vector missing_files( - std::filesystem::path const& hrd_root) const override; - - static std::vector missing_files( - std::filesystem::path const& hrd_root, config const& c); - - void parse(parser_options const&, std::filesystem::path const& hrd_root, - flatbuffers64::FlatBufferBuilder&) override; - static void parse(std::filesystem::path const& hrd_root, - flatbuffers64::FlatBufferBuilder&, config const& c); -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/hrd_service.h b/base/loader/include/motis/loader/hrd/model/hrd_service.h deleted file mode 100644 index 73a6a9567..000000000 --- a/base/loader/include/motis/loader/hrd/model/hrd_service.h +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once - -#include - -#include "utl/parser/cstr.h" - -#include "motis/loader/bitfield.h" -#include "motis/loader/hrd/model/specification.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -struct parser_info { - char const* filename_; - int line_number_from_; - int line_number_to_; -}; - -enum class event_type : uint8_t { DEP, ARR }; - -struct hrd_service { - static const constexpr auto NOT_SET = -1; // NOLINT - - struct event { - int time_; - bool in_out_allowed_; - }; - - struct stop { - int eva_num_; - event arr_, dep_; - }; - - struct attribute { - attribute(int bitfield_num, utl::cstr code) - : bitfield_num_(bitfield_num), code_(code) {} - - int bitfield_num_; - utl::cstr code_; - - friend bool operator==(attribute const& lhs, attribute const& rhs) { - return lhs.bitfield_num_ == rhs.bitfield_num_ && lhs.code_ == rhs.code_; - } - }; - - enum direction_type { EVA_NUMBER, DIRECTION_CODE }; - struct section { - section() = default; - section(int train_num, utl::cstr admin) - : train_num_(train_num), admin_(admin) {} - - int train_num_{0}; - utl::cstr admin_; - std::vector attributes_; - std::vector category_; - std::vector line_information_; - std::vector> directions_; - std::vector traffic_days_; - }; - - hrd_service(parser_info origin, int num_repetitions, int interval, - std::vector stops, std::vector
sections, - bitfield traffic_days, int initial_train_num) - : origin_(origin), - num_repetitions_(num_repetitions), - interval_(interval), - stops_(std::move(stops)), - sections_(std::move(sections)), - traffic_days_(traffic_days), - initial_train_num_(initial_train_num) {} - - hrd_service(specification const& spec, config const&); - - void verify_service(); - - std::vector> get_ids() const { - std::vector> ids; - - // Add first service id. - auto const& first_section = sections_.front(); - ids.emplace_back(std::make_pair( - first_section.train_num_, raw_to_int(first_section.admin_))); - - // Add new service id if it changed. - for (size_t i = 1; i < sections_.size(); ++i) { - auto id = std::make_pair(sections_[i].train_num_, - raw_to_int(sections_[i].admin_)); - if (id != ids.back()) { - ids.emplace_back(id); - } - } - - return ids; - } - - inline int find_first_stop_at(int eva_num) const { - for (auto i = 0UL; i < stops_.size(); ++i) { - if (stops_[i].eva_num_ == eva_num) { - return i; - } - } - return NOT_SET; - } - - inline int get_first_stop_index_at(int eva_num) const { - auto const idx = find_first_stop_at(eva_num); - utl::verify(idx != NOT_SET, - "hrd_service::get_first_stop_index_at: stop not found"); - return idx; - } - - inline int event_time(int stop_index, event_type evt) const { - return evt == event_type::DEP ? stops_[stop_index].dep_.time_ - : stops_[stop_index].arr_.time_; - } - - inline unsigned traffic_days_offset_at_stop(int stop_index, - event_type evt) const { - return static_cast(event_time(stop_index, evt) / 1440); - } - - inline bitfield traffic_days_at_stop(int stop_index, event_type evt) const { - return traffic_days_ << traffic_days_offset_at_stop(stop_index, evt); - } - - parser_info origin_; - int num_repetitions_; - int interval_; - std::vector stops_; - std::vector
sections_; - bitfield traffic_days_; - int initial_train_num_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/range.h b/base/loader/include/motis/loader/hrd/model/range.h deleted file mode 100644 index 801aaeb51..000000000 --- a/base/loader/include/motis/loader/hrd/model/range.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "utl/parser/cstr.h" - -#include "motis/loader/hrd/model/hrd_service.h" - -namespace motis::loader::hrd { - -struct range { - range() = default; - range(std::vector const& stops, utl::cstr from_eva_or_idx, - utl::cstr to_eva_or_idx, utl::cstr from_hhmm_or_idx, - utl::cstr to_hhmm_or_idx); - - int from_idx_, to_idx_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/repeat_service.h b/base/loader/include/motis/loader/hrd/model/repeat_service.h deleted file mode 100644 index 07138ab9e..000000000 --- a/base/loader/include/motis/loader/hrd/model/repeat_service.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include - -#include "motis/loader/hrd/model/hrd_service.h" - -namespace motis::loader::hrd { - -void expand_repetitions(std::vector&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/rule_service.h b/base/loader/include/motis/loader/hrd/model/rule_service.h deleted file mode 100644 index 92c51e9c0..000000000 --- a/base/loader/include/motis/loader/hrd/model/rule_service.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/model/service_rule.h" - -namespace motis::loader::hrd { - -struct service_resolvent { - explicit service_resolvent(hrd_service* origin) - : service_(nullptr), origin_(origin) {} - - service_resolvent( -#ifdef _WIN32 - std::shared_ptr service, -#else - std::unique_ptr service, -#endif - hrd_service* origin) - : service_(std::move(service)), origin_(origin) { - } - - friend bool operator<(service_resolvent const& rhs, - service_resolvent const& lhs) { - return rhs.origin_ < lhs.origin_; - } - - friend bool operator==(service_resolvent const& rhs, - service_resolvent const& lhs) { - return rhs.origin_ == lhs.origin_; - } - -#ifdef _WIN32 - // Bug in std::set of MSVC requires copy constructor. - std::shared_ptr service_; -#else - std::unique_ptr service_; -#endif - hrd_service* origin_{nullptr}; -}; - -struct service_rule_resolvent { - service_rule_resolvent(resolved_rule_info rule_info, hrd_service* s1, - hrd_service* s2) - : rule_info_(rule_info), s1_(s1), s2_(s2) {} - - resolved_rule_info rule_info_; - hrd_service* s1_{nullptr}; - hrd_service* s2_{nullptr}; -}; - -struct rule_service { - rule_service(std::vector rules, - std::set services) - : rules_(std::move(rules)), services_(std::move(services)) {} - std::vector rules_; - std::set services_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/rules_graph.h b/base/loader/include/motis/loader/hrd/model/rules_graph.h deleted file mode 100644 index 4a6ea563d..000000000 --- a/base/loader/include/motis/loader/hrd/model/rules_graph.h +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/bitfield.h" -#include "motis/loader/hrd/model/rule_service.h" - -namespace motis::loader::hrd { - -struct rule_node; - -struct node { - node() = default; - node(node const&) = default; - node(node&&) = default; - node& operator=(node const&) = default; - node& operator=(node&&) = default; - virtual ~node() = default; -}; - -struct service_node : public node { - explicit service_node(hrd_service*); - - std::vector rule_nodes_; - hrd_service* service_{nullptr}; -}; - -struct rule_node : public node { - rule_node(service_node*, service_node*, resolved_rule_info); - - std::pair, bitfield> max_component(); - void resolve_services(bitfield const& upper_traffic_days, - std::set& s_resolvents, - std::vector& sr_resolvents); - - service_node *s1_, *s2_; - resolved_rule_info rule_; - bitfield traffic_days_; -}; - -struct rules_graph { - std::vector> nodes_; - std::vector rule_nodes_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/service_rule.h b/base/loader/include/motis/loader/hrd/model/service_rule.h deleted file mode 100644 index ec1fb7314..000000000 --- a/base/loader/include/motis/loader/hrd/model/service_rule.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "motis/loader/bitfield.h" -#include "motis/loader/hrd/model/hrd_service.h" - -namespace motis::loader::hrd { - -struct resolved_rule_info { - bitfield traffic_days_; - int eva_num_1_{0}, eva_num_2_{0}; - uint8_t type_{0}; - bool day_switch_{false}; - unsigned s1_traffic_days_offset_{0}; - unsigned s2_traffic_days_offset_{0}; -}; - -using service_combination = - std::tuple; - -struct service_rule { - service_rule(service_rule const&) = default; - service_rule(service_rule&&) = default; - service_rule& operator=(service_rule const&) = delete; - service_rule& operator=(service_rule&&) = delete; - - explicit service_rule(bitfield const& mask) : mask_(mask) {} - virtual ~service_rule() = default; - virtual int applies(hrd_service const&) const = 0; - virtual void add(hrd_service*, int info) = 0; - virtual std::vector service_combinations() const = 0; - virtual resolved_rule_info rule_info() const = 0; - - bitfield const& mask_; -}; - -using service_id = std::pair; // (train_num, admin) -using service_rules = - std::map>>; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/specification.h b/base/loader/include/motis/loader/hrd/model/specification.h deleted file mode 100644 index bb0f2c6bf..000000000 --- a/base/loader/include/motis/loader/hrd/model/specification.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -#include "utl/parser/cstr.h" - -namespace motis::loader::hrd { - -constexpr char const* UNKNOWN_FILE = "unknown_file"; -constexpr int BEFORE_FIRST_LINE = -1; - -struct specification { - specification() - : filename_(UNKNOWN_FILE), - line_number_from_(BEFORE_FIRST_LINE), - line_number_to_(BEFORE_FIRST_LINE), - internal_service_(nullptr, 0) {} - - bool is_empty() const; - - bool valid() const; - - bool ignore() const; - - void reset(); - - bool read_line(utl::cstr line, char const* filename, int line_number); - - char const* filename_; - int line_number_from_; - int line_number_to_; - utl::cstr internal_service_; - std::vector traffic_days_; - std::vector categories_; - std::vector line_information_; - std::vector attributes_; - std::vector directions_; - std::vector stops_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/split_service.h b/base/loader/include/motis/loader/hrd/model/split_service.h deleted file mode 100644 index 10b036787..000000000 --- a/base/loader/include/motis/loader/hrd/model/split_service.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/parser/bitfields_parser.h" - -namespace motis::loader::hrd { - -void expand_traffic_days(hrd_service const&, std::map const&, - std::vector&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/model/timezones.h b/base/loader/include/motis/loader/hrd/model/timezones.h deleted file mode 100644 index c82908cd8..000000000 --- a/base/loader/include/motis/loader/hrd/model/timezones.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "boost/optional.hpp" - -#include "utl/verify.h" - -namespace motis::loader::hrd { - -struct season_entry { - season_entry() = default; - season_entry(int const gmt_offset, int const first_day_idx, - int const last_day_idx, int const season_begin_time, - int const season_end_time) - : gmt_offset_(gmt_offset), - first_day_idx_(first_day_idx), - last_day_idx_(last_day_idx), - season_begin_time_(season_begin_time), - season_end_time_(season_end_time) {} - - int gmt_offset_; // in minutes - int first_day_idx_; // bitfield index (closed) - int last_day_idx_; // bitfield index (closed) - int season_begin_time_; // minutes after midnight - int season_end_time_; // minutes after midnight -}; - -struct timezone_entry { - timezone_entry() = default; - timezone_entry(int general_gmt_offset, std::vector seasons) - : general_gmt_offset_(general_gmt_offset), seasons_(std::move(seasons)) {} - int general_gmt_offset_; // in minutes - std::vector seasons_; -}; - -struct timezones { - inline timezone_entry const* find(int eva_number) const { - utl::verify(0 <= eva_number && eva_number <= 9999999, - "invalid eva number: {}", eva_number); - - auto it = eva_to_tze_.upper_bound(eva_number); - utl::verify(it != end(eva_to_tze_) || !timezone_entries_.empty(), - "no timezone entry for eva number: {}", eva_number); - return std::next(it, -1)->second; - } - - std::map eva_to_tze_; - std::vector> timezone_entries_; -}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parse_config.h b/base/loader/include/motis/loader/hrd/parse_config.h deleted file mode 100755 index 77f92e730..000000000 --- a/base/loader/include/motis/loader/hrd/parse_config.h +++ /dev/null @@ -1,792 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "utl/parser/cstr.h" - -#ifdef HAVE_DESIGNATED_INITIALIZERS -#define INIT(f, ...) f = __VA_ARGS__ -#else -#define INIT(f, ...) __VA_ARGS__ -#endif - -namespace motis::loader::hrd { - -struct range_parse_information { - utl::field from_eva_or_idx_; - utl::field to_eva_or_idx_; - utl::field from_hhmm_or_idx_; - utl::field to_hhmm_or_idx_; -}; - -enum filename_key { - ATTRIBUTES, - STATIONS, - COORDINATES, - BITFIELDS, - TRACKS, - INFOTEXT, - BASIC_DATA, - CATEGORIES, - DIRECTIONS, - PROVIDERS, - THROUGH_SERVICES, - MERGE_SPLIT_SERVICES, - TIMEZONES, - FOOTPATHS, - FOOTPATHS_EXT, - MIN_CT_FILE -}; - -static constexpr auto const ENCODING = "ISO8859-1"; -static constexpr auto const SCHEDULE_DATA = "fahrten"; -static constexpr auto const CORE_DATA = "stamm"; - -struct config { - struct { - utl::field code_; - utl::field text_mul_spaces_; - utl::field text_normal_; - } att_; - struct { - utl::field index_; - utl::field value_; - } bf_; - struct { - utl::field code_; - utl::field output_rule_; - utl::field name_; - } cat_; - struct { - utl::field eva_; - utl::field text_; - } dir_; - struct { - unsigned line_length_; - utl::field bitfield_; - utl::field key1_nr_; - utl::field key1_admin_; - utl::field key2_nr_; - utl::field key2_admin_; - utl::field eva_begin_; - utl::field eva_end_; - } merge_spl_; - struct { - struct { - utl::field eva_; - } meta_stations_; - struct { - utl::field from_; - utl::field to_; - utl::field duration_; - } footpaths_; - } meta_; - struct { - struct { - utl::field eva_; - utl::field name_; - } names_; - struct { - utl::field eva_; - utl::field lng_; - utl::field lat_; - } coords_; - } st_; - struct { - utl::field bitfield_; - utl::field key1_nr_; - utl::field key1_admin_; - utl::field key2_nr_; - utl::field key2_admin_; - utl::field eva_; - } th_s_; - struct { - utl::field type1_eva_; - utl::field type1_first_valid_eva_; - utl::field type2_eva_; - utl::field type2_dst_to_midnight_; - utl::field type3_dst_to_midnight1_; - utl::field type3_bitfield_idx1_; - utl::field type3_bitfield_idx2_; - utl::field type3_dst_to_midnight2_; - utl::field type3_dst_to_midnight3_; - } tz_; - struct { - utl::field prov_nr_; - } track_; - struct { - unsigned min_line_length_; - utl::field eva_num_; - utl::field train_num_; - utl::field train_admin_; - utl::field track_name_; - utl::field time_; - utl::field bitfield_; - } track_rul_; - struct { - utl::field att_eva_; - utl::field att_code_; - utl::field cat_; - utl::field line_; - utl::field traff_days_; - utl::field dir_; - } s_info_; - - range_parse_information attribute_parse_info_; - range_parse_information line_parse_info_; - range_parse_information category_parse_info_; - range_parse_information traffic_days_parse_info_; - range_parse_information direction_parse_info_; - - utl::cstr version_; - std::vector> required_files_; - - std::string core_data_; - std::string fplan_; - std::string fplan_file_extension_; - - bool convert_utf8_; - - const char* files(filename_key k, int index = 0) const { - return required_files_[k][index].c_str(); - } - - bool is_available(filename_key const k) const { - return !required_files_[k].empty(); - } -}; - -const config hrd_5_00_8 = { - INIT(.att_, - { - INIT(.code_, {0, 2}), - INIT(.text_mul_spaces_, {21, utl::field::MAX_SIZE}), - INIT(.text_normal_, {12, utl::field::MAX_SIZE}), - }), - INIT(.bf_, - { - INIT(.index_, {0, 6}), - INIT(.value_, {7, utl::field::MAX_SIZE}), - }), - INIT(.cat_, - { - INIT(.code_, {0, 3}), - INIT(.output_rule_, {9, 2}), - INIT(.name_, {12, 8}), - }), - INIT(.dir_, - { - INIT(.eva_, {0, 7}), - INIT(.text_, {8, utl::field::MAX_SIZE}), - }), - INIT(.merge_spl_, - { - INIT(.line_length_, 53), - INIT(.bitfield_, {47, 6}), - INIT(.key1_nr_, {18, 5}), - INIT(.key1_admin_, {25, 6}), - INIT(.key2_nr_, {33, 5}), - INIT(.key2_admin_, {40, 6}), - INIT(.eva_begin_, {0, 7}), - INIT(.eva_end_, {9, 7}), - }), - INIT(.meta_, - { - INIT(.meta_stations_, {INIT(.eva_, {0, 7})}), - INIT(.footpaths_, - { - INIT(.from_, {0, 7}), - INIT(.to_, {8, 7}), - INIT(.duration_, {16, 3}), - }), - }), - INIT(.st_, - { - INIT(.names_, - { - INIT(.eva_, {0, 7}), - INIT(.name_, {12, utl::field::MAX_SIZE}), - }), - INIT(.coords_, - { - INIT(.eva_, {0, 7}), - INIT(.lng_, {8, 10}), - INIT(.lat_, {19, 10}), - }), - }), - INIT(.th_s_, - { - INIT(.bitfield_, {34, 6}), - INIT(.key1_nr_, {0, 5}), - INIT(.key1_admin_, {6, 6}), - INIT(.key2_nr_, {21, 5}), - INIT(.key2_admin_, {27, 6}), - INIT(.eva_, {13, 7}), - }), - INIT(.tz_, - { - INIT(.type1_eva_, {0, 7}), - INIT(.type1_first_valid_eva_, {8, 7}), - INIT(.type2_eva_, {0, 7}), - INIT(.type2_dst_to_midnight_, {8, 5}), - INIT(.type3_dst_to_midnight1_, {14, 5}), - INIT(.type3_bitfield_idx1_, {20, 8}), - INIT(.type3_bitfield_idx2_, {34, 8}), - INIT(.type3_dst_to_midnight2_, {29, 4}), - INIT(.type3_dst_to_midnight3_, {43, 4}), - }), - INIT(.track_, {INIT(.prov_nr_, {0, 5})}), - INIT(.track_rul_, - { - INIT(.min_line_length_, 22), - INIT(.eva_num_, {0, 7}), - INIT(.train_num_, {8, 5}), - INIT(.train_admin_, {14, 6}), - INIT(.track_name_, {21, 8}), - INIT(.time_, {30, 4}), - INIT(.bitfield_, {35, 6}), - }), - INIT(.s_info_, - { - INIT(.att_eva_, {22, 6}), - INIT(.att_code_, {3, 2}), - INIT(.cat_, {3, 3}), - INIT(.line_, {3, 5}), - INIT(.traff_days_, {22, 6}), - INIT(.dir_, {5, 7}), - }), - INIT(.attribute_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.line_parse_info_, - { - INIT(.from_eva_or_idx_, {9, 7}), - INIT(.to_eva_or_idx_, {17, 7}), - INIT(.from_hhmm_or_idx_, {25, 6}), - INIT(.to_hhmm_or_idx_, {32, 6}), - }), - INIT(.category_parse_info_, - { - INIT(.from_eva_or_idx_, {7, 7}), - INIT(.to_eva_or_idx_, {15, 7}), - INIT(.from_hhmm_or_idx_, {23, 6}), - INIT(.to_hhmm_or_idx_, {30, 6}), - }), - INIT(.traffic_days_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.direction_parse_info_, - { - INIT(.from_eva_or_idx_, {13, 7}), - INIT(.to_eva_or_idx_, {21, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.version_, "hrd_5_00_8"), - INIT(.required_files_, {{"attributd_int_int.101", "attributd_int.101"}, - {"bahnhof.101"}, - {"dbkoord_geo.101"}, - {"bitfield.101"}, - {"gleise.101"}, - {"infotext.101"}, - {"eckdaten.101"}, - {"zugart_int.101"}, - {"richtung.101"}, - {"unternehmen_ris.101"}, - {"durchbi.101"}, - {"vereinig_vt.101"}, - {"zeitvs.101"}, - {"metabhf.101"}, - {"metabhf_zusatz.101"}, - {"minct.csv"}}), - INIT(.core_data_, "stamm"), - INIT(.fplan_, "fahrten"), - INIT(.fplan_file_extension_, ""), - INIT(.convert_utf8_, false), -}; - -const config hrd_5_20_26 = { - INIT(.att_, - { - INIT(.code_, {0, 2}), - INIT(.text_mul_spaces_, {21, utl::field::MAX_SIZE}), - INIT(.text_normal_, {12, utl::field::MAX_SIZE}), - }), - INIT(.bf_, - { - INIT(.index_, {0, 6}), - INIT(.value_, {7, utl::field::MAX_SIZE}), - }), - INIT(.cat_, - { - INIT(.code_, {0, 3}), - INIT(.output_rule_, {9, 2}), - INIT(.name_, {12, 8}), - }), - INIT(.dir_, - { - INIT(.eva_, {0, 7}), - INIT(.text_, {8, utl::field::MAX_SIZE}), - }), - INIT(.merge_spl_, - { - INIT(.line_length_, 50), - INIT(.bitfield_, {44, 6}), - INIT(.key1_nr_, {16, 6}), - INIT(.key1_admin_, {23, 6}), - INIT(.key2_nr_, {30, 6}), - INIT(.key2_admin_, {37, 6}), - INIT(.eva_begin_, {0, 7}), - INIT(.eva_end_, {8, 7}), - }), - INIT(.meta_, - { - INIT(.meta_stations_, {INIT(.eva_, {0, 7})}), - INIT(.footpaths_, - { - INIT(.from_, {0, 7}), - INIT(.to_, {8, 7}), - INIT(.duration_, {16, 3}), - }), - }), - INIT(.st_, - { - INIT(.names_, - { - INIT(.eva_, {0, 7}), - INIT(.name_, {12, utl::field::MAX_SIZE}), - }), - INIT(.coords_, - { - INIT(.eva_, {0, 7}), - INIT(.lng_, {8, 10}), - INIT(.lat_, {19, 10}), - }), - }), - INIT(.th_s_, - { - INIT(.bitfield_, {34, 6}), - INIT(.key1_nr_, {0, 5}), - INIT(.key1_admin_, {6, 6}), - INIT(.key2_nr_, {21, 5}), - INIT(.key2_admin_, {27, 6}), - INIT(.eva_, {13, 7}), - }), - INIT(.tz_, - { - INIT(.type1_eva_, {0, 7}), - INIT(.type1_first_valid_eva_, {8, 7}), - INIT(.type2_eva_, {0, 7}), - INIT(.type2_dst_to_midnight_, {8, 5}), - INIT(.type3_dst_to_midnight1_, {14, 5}), - INIT(.type3_bitfield_idx1_, {20, 8}), - INIT(.type3_bitfield_idx2_, {34, 8}), - INIT(.type3_dst_to_midnight2_, {29, 4}), - INIT(.type3_dst_to_midnight3_, {43, 4}), - }), - INIT(.track_, {INIT(.prov_nr_, {0, 5})}), - INIT(.track_rul_, - { - INIT(.min_line_length_, 22), - INIT(.eva_num_, {0, 7}), - INIT(.train_num_, {8, 5}), - INIT(.train_admin_, {14, 6}), - INIT(.track_name_, {21, 8}), - INIT(.time_, {30, 4}), - INIT(.bitfield_, {35, 6}), - }), - INIT(.s_info_, - { - INIT(.att_eva_, {22, 6}), - INIT(.att_code_, {3, 2}), - INIT(.cat_, {3, 3}), - INIT(.line_, {3, 8}), - INIT(.traff_days_, {22, 6}), - INIT(.dir_, {5, 7}), - }), - INIT(.attribute_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.line_parse_info_, - { - INIT(.from_eva_or_idx_, {12, 7}), - INIT(.to_eva_or_idx_, {20, 7}), - INIT(.from_hhmm_or_idx_, {28, 6}), - INIT(.to_hhmm_or_idx_, {35, 6}), - }), - INIT(.category_parse_info_, - { - INIT(.from_eva_or_idx_, {7, 7}), - INIT(.to_eva_or_idx_, {15, 7}), - INIT(.from_hhmm_or_idx_, {23, 6}), - INIT(.to_hhmm_or_idx_, {30, 6}), - }), - INIT(.traffic_days_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.direction_parse_info_, - { - INIT(.from_eva_or_idx_, {13, 7}), - INIT(.to_eva_or_idx_, {21, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.version_, "hrd_5_20_26"), - INIT(.required_files_, {{"attributd.txt"}, - {"bahnhof.txt"}, - {"bfkoord.txt"}, - {"bitfield.txt"}, - {"gleise.txt"}, - {"infotext.txt"}, - {"eckdaten.txt"}, - {"zugart.txt"}, - {"richtung.txt"}, - {"unternehmen_ris.txt"}, - {"durchbi.txt"}, - {"vereinig_vt.txt"}, - {"zeitvs.txt"}, - {"metabhf.txt"}, - {}, - {"minct.csv"}}), - INIT(.core_data_, "stamm"), - INIT(.fplan_, "fahrten"), - INIT(.fplan_file_extension_, ""), - INIT(.convert_utf8_, false), -}; - -const config hrd_5_20_39 = { - INIT(.att_, - { - INIT(.code_, {0, 2}), - INIT(.text_mul_spaces_, {21, utl::field::MAX_SIZE}), - INIT(.text_normal_, {12, utl::field::MAX_SIZE}), - }), - INIT(.bf_, - { - INIT(.index_, {0, 6}), - INIT(.value_, {7, utl::field::MAX_SIZE}), - }), - INIT(.cat_, - { - INIT(.code_, {0, 3}), - INIT(.output_rule_, {9, 1}), - INIT(.name_, {11, 8}), - }), - INIT(.dir_, - { - INIT(.eva_, {0, 7}), - INIT(.text_, {8, utl::field::MAX_SIZE}), - }), - INIT(.merge_spl_, - { - INIT(.line_length_, 50), - INIT(.bitfield_, {44, 6}), - INIT(.key1_nr_, {16, 6}), - INIT(.key1_admin_, {23, 6}), - INIT(.key2_nr_, {30, 6}), - INIT(.key2_admin_, {37, 6}), - INIT(.eva_begin_, {0, 7}), - INIT(.eva_end_, {8, 7}), - }), - INIT(.meta_, - { - INIT(.meta_stations_, {INIT(.eva_, {0, 7})}), - INIT(.footpaths_, - { - INIT(.from_, {0, 7}), - INIT(.to_, {8, 7}), - INIT(.duration_, {16, 3}), - }), - }), - INIT(.st_, - { - INIT(.names_, - { - INIT(.eva_, {0, 7}), - INIT(.name_, {12, utl::field::MAX_SIZE}), - }), - INIT(.coords_, - { - INIT(.eva_, {0, 7}), - INIT(.lng_, {8, 10}), - INIT(.lat_, {19, 10}), - }), - }), - INIT(.th_s_, - { - INIT(.bitfield_, {34, 6}), - INIT(.key1_nr_, {0, 5}), - INIT(.key1_admin_, {6, 6}), - INIT(.key2_nr_, {21, 5}), - INIT(.key2_admin_, {27, 6}), - INIT(.eva_, {13, 7}), - }), - INIT(.tz_, - { - INIT(.type1_eva_, {0, 7}), - INIT(.type1_first_valid_eva_, {8, 7}), - INIT(.type2_eva_, {0, 7}), - INIT(.type2_dst_to_midnight_, {8, 5}), - INIT(.type3_dst_to_midnight1_, {14, 5}), - INIT(.type3_bitfield_idx1_, {20, 8}), - INIT(.type3_bitfield_idx2_, {34, 8}), - INIT(.type3_dst_to_midnight2_, {29, 4}), - INIT(.type3_dst_to_midnight3_, {43, 4}), - }), - INIT(.track_, {INIT(.prov_nr_, {0, 5})}), - INIT(.track_rul_, - { - INIT(.min_line_length_, 34), - INIT(.eva_num_, {0, 7}), - INIT(.train_num_, {8, 5}), - INIT(.train_admin_, {14, 6}), - INIT(.track_name_, {21, 8}), - INIT(.time_, {30, 4}), - INIT(.bitfield_, {35, 6}), - }), - INIT(.s_info_, - { - INIT(.att_eva_, {22, 6}), - INIT(.att_code_, {3, 2}), - INIT(.cat_, {3, 3}), - INIT(.line_, {3, 8}), - INIT(.traff_days_, {22, 6}), - INIT(.dir_, {5, 7}), - }), - INIT(.attribute_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.line_parse_info_, - { - INIT(.from_eva_or_idx_, {12, 7}), - INIT(.to_eva_or_idx_, {20, 7}), - INIT(.from_hhmm_or_idx_, {28, 6}), - INIT(.to_hhmm_or_idx_, {35, 6}), - }), - INIT(.category_parse_info_, - { - INIT(.from_eva_or_idx_, {7, 7}), - INIT(.to_eva_or_idx_, {15, 7}), - INIT(.from_hhmm_or_idx_, {23, 6}), - INIT(.to_hhmm_or_idx_, {30, 6}), - }), - INIT(.traffic_days_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.direction_parse_info_, - { - INIT(.from_eva_or_idx_, {13, 7}), - INIT(.to_eva_or_idx_, {21, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.version_, "hrd_5_20_39"), - INIT(.required_files_, {{"ATTRIBUT_DE"}, - {"BAHNHOF"}, - {"BFKOORD_GEO", "BFKOORD_WGS"}, - {"BITFELD"}, - {"GLEIS"}, - {"INFOTEXT_DE"}, - {"ECKDATEN"}, - {"ZUGART"}, - {"RICHTUNG"}, - {"BETRIEB_DE"}, - {"DURCHBI"}, - {/* vereinig */}, - {"ZEITVS"}, - {"METABHF"}, - {/* meta bhf zusatz */}, - {/* min ct csv */}}), - INIT(.core_data_, "."), - INIT(.fplan_, "FPLAN"), - INIT(.fplan_file_extension_, ""), - INIT(.convert_utf8_, true), -}; - -const config hrd_5_20_avv = { - INIT(.att_, - { - INIT(.code_, {0, 2}), - INIT(.text_mul_spaces_, {21, utl::field::MAX_SIZE}), - INIT(.text_normal_, {12, utl::field::MAX_SIZE}), - }), - INIT(.bf_, - { - INIT(.index_, {0, 6}), - INIT(.value_, {7, utl::field::MAX_SIZE}), - }), - INIT(.cat_, - { - INIT(.code_, {0, 3}), - INIT(.output_rule_, {9, 1}), - INIT(.name_, {11, 8}), - }), - INIT(.dir_, - { - INIT(.eva_, {0, 7}), - INIT(.text_, {8, utl::field::MAX_SIZE}), - }), - INIT(.merge_spl_, - { - INIT(.line_length_, 50), - INIT(.bitfield_, {std::numeric_limits::max(), 0U}), - INIT(.key1_nr_, {16, 5}), - INIT(.key1_admin_, {22, 6}), - INIT(.key2_nr_, {29, 5}), - INIT(.key2_admin_, {35, 6}), - INIT(.eva_begin_, {0, 7}), - INIT(.eva_end_, {8, 7}), - }), - INIT(.meta_, - { - INIT(.meta_stations_, {INIT(.eva_, {0, 7})}), - INIT(.footpaths_, - { - INIT(.from_, {0, 7}), - INIT(.to_, {8, 7}), - INIT(.duration_, {16, 3}), - }), - }), - INIT(.st_, - { - INIT(.names_, - { - INIT(.eva_, {0, 7}), - INIT(.name_, {12, utl::field::MAX_SIZE}), - }), - INIT(.coords_, - { - INIT(.eva_, {0, 7}), - INIT(.lng_, {8, 10}), - INIT(.lat_, {19, 10}), - }), - }), - INIT(.th_s_, - { - INIT(.bitfield_, {34, 6}), - INIT(.key1_nr_, {0, 5}), - INIT(.key1_admin_, {6, 6}), - INIT(.key2_nr_, {21, 5}), - INIT(.key2_admin_, {27, 6}), - INIT(.eva_, {13, 7}), - }), - INIT(.tz_, - { - INIT(.type1_eva_, {0, 7}), - INIT(.type1_first_valid_eva_, {8, 7}), - INIT(.type2_eva_, {0, 7}), - INIT(.type2_dst_to_midnight_, {8, 5}), - INIT(.type3_dst_to_midnight1_, {14, 5}), - INIT(.type3_bitfield_idx1_, {20, 8}), - INIT(.type3_bitfield_idx2_, {34, 8}), - INIT(.type3_dst_to_midnight2_, {29, 4}), - INIT(.type3_dst_to_midnight3_, {43, 4}), - }), - INIT(.track_, {INIT(.prov_nr_, {0, 5})}), - INIT(.track_rul_, - { - INIT(.min_line_length_, 22), - INIT(.eva_num_, {0, 7}), - INIT(.train_num_, {8, 5}), - INIT(.train_admin_, {14, 6}), - INIT(.track_name_, {21, 8}), - INIT(.time_, {30, 4}), - INIT(.bitfield_, {35, 6}), - }), - INIT(.s_info_, - { - INIT(.att_eva_, {22, 6}), - INIT(.att_code_, {3, 2}), - INIT(.cat_, {3, 3}), - INIT(.line_, {3, 8}), - INIT(.traff_days_, {22, 6}), - INIT(.dir_, {5, 7}), - }), - INIT(.attribute_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.line_parse_info_, - { - INIT(.from_eva_or_idx_, {12, 7}), - INIT(.to_eva_or_idx_, {20, 7}), - INIT(.from_hhmm_or_idx_, {28, 6}), - INIT(.to_hhmm_or_idx_, {35, 6}), - }), - INIT(.category_parse_info_, - { - INIT(.from_eva_or_idx_, {7, 7}), - INIT(.to_eva_or_idx_, {15, 7}), - INIT(.from_hhmm_or_idx_, {23, 6}), - INIT(.to_hhmm_or_idx_, {30, 6}), - }), - INIT(.traffic_days_parse_info_, - { - INIT(.from_eva_or_idx_, {6, 7}), - INIT(.to_eva_or_idx_, {14, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.direction_parse_info_, - { - INIT(.from_eva_or_idx_, {13, 7}), - INIT(.to_eva_or_idx_, {21, 7}), - INIT(.from_hhmm_or_idx_, {29, 6}), - INIT(.to_hhmm_or_idx_, {36, 6}), - }), - INIT(.version_, "hrd_5_20_avv"), - INIT(.required_files_, {{"attribut_de"}, - {"bahnhof"}, - {"bfkoord"}, - {"bitfeld"}, - {"gleise"}, - {"infotext"}, - {"eckdaten"}, - {"zugart"}, - {"richtung"}, - {"betrieb"}, - {"durchbi"}, - {"vereinig"}, - {"zeitvs"}, - {"metabf"}, - {/* meta bhf zusatz */}, - {/* min ct csv */}}), - INIT(.core_data_, "."), - INIT(.fplan_, "."), - INIT(.fplan_file_extension_, ".LIN"), - INIT(.convert_utf8_, false), -}; - -const std::vector configs = {hrd_5_00_8, hrd_5_20_26, hrd_5_20_39, - hrd_5_20_avv}; - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/attributes_parser.h b/base/loader/include/motis/loader/hrd/parser/attributes_parser.h deleted file mode 100644 index 90808942d..000000000 --- a/base/loader/include/motis/loader/hrd/parser/attributes_parser.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -std::map parse_attributes(loaded_file const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/basic_info_parser.h b/base/loader/include/motis/loader/hrd/parser/basic_info_parser.h deleted file mode 100644 index a5f0eedc9..000000000 --- a/base/loader/include/motis/loader/hrd/parser/basic_info_parser.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "boost/date_time/gregorian/gregorian_types.hpp" - -#include "motis/schedule-format/Interval_generated.h" - -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -Interval parse_interval(loaded_file const&); - -boost::gregorian::date get_first_schedule_date(loaded_file const& lf); - -std::string parse_schedule_name(loaded_file const& basic_info_file); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/bitfields_parser.h b/base/loader/include/motis/loader/hrd/parser/bitfields_parser.h deleted file mode 100644 index 1d5fdd897..000000000 --- a/base/loader/include/motis/loader/hrd/parser/bitfields_parser.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -#include "utl/parser/cstr.h" - -#include "motis/loader/bitfield.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -constexpr int ALL_DAYS_KEY = 0; - -bitfield hex_str_to_bitset(utl::cstr hex, char const* filename, - int line_number); - -std::map parse_bitfields(loaded_file const&, config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/categories_parser.h b/base/loader/include/motis/loader/hrd/parser/categories_parser.h deleted file mode 100644 index cbcee7ba0..000000000 --- a/base/loader/include/motis/loader/hrd/parser/categories_parser.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" -#include "motis/schedule-format/Category_generated.h" - -namespace motis::loader::hrd { - -struct category { - category() = default; - category(std::string name, uint8_t output_rule) - : name_(std::move(name)), output_rule_(output_rule) {} - - std::string name_; - uint8_t output_rule_{0}; -}; - -std::map parse_categories(loaded_file const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/directions_parser.h b/base/loader/include/motis/loader/hrd/parser/directions_parser.h deleted file mode 100644 index 9373af88b..000000000 --- a/base/loader/include/motis/loader/hrd/parser/directions_parser.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -using namespace utl; - -std::map parse_directions(loaded_file const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/merge_split_rules_parser.h b/base/loader/include/motis/loader/hrd/parser/merge_split_rules_parser.h deleted file mode 100644 index 0ea7705d0..000000000 --- a/base/loader/include/motis/loader/hrd/parser/merge_split_rules_parser.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/bitfield.h" -#include "motis/loader/hrd/model/service_rule.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -void parse_merge_split_service_rules(loaded_file const&, - std::map const&, - service_rules&, config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/providers_parser.h b/base/loader/include/motis/loader/hrd/parser/providers_parser.h deleted file mode 100644 index 82b915c5d..000000000 --- a/base/loader/include/motis/loader/hrd/parser/providers_parser.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -struct provider_info { - std::string short_name_; - std::string long_name_; - std::string full_name_; -}; - -std::map parse_providers(loaded_file const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/service_parser.h b/base/loader/include/motis/loader/hrd/parser/service_parser.h deleted file mode 100644 index 799ea8aec..000000000 --- a/base/loader/include/motis/loader/hrd/parser/service_parser.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/model/specification.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -void parse_specification( - loaded_file const&, std::function, - std::function bytes_consumed = [](std::size_t) {}); - -void for_each_service(loaded_file const&, std::map const&, - std::function, - std::function bytes_consumed, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/station_meta_data_parser.h b/base/loader/include/motis/loader/hrd/parser/station_meta_data_parser.h deleted file mode 100644 index 0888412a0..000000000 --- a/base/loader/include/motis/loader/hrd/parser/station_meta_data_parser.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -struct station_meta_data { - struct footpath { - bool operator<(footpath const& rh) const { - return std::tie(from_eva_num_, to_eva_num_) < - std::tie(rh.from_eva_num_, rh.to_eva_num_); - } - int from_eva_num_; - int to_eva_num_; - int duration_; - bool f_equal_; - }; - - struct meta_station { - bool operator<(meta_station const& rh) const { return eva_ < rh.eva_; } - int eva_; - std::vector equivalent_; - }; - - std::pair get_station_change_time(int eva_num) const; - - std::map> station_change_times_; - std::set footpaths_; - std::set meta_stations_; - std::map ds100_to_eva_num_; - std::map>> - platforms_; -}; - -void parse_station_meta_data(loaded_file const& infotext_file, - loaded_file const& metabhf_file, - loaded_file const& metabhf_zusatz_file, - loaded_file const& minct_file, - loaded_file const& platform_file, - station_meta_data&, config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/stations_parser.h b/base/loader/include/motis/loader/hrd/parser/stations_parser.h deleted file mode 100644 index f1bd40a3c..000000000 --- a/base/loader/include/motis/loader/hrd/parser/stations_parser.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/hrd/parser/station_meta_data_parser.h" -#include "motis/loader/loaded_file.h" -#include "motis/schedule-format/Station_generated.h" - -namespace motis::loader::hrd { - -struct intermediate_station { - std::string name_; - int change_time_{0}; - int platform_change_time_{0}; - double lng_{0.0}, lat_{0.0}; - std::vector ds100_; - std::map> platforms_; -}; - -std::map parse_stations( - loaded_file const& station_names_file, - loaded_file const& station_coordinates_file, station_meta_data const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/through_services_parser.h b/base/loader/include/motis/loader/hrd/parser/through_services_parser.h deleted file mode 100644 index 9879ee085..000000000 --- a/base/loader/include/motis/loader/hrd/parser/through_services_parser.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include -#include - -#include "motis/loader/hrd/model/service_rule.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -void parse_through_service_rules(loaded_file const&, - std::map const&, service_rules&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/timezones_parser.h b/base/loader/include/motis/loader/hrd/parser/timezones_parser.h deleted file mode 100644 index fe70e0979..000000000 --- a/base/loader/include/motis/loader/hrd/parser/timezones_parser.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "motis/loader/hrd/model/timezones.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -timezones parse_timezones(loaded_file const&, loaded_file const&, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/hrd/parser/track_rules_parser.h b/base/loader/include/motis/loader/hrd/parser/track_rules_parser.h deleted file mode 100644 index e62281f3a..000000000 --- a/base/loader/include/motis/loader/hrd/parser/track_rules_parser.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "flatbuffers/flatbuffers.h" - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/loaded_file.h" - -namespace motis::loader::hrd { - -constexpr int TIME_NOT_SET = -1; -struct track_rule { - flatbuffers64::Offset track_name_; - int bitfield_num_{0}; - int time_{0}; -}; - -using track_rule_key = std::tuple; -using track_rules = std::map>; - -track_rules parse_track_rules(loaded_file const&, - flatbuffers64::FlatBufferBuilder& b, - config const&); - -} // namespace motis::loader::hrd diff --git a/base/loader/include/motis/loader/interval_util.h b/base/loader/include/motis/loader/interval_util.h deleted file mode 100644 index 1174bb940..000000000 --- a/base/loader/include/motis/loader/interval_util.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -namespace motis { - -struct schedule; - -namespace loader { - -struct Interval; // NOLINT - -std::pair first_last_days(schedule const& sched, - std::size_t src_index, Interval const*); - -} // namespace loader -} // namespace motis diff --git a/base/loader/include/motis/loader/loaded_file.h b/base/loader/include/motis/loader/loaded_file.h deleted file mode 100644 index ee424ad81..000000000 --- a/base/loader/include/motis/loader/loaded_file.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include - -#include "utl/parser/buffer.h" -#include "utl/parser/cstr.h" - -namespace motis::loader { - -struct loaded_file { - loaded_file(); - - loaded_file(char const* filename, char const* str, bool convert_utf8 = false); - - loaded_file(char const* filename, std::string&& buf, - bool convert_utf8 = false); - - explicit loaded_file(std::filesystem::path const& p, - bool convert_utf8 = false); - - loaded_file(loaded_file const&) = delete; - - loaded_file(loaded_file&& o) noexcept; - - ~loaded_file(); - - loaded_file& operator=(loaded_file const&) = delete; - - loaded_file& operator=(loaded_file&& o) noexcept; - - char const* name() const; - - utl::cstr content() const; - - bool empty() const; - -private: - bool contains_utf8_bom() const; - - std::string name_; - std::string buf_; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/loader.h b/base/loader/include/motis/loader/loader.h deleted file mode 100644 index 830d71dd8..000000000 --- a/base/loader/include/motis/loader/loader.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include "cista/memory_holder.h" - -#include "motis/core/schedule/schedule.h" - -#include "motis/loader/loader_options.h" -#include "motis/loader/parser.h" - -namespace motis::loader { - -std::vector> parsers(); - -schedule_ptr load_schedule(loader_options const&, - cista::memory_holder& schedule_buf, - std::string const& data_dir); - -schedule_ptr load_schedule(loader_options const&); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/loader_options.h b/base/loader/include/motis/loader/loader_options.h deleted file mode 100644 index 231e7be3d..000000000 --- a/base/loader/include/motis/loader/loader_options.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "motis/core/schedule/time.h" - -namespace motis::loader { - -struct loader_options { - std::pair interval() const; - std::string graph_path(std::string const& data_dir) const; - std::string fbs_schedule_path(std::string const& data_dir, size_t id) const; - - std::vector dataset_{}; - std::vector dataset_prefix_{}; - std::string schedule_begin_{"TODAY"}; - int num_days_{2}; - bool no_schedule_{false}; - bool write_serialized_{false}; - bool write_graph_{false}; - bool read_graph_{false}; - bool read_graph_mmap_{false}; - bool cache_graph_{false}; - bool apply_rules_{true}; - bool adjust_footpaths_{false}; - bool expand_footpaths_{true}; - bool use_platforms_{false}; - bool no_local_transport_{false}; - bool debug_broken_trips_{false}; - duration planned_transfer_delta_{30}; - std::string graph_path_{"default"}; - std::string wzr_classes_path_{}; - std::string wzr_matrix_path_{}; - unsigned link_stop_distance_{100U}; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/parser.h b/base/loader/include/motis/loader/parser.h deleted file mode 100644 index 720eca56d..000000000 --- a/base/loader/include/motis/loader/parser.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "flatbuffers/flatbuffers.h" - -namespace flatbuffers64 { -class FlatBufferBuilder; // NOLINT(readability-identifier-naming) -} // namespace flatbuffers64 - -namespace motis::loader { - -struct parser_options { - // Set to zero to not create additional connections - // based on proximity of stops at all. - unsigned link_stop_distance_{100}; -}; - -struct format_parser { - format_parser() = default; - format_parser(format_parser const&) = default; - format_parser(format_parser&&) = default; - format_parser& operator=(format_parser const&) = default; - format_parser& operator=(format_parser&&) = default; - - virtual ~format_parser() = default; - virtual bool applicable(std::filesystem::path const&) = 0; - virtual std::vector missing_files( - std::filesystem::path const&) const = 0; - virtual void parse(parser_options const&, std::filesystem::path const&, - flatbuffers64::FlatBufferBuilder&) = 0; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/parser_error.h b/base/loader/include/motis/loader/parser_error.h deleted file mode 100644 index 784a5bad0..000000000 --- a/base/loader/include/motis/loader/parser_error.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -namespace motis::loader { - -struct parser_error : public std::exception { - parser_error(char const* filename, int line_number) - : filename_copy_(filename), - filename_(filename_copy_.c_str()), - line_number_(line_number) {} - - char const* what() const noexcept override { return "parser_error"; } - - void print_what() const noexcept { - printf("%s:%s:%d\n", what(), filename_, line_number_); - } - - std::string filename_copy_; - char const* filename_; - int line_number_; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/rule_route_builder.h b/base/loader/include/motis/loader/rule_route_builder.h deleted file mode 100644 index 69823aad4..000000000 --- a/base/loader/include/motis/loader/rule_route_builder.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -#include "motis/loader/rule_service_graph_builder.h" - -#include "motis/schedule-format/Schedule_generated.h" - -namespace motis::loader { - -void build_rule_routes( - graph_builder& gb, - flatbuffers64::Vector> const* - rule_services); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/rule_service_graph_builder.h b/base/loader/include/motis/loader/rule_service_graph_builder.h deleted file mode 100644 index 30b7d9ace..000000000 --- a/base/loader/include/motis/loader/rule_service_graph_builder.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include - -#include "motis/vector.h" - -#include "motis/loader/graph_builder.h" - -namespace motis::loader { - -struct rule_route { - std::map traffic_days_; - std::vector rules_; - unsigned first_day_{}, last_day_{}; -}; - -struct rule_service_graph_builder { - explicit rule_service_graph_builder(graph_builder&); - - void add_rule_services(mcd::vector const& rule_services); - - graph_builder& gb_; -}; - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/timezone_util.h b/base/loader/include/motis/loader/timezone_util.h deleted file mode 100644 index 41eb21a17..000000000 --- a/base/loader/include/motis/loader/timezone_util.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "cista/reflection/comparable.h" - -#include "date/tz.h" - -#include "motis/core/schedule/timezone.h" -#include "motis/hash_map.h" - -#include "motis/schedule-format/Timezone_generated.h" - -namespace motis::loader { - -constexpr auto kAdjust = 60; - -using timezone_name_idx = uint8_t; - -struct tz_cache_key { - CISTA_COMPARABLE() - timezone_name_idx tz_{0U}; - uint8_t day_idx_{0U}; - time minutes_after_midnight_{0U}; -}; - -struct tz_cache { - timezone_name_idx lookup_name(std::string_view timezone_name); - std::string prev_name_; - timezone_name_idx prev_name_idx_{0U}; - mcd::hash_map timezone_name_idx_; - mcd::hash_map cache_; -}; - -timezone create_timezone(int general_offset, int day_idx_schedule_first_day, - int day_idx_schedule_last_day, - std::vector const&); - -time get_event_time(tz_cache&, std::time_t schedule_begin, int day_idx, - int local_time, timezone const* tz, - char const* stop_tz = nullptr, - char const* provider_tz = nullptr); - -time get_adjusted_event_time(tz_cache&, std::time_t schedule_begin, int day_idx, - int local_time, timezone const* tz, - char const* stop_tz = nullptr, - char const* provider_tz = nullptr); - -std::tuple> get_event_times( - tz_cache&, std::time_t schedule_begin, int day_idx, // - motis::time prev_arr_motis_time, int curr_dep_local_time, - int curr_arr_local_time, timezone const* tz_dep, char const* dep_stop_tz, - char const* dep_provider_tz, timezone const* tz_arr, - char const* arr_stop_tz, char const* arr_provider_tz, bool& adjusted); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/util.h b/base/loader/include/motis/loader/util.h deleted file mode 100644 index fd93e6832..000000000 --- a/base/loader/include/motis/loader/util.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "flatbuffers/flatbuffers.h" - -#include "date/date.h" - -#include "utl/to_vec.h" - -#include "utl/parser/buffer.h" -#include "utl/parser/cstr.h" -#include "utl/parser/file.h" - -namespace motis::loader { - -std::string pad_to_7_digits(int eva_num); - -void write_schedule(flatbuffers64::FlatBufferBuilder& b, - std::filesystem::path const& path); - -template -inline flatbuffers64::Offset to_fbs_string( - flatbuffers64::FlatBufferBuilder& b, T const& s) { - return b.CreateString(s.c_str(), s.length()); -} - -template -flatbuffers64::Offset to_fbs_string( - flatbuffers64::FlatBufferBuilder& b, T const& s, - std::string const& /* charset -> currently only supported: ISO-8859-1 */) { - std::vector utf8(s.length() * 2, '\0'); - auto number_of_input_bytes = s.length(); - auto in = reinterpret_cast(s.c_str()); - auto out_begin = &utf8[0]; - auto out = out_begin; - for (std::size_t i = 0; i < number_of_input_bytes; ++i) { - if (*in < 128) { - *out++ = *in++; - } else { - *out++ = 0xc2 + (*in > 0xbfU); - *out++ = (*in++ & 0x3fU) + 0x80U; - } - } - return to_fbs_string(b, utl::cstr(reinterpret_cast(out_begin), - std::distance(out_begin, out))); -} - -template -inline std::vector values( - MapType const& m) { - return utl::to_vec(m, [](auto&& el) { return el.second; }); -} - -template -inline IntType raw_to_int(utl::cstr s) { - IntType key = 0; - std::memcpy(&key, s.str, std::min(s.len, sizeof(IntType))); - return key; -} - -template -inline It find_nth(It begin, It end, std::size_t n, Predicate fun) { - assert(n != 0); - std::size_t num_elements_found = 0; - auto it = begin; - while (it != end && num_elements_found != n) { - it = std::find_if(it, end, fun); - ++num_elements_found; - if (it != end && num_elements_found != n) { - ++it; - } - } - return it; -} - -template -inline TargetCollection transform(It s, It e, UnaryOperation op) { - TargetCollection c; - std::transform(s, e, std::back_insert_iterator(c), op); - return c; -} - -template -inline std::vector repeat_n(T const& el, std::size_t n) { - std::vector els(n); - std::fill(begin(els), end(els), el); - return els; -} - -inline date::year yyyymmdd_year(int yyyymmdd) { - return date::year{yyyymmdd / 10000}; -} -inline date::month yyyymmdd_month(int yyyymmdd) { - return date::month{static_cast((yyyymmdd % 10000) / 100)}; -} -inline date::day yyyymmdd_day(int yyyymmdd) { - return date::day{static_cast(yyyymmdd % 100)}; -} - -size_t collect_files(std::filesystem::path const& root, - std::string const& file_extension, - std::vector& files); - -} // namespace motis::loader diff --git a/base/loader/include/motis/loader/wzr_loader.h b/base/loader/include/motis/loader/wzr_loader.h deleted file mode 100644 index a6fb6ca6c..000000000 --- a/base/loader/include/motis/loader/wzr_loader.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "motis/memory.h" -#include "motis/vector.h" - -#include "motis/core/schedule/category.h" -#include "motis/core/schedule/waiting_time_rules.h" - -#include "motis/core/schedule/schedule.h" - -namespace motis::loader { - -waiting_time_rules load_waiting_time_rules( - std::string const& wzr_classes_path, std::string const& wzr_matrix_path, - mcd::vector> const& category_ptrs); - -void calc_waits_for(schedule& sched, duration planned_transfer_delta); - -} // namespace motis::loader diff --git a/base/loader/schedule-format/Attribute.fbs b/base/loader/schedule-format/Attribute.fbs deleted file mode 100644 index 5cc880db6..000000000 --- a/base/loader/schedule-format/Attribute.fbs +++ /dev/null @@ -1,11 +0,0 @@ -namespace motis.loader; - -table AttributeInfo { - code : string; - text : string; -} - -table Attribute { - info: AttributeInfo; - traffic_days : string; -} diff --git a/base/loader/schedule-format/Category.fbs b/base/loader/schedule-format/Category.fbs deleted file mode 100644 index b81012b1a..000000000 --- a/base/loader/schedule-format/Category.fbs +++ /dev/null @@ -1,6 +0,0 @@ -namespace motis.loader; - -table Category { - name: string; - output_rule: ubyte; -} diff --git a/base/loader/schedule-format/Direction.fbs b/base/loader/schedule-format/Direction.fbs deleted file mode 100644 index 49bea4bf1..000000000 --- a/base/loader/schedule-format/Direction.fbs +++ /dev/null @@ -1,8 +0,0 @@ -include "Station.fbs"; - -namespace motis.loader; - -table Direction { - station: Station; - text: string; -} diff --git a/base/loader/schedule-format/Footpath.fbs b/base/loader/schedule-format/Footpath.fbs deleted file mode 100644 index e74544746..000000000 --- a/base/loader/schedule-format/Footpath.fbs +++ /dev/null @@ -1,9 +0,0 @@ -include "Station.fbs"; - -namespace motis.loader; - -table Footpath { - from : Station; - to : Station; - duration : uint; -} diff --git a/base/loader/schedule-format/Interval.fbs b/base/loader/schedule-format/Interval.fbs deleted file mode 100644 index cdf63cff5..000000000 --- a/base/loader/schedule-format/Interval.fbs +++ /dev/null @@ -1,6 +0,0 @@ -namespace motis.loader; - -struct Interval { - from: long; - to: long; -} diff --git a/base/loader/schedule-format/MetaStation.fbs b/base/loader/schedule-format/MetaStation.fbs deleted file mode 100644 index 25f0c0bc2..000000000 --- a/base/loader/schedule-format/MetaStation.fbs +++ /dev/null @@ -1,8 +0,0 @@ -include "Station.fbs"; - -namespace motis.loader; - -table MetaStation { - station: Station; - equivalent: [Station]; -} diff --git a/base/loader/schedule-format/Platform.fbs b/base/loader/schedule-format/Platform.fbs deleted file mode 100644 index 0a9e72279..000000000 --- a/base/loader/schedule-format/Platform.fbs +++ /dev/null @@ -1,6 +0,0 @@ -namespace motis.loader; - -table Platform { - name: string; - tracks: [string]; -} diff --git a/base/loader/schedule-format/Provider.fbs b/base/loader/schedule-format/Provider.fbs deleted file mode 100644 index 1203e8cd4..000000000 --- a/base/loader/schedule-format/Provider.fbs +++ /dev/null @@ -1,8 +0,0 @@ -namespace motis.loader; - -table Provider { - short_name: string; - long_name: string; - full_name: string; - timezone_name: string; -} diff --git a/base/loader/schedule-format/Route.fbs b/base/loader/schedule-format/Route.fbs deleted file mode 100644 index db8e9b767..000000000 --- a/base/loader/schedule-format/Route.fbs +++ /dev/null @@ -1,9 +0,0 @@ -include "Station.fbs"; - -namespace motis.loader; - -table Route { - stations: [Station]; - in_allowed: [bool]; - out_allowed: [bool]; -} diff --git a/base/loader/schedule-format/RuleService.fbs b/base/loader/schedule-format/RuleService.fbs deleted file mode 100644 index b45923cf3..000000000 --- a/base/loader/schedule-format/RuleService.fbs +++ /dev/null @@ -1,23 +0,0 @@ -include "Service.fbs"; -include "Station.fbs"; - -namespace motis.loader; - -enum RuleType : byte { - THROUGH, MERGE_SPLIT -} - -table Rule { - type: RuleType; - service1: Service; - service2: Service; - from: Station; - to: Station; - day_offset1: uint; - day_offset2: uint; - day_switch: bool; -} - -table RuleService { - rules: [Rule]; -} diff --git a/base/loader/schedule-format/Schedule.fbs b/base/loader/schedule-format/Schedule.fbs deleted file mode 100644 index ec558eb96..000000000 --- a/base/loader/schedule-format/Schedule.fbs +++ /dev/null @@ -1,25 +0,0 @@ -include "Service.fbs"; -include "Station.fbs"; -include "Route.fbs"; -include "Track.fbs"; -include "Attribute.fbs"; -include "Interval.fbs"; -include "Footpath.fbs"; -include "RuleService.fbs"; -include "MetaStation.fbs"; - -namespace motis.loader; - -table Schedule { - services : [Service]; - stations: [Station]; - routes: [Route]; - interval: Interval; - footpaths: [Footpath]; - rule_services: [RuleService]; - meta_stations: [MetaStation]; - name: string; - hash: ulong; -} - -root_type Schedule; diff --git a/base/loader/schedule-format/Section.fbs b/base/loader/schedule-format/Section.fbs deleted file mode 100644 index 634630a2e..000000000 --- a/base/loader/schedule-format/Section.fbs +++ /dev/null @@ -1,15 +0,0 @@ -include "Attribute.fbs"; -include "Provider.fbs"; -include "Category.fbs"; -include "Direction.fbs"; - -namespace motis.loader; - -table Section { - category: Category; - provider: Provider; - train_nr: int; - line_id: string; - attributes: [Attribute]; - direction: Direction; -} diff --git a/base/loader/schedule-format/Service.fbs b/base/loader/schedule-format/Service.fbs deleted file mode 100644 index c79661315..000000000 --- a/base/loader/schedule-format/Service.fbs +++ /dev/null @@ -1,32 +0,0 @@ -include "Route.fbs"; -include "Section.fbs"; -include "Track.fbs"; - -namespace motis.loader; - -table ServiceDebugInfo { - file : string; - line_from : int; - line_to : int; -} - -// for GTFS frequencies.txt -enum ScheduleRelationship : byte { - SCHEDULED, // scheduled trip or frequency.txt with exact_times=true - UNSCHEDULED // frequency based trip with exact_times=false -} - -table Service { - route : Route; - traffic_days : string; - sections : [Section]; - tracks : [TrackRules]; - times : [int]; - route_key : uint (key); - debug : ServiceDebugInfo; - rule_participant : bool = false; - initial_train_nr : int; - trip_id : string; // optional, GTFS trip ID (GTFS-RT matching) - seq_numbers : [uint]; // optional, GTFS sequence numbers (GTFS-RT matching) - schedule_relationship: ScheduleRelationship; // optional (GTFS-RT UNSCHEDULED matching) -} diff --git a/base/loader/schedule-format/Station.fbs b/base/loader/schedule-format/Station.fbs deleted file mode 100644 index b0d1a785b..000000000 --- a/base/loader/schedule-format/Station.fbs +++ /dev/null @@ -1,17 +0,0 @@ -include "Timezone.fbs"; -include "Platform.fbs"; - -namespace motis.loader; - -table Station { - id : string; - name : string; - lat : double; - lng : double; - interchange_time : int; - external_ids : [string]; - timezone : Timezone; - timezone_name : string; - platform_interchange_time : int; - platforms : [Platform]; -} diff --git a/base/loader/schedule-format/Timezone.fbs b/base/loader/schedule-format/Timezone.fbs deleted file mode 100644 index 1d8151c48..000000000 --- a/base/loader/schedule-format/Timezone.fbs +++ /dev/null @@ -1,14 +0,0 @@ -namespace motis.loader; - -struct Season { - offset : int; - day_idx_first_day : int; - day_idx_last_day : int; - minutes_after_midnight_first_day: int; - minutes_after_midnight_last_day : int; -} - -table Timezone { - general_offset: int; - seasons: [Season]; -} diff --git a/base/loader/schedule-format/Track.fbs b/base/loader/schedule-format/Track.fbs deleted file mode 100644 index 75625ad42..000000000 --- a/base/loader/schedule-format/Track.fbs +++ /dev/null @@ -1,11 +0,0 @@ -namespace motis.loader; - -table Track { - bitfield: string; - name : string; -} - -table TrackRules { - arr_tracks: [Track]; - dep_tracks: [Track]; -} diff --git a/base/loader/src/build_footpaths.cc b/base/loader/src/build_footpaths.cc deleted file mode 100644 index 301d8653b..000000000 --- a/base/loader/src/build_footpaths.cc +++ /dev/null @@ -1,490 +0,0 @@ -#include "motis/loader/build_footpaths.h" - -#include -#include - -#include "geo/latlng.h" - -#include "utl/enumerate.h" -#include "utl/equal_ranges_linear.h" -#include "utl/erase_duplicates.h" -#include "utl/parallel_for.h" -#include "utl/verify.h" - -#include "motis/core/common/floyd_warshall.h" -#include "motis/core/common/logging.h" -#include "motis/core/schedule/price.h" -#include "motis/core/schedule/time.h" -#include "motis/loader/filter/local_stations.h" - -#include "motis/schedule-format/Schedule_generated.h" - -template -struct fmt::formatter>> { - constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } - - template - auto format(motis::flat_matrix> const& m, - FormatContext& ctx) const -> decltype(ctx.out()) { - for (auto i = 0U; i != m.entries_.size() / m.column_count_; ++i) { - for (auto j = 0U; j != m.column_count_; ++j) { - if (m[i][j] == std::numeric_limits::max()) { - fmt::format_to(ctx.out(), "** "); - } else { - fmt::format_to(ctx.out(), "{:2} ", m[i][j]); - } - } - fmt::format_to(ctx.out(), "\n"); - } - return ctx.out(); - } -}; - -namespace f = flatbuffers64; -namespace ml = motis::logging; - -namespace motis::loader { - -constexpr auto const kTracing = false; - -constexpr auto const kAdjustedMaxDuration = 15; // [minutes] - -constexpr auto kNoComponent = std::numeric_limits::max(); - -// station_idx -> [footpath, ...] -using footgraph = std::vector>; - -// (component, original station_idx) -using component_vec = std::vector>; -using component_it = component_vec::iterator; -using component_range = std::pair; - -template -void trace(char const* fmt_str, Args... args) { - if constexpr (kTracing) { - fmt::print(std::cout, fmt_str, std::forward(args)...); - } -} - -struct footpath_builder { - footpath_builder( - schedule& sched, loader_options const& opt, - mcd::hash_map const& station_nodes) - : sched_{sched}, opt_{opt}, station_nodes_{station_nodes} {} - - void add_footpaths(f::Vector> const* footpaths) { - auto skipped = 0U; - for (auto const& footpath : *footpaths) { - auto const get_station = [&](char const* tag, Station const* s) { - auto const it = station_nodes_.find(s); - utl::verify(it != end(station_nodes_), - "footpath {} node not found {} [{}] ", tag, - footpath->from()->name()->c_str(), - footpath->from()->id()->c_str()); - return it->second; - }; - - if (skip_station(footpath->from()) || skip_station(footpath->to())) { - continue; - } - - auto const from_node = get_station("from", footpath->from()); - auto const to_node = get_station("to", footpath->to()); - auto& from_station = sched_.stations_.at(from_node->id_); - auto& to_station = sched_.stations_.at(to_node->id_); - auto duration = - std::max({from_station->transfer_time_, to_station->transfer_time_, - static_cast(footpath->duration())}); - - if (from_node == to_node) { - LOG(ml::warn) << "Footpath loop at station " << from_station->eva_nr_ - << " ignored"; - continue; - } - - if (opt_.adjust_footpaths_) { - auto const distance = get_distance(*from_station, *to_station) * 1000; - - auto adjusted_duration = adjust_footpath_duration(duration, distance); - if (!adjusted_duration.has_value()) { - continue; - } - duration = *adjusted_duration; - } - - add_foot_edge_pair(from_node, to_node, duration); - } - LOG(ml::info) << "Skipped " << skipped - << " footpaths connecting stations with no events"; - } - - static std::optional adjust_footpath_duration(int duration, - int const distance) { - auto const max_distance_adjust = duration * 60 * WALK_SPEED; - auto const max_distance = 2 * duration * 60 * WALK_SPEED; - - if (distance > max_distance) { - return {}; - } else if (distance > max_distance_adjust) { - duration = std::round(distance / (60 * WALK_SPEED)); - } - - if (duration > kAdjustedMaxDuration) { - return {}; - } - - return {duration}; - } - - void add_foot_edge_pair(station_node* from_sn, station_node* to_sn, - uint16_t const duration) { - auto* from_fn = get_or_create_foot_node(from_sn); - auto* to_fn = get_or_create_foot_node(to_sn); - - // FROM_FOOT -(FWD)-> TO_STATION - from_fn->edges_.emplace_back(make_fwd_edge(from_fn, to_sn, duration)); - - // FROM_STATION -(BWD)-> TO_FOOT - from_sn->edges_.emplace_back(make_bwd_edge(from_sn, to_fn, duration)); - } - - node* get_or_create_foot_node(node* n) { - station_node* sn = n->get_station(); - if (sn->foot_node_ != nullptr) { - return sn->foot_node_.get(); - } - - // Create the foot node. - auto foot_node = mcd::make_unique(); - foot_node->type_ = node_type::FOOT_NODE; - foot_node->station_node_ = sn; - foot_node->id_ = sched_.next_node_id_++; - - // STATION_NODE -(FWD_EDGE)-> FOOT_NODE - sn->edges_.emplace_back(make_fwd_edge(sn, foot_node.get())); - - // FOOT_NODE -(BWD_EDGE)-> STATION_NODE - foot_node->edges_.emplace_back(make_bwd_edge(foot_node.get(), sn)); - - // ROUTE_NODE -(AFTER_TRAIN_FWD)-> STATION_NODE - sn->for_each_route_node([&](auto&& route_node) { - // check whether it is allowed to transfer at the route-node - // we do this by checking, whether it has an edge to the station - for (auto const& e : route_node->edges_) { - if (e.to_ == sn && e.type() != edge::INVALID_EDGE) { - // the foot-edge may only be used - // if a train was used beforewards when - // trying to use it from a route node - route_node->edges_.push_back( - make_after_train_fwd_edge(route_node, foot_node.get(), 0, true)); - break; - } - } - }); - - // STATION_NODE -(AFTER_TRAIN_BWD)-> ROUTE_NODE - for (auto const& e : sn->edges_) { - if (e.to_->is_route_node() && e.type() != edge::INVALID_EDGE) { - foot_node->edges_.emplace_back( - make_after_train_bwd_edge(foot_node.get(), e.to_, 0, true)); - } - } - - sn->foot_node_ = std::move(foot_node); - return sn->foot_node_.get(); - } - - void equivalences_to_footpaths() { - for (auto const& from_s : sched_.stations_) { - auto* from_sn = sched_.station_nodes_.at(from_s->index_).get(); - - for (auto const& to_s : from_s->equivalent_) { - if (from_s->source_schedule_ == to_s->source_schedule_) { - continue; // no footpaths for schedule-defined meta stations - } - - auto* to_sn = sched_.station_nodes_.at(to_s->index_).get(); - - auto const distance = - geo::distance(geo::latlng{from_s->lat(), from_s->lng()}, - geo::latlng{to_s->lat(), to_s->lng()}); - auto const duration = - std::max({from_s->transfer_time_, to_s->transfer_time_, - static_cast(std::round( - static_cast(distance) / (60 * WALK_SPEED)))}); - add_foot_edge_pair(from_sn, to_sn, duration); - } - } - } - - void transitivize_footpaths() { - ml::scoped_timer const timer("building transitively closed foot graph"); - - auto const fgraph = get_footpath_graph(); - - auto components = find_components(fgraph); - std::sort(begin(components), end(components)); - - std::vector ranges; - utl::equal_ranges_linear( - components, - [](auto const& a, auto const& b) { return a.first == b.first; }, - [&](auto lb, auto ub) { ranges.emplace_back(lb, ub); }); - - auto const errors = utl::parallel_for( - ranges, - [&](auto const& range) { - process_component(range.first, range.second, fgraph); - }, - utl::noop_progress_update{}, - utl::parallel_error_strategy::CONTINUE_EXEC); - for (auto const& [idx, ex] : errors) { - try { - std::rethrow_exception(ex); - } catch (std::exception const& e) { - LOG(ml::error) << "footpath error: " << idx << " (" << e.what() << ")"; - } - } - } - - void make_station_equivalents_unique() { - for (auto& s : sched_.stations_) { - if (s->equivalent_.size() <= 1) { - continue; - } - - utl::erase_duplicates( - s->equivalent_, begin(s->equivalent_) + 1, end(s->equivalent_), - [](auto const& a, auto const& b) { return a->index_ < b->index_; }, - [](auto const& a, auto const& b) { return a->index_ == b->index_; }); - - s->equivalent_.erase( - std::remove_if(begin(s->equivalent_) + 1, end(s->equivalent_), - [&s](auto const& equivalent) { - return equivalent->index_ == s->index_; - }), - end(s->equivalent_)); - } - } - - footgraph get_footpath_graph() const { - return utl::to_vec(sched_.station_nodes_, [](auto const& station_node) { - std::vector fps; - if (station_node->foot_node_ != nullptr) { - for (auto const& foot_edge : station_node->foot_node_->edges_) { - auto const from_station = foot_edge.from_->get_station()->id_; - auto const to_station = foot_edge.to_->get_station()->id_; - auto const duration = foot_edge.m_.foot_edge_.time_cost_; - - utl::verify(from_station == station_node->id_, - "foot path wrong at station"); - if (from_station != to_station) { - fps.emplace_back(footpath{from_station, to_station, duration}); - } - } - - std::sort(begin(fps), end(fps)); - } - return fps; - }); - } - - static std::vector> find_components( - footgraph const& fgraph) { - std::vector> components(fgraph.size()); - std::generate(begin(components), end(components), [i = 0UL]() mutable { - return std::pair{kNoComponent, i++}; - }); - - std::stack stack; // invariant: stack is empty - for (auto i = 0UL; i < fgraph.size(); ++i) { - if (components[i].first != kNoComponent || fgraph[i].empty()) { - continue; - } - - stack.emplace(i); - while (!stack.empty()) { - auto j = stack.top(); - stack.pop(); - - if (components[j].first == i) { - continue; - } - - components[j].first = i; - for (auto const& f : fgraph[j]) { - if (components[f.to_station_].first != i) { - stack.push(f.to_station_); - } - } - } - } - - return components; - } - - void process_component(component_it const lb, component_it const ub, - footgraph const& fgraph) { - if (lb->first == kNoComponent) { - return; - } - - auto const size = std::distance(lb, ub); - if (size == 2) { - auto idx_a = lb->second; - auto idx_b = std::next(lb)->second; - - if (!fgraph[idx_a].empty()) { - utl::verify_silent(fgraph[idx_a].size() == 1, - "invalid size (a): idx_a={}, size={}, data=[{}], " - "idx_b={}, size = {} ", - idx_a, fgraph[idx_a].size(), to_str(fgraph[idx_a]), - idx_b, fgraph[idx_b].size(), to_str(fgraph[idx_b])); - sched_.stations_[idx_a]->outgoing_footpaths_.push_back( - fgraph[idx_a].front()); - sched_.stations_[idx_b]->incoming_footpaths_.push_back( - fgraph[idx_a].front()); - } - if (!fgraph[idx_b].empty()) { - utl::verify_silent( - fgraph[idx_b].size() == 1, - "invalid size (a): idx_a={}, size={}, idx_b={}, size={}", idx_a, - fgraph[idx_a].size(), idx_b, fgraph[idx_b].size()); - sched_.stations_[idx_b]->outgoing_footpaths_.push_back( - fgraph[idx_b].front()); - sched_.stations_[idx_a]->incoming_footpaths_.push_back( - fgraph[idx_b].front()); - } - return; - } - utl::verify(size > 2, "invalid size {}", size); - - constexpr auto const kInvalidTime = - std::numeric_limits::max(); - auto mat = make_std_flat_matrix(size, kInvalidTime); - - for (auto i = 0; i < size; ++i) { - auto it = lb; - for (auto const& edge : fgraph[(lb + i)->second]) { // precond.: sorted! - while (it != ub && edge.to_station_ != it->second) { - ++it; - } - auto j = std::distance(lb, it); - mat(i, j) = edge.duration_; - } - } - - auto dbg = false; - auto const print_dbg = [&](auto... args) { - if constexpr (kTracing) { - if (dbg) { - trace(args...); - } - } - }; - - if constexpr (kTracing) { - auto const id = std::string_view{"berlin_de:11000:900160002:1:50"}; - auto const needle = sched_.eva_to_station_.find(id); - - if (needle != end(sched_.eva_to_station_)) { - auto const needle_l = (*needle).second->index_; - for (auto i = 0U; i != size; ++i) { - if ((lb + i)->second == needle_l) { - if constexpr (kTracing) { - std::cout << "FOUND\n"; - } - dbg = true; - goto next; - } - for (auto const& edge : fgraph[(lb + i)->second]) { - if (edge.to_station_ == needle_l) { - if constexpr (kTracing) { - std::cout << "FOUND\n"; - } - dbg = true; - goto next; - } - } - } - } else { - if constexpr (kTracing) { - std::cout << "NEEDLE NOT FOUND\n"; - } - } - } - - next: - print_dbg("MOTIS STATIONS:\n"); - for (auto i = 0U; i != size; ++i) { - print_dbg("{} = {} \n", i, sched_.stations_[(lb + i)->second]->eva_nr_); - } - - print_dbg("MOTIS MAT BEFORE\n{}\n", mat); - - floyd_warshall(mat); - - print_dbg("MOTIS MAT AFTER\n{}", mat); - - for (auto i = 0; i < size; ++i) { - for (auto j = 0; j < size; ++j) { - if (mat(i, j) == kInvalidTime || i == j) { - continue; - } - - auto idx_a = std::next(lb, i)->second; - auto idx_b = std::next(lb, j)->second; - - print_dbg("MOTIS OUTPUT: {} --{}--> {}\n", - sched_.stations_[idx_a]->eva_nr_, mat(i, j), - sched_.stations_[idx_b]->eva_nr_); - - // each node only in one cluster -> no sync required - sched_.stations_[idx_a]->outgoing_footpaths_.emplace_back(idx_a, idx_b, - mat(i, j)); - sched_.stations_[idx_b]->incoming_footpaths_.emplace_back(idx_a, idx_b, - mat(i, j)); - } - } - } - - static std::string to_str(std::vector const& footpaths) { - std::stringstream s; - for (auto const& [i, fp] : utl::enumerate(footpaths)) { - s << (i == 0 ? "" : ", ") << fp.from_station_ << "-" << fp.to_station_ - << "-" << fp.duration_ << "min"; - } - return s.str(); - } - - inline bool skip_station(Station const* station) const { - return opt_.no_local_transport_ && is_local_station(station); - } - - schedule& sched_; - loader_options const& opt_; - mcd::hash_map const& station_nodes_; -}; - -void build_footpaths( - schedule& sched, loader_options const& opt, - mcd::hash_map const& station_nodes, - std::vector const& fbs_schedules) { - footpath_builder b{sched, opt, station_nodes}; - - for (auto const* fbs_schedule : fbs_schedules) { - b.add_footpaths(fbs_schedule->footpaths()); - } - - b.equivalences_to_footpaths(); - b.make_station_equivalents_unique(); - - if (opt.expand_footpaths_) { - // progress_tracker.status("Expand Footpaths").out_bounds(95, 96); - b.transitivize_footpaths(); - } -} - -} // namespace motis::loader diff --git a/base/loader/src/build_stations.cc b/base/loader/src/build_stations.cc deleted file mode 100644 index 8ea4754e1..000000000 --- a/base/loader/src/build_stations.cc +++ /dev/null @@ -1,266 +0,0 @@ -#include "motis/loader/build_stations.h" - -#include "geo/point_rtree.h" - -#include "utl/enumerate.h" -#include "utl/get_or_create.h" -#include "utl/verify.h" - -#include "motis/memory.h" - -#include "motis/core/schedule/schedule.h" - -#include "motis/loader/filter/local_stations.h" -#include "motis/loader/interval_util.h" -#include "motis/loader/timezone_util.h" - -#include "motis/schedule-format/Schedule_generated.h" - -namespace f = flatbuffers64; - -namespace motis::loader { - -constexpr auto const kLinkNearbyMaxDistance = 300; // [m]; - -struct stations_builder { - explicit stations_builder(schedule& sched, std::map& tracks, - bool no_local_stations) - : sched_{sched}, tracks_{tracks}, no_local_stations_{no_local_stations} {} - - void add_dummy_node(std::string const& name) { - auto const station_idx = sched_.station_nodes_.size(); - - // Create dummy station node. - sched_.station_nodes_.emplace_back(mcd::make_unique( - make_station_node(static_cast(station_idx)))); - - // Create dummy station object. - auto s = mcd::make_unique(); - s->index_ = station_idx; - s->eva_nr_ = name; - s->name_ = name; - s->dummy_ = true; - - sched_.eva_to_station_.emplace(name, s.get()); - sched_.stations_.emplace_back(std::move(s)); - } - - void add_station(uint32_t const source_schedule, Station const* fbs_station, - bool const use_platforms) { - if (skip_station(fbs_station)) { - return; - } - - auto const station_idx = sched_.station_nodes_.size(); - - // Create station node. - auto node_ptr = mcd::make_unique( - make_station_node(static_cast(station_idx))); - station_nodes_[fbs_station] = node_ptr.get(); - sched_.station_nodes_.emplace_back(std::move(node_ptr)); - - // Create station object. - auto s = mcd::make_unique(); - s->index_ = station_idx; - s->name_ = fbs_station->name()->str(); - s->width_ = fbs_station->lat(); - s->length_ = fbs_station->lng(); - s->eva_nr_ = std::string{sched_.prefixes_[source_schedule]} + - fbs_station->id()->str(); - s->transfer_time_ = - static_cast(std::max(1, fbs_station->interchange_time())); - s->platform_transfer_time_ = - static_cast(fbs_station->platform_interchange_time()); - if (s->platform_transfer_time_ == 0 || - s->platform_transfer_time_ > s->transfer_time_) { - s->platform_transfer_time_ = s->transfer_time_; - } - s->timez_ = fbs_station->timezone() != nullptr - ? get_or_create_timezone(fbs_station->timezone()) - : nullptr; - s->equivalent_.push_back(s.get()); - s->source_schedule_ = source_schedule; - - if (use_platforms && s->platform_transfer_time_ != 0 && - s->platform_transfer_time_ != s->transfer_time_ && - fbs_station->platforms() != nullptr && - fbs_station->platforms()->size() > 0) { - auto platform_id = 1; - for (auto const& platform : *fbs_station->platforms()) { - for (auto const& track : *platform->tracks()) { - s->track_to_platform_[get_or_create_track(track->str())] = - platform_id; - } - ++platform_id; - } - station_nodes_[fbs_station]->platform_nodes_.resize(platform_id); - ++stations_with_platforms_; - } - - // Store DS100. - if (fbs_station->external_ids() != nullptr) { - s->external_ids_.reserve(fbs_station->external_ids()->size()); - for (auto const& ds100 : *fbs_station->external_ids()) { - sched_.ds100_to_station_.emplace(ds100->str(), s.get()); - s->external_ids_.emplace_back(ds100->str()); - } - } - - utl::verify( - sched_.eva_to_station_.find(s->eva_nr_) == end(sched_.eva_to_station_), - "add_station: have non-unique station_id: {}", s->eva_nr_); - - sched_.eva_to_station_.emplace(s->eva_nr_, s.get()); - sched_.stations_.emplace_back(std::move(s)); - } - - timezone const* get_or_create_timezone(Timezone const* input_timez) { - return utl::get_or_create(timezones_, input_timez, [&] { - auto const tz = - input_timez->seasons() != nullptr - ? create_timezone(input_timez->general_offset(), first_day_, - last_day_, - utl::to_vec(*input_timez->seasons(), - [](Season const* s) { return *s; })) - : timezone{input_timez->general_offset(), {}}; - sched_.timezones_.emplace_back(mcd::make_unique(tz)); - return sched_.timezones_.back().get(); - }); - } - - void link_meta_stations( - f::Vector> const* meta_stations) { - for (auto const& meta : *meta_stations) { - if (skip_station(meta->station())) { - continue; - } - auto& station = - *sched_.stations_[station_nodes_.at(meta->station())->id_]; - for (auto const& fbs_equivalent : *meta->equivalent()) { - if (skip_station(fbs_equivalent)) { - continue; - } - auto& equivalent = - *sched_.stations_[station_nodes_.at(fbs_equivalent)->id_]; - if (station.index_ != equivalent.index_) { - station.equivalent_.push_back(&equivalent); - } - } - } - } - - void link_nearby_stations() { - auto const station_rtree = - geo::make_point_rtree(sched_.stations_, [](auto const& s) { - return geo::latlng{s->lat(), s->lng()}; - }); - - for (auto const& [from_idx, from_station] : - utl::enumerate(sched_.stations_)) { - if (from_station->source_schedule_ == NO_SOURCE_SCHEDULE) { - continue; // no dummy stations - } - - if (std::abs(from_station->lat()) < 2.0 && - std::abs(from_station->lng()) < 2.0) { - continue; // don't connect data errors (creates loopholes) - } - - for (auto const& to_idx : station_rtree.in_radius( - geo::latlng{from_station->lat(), from_station->lng()}, - kLinkNearbyMaxDistance)) { - if (from_idx == to_idx) { - continue; - } - - auto& to_station = sched_.stations_.at(to_idx); - if (to_station->source_schedule_ == NO_SOURCE_SCHEDULE) { - continue; // no dummy stations - } - - if (from_station->source_schedule_ == to_station->source_schedule_) { - continue; // don't shortcut yourself - } - - from_station->equivalent_.push_back(to_station.get()); - } - } - } - - int get_or_create_track(std::string const& name) { - if (sched_.tracks_.empty()) { - sched_.tracks_.emplace_back(""); - } - return utl::get_or_create(tracks_, name, [&]() { - int const index = sched_.tracks_.size(); - sched_.tracks_.emplace_back(name); - return index; - }); - } - - inline bool skip_station(Station const* station) const { - return no_local_stations_ && is_local_station(station); - } - - schedule& sched_; - int first_day_{0}, last_day_{0}; - mcd::hash_map station_nodes_; - mcd::hash_map timezones_; - std::map& tracks_; - bool no_local_stations_{false}; - std::size_t stations_with_platforms_{}; -}; - -mcd::hash_map build_stations( - schedule& sched, std::vector const& fbs_schedules, - std::map& tracks, bool const use_platforms, - bool no_local_stations) { - stations_builder b{sched, tracks, no_local_stations}; - - // Add dummy stations. - b.add_dummy_node(STATION_START); - b.add_dummy_node(STATION_END); - b.add_dummy_node(STATION_VIA0); - b.add_dummy_node(STATION_VIA1); - b.add_dummy_node(STATION_VIA2); - b.add_dummy_node(STATION_VIA3); - b.add_dummy_node(STATION_VIA4); - b.add_dummy_node(STATION_VIA5); - b.add_dummy_node(STATION_VIA6); - b.add_dummy_node(STATION_VIA7); - b.add_dummy_node(STATION_VIA8); - b.add_dummy_node(STATION_VIA9); - - // Add actual stations. - for (auto const& [src_index, fbs_schedule] : utl::enumerate(fbs_schedules)) { - std::tie(b.first_day_, b.last_day_) = - first_last_days(sched, src_index, fbs_schedule->interval()); - - for (auto const* fbs_station : *fbs_schedule->stations()) { - b.add_station(src_index, fbs_station, use_platforms); - } - - if (fbs_schedule->meta_stations() != nullptr) { - b.link_meta_stations(fbs_schedule->meta_stations()); - } - } - - if (use_platforms) { - utl::verify(b.stations_with_platforms_ > 0, - "use_platforms set, but no platform information available"); - } - - if (fbs_schedules.size() > 1) { - b.link_nearby_stations(); - } - - auto const station_count = sched.station_nodes_.size(); - if (station_count > sched.non_station_node_offset_) { - sched.non_station_node_offset_ = station_count + 1'000'000U; - } - sched.next_node_id_ = sched.non_station_node_offset_; - - return std::move(b.station_nodes_); -} - -} // namespace motis::loader diff --git a/base/loader/src/classes.cc b/base/loader/src/classes.cc deleted file mode 100644 index ac2938770..000000000 --- a/base/loader/src/classes.cc +++ /dev/null @@ -1,214 +0,0 @@ -#include "motis/loader/classes.h" - -namespace motis::loader { - -mcd::hash_map const& class_mapping() { - static auto const mapping = mcd::hash_map{ - // planes - {"Flug", service_class::AIR}, - {"Air", service_class::AIR}, - {"International Air", service_class::AIR}, - {"Domestic Air", service_class::AIR}, - {"Intercontinental Air", service_class::AIR}, - {"Domestic Scheduled Air", service_class::AIR}, - {"Shuttle Air", service_class::AIR}, - {"Intercontinental Charter Air", service_class::AIR}, - {"International Charter Air", service_class::AIR}, - {"Round-Trip Charter Air", service_class::AIR}, - {"Sightseeing Air", service_class::AIR}, - {"Helicopter Air", service_class::AIR}, - {"Domestic Charter Air", service_class::AIR}, - {"Schengen-Area Air", service_class::AIR}, - {"Airship", service_class::AIR}, - {"All Airs", service_class::AIR}, - - // high speed - {"High Speed Rail", service_class::ICE}, - {"ICE", service_class::ICE}, - {"THA", service_class::ICE}, - {"TGV", service_class::ICE}, - {"RJ", service_class::ICE}, - {"RJX", service_class::ICE}, - {"ECE", service_class::ICE}, // EuroCity-Express - - // long range rail - {"Long Distance Trains", service_class::IC}, - {"Inter Regional Rail", service_class::IC}, - {"Eurocity", service_class::IC}, - {"EC", service_class::IC}, - {"IC", service_class::IC}, - {"EX", service_class::IC}, - {"EXT", service_class::IC}, - {"D", service_class::IC}, - {"InterRegio", service_class::IC}, - {"Intercity", service_class::IC}, - - // long range bus - {"Coach", service_class::COACH}, - {"International Coach", service_class::COACH}, - {"National Coach", service_class::COACH}, - {"Shuttle Coach", service_class::COACH}, - {"Regional Coach", service_class::COACH}, - {"Special Coach", service_class::COACH}, - {"Sightseeing Coach", service_class::COACH}, - {"Tourist Coach", service_class::COACH}, - {"Commuter Coach", service_class::COACH}, - {"All Coachs", service_class::COACH}, - {"EXB", service_class::COACH}, // long-distance bus - - // night trains - {"Sleeper Rail", service_class::N}, - {"CNL", service_class::N}, - {"EN", service_class::N}, - {"Car Transport Rail", service_class::N}, - {"Lorry Transport Rail", service_class::N}, - {"Vehicle Transport Rail", service_class::N}, - {"AZ", service_class::N}, - {"NJ", service_class::N}, // Night Jet - - // fast local trains - {"RE", service_class::RE}, - {"REX", service_class::RE}, - {"IR", service_class::RE}, - {"IRE", service_class::RE}, - {"X", service_class::RE}, - {"DPX", service_class::RE}, - {"E", service_class::RE}, - {"Sp", service_class::RE}, - {"RegioExpress", service_class::RE}, - {"TER", service_class::RE}, // Transport express regional - {"TE2", service_class::RE}, // Transport express regional - {"Cross-Country Rail", service_class::RE}, - {"CJX", service_class::RE}, // Cityjet xpress - {"MEX", service_class::RE}, // Metropolexpress - {"FEX", service_class::RE}, // Flughafen-Express - - // local trains - {"Railway Service", service_class::RB}, - {"Regional Rail", service_class::RB}, - {"Tourist Railway", service_class::RB}, - {"Rail Shuttle (Within Complex)", service_class::RB}, - {"Replacement Rail", service_class::RB}, - {"Special Rail", service_class::RB}, - {"Rack and Pinion Railway", service_class::RB}, - {"Additional Rail", service_class::RB}, - {"All Rails", service_class::RB}, - {"DPN", service_class::RB}, - {"R", service_class::RB}, - {"DPF", service_class::RB}, - {"RB", service_class::RB}, - {"Os", service_class::RB}, - {"Regionalzug", service_class::RB}, - {"RZ", service_class::RB}, - {"CC", service_class::RB}, // narrow-gauge mountain train - {"PE", service_class::RB}, // Panorama Express - - // metro - {"S", service_class::S}, - {"S-Bahn", service_class::S}, - {"SB", service_class::S}, - {"Metro", service_class::S}, - {"Schnelles Nachtnetz", service_class::S}, - {"SN", service_class::S}, // S-Bahn Nachtlinie - {"Metropolitan", service_class::S}, - - // subway - {"Subway", service_class::U}, - {"U", service_class::U}, - {"STB", service_class::U}, - {"M", service_class::U}, // subway in Lausanne - - // street-car - {"Tram", service_class::STR}, - {"STR", service_class::STR}, - {"Str", service_class::STR}, - {"T", service_class::STR}, - {"Tramvai", service_class::STR}, - - // bus - {"Bus", service_class::BUS}, - {"B", service_class::BUS}, - {"BN", service_class::BUS}, - {"BP", service_class::BUS}, - {"CAR", service_class::BUS}, - {"KB", service_class::BUS}, - {"Trolleybus", service_class::BUS}, - {"Scoala", service_class::BUS}, - - // ship - {"Schiff", service_class::SHIP}, - {"Fähre", service_class::SHIP}, - {"BAT", service_class::SHIP}, // "bateau" - {"KAT", service_class::SHIP}, - {"Ferry", service_class::SHIP}, - {"Water Transport", service_class::SHIP}, - {"International Car Ferry", service_class::SHIP}, - {"National Car Ferry", service_class::SHIP}, - {"Regional Car Ferry", service_class::SHIP}, - {"Local Car Ferry", service_class::SHIP}, - {"International Passenger Ferry", service_class::SHIP}, - {"National Passenger Ferry", service_class::SHIP}, - {"Regional Passenger Ferry", service_class::SHIP}, - {"Local Passenger Ferry", service_class::SHIP}, - {"Post Boat", service_class::SHIP}, - {"Train Ferry", service_class::SHIP}, - {"Road-Link Ferry", service_class::SHIP}, - {"Airport-Link Ferry", service_class::SHIP}, - {"Car High-Speed Ferry", service_class::SHIP}, - {"Passenger High-Speed Ferry", service_class::SHIP}, - {"Sightseeing Boat", service_class::SHIP}, - {"School Boat", service_class::SHIP}, - {"Cable-Drawn Boat", service_class::SHIP}, - {"River Bus", service_class::SHIP}, - {"Scheduled Ferry", service_class::SHIP}, - {"Shuttle Ferry", service_class::SHIP}, - {"All Water Transports", service_class::SHIP}, - - // other - {"Other", service_class::OTHER}, - {"ZahnR", service_class::OTHER}, - {"Schw-B", service_class::OTHER}, - {"EZ", service_class::OTHER}, - {"Taxi", service_class::OTHER}, - {"ALT", service_class::OTHER}, // "Anruflinientaxi" - {"AST", service_class::OTHER}, // "Anrufsammeltaxi" - {"RFB", service_class::OTHER}, - {"RT", service_class::OTHER}, - {"Taxi", service_class::OTHER}, - {"Communal Taxi", service_class::OTHER}, - {"Water Taxi", service_class::OTHER}, - {"Rail Taxi", service_class::OTHER}, - {"Bike Taxi", service_class::OTHER}, - {"Licensed Taxi", service_class::OTHER}, - {"Private Hire Vehicle", service_class::OTHER}, - {"All Taxis", service_class::OTHER}, - {"Self Drive", service_class::OTHER}, - {"Hire Car", service_class::OTHER}, - {"Hire Van", service_class::OTHER}, - {"Hire Motorbike", service_class::OTHER}, - {"Hire Cycle", service_class::OTHER}, - {"All Self-Drive Vehicles", service_class::OTHER}, - {"Car train", service_class::OTHER}, - {"GB", service_class::OTHER}, // ski lift / "funicular"? - {"PB", service_class::OTHER}, // also a ski lift(?) - {"FUN", service_class::OTHER}, // "funicular" - {"Funicular", service_class::OTHER}, - {"Telecabin", service_class::OTHER}, - {"Cable Car", service_class::OTHER}, - {"Chair Lift", service_class::OTHER}, - {"Drag Lift", service_class::OTHER}, - {"Small Telecabin", service_class::OTHER}, - {"All Telecabins", service_class::OTHER}, - {"All Funicular", service_class::OTHER}, - {"Drahtseilbahn", service_class::OTHER}, - {"Standseilbahn", service_class::OTHER}, - {"Sesselbahn", service_class::OTHER}, - {"Gondola, Suspended cable car", service_class::OTHER}, - {"Aufzug", service_class::OTHER}, - {"Elevator", service_class::OTHER}, - {"ASC", service_class::OTHER} // some elevator in Bern - }; - return mapping; -} - -} // namespace motis::loader diff --git a/base/loader/src/graph_builder.cc b/base/loader/src/graph_builder.cc deleted file mode 100644 index a669379f0..000000000 --- a/base/loader/src/graph_builder.cc +++ /dev/null @@ -1,990 +0,0 @@ -#include "motis/loader/graph_builder.h" - -#include -#include -#include -#include - -#include "boost/uuid/nil_generator.hpp" - -#include "utl/enumerate.h" -#include "utl/get_or_create.h" -#include "utl/progress_tracker.h" -#include "utl/verify.h" - -#include "utl/parser/cstr.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/build_platform_node.h" -#include "motis/core/schedule/build_route_node.h" -#include "motis/core/schedule/category.h" -#include "motis/core/schedule/price.h" -#include "motis/core/schedule/validate_graph.h" -#include "motis/core/access/time_access.h" -#include "motis/core/access/trip_iterator.h" -#include "motis/core/debug/route_graph.h" -#include "motis/core/debug/trip.h" - -#include "motis/loader/build_footpaths.h" -#include "motis/loader/build_graph.h" -#include "motis/loader/build_stations.h" -#include "motis/loader/classes.h" -#include "motis/loader/filter/local_stations.h" -#include "motis/loader/interval_util.h" -#include "motis/loader/rule_route_builder.h" -#include "motis/loader/rule_service_graph_builder.h" -#include "motis/loader/util.h" -#include "motis/loader/wzr_loader.h" - -using namespace motis::logging; -using namespace flatbuffers64; - -namespace motis::loader { - -char const* c_str(flatbuffers64::String const* str) { - return str == nullptr ? nullptr : str->c_str(); -} - -graph_builder::graph_builder(schedule& sched, loader_options const& opt) - : sched_{sched}, - apply_rules_{opt.apply_rules_}, - no_local_transport_{opt.no_local_transport_}, - debug_broken_trips_{opt.debug_broken_trips_} {} - -full_trip_id graph_builder::get_full_trip_id(Service const* s, int day, - int section_idx) { - auto const& stops = s->route()->stations(); - auto const dep_station = stops->Get(section_idx); - auto const arr_station = stops->Get(stops->size() - 1); - auto const dep_station_idx = stations_.at(dep_station)->id_; - auto const arr_station_idx = stations_.at(arr_station)->id_; - - auto const dep_tz = sched_.stations_[dep_station_idx]->timez_; - auto const provider_first_section = s->sections()->Get(0)->provider(); - auto const dep_time = get_adjusted_event_time( - tz_cache_, sched_.schedule_begin_, day - first_day_, - s->times()->Get(section_idx * 2 + 1), dep_tz, - c_str(dep_station->timezone_name()), - provider_first_section == nullptr - ? nullptr - : c_str(provider_first_section->timezone_name())); - - auto const arr_tz = sched_.stations_[arr_station_idx]->timez_; - auto const provider_last_section = - s->sections()->Get(s->sections()->size() - 1)->provider(); - auto const arr_time = get_adjusted_event_time( - tz_cache_, sched_.schedule_begin_, day - first_day_, - s->times()->Get(s->times()->size() - 2), arr_tz, - c_str(arr_station->timezone_name()), - provider_last_section == nullptr - ? nullptr - : c_str(provider_last_section->timezone_name())); - - auto const train_nr = s->sections()->Get(section_idx)->train_nr(); - auto const line_id_ptr = s->sections()->Get(0)->line_id(); - auto const line_id = line_id_ptr != nullptr ? line_id_ptr->str() : ""; - - full_trip_id id; - id.primary_ = primary_trip_id{dep_station_idx, - static_cast(train_nr), dep_time}; - id.secondary_ = secondary_trip_id{arr_station_idx, arr_time, line_id}; - return id; -} - -std::optional graph_builder::create_merged_trips( - Service const* s, int day_idx, light_connection const* first_lcon) { - auto const trp = register_service(s, day_idx, false); - if (trp != nullptr) { - if (first_lcon != nullptr) { - trp->original_first_connection_info_ = first_lcon->full_con_->con_info_; - trp->original_first_clasz_ = first_lcon->full_con_->clasz_; - } - return static_cast( - push_mem(sched_.merged_trips_, mcd::vector>({trp}))); - } else { - return {}; - } -} - -trip* graph_builder::register_service(Service const* s, int day_idx, - bool allow_duplicates) { - auto const ftid = get_full_trip_id(s, day_idx); - if (auto const it = added_full_trip_ids_.find(ftid); - it != added_full_trip_ids_.end()) { - LOG(warn) << "service with duplicate trip id: " - << debug::trip_id{sched_, ftid} - << (allow_duplicates ? " - may cause problems!" : " - ignored"); - if (s->debug() != nullptr) { - LOG(warn) << "duplicate service definition: " << s->debug()->file()->str() - << " lines " << s->debug()->line_from() << "-" - << s->debug()->line_to(); - } - auto const& existing_trp = sched_.trip_mem_.at(it->second); - if (existing_trp->dbg_.file_ != nullptr) { - LOG(warn) << "existing service definition: " << *existing_trp->dbg_.file_ - << " lines " << existing_trp->dbg_.line_from_ << "-" - << existing_trp->dbg_.line_to_; - } - if (!allow_duplicates) { - return nullptr; - } - } - - auto const build_id = [&]() { - auto const dep_station = s->route()->stations()->Get(0U); - auto const arr_station = - s->route()->stations()->Get(s->route()->stations()->size() - 1); - return fmt::format("{}{}/{}/{}/{}/{}/{}", dataset_prefix_, - ftid.primary_.train_nr_, dep_station->id()->view(), - ftid.primary_.time_ % 1440, arr_station->id()->view(), - ftid.secondary_.target_time_ % 1440, - ftid.secondary_.line_id_); - }; - - auto const stored = - sched_.trip_mem_ - .emplace_back(mcd::make_unique( - ftid, - s->trip_id() == nullptr ? build_id() - : dataset_prefix_ + s->trip_id()->str(), - nullptr, 0U, static_cast(sched_.trip_mem_.size()), - s->debug() == nullptr - ? trip_debug{} - : trip_debug{utl::get_or_create( - filenames_, s->debug()->file(), - [&]() { - return sched_.filenames_ - .emplace_back( - mcd::make_unique( - s->debug()->file()->str())) - .get(); - }), - s->debug()->line_from(), s->debug()->line_to()}, - s->seq_numbers() == nullptr ? mcd::vector{} - : mcd::to_vec(*s->seq_numbers()), - boost::uuids::nil_uuid(), - s->schedule_relationship() == ScheduleRelationship_UNSCHEDULED, - nullptr, service_class::OTHER)) - .get(); - sched_.trips_.emplace_back(stored->id_.primary_, stored); - added_full_trip_ids_[ftid] = stored->trip_idx_; - - if (s->trip_id() != nullptr) { - auto const motis_time = to_motis_time(day_idx - first_day_ - 5, 0); - auto const date = motis_to_unixtime(sched_, motis_time); - sched_.gtfs_trip_ids_[dataset_prefix_ + s->trip_id()->str()].emplace_back( - date, stored); - } - - for (auto i = 1UL; i < s->sections()->size(); ++i) { - auto curr_section = s->sections()->Get(i); - auto prev_section = s->sections()->Get(i - 1); - - if (curr_section->train_nr() != prev_section->train_nr()) { - sched_.trips_.emplace_back(get_full_trip_id(s, day_idx, i).primary_, - stored); - } - } - - if (s->initial_train_nr() != stored->id_.primary_.train_nr_) { - auto primary = stored->id_.primary_; - primary.train_nr_ = s->initial_train_nr(); - sched_.trips_.emplace_back(primary, stored); - } - - return stored; -} - -void graph_builder::add_services(Vector> const* services) { - mcd::vector sorted(services->size()); - std::copy(std::begin(*services), std::end(*services), begin(sorted)); - std::stable_sort(begin(sorted), end(sorted), - [](Service const* lhs, Service const* rhs) { - return lhs->route() < rhs->route(); - }); - - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->in_high(sorted.size()); - - auto it = begin(sorted); - mcd::vector route_services; - while (it != end(sorted)) { - auto route = (*it)->route(); - do { - if (!apply_rules_ || !(*it)->rule_participant()) { - route_services.push_back(*it); - } - ++it; - } while (it != end(sorted) && route == (*it)->route()); - - if (!route_services.empty() && !skip_route(route)) { - add_route_services(mcd::to_vec(route_services, [&](Service const* s) { - return std::make_pair(s, get_or_create_bitfield(s->traffic_days())); - })); - } - - route_services.clear(); - progress_tracker->update(std::distance(begin(sorted), it)); - } -} - -void graph_builder::index_first_route_node(route const& r) { - assert(!r.empty()); - auto route_index = r[0].from_route_node_->route_; - if (static_cast(sched_.route_index_to_first_route_node_.size()) <= - route_index) { - sched_.route_index_to_first_route_node_.resize(route_index + 1); - } - sched_.route_index_to_first_route_node_[route_index] = r[0].from_route_node_; -} - -void graph_builder::add_route_services( - mcd::vector> const& services) { - mcd::vector alt_routes; - for (auto const& [s, traffic_days] : services) { - auto const first_day_offset = - s->times()->Get(s->times()->size() - 2) / 1440; - auto const first_day = std::max(0, first_day_ - first_day_offset); - - auto const stations = - mcd::to_vec(*s->route()->stations(), [&](auto const& s) { - return sched_.stations_[stations_.find(s)->second->id_].get(); - }); - - for (int day = first_day; day <= last_day_; ++day) { - if (day >= traffic_days.size() || !traffic_days.test(day)) { - continue; - } - - time prev_arr = 0; - bool adjusted = false; - mcd::vector lcons; - auto const merged_trips_idx = sched_.merged_trips_.size(); - for (unsigned section_idx = 0; section_idx < s->sections()->size(); - ++section_idx) { - lcons.push_back(section_to_connection(merged_trips_idx, - {{participant{s, section_idx}}}, - day, prev_arr, adjusted)); - prev_arr = lcons.back().a_time_; - } - - if (has_duplicate(s, lcons)) { - continue; - } - - auto const first_lcon = !lcons.empty() ? &lcons.front() : nullptr; - - auto const created_merged_trips_idx = - create_merged_trips(s, day, first_lcon); - if (!created_merged_trips_idx) { - // duplicate trip id - continue; - } - - utl::verify(merged_trips_idx == *created_merged_trips_idx, - "unexpected merged_trips_idx"); - add_to_routes(alt_routes, lcons, stations); - } - } - - for (auto const& route : alt_routes) { - if (route.empty() || route[0].empty()) { - continue; - } - - auto const route_id = next_route_index_++; - auto r = create_route(services[0].first->route(), route, route_id); - index_first_route_node(*r); - write_trip_info(*r); - add_expanded_trips(*r); - } -} - -bool graph_builder::has_duplicate(Service const* service, - mcd::vector const& lcons) { - auto const& first_station = sched_.stations_.at( - stations_.at(service->route()->stations()->Get(0))->id_); - for (auto const& eq : first_station->equivalent_) { - if (eq->source_schedule_ == first_station->source_schedule_) { - continue; // Ignore duplicates from same schedule. - } - - for (auto const& route_node : - sched_.station_nodes_[eq->index_]->child_nodes_) { - if (!route_node->is_route_node()) { - continue; - } - for (auto const& route_edge : route_node->edges_) { - if (route_edge.type() != edge::ROUTE_EDGE) { - continue; - } - - for (auto* lc = route_edge.get_connection(lcons.front().d_time_); - lc != nullptr && lc->d_time_ == lcons.front().d_time_; - lc = route_edge.get_next_valid_lcon(lc, 1U)) { - for (auto const& trp : *sched_.merged_trips_[lc->trips_]) { - if (are_duplicates(service, lcons, trp)) { - return true; - } - } - } - } - } - } - - return false; -} - -bool graph_builder::are_duplicates(Service const* service_a, - mcd::vector const& lcons_a, - trip const* trp_b) { - auto const* stations_a = service_a->route()->stations(); - auto const stops_b = access::stops{trp_b}; - auto const stop_count_b = std::distance(begin(stops_b), end(stops_b)); - - if (stations_a->size() != stop_count_b) { - return false; - } - - auto const are_equivalent = [&](Station const* st_a, station const& s_b) { - auto const& s_a = sched_.stations_.at(stations_.at(st_a)->id_); - return s_a->source_schedule_ != s_b.source_schedule_ && - std::any_of( - begin(s_a->equivalent_), end(s_a->equivalent_), - [&](auto const& eq_a) { return eq_a->index_ == s_b.index_; }); - }; - - auto const& last_stop_b = *std::next(begin(stops_b), stop_count_b - 1); - if (lcons_a.back().a_time_ != last_stop_b.arr_lcon().a_time_ || - !are_equivalent(stations_a->Get(stations_a->size() - 1), - last_stop_b.get_station(sched_))) { - return false; - } - - for (auto [i_a, it_b] = std::tuple{1ULL, std::next(begin(stops_b))}; - std::next(it_b) != end(stops_b); ++i_a, ++it_b) { - if (lcons_a[i_a - 1].a_time_ != (*it_b).arr_lcon().a_time_ || - lcons_a[i_a].d_time_ != (*it_b).dep_lcon().d_time_ || - !are_equivalent(stations_a->Get(i_a), (*it_b).get_station(sched_))) { - return false; - } - } - - return true; -} - -void graph_builder::add_expanded_trips(route const& r) { - assert(!r.empty()); - auto const& re = r.front().get_route_edge(); - if (re != nullptr) { - auto const route_id = re->from_->route_; - auto route_trips = sched_.expanded_trips_.emplace_back(); - for (auto const& lc : re->m_.route_edge_.conns_) { - auto const& merged_trips = sched_.merged_trips_[lc.trips_]; - assert(merged_trips != nullptr); - assert(merged_trips->size() == 1); - auto const trp = merged_trips->front(); - if (check_trip(trp)) { - route_trips.push_back(trp); - } - } - if (!route_trips.empty()) { - sched_.route_to_expanded_routes_[route_id].emplace_back( - route_trips.index()); - } - } -} - -bool graph_builder::check_trip(trip const* trp) { - if (trp->edges_->empty()) { - LOG(info) << "broken trip: " << debug::trip{sched_, trp} << ": no edges"; - return false; - } - time last_time = 0; - for (auto const sec : access::sections{trp}) { - auto const& lc = sec.lcon(); - auto const section_times_ok = lc.d_time_ <= lc.a_time_; - auto const stop_times_ok = last_time <= lc.d_time_; - if (!section_times_ok || !stop_times_ok) { - if (debug_broken_trips_) { - LOG(info) << "broken trip: " << debug::trip{sched_, trp} - << ": lc={dep=" << format_time(lc.d_time_) - << ", arr=" << format_time(lc.a_time_) - << "}, last_time=" << format_time(last_time) << ":\n" - << debug::rule_service_trip_with_sections{sched_, trp} - << "\nroute graph:\n\n" - << debug::route_graph{sched_, trp} << "\n"; - } - ++broken_trips_; - return false; - } - last_time = lc.a_time_; - } - return true; -} - -int graph_builder::get_index( - mcd::vector> const& alt_route, - mcd::vector const& sections, - mcd::vector const& stations) { - assert(!sections.empty()); - assert(!alt_route.empty()); - assert(stations.size() == sections.size() + 1); - - if (alt_route[0].empty()) { - return 0; - } - - int index = -1; - for (auto section_idx = 0UL; section_idx < sections.size(); ++section_idx) { - auto const& route_section = alt_route[section_idx]; - auto const& lc = sections[section_idx]; - if (index == -1) { - index = std::distance( - begin(route_section), - std::lower_bound(begin(route_section), end(route_section), - sections[section_idx])); - --section_idx; - } else { - // Check if departures stay sorted. - bool const earlier_eq_dep = - index > 0 && lc.d_time_ <= route_section[index - 1].d_time_; - bool const later_eq_dep = - static_cast(index) < route_section.size() && - lc.d_time_ >= route_section[index].d_time_; - - // Check if arrivals stay sorted. - bool const earlier_eq_arr = - index > 0 && lc.a_time_ <= route_section[index - 1].a_time_; - bool const later_eq_arr = - static_cast(index) < route_section.size() && - lc.a_time_ >= route_section[index].a_time_; - - // Check if both tracks have the same platform or both tracks have no - // platform information. - auto const& dep_station = stations[section_idx]; - auto const& arr_station = stations[section_idx + 1]; - auto const different_dep_platform = - dep_station->get_platform(lc.full_con_->d_track_) != - dep_station->get_platform(route_section[0].full_con_->d_track_); - auto const different_arr_platform = - arr_station->get_platform(lc.full_con_->a_track_) != - arr_station->get_platform(route_section[0].full_con_->a_track_); - - if (earlier_eq_dep || later_eq_dep || earlier_eq_arr || later_eq_arr || - different_dep_platform || different_arr_platform) { - return -1; - } - } - } - return index; -} - -void graph_builder::add_to_route( - mcd::vector>& route, - mcd::vector const& sections, int index) { - for (auto section_idx = 0UL; section_idx < sections.size(); ++section_idx) { - route[section_idx].insert(std::next(begin(route[section_idx]), index), - sections[section_idx]); - } -} - -void graph_builder::add_to_routes( - mcd::vector>>& alt_routes, - mcd::vector const& sections, - mcd::vector const& stations) { - for (auto& alt_route : alt_routes) { - int const index = get_index(alt_route, sections, stations); - if (index == -1) { - continue; - } - - add_to_route(alt_route, sections, index); - return; - } - - alt_routes.emplace_back(sections.size()); - add_to_route(alt_routes.back(), sections, 0); -} - -connection_info* graph_builder::get_or_create_connection_info( - Section const* section, int dep_day_index, connection_info* merged_with) { - con_info_.line_identifier_ = - section->line_id() != nullptr ? section->line_id()->str() : ""; - con_info_.train_nr_ = section->train_nr(); - con_info_.family_ = get_or_create_category_index(section->category()); - con_info_.dir_ = get_or_create_direction(section->direction()); - con_info_.provider_ = get_or_create_provider(section->provider()); - con_info_.merged_with_ = merged_with; - read_attributes(dep_day_index, section->attributes(), con_info_.attributes_); - - return mcd::set_get_or_create(con_infos_, &con_info_, [&]() { - sched_.connection_infos_.emplace_back( - mcd::make_unique(con_info_)); - return sched_.connection_infos_.back().get(); - }); -} - -connection_info* graph_builder::get_or_create_connection_info( - std::array const& services, int dep_day_index) { - connection_info* prev_con_info = nullptr; - - for (auto service : services) { - if (service.service_ == nullptr) { - return prev_con_info; - } - - auto const& s = service; - prev_con_info = get_or_create_connection_info( - s.service_->sections()->Get(s.section_idx_), dep_day_index, - prev_con_info); - } - - return prev_con_info; -} - -light_connection graph_builder::section_to_connection( - merged_trips_idx trips, std::array const& services, - int day, time prev_arr, bool& adjusted) { - auto const& ref = services[0].service_; - auto const& section_idx = services[0].section_idx_; - - assert(ref != nullptr); - - assert(std::all_of(begin(services), end(services), [&](participant const& s) { - if (s.service_ == nullptr) { - return true; - } - - auto const& ref_stops = ref->route()->stations(); - auto const& s_stops = s.service_->route()->stations(); - auto stations_match = - s_stops->Get(s.section_idx_) == ref_stops->Get(section_idx) && - s_stops->Get(s.section_idx_ + 1) == ref_stops->Get(section_idx + 1); - - auto times_match = - s.service_->times()->Get(s.section_idx_ * 2 + 1) % 1440 == - ref->times()->Get(section_idx * 2 + 1) % 1440 && - s.service_->times()->Get(s.section_idx_ * 2 + 2) % 1440 == - ref->times()->Get(section_idx * 2 + 2) % 1440; - - return stations_match && times_match; - })); - assert(std::is_sorted(begin(services), end(services))); - - auto const from_station = ref->route()->stations()->Get(section_idx); - auto const to_station = ref->route()->stations()->Get(section_idx + 1); - auto& from = *sched_.stations_.at(stations_[from_station]->id_); - auto& to = *sched_.stations_.at(stations_[to_station]->id_); - - auto plfs = ref->tracks(); - auto dep_platf = - plfs != nullptr ? plfs->Get(section_idx)->dep_tracks() : nullptr; - auto arr_platf = - plfs != nullptr ? plfs->Get(section_idx + 1)->arr_tracks() : nullptr; - - auto section = ref->sections()->Get(section_idx); - auto dep_time = ref->times()->Get(section_idx * 2 + 1); - auto arr_time = ref->times()->Get(section_idx * 2 + 2); - - // Day indices for shifted bitfields (tracks, attributes) - int const dep_day_index = day + (dep_time / MINUTES_A_DAY); - int const arr_day_index = day + (arr_time / MINUTES_A_DAY); - - // Build full connection. - auto clasz_it = sched_.classes_.find(section->category()->name()->str()); - con_.clasz_ = (clasz_it == end(sched_.classes_)) ? service_class::OTHER - : clasz_it->second; - con_.price_ = get_distance(from, to) * get_price_per_km(con_.clasz_); - con_.d_track_ = get_or_create_track(dep_day_index, dep_platf); - con_.a_track_ = get_or_create_track(arr_day_index, arr_platf); - con_.con_info_ = get_or_create_connection_info(services, dep_day_index); - - // Build light connection. - time dep_motis_time = 0, arr_motis_time = 0; - auto const section_timezone = section->provider() == nullptr - ? nullptr - : section->provider()->timezone_name(); - std::optional error; - std::tie(dep_motis_time, arr_motis_time, error) = get_event_times( - tz_cache_, sched_.schedule_begin_, day - first_day_, prev_arr, dep_time, - arr_time, from.timez_, c_str(from_station->timezone_name()), - c_str(section_timezone), to.timez_, c_str(to_station->timezone_name()), - c_str(section_timezone), adjusted); - if (error.has_value()) { - LOG(logging::error) << "invalid times: " << *error - << ", section_idx=" << section_idx << ", trip=" - << (ref->trip_id() != nullptr ? ref->trip_id()->str() - : "unknown"); - } - - // Count events. - ++from.dep_class_events_.at(static_cast(con_.clasz_)); - ++to.arr_class_events_.at(static_cast(con_.clasz_)); - - // Track first event. - sched_.first_event_schedule_time_ = std::min( - sched_.first_event_schedule_time_, - motis_to_unixtime(sched_, dep_motis_time) - SCHEDULE_OFFSET_MINUTES * 60); - sched_.last_event_schedule_time_ = std::max( - sched_.last_event_schedule_time_, - motis_to_unixtime(sched_, arr_motis_time) - SCHEDULE_OFFSET_MINUTES * 60); - - return {dep_motis_time, arr_motis_time, - mcd::set_get_or_create(connections_, &con_, - [&]() { - sched_.full_connections_.emplace_back( - mcd::make_unique(con_)); - return sched_.full_connections_.back().get(); - }), - trips}; -} - -void graph_builder::connect_reverse() { - for (auto& station_node : sched_.station_nodes_) { - for (auto& station_edge : station_node->edges_) { - station_edge.to_->incoming_edges_.push_back(&station_edge); - if (station_edge.to_->get_station() != station_node.get()) { - continue; - } - for (auto& edge : station_edge.to_->edges_) { - edge.to_->incoming_edges_.push_back(&edge); - } - } - for (auto& platform_node : station_node->platform_nodes_) { - if (platform_node != nullptr) { - for (auto& edge : platform_node->edges_) { - edge.to_->incoming_edges_.push_back(&edge); - } - } - } - } -} - -void graph_builder::sort_trips() { - std::sort( - begin(sched_.trips_), end(sched_.trips_), - [](auto const& lhs, auto const& rhs) { return lhs.first < rhs.first; }); -} - -bitfield const& graph_builder::get_or_create_bitfield( - String const* serialized_bitfield) { - return utl::get_or_create(bitfields_, serialized_bitfield, [&]() { - return deserialize_bitset( - {serialized_bitfield->c_str(), - static_cast(serialized_bitfield->Length())}); - }); -} - -void graph_builder::read_attributes( - int day, Vector> const* attributes, - mcd::vector>& active_attributes) { - active_attributes.clear(); - active_attributes.reserve(attributes->size()); - for (auto const& attr : *attributes) { - if (!get_or_create_bitfield(attr->traffic_days()).test(day)) { - continue; - } - auto const attribute_info = attr->info(); - active_attributes.push_back( - utl::get_or_create(attributes_, attribute_info, [&]() { - auto new_attr = mcd::make_unique(); - new_attr->code_ = attribute_info->code()->str(); - new_attr->text_ = attribute_info->text()->str(); - sched_.attributes_.emplace_back(std::move(new_attr)); - return sched_.attributes_.back().get(); - })); - } -} - -mcd::string const* graph_builder::get_or_create_direction( - Direction const* dir) { - if (dir == nullptr) { - return nullptr; - } else if (dir->station() != nullptr) { - return &sched_.stations_[stations_[dir->station()]->id_]->name_; - } else /* direction text */ { - return utl::get_or_create(directions_, dir->text(), [&]() { - sched_.directions_.emplace_back( - mcd::make_unique(dir->text()->str())); - return sched_.directions_.back().get(); - }); - } -} - -provider const* graph_builder::get_or_create_provider(Provider const* p) { - if (p == nullptr) { - return nullptr; - } else { - return utl::get_or_create(providers_, p, [&]() { - auto const ptr = sched_.providers_ - .emplace_back(mcd::make_unique( - p->short_name()->str(), p->long_name()->str(), - p->full_name()->str())) - .get(); - sched_.provider_by_full_name_[ptr->full_name_] = ptr; - return ptr; - }); - } -} - -int graph_builder::get_or_create_category_index(Category const* c) { - return utl::get_or_create(categories_, c, [&]() { - int const index = sched_.categories_.size(); - sched_.categories_.emplace_back(mcd::make_unique( - c->name()->str(), static_cast(c->output_rule()))); - return index; - }); -} - -int graph_builder::get_or_create_track(int day, - Vector> const* tracks) { - static constexpr int no_track = 0; - if (sched_.tracks_.empty()) { - sched_.tracks_.emplace_back(""); - } - - if (tracks == nullptr) { - return no_track; - } - - auto track_it = std::find_if( - std::begin(*tracks), std::end(*tracks), [&](Track const* track) { - return get_or_create_bitfield(track->bitfield()).test(day); - }); - if (track_it == std::end(*tracks)) { - return no_track; - } else { - auto name = track_it->name()->str(); - return utl::get_or_create(tracks_, name, [&]() { - int const index = sched_.tracks_.size(); - sched_.tracks_.emplace_back(name); - return index; - }); - } -} - -void graph_builder::write_trip_info(route const& r) { - auto edges_ptr = - sched_.trip_edges_ - .emplace_back(mcd::make_unique>( - mcd::to_vec(r, - [](route_section const& s) { - return trip::route_edge{s.get_route_edge()}; - }))) - .get(); - - auto& lcons = edges_ptr->front().get_edge()->m_.route_edge_.conns_; - for (auto lcon_idx = lcon_idx_t{}; lcon_idx < lcons.size(); ++lcon_idx) { - auto trp = sched_.merged_trips_[lcons[lcon_idx].trips_]->front(); - trp->edges_ = edges_ptr; - trp->lcon_idx_ = lcon_idx; - } -} - -mcd::unique_ptr graph_builder::create_route(Route const* r, - route_lcs const& lcons, - unsigned route_index) { - auto const& stops = r->stations(); - auto const& in_allowed = r->in_allowed(); - auto const& out_allowed = r->out_allowed(); - auto route_sections = mcd::make_unique(); - - route_section last_route_section; - for (auto i = 0UL; i < r->stations()->size() - 1; ++i) { - auto from = i; - auto to = i + 1; - route_sections->push_back( - add_route_section(route_index, lcons[i], // - stops->Get(from), in_allowed->Get(from) != 0U, - out_allowed->Get(from) != 0U, stops->Get(to), - in_allowed->Get(to) != 0U, out_allowed->Get(to) != 0U, - last_route_section.to_route_node_, nullptr)); - last_route_section = route_sections->back(); - } - - return route_sections; -} - -route_section graph_builder::add_route_section( - int route_index, mcd::vector const& connections, - Station const* from_stop, bool from_in_allowed, bool from_out_allowed, - Station const* to_stop, bool to_in_allowed, bool to_out_allowed, - node* from_route_node, node* to_route_node) { - route_section section; - - auto const from_station_node = stations_[from_stop]; - auto const to_station_node = stations_[to_stop]; - auto const from_station = sched_.stations_[from_station_node->id_].get(); - auto const to_station = sched_.stations_[to_station_node->id_].get(); - - if (from_route_node != nullptr) { - section.from_route_node_ = from_route_node; - } else { - section.from_route_node_ = build_route_node( - route_index, sched_.next_node_id_++, from_station_node, - from_station->transfer_time_, from_in_allowed, from_out_allowed); - } - auto const from_platform = - from_station->get_platform(connections[0].full_con_->d_track_); - if (from_in_allowed && from_platform) { - add_platform_enter_edge(sched_, section.from_route_node_, from_station_node, - from_station->platform_transfer_time_, - from_platform.value()); - } - - if (to_route_node != nullptr) { - section.to_route_node_ = to_route_node; - } else { - section.to_route_node_ = build_route_node( - route_index, sched_.next_node_id_++, to_station_node, - to_station->transfer_time_, to_in_allowed, to_out_allowed); - } - auto const to_platform = - to_station->get_platform(connections[0].full_con_->a_track_); - if (to_out_allowed && to_platform) { - add_platform_exit_edge(sched_, section.to_route_node_, to_station_node, - to_station->platform_transfer_time_, - to_platform.value()); - } - - section.outgoing_route_edge_index_ = section.from_route_node_->edges_.size(); - section.from_route_node_->edges_.push_back(make_route_edge( - section.from_route_node_, section.to_route_node_, connections)); - lcon_count_ += connections.size(); - - return section; -} - -bool graph_builder::skip_station(Station const* station) const { - return no_local_transport_ && is_local_station(station); -} - -bool graph_builder::skip_route(Route const* route) const { - return no_local_transport_ && - std::any_of( - route->stations()->begin(), route->stations()->end(), - [&](Station const* station) { return skip_station(station); }); -} - -schedule_ptr build_graph(std::vector const& fbs_schedules, - loader_options const& opt) { - utl::verify(!fbs_schedules.empty(), "build_graph: no schedules"); - - scoped_timer const timer("building graph"); - for (auto const* fbs_schedule : fbs_schedules) { - LOG(info) << "schedule: " << fbs_schedule->name()->str(); - } - - auto sched = mcd::make_unique(); - sched->classes_ = class_mapping(); - std::tie(sched->schedule_begin_, sched->schedule_end_) = opt.interval(); - - for (auto const& [index, fbs_schedule] : utl::enumerate(fbs_schedules)) { - sched->names_.push_back( - fbs_schedule->name() != nullptr - ? fbs_schedule->name()->str() - : std::string{"unknown-"}.append(std::to_string(index))); - } - - if (fbs_schedules.size() == 1 && opt.dataset_prefix_.empty()) { - sched->prefixes_.emplace_back(""); // dont force prefix for single - } else { - utl::verify(std::set{begin(opt.dataset_prefix_), - end(opt.dataset_prefix_)} - .size() == fbs_schedules.size(), - "graph_builder: some prefixes are missing or non-unique"); - sched->prefixes_ = mcd::to_vec( - opt.dataset_prefix_, - [](auto const& s) -> mcd::string { return s.empty() ? s : s + "_"; }); - } - - auto progress_tracker = utl::get_active_progress_tracker(); - graph_builder builder{*sched, opt}; - - progress_tracker->status("Add Stations").out_bounds(0, 5); - builder.stations_ = - build_stations(*sched, fbs_schedules, builder.tracks_, opt.use_platforms_, - opt.no_local_transport_); - - for (auto const& [i, fbs_schedule] : utl::enumerate(fbs_schedules)) { - auto const dataset_prefix = - opt.dataset_prefix_.empty() ? "" : opt.dataset_prefix_[i]; - auto const out_low = 5.F + (80.F / fbs_schedules.size()) * i; - auto const out_high = 5.F + (80.F / fbs_schedules.size()) * (i + 1); - auto const out_mid = out_low + (out_high - out_low) * .9F; - progress_tracker->status(fmt::format("Add Services {}", dataset_prefix)) - .out_bounds(out_low, out_mid); - - builder.dataset_prefix_ = - dataset_prefix.empty() ? dataset_prefix : dataset_prefix + "_"; - - std::tie(builder.first_day_, builder.last_day_) = - first_last_days(*sched, i, fbs_schedule->interval()); - builder.add_services(fbs_schedule->services()); - if (opt.apply_rules_) { - scoped_timer const timer("rule services"); - progress_tracker->status(fmt::format("Rule Services {}", dataset_prefix)) - .out_bounds(out_mid, out_high); - build_rule_routes(builder, fbs_schedule->rule_services()); - } - } - - progress_tracker->status("Footpaths").out_bounds(85, 90); - build_footpaths(*sched, opt, builder.stations_, fbs_schedules); - - progress_tracker->status("Connect Reverse").out_bounds(90, 93); - builder.connect_reverse(); - - progress_tracker->status("Sort Trips").out_bounds(93, 95); - builder.sort_trips(); - - auto hash = cista::BASE_HASH; - for (auto const* fbs_schedule : fbs_schedules) { - hash = cista::hash_combine(hash, fbs_schedule->hash()); - } - for (auto const& prefix : sched->prefixes_) { - hash = cista::hash(prefix, hash); - } - sched->hash_ = hash; - - sched->route_count_ = builder.next_route_index_; - - progress_tracker->status("Lower Bounds").out_bounds(96, 100).in_high(4); - sched->transfers_lower_bounds_fwd_ = build_interchange_graph( - sched->station_nodes_, sched->non_station_node_offset_, - sched->route_count_, search_dir::FWD); - progress_tracker->increment(); - sched->transfers_lower_bounds_bwd_ = build_interchange_graph( - sched->station_nodes_, sched->non_station_node_offset_, - sched->route_count_, search_dir::BWD); - progress_tracker->increment(); - sched->travel_time_lower_bounds_fwd_ = - build_station_graph(sched->station_nodes_, search_dir::FWD); - progress_tracker->increment(); - sched->travel_time_lower_bounds_bwd_ = - build_station_graph(sched->station_nodes_, search_dir::BWD); - progress_tracker->increment(); - - sched->waiting_time_rules_ = load_waiting_time_rules( - opt.wzr_classes_path_, opt.wzr_matrix_path_, sched->categories_); - sched->schedule_begin_ -= SCHEDULE_OFFSET_MINUTES * 60; - calc_waits_for(*sched, opt.planned_transfer_delta_); - - LOG(info) << sched->connection_infos_.size() << " connection infos"; - LOG(info) << builder.lcon_count_ << " light connections"; - LOG(info) << builder.next_route_index_ << " routes"; - LOG(info) << sched->trip_mem_.size() << " trips"; - LOG(info) << sched->expanded_trips_.index_size() << " expanded routes"; - LOG(info) << sched->expanded_trips_.element_count() << " expanded trips"; - LOG(info) << builder.broken_trips_ << " broken trips ignored"; - - validate_graph(*sched); - utl::verify( - std::all_of(begin(sched->trips_), end(sched->trips_), - [](auto const& t) { return t.second->edges_ != nullptr; }), - "missing trip edges"); - return sched; -} - -} // namespace motis::loader diff --git a/base/loader/src/gtfs/agency.cc b/base/loader/src/gtfs/agency.cc deleted file mode 100644 index 45f770c0d..000000000 --- a/base/loader/src/gtfs/agency.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "motis/loader/gtfs/agency.h" - -#include -#include - -#include "utl/parser/csv.h" - -#include "motis/loader/util.h" - -using namespace utl; -using namespace flatbuffers64; -using std::get; - -namespace motis::loader::gtfs { - -enum { agency_id, agency_name, agency_timezone }; -using gtfs_agency = std::tuple; -static const column_mapping columns = { - {"agency_id", "agency_name", "agency_timezone"}}; - -agency_map read_agencies(loaded_file file) { - agency_map agencies; - for (auto const& a : read(file.content(), columns)) { - agencies.emplace( - get(a).to_str(), - std::make_unique(get(a).to_str(), - get(a).to_str(), - get(a).to_str())); - } - return agencies; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/calendar.cc b/base/loader/src/gtfs/calendar.cc deleted file mode 100644 index 741f2ccae..000000000 --- a/base/loader/src/gtfs/calendar.cc +++ /dev/null @@ -1,63 +0,0 @@ -#include "motis/loader/gtfs/calendar.h" - -#include "utl/parser/csv.h" - -#include "motis/loader/util.h" - -using namespace utl; -using std::get; - -namespace motis::loader::gtfs { - -using gtfs_calendar = - std::tuple; -enum { - service_id, - monday, - tuesday, - wednesday, - thursday, - friday, - saturday, - sunday, - start_date, - end_date -}; - -static const column_mapping calendar_columns = { - {"service_id", "monday", "tuesday", "wednesday", "thursday", "friday", - "saturday", "sunday", "start_date", "end_date"}}; - -std::bitset<7> traffic_week_days(gtfs_calendar const& c) { - std::bitset<7> days; - days.set(0, get(c) == 1); - days.set(1, get(c) == 1); - days.set(2, get(c) == 1); - days.set(3, get(c) == 1); - days.set(4, get(c) == 1); - days.set(5, get(c) == 1); - days.set(6, get(c) == 1); - return days; -} - -std::map read_calendar(loaded_file file) { - if (file.empty()) { - return {}; - } - - std::map services; - for (auto const& c : read(file.content(), calendar_columns)) { - services.insert(std::make_pair( - get(c).to_str(), - calendar{traffic_week_days(c), - date::year_month_day{yyyymmdd_year(get(c)), - yyyymmdd_month(get(c)), - yyyymmdd_day(get(c))}, - date::year_month_day{yyyymmdd_year(get(c)), - yyyymmdd_month(get(c)), - yyyymmdd_day(get(c))}})); - } - return services; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/calendar_date.cc b/base/loader/src/gtfs/calendar_date.cc deleted file mode 100644 index 453d6e311..000000000 --- a/base/loader/src/gtfs/calendar_date.cc +++ /dev/null @@ -1,47 +0,0 @@ -#include "motis/loader/gtfs/calendar_date.h" - -#include "utl/enumerate.h" -#include "utl/parser/csv.h" -#include "utl/progress_tracker.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/util.h" - -using namespace utl; -using std::get; - -namespace motis::loader::gtfs { - -using gtfs_calendar_date = std::tuple; -enum { service_id, date_column, exception_type }; - -static const column_mapping calendar_columns = { - {"service_id", "date", "exception_type"}}; - -calendar_date read_date(gtfs_calendar_date const& gtfs_date) { - calendar_date d; - d.day_ = date::year_month_day{yyyymmdd_year(get(gtfs_date)), - yyyymmdd_month(get(gtfs_date)), - yyyymmdd_day(get(gtfs_date))}; - d.type_ = get(gtfs_date) == 1 ? calendar_date::ADD - : calendar_date::REMOVE; - return d; -} - -std::map> read_calendar_date( - loaded_file f) { - motis::logging::scoped_timer const timer{"calendar dates"}; - std::map> services; - auto const entries = read(f.content(), calendar_columns); - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->status("Parse Calendar Dates") - .out_bounds(0.F, 5.F) - .in_high(entries.size()); - for (auto const& d : entries) { - progress_tracker->increment(); - services[get(d).to_str()].push_back(read_date(d)); - } - return services; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/feed_info.cc b/base/loader/src/gtfs/feed_info.cc deleted file mode 100644 index b7496119f..000000000 --- a/base/loader/src/gtfs/feed_info.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include "motis/loader/gtfs/feed_info.h" - -#include -#include - -#include "utl/parser/csv.h" - -#include "motis/loader/util.h" - -using namespace utl; -using namespace flatbuffers64; -using std::get; - -namespace motis::loader::gtfs { - -enum { feed_publisher_name, feed_version }; -using gtfs_feed_publisher = std::tuple; -static const column_mapping columns = { - {"feed_publisher_name", "feed_version"}}; - -feed_map read_feed_publisher(loaded_file file) { - feed_map feeds; - for (auto const& f : read(file.content(), columns)) { - feeds.emplace(get(f).to_str(), - feed{get(f).to_str(), - get(f).to_str()}); - } - return feeds; -} - -} // namespace motis::loader::gtfs \ No newline at end of file diff --git a/base/loader/src/gtfs/gtfs_parser.cc b/base/loader/src/gtfs/gtfs_parser.cc deleted file mode 100644 index 88c15aacd..000000000 --- a/base/loader/src/gtfs/gtfs_parser.cc +++ /dev/null @@ -1,555 +0,0 @@ -// clang-tidy crashes while processing this file -// NOLINTBEGIN(bugprone-unchecked-optional-access) - -#include "motis/loader/gtfs/gtfs_parser.h" - -#include -#include -#include - -#include "boost/algorithm/string.hpp" -#include "boost/date_time/posix_time/posix_time.hpp" - -#include "utl/erase_if.h" -#include "utl/get_or_create.h" -#include "utl/pairwise.h" -#include "utl/parallel_for.h" -#include "utl/parser/cstr.h" -#include "utl/pipes/accumulate.h" -#include "utl/pipes/all.h" -#include "utl/pipes/remove_if.h" -#include "utl/pipes/transform.h" -#include "utl/pipes/vec.h" -#include "utl/progress_tracker.h" - -#include "cista/hash.h" -#include "cista/mmap.h" - -#include "geo/latlng.h" -#include "geo/point_rtree.h" - -#include "motis/core/common/constants.h" -#include "motis/core/common/date_time_util.h" -#include "motis/core/common/logging.h" -#include "motis/core/schedule/time.h" -#include "motis/loader/gtfs/agency.h" -#include "motis/loader/gtfs/calendar.h" -#include "motis/loader/gtfs/calendar_date.h" -#include "motis/loader/gtfs/feed_info.h" -#include "motis/loader/gtfs/files.h" -#include "motis/loader/gtfs/route.h" -#include "motis/loader/gtfs/services.h" -#include "motis/loader/gtfs/stop.h" -#include "motis/loader/gtfs/stop_time.h" -#include "motis/loader/gtfs/transfers.h" -#include "motis/loader/gtfs/trip.h" -#include "motis/loader/util.h" -#include "motis/schedule-format/Schedule_generated.h" - -namespace fbs64 = flatbuffers64; -namespace fs = std::filesystem; -using namespace motis::logging; -using std::get; - -namespace motis::loader::gtfs { - -auto const required_files = {AGENCY_FILE, STOPS_FILE, ROUTES_FILE, TRIPS_FILE, - STOP_TIMES_FILE}; - -cista::hash_t hash(fs::path const& path) { - auto hash = cista::BASE_HASH; - auto const hash_file = [&](fs::path const& p) { - if (!fs::is_regular_file(p)) { - return; - } - cista::mmap m{p.generic_string().c_str(), cista::mmap::protection::READ}; - hash = cista::hash_combine( - cista::hash(std::string_view{ - reinterpret_cast(m.begin()), - std::min(static_cast(50 * 1024 * 1024), m.size())}), - hash); - }; - - for (auto const& file_name : required_files) { - hash_file(path / file_name); - } - hash_file(path / CALENDAR_FILE); - hash_file(path / CALENDAR_DATES_FILE); - - return hash; -} - -bool gtfs_parser::applicable(fs::path const& path) { - for (auto const& file_name : required_files) { - if (!fs::is_regular_file(path / file_name)) { - return false; - } - } - - return fs::is_regular_file(path / CALENDAR_FILE) || - fs::is_regular_file(path / CALENDAR_DATES_FILE); -} - -std::vector gtfs_parser::missing_files( - fs::path const& path) const { - std::vector files; - if (!fs::is_directory(path)) { - files.emplace_back(path.string()); - } - - std::copy_if( - begin(required_files), end(required_files), std::back_inserter(files), - [&](std::string const& f) { return !fs::is_regular_file(path / f); }); - - if (!fs::is_regular_file(path / CALENDAR_FILE) && - !fs::is_regular_file(path / CALENDAR_DATES_FILE)) { - files.emplace_back(CALENDAR_FILE); - files.emplace_back(CALENDAR_DATES_FILE); - } - - return files; -} - -std::time_t to_unix_time(date::sys_days const& date) { - return std::chrono::time_point_cast(date) - .time_since_epoch() - .count(); -} - -void fix_flixtrain_transfers(trip_map& trips, - std::map& transfers) { - for (auto const& id_prefix : {"FLIXBUS:FLX", "FLIXBUS:K"}) { - for (auto it = trips.lower_bound(id_prefix); - it != end(trips) && boost::starts_with(it->first, id_prefix); ++it) { - for (auto const& [dep_entry, arr_entry] : - utl::pairwise(it->second->stop_times_)) { - auto& dep = dep_entry.second; - auto& arr = arr_entry.second; - - if (dep.stop_ == nullptr) { - continue; // already gone - } - - auto const& dep_name = dep.stop_->name_; - auto const& arr_name = arr.stop_->name_; - if (utl::get_until(utl::cstr{dep_name}, ',') != - utl::get_until(utl::cstr{arr_name}, ',')) { - continue; // different towns - } - - // normal case: bus stop after train stop - auto const arr_duplicate = - static_cast(boost::ifind_first(dep_name, "train")) && - !static_cast(boost::ifind_first(arr_name, "train")) && - dep.dep_.time_ == arr.arr_.time_ && - arr.arr_.time_ == arr.dep_.time_; - - // may happen on last stop: train stop after bus_stop - auto const dep_duplicate = - !static_cast(boost::ifind_first(dep_name, "train")) && - static_cast(boost::ifind_first(arr_name, "train")) && - dep.dep_.time_ == arr.arr_.time_ && - dep.arr_.time_ == dep.dep_.time_; - - if (arr_duplicate || dep_duplicate) { - auto dur = static_cast( - geo::distance(dep.stop_->coord_, arr.stop_->coord_) / WALK_SPEED / - 60); - transfers.insert( - {{dep.stop_, arr.stop_}, {dur, transfer::GENERATED}}); - transfers.insert( - {{arr.stop_, dep.stop_}, {dur, transfer::GENERATED}}); - } - - if (arr_duplicate) { - arr.stop_ = nullptr; - } - if (dep_duplicate) { - dep.stop_ = nullptr; - } - } - - utl::erase_if(it->second->stop_times_, - [](auto const& s) { return s.second.stop_ == nullptr; }); - } - } -} - -void gtfs_parser::parse(parser_options const& opt, fs::path const& root, - fbs64::FlatBufferBuilder& fbb) { - motis::logging::scoped_timer const global_timer{"gtfs parser"}; - - auto const load = [&](char const* file) { - return fs::is_regular_file(root / file) ? loaded_file{root / file} - : loaded_file{}; - }; - auto const feeds = read_feed_publisher(load(FEED_INFO_FILE)); - auto const agencies = read_agencies(load(AGENCY_FILE)); - auto const stops = read_stops(load(STOPS_FILE)); - auto const routes = read_routes(load(ROUTES_FILE), agencies); - auto const calendar = read_calendar(load(CALENDAR_FILE)); - auto const dates = read_calendar_date(load(CALENDAR_DATES_FILE)); - auto const service = merge_traffic_days(calendar, dates); - auto transfers = read_transfers(load(TRANSFERS_FILE), stops); - auto [trips, blocks] = read_trips(load(TRIPS_FILE), routes, service); - read_frequencies(load(FREQUENCIES_FILE), trips); - read_stop_times(load(STOP_TIMES_FILE), trips, stops); - fix_flixtrain_transfers(trips, transfers); - for (auto& [_, trip] : trips) { - trip->interpolate(); - } - - LOG(logging::info) << "read " << trips.size() << " trips, " << routes.size() - << " routes"; - - std::map> fbs_categories; - std::map> fbs_providers; - std::map> fbs_strings; - std::map> fbs_stations; - std::map> fbs_routes; - std::map>> - fbs_seq_numbers; - std::vector> const fbs_services; - - auto get_or_create_stop = [&](stop const* s) { - return utl::get_or_create(fbs_stations, s, [&]() { - return CreateStation( - fbb, fbb.CreateString(s->id_), fbb.CreateString(s->name_), - s->coord_.lat_, s->coord_.lng_, 2, - fbb.CreateVector(std::vector>()), 0, - s->timezone_.empty() ? 0 : fbb.CreateString(s->timezone_)); - }); - }; - - auto get_or_create_category = [&](trip const* t) { - auto const* r = t->route_; - if (auto cat = r->get_category(); cat.has_value()) { - auto const create = [&]() { - return utl::get_or_create(fbs_categories, *cat, [&]() { - return CreateCategory(fbb, fbb.CreateString(cat->name_), - cat->output_rule_ & category::output::BASE); - }); - }; - - if (cat->name_ == "DPN") { - if (t->avg_speed() > 100) { - cat->name_ = "High Speed Rail"; - return create(); - } else if (t->distance() > 400) { - cat->name_ = "Long Distance Trains"; - return create(); - } - } else if (cat->name_ == "Bus" && t->distance() > 100) { - cat->output_rule_ = - category::output::FORCE_PROVIDER_INSTEAD_OF_CATEGORY; - cat->name_ = "Coach"; - return create(); - } - - if ((cat->output_rule_ & - category::output::ROUTE_NAME_SHORT_INSTEAD_OF_CATEGORY) == - category::output::ROUTE_NAME_SHORT_INSTEAD_OF_CATEGORY) { - auto const is_number = - std::all_of(begin(r->short_name_), end(r->short_name_), - [](auto c) { return std::isdigit(c); }); - cat->name_ = is_number ? cat->name_ : r->short_name_; - } - return create(); - } else { - auto desc = r->desc_; - static auto const short_tags = - std::map{{"RegioExpress", "RE"}, - {"Regionalzug", "RZ"}, - {"InterRegio", "IR"}, - {"Intercity", "IC"}}; - if (auto it = short_tags.find(desc); it != end(short_tags)) { - desc = it->second; - } - return utl::get_or_create(fbs_categories, category{desc, 0}, [&]() { - return CreateCategory(fbb, fbb.CreateString(desc), 0); - }); - } - }; - - auto get_or_create_provider = [&](agency const* a) { - return utl::get_or_create(fbs_providers, a, [&]() { - if (a == nullptr) { - auto const name = fbb.CreateString("UNKNOWN_AGENCY"); - return CreateProvider(fbb, name, name, name, 0); - } - - auto const name = fbb.CreateString(a->name_); - return CreateProvider( - fbb, fbb.CreateString(a->id_), name, name, - a->timezone_.empty() ? 0 : fbb.CreateString(a->timezone_)); - }); - }; - - auto get_or_create_str = [&](std::string const& s) { - return utl::get_or_create(fbs_strings, s, - [&]() { return fbb.CreateString(s); }); - }; - - auto get_or_create_direction = [&](trip const* t) { - if (!t->headsign_.empty()) { - return get_or_create_str(t->headsign_); - } else { - return get_or_create_str(t->stops().back().stop_->name_); - } - }; - - motis::logging::scoped_timer const export_timer{"export"}; - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->status("Export schedule.raw") - .out_bounds(60.F, 100.F) - .in_high(trips.size()); - auto const interval = Interval{to_unix_time(service.first_day_), - to_unix_time(service.last_day_)}; - - auto n_services = 0U; - auto const trips_file = - fbb.CreateString((root / STOP_TIMES_FILE).generic_string()); - auto const create_service = - [&](trip* t, bitfield const& traffic_days, - bool const is_rule_service_participant, - ScheduleRelationship const schedule_relationship) { - auto const is_train_number = [](auto const& s) { - return !s.empty() && - std::all_of(begin(s), end(s), - [](auto&& c) -> bool { return std::isdigit(c); }); - }; - - auto const day_offset = t->stop_times_.front().dep_.time_ / 1440; - auto const adjusted_traffic_days = traffic_days << day_offset; - - int train_nr = 0; - if (is_train_number(t->short_name_)) { - train_nr = std::stoi(t->short_name_); - } else if (is_train_number(t->headsign_)) { - train_nr = std::stoi(t->headsign_); - } - - ++n_services; - auto const stop_seq = t->stops(); - return CreateService( - fbb, - utl::get_or_create( - fbs_routes, stop_seq, - [&]() { - return CreateRoute( - fbb, // - fbb.CreateVector( - utl::to_vec(stop_seq, - [&](trip::stop_identity const& s) { - return get_or_create_stop(s.stop_); - })), - fbb.CreateVector(utl::to_vec( - stop_seq, - [](trip::stop_identity const& s) { - return static_cast(s.in_allowed_ ? 1U - : 0U); - })), - fbb.CreateVector(utl::to_vec( - stop_seq, [](trip::stop_identity const& s) { - return static_cast(s.out_allowed_ ? 1U - : 0U); - }))); - }), - fbb.CreateString(serialize_bitset(adjusted_traffic_days)), - fbb.CreateVector(repeat_n( - CreateSection( - fbb, get_or_create_category(t), - get_or_create_provider(t->route_->agency_), train_nr, - get_or_create_str(t->route_->short_name_), - fbb.CreateVector(std::vector>()), - CreateDirection(fbb, 0, get_or_create_direction(t))), - stop_seq.size() - 1)), - 0 /* tracks currently not extracted */, - fbb.CreateVector(utl::all(t->stop_times_) // - | utl::accumulate( - [&](std::vector&& times, - flat_map::entry_t const& st) { - times.emplace_back(st.second.arr_.time_ - - day_offset * 1440); - times.emplace_back(st.second.dep_.time_ - - day_offset * 1440); - return std::move(times); - }, - std::vector())), - 0 /* route key obsolete */, - CreateServiceDebugInfo(fbb, trips_file, t->from_line_, t->to_line_), - is_rule_service_participant, 0 /* initial train number */, - get_or_create_str(t->id_), - utl::get_or_create( - fbs_seq_numbers, t->seq_numbers(), - [&]() { return fbb.CreateVector(t->seq_numbers()); }), - schedule_relationship); - }; - - auto output_services = - utl::all(trips) // - | utl::remove_if([&](auto const& entry) { - progress_tracker->increment(); - auto const stop_count = entry.second->stops().size(); - if (stop_count < 2) { - LOG(warn) << "invalid trip " << entry.first << ": " - << entry.second->stops().size() << " stops"; - } - return stop_count < 2; - }) // - | utl::remove_if([&](auto const& entry) { - // Frequency services are written separately. - return entry.second->frequency_.has_value(); - }) // - | utl::transform([&](auto const& entry) { - auto const t = entry.second.get(); - return create_service( - entry.second.get(), *t->service_, - t->block_ != nullptr && t->block_->trips_.size() >= 2, - ScheduleRelationship_SCHEDULED); // - }) // - | utl::vec(); - - for (auto const& [id, t] : trips) { - if (t->frequency_.has_value()) { - t->expand_frequencies( - [&](trip& x, ScheduleRelationship const schedule_relationship) { - output_services.emplace_back( - create_service(&x, *x.service_, false, schedule_relationship)); - }); - } - } - - std::vector> rule_services; - for (auto const& blk : blocks) { - for (auto const& [trips, traffic_days] : blk.second->rule_services()) { - auto const td = traffic_days; - - if (trips.size() == 1) { - output_services.emplace_back( - create_service(trips.front(), traffic_days, false, - ScheduleRelationship_SCHEDULED)); - continue; - } - - std::vector> rules; - std::map> services; - for (auto const& p : utl::pairwise(trips)) { - auto const& a = get<0>(p); - auto const& b = get<1>(p); - auto const transition_stop = - get_or_create_stop(a->stop_times_.back().stop_); - auto const base_offset_a = a->stop_times_.front().dep_.time_ / 1440; - rules.emplace_back(CreateRule( - fbb, RuleType_THROUGH, - utl::get_or_create(services, a, - [&] { - return create_service( - a, td, true, - ScheduleRelationship_SCHEDULED); - }), - utl::get_or_create(services, b, - [&] { - return create_service( - b, td, true, - ScheduleRelationship_SCHEDULED); - }), - transition_stop, transition_stop, - (a->stop_times_.back().arr_.time_ / 1440) - base_offset_a, 0, - ((a->stop_times_.back().arr_.time_ / 1440) != - (b->stop_times_.front().dep_.time_ / 1440)))); - } - rule_services.emplace_back( - CreateRuleService(fbb, fbb.CreateVector(rules))); - } - } - - auto const dataset_name = - std::accumulate(begin(feeds), end(feeds), std::string("GTFS"), - [&](std::string const& v, - std::pair const& feed_pair) { - return v + " - " + feed_pair.second.publisher_name_ + - " (" + feed_pair.second.version_ + ")"; - }); - - std::vector> - missing_symmetry_transfers; - for (auto const& [p, t] : transfers) { - auto const& [from, to] = p; - auto const inverse_it = transfers.find({to, from}); - if (inverse_it == end(transfers)) { - l(logging::warn, "adding symmetric transfer: {}({}) -> {}({}): {} min", - to->name_, to->id_, from->name_, from->id_, t.minutes_); - missing_symmetry_transfers.emplace_back(to, from, t); - } - } - for (auto const& [from, to, t] : missing_symmetry_transfers) { - transfers.emplace(stop_pair{from, to}, t); - } - - auto footpaths = - utl::all(transfers) // - | utl::remove_if([](std::pair&& t) { - return t.second.type_ == transfer::NOT_POSSIBLE || - t.first.first == t.first.second; - }) // - | utl::transform([&](std::pair&& t) { - return CreateFootpath(fbb, get_or_create_stop(t.first.first), - get_or_create_stop(t.first.second), - t.second.minutes_); - }) // - | utl::vec(); - - auto const stop_vec = - utl::to_vec(stops, [](auto const& s) { return s.second.get(); }); - auto const stop_rtree = - geo::make_point_rtree(stop_vec, [](auto const& s) { return s->coord_; }); - auto const generate_transfer = [&](stop_pair const& stops) { - if (stops.first != stops.second && - transfers.find(stops) == end(transfers)) { - footpaths.emplace_back( - CreateFootpath(fbb, get_or_create_stop(stops.first), - get_or_create_stop(stops.second), 2)); - transfers.emplace(stops, transfer{2, transfer::GENERATED}); - } - }; - - if (opt.link_stop_distance_ != 0U) { - utl::parallel_for(stops, [&](auto const& s) { - s.second->compute_close_stations(stop_rtree, opt.link_stop_distance_); - }); - } - - auto const meta_stations = - utl::all(stops) // - | utl::transform([&](auto const& s) { - return std::make_pair(s.second.get(), s.second->get_metas(stop_vec)); - }) // - | utl::remove_if([](auto const& s) { return s.second.empty(); }) // - | - utl::transform([&](auto const& s_metas) { - auto const& [this_stop, metas] = s_metas; - return CreateMetaStation(fbb, get_or_create_stop(this_stop), - fbb.CreateVector(utl::to_vec( - metas, [&, s = this_stop](auto const* eq) { - generate_transfer(std::make_pair(s, eq)); - generate_transfer(std::make_pair(eq, s)); - return get_or_create_stop(eq); - }))); - }) // - | utl::vec(); - - fbb.Finish(CreateSchedule(fbb, fbb.CreateVector(output_services), - fbb.CreateVector(values(fbs_stations)), - fbb.CreateVector(values(fbs_routes)), &interval, - fbb.CreateVector(footpaths), - fbb.CreateVector(rule_services), - fbb.CreateVector(meta_stations), - fbb.CreateString(dataset_name), hash(root))); - - LOG(logging::info) << "wrote " << n_services << " services"; -} - -} // namespace motis::loader::gtfs - -// NOLINTEND(bugprone-unchecked-optional-access) diff --git a/base/loader/src/gtfs/parse_time.cc b/base/loader/src/gtfs/parse_time.cc deleted file mode 100644 index 7a6ae554f..000000000 --- a/base/loader/src/gtfs/parse_time.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include "motis/loader/gtfs/parse_time.h" - -#include "utl/parser/arg_parser.h" - -using namespace utl; - -namespace motis::loader::gtfs { - -int hhmm_to_min(cstr s) { - if (s.empty()) { - return kInterpolate; - } else { - int hours = 0; - parse_arg(s, hours, 0); - if (s) { - ++s; - } else { - return -1; - } - - int minutes = 0; - parse_arg(s, minutes, 0); - - return hours * 60 + minutes; - } -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/route.cc b/base/loader/src/gtfs/route.cc deleted file mode 100644 index 6cb44f299..000000000 --- a/base/loader/src/gtfs/route.cc +++ /dev/null @@ -1,223 +0,0 @@ -#include "motis/loader/gtfs/route.h" - -#include -#include - -#include "utl/enumerate.h" -#include "utl/parser/csv.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/classes.h" -#include "motis/loader/util.h" - -using namespace utl; -using std::get; - -namespace motis::loader::gtfs { - -// Source: https://groups.google.com/d/msg/gtfs-changes/keT5rTPS7Y0/71uMz2l6ke0J -std::map const route::s_types = - std::map{ - {0, category{"Tram"}}, - {1, category{"U"}}, - {2, category{"DPN"}}, - {3, category{"Bus"}}, - {4, category{"Ferry"}}, - {5, category{"Str"}}, - {6, category{"Gondola, Suspended cable car"}}, - {7, category{"Funicular"}}, - {11, category{"Trolleybus"}}, - {100, category{"Railway Service"}}, - {101, category{/* "Long Distance Trains" hack for DELFI */ "ICE"}}, - {102, category{/* "Long Distance Trains" hack for DELFI */ "IC"}}, - {103, category{"Inter Regional Rail"}}, - {104, category{"Car Transport Rail"}}, - {105, category{"Sleeper Rail"}}, - {106, category{"Regional Rail"}}, - {107, category{"Tourist Railway"}}, - {108, category{"Rail Shuttle (Within Complex)"}}, - {109, category{"S"}}, - {110, category{"Replacement Rail"}}, - {111, category{"Special Rail"}}, - {112, category{"Lorry Transport Rail"}}, - {113, category{"All Rails"}}, - {114, category{"Cross-Country Rail"}}, - {115, category{"Vehicle Transport Rail"}}, - {116, category{"Rack and Pinion Railway"}}, - {117, category{"Additional Rail"}}, - {200, category{"Coach"}}, - {201, category{"International Coach"}}, - {202, category{"National Coach"}}, - {203, category{"Shuttle Coach"}}, - {204, category{"Regional Coach"}}, - {205, category{"Special Coach"}}, - {206, category{"Sightseeing Coach"}}, - {207, category{"Tourist Coach"}}, - {208, category{"Commuter Coach"}}, - {209, category{"All Coachs"}}, - {300, category{"S"}}, - {400, category{"U"}}, - {401, category{"U"}}, - {402, category{"U"}}, - {403, category{"U"}}, - {404, category{"U"}}, - {500, category{"Metro"}}, - {600, category{"U"}}, - {700, category{"Bus"}}, - {701, category{"Bus"}}, - {702, category{"Bus"}}, - {703, category{"Bus"}}, - {704, category{"Bus"}}, - {705, category{"Bus"}}, - {706, category{"Bus"}}, - {707, category{"Bus"}}, - {708, category{"Bus"}}, - {709, category{"Bus"}}, - {710, category{"Bus"}}, - {711, category{"Bus"}}, - {712, category{"Bus"}}, - {713, category{"Bus"}}, - {714, category{"Bus"}}, - {715, category{"Bus"}}, - {716, category{"Bus"}}, - {800, category{"Bus"}}, - {900, category{"Str"}}, - {901, category{"Str"}}, - {902, category{"Str"}}, - {903, category{"Str"}}, - {904, category{"Str"}}, - {905, category{"Str"}}, - {906, category{"Str"}}, - {1000, category{"Water Transport"}}, - {1001, category{"International Car Ferry"}}, - {1002, category{"National Car Ferry"}}, - {1003, category{"Regional Car Ferry"}}, - {1004, category{"Local Car Ferry"}}, - {1005, category{"International Passenger Ferry"}}, - {1006, category{"National Passenger Ferry"}}, - {1007, category{"Regional Passenger Ferry"}}, - {1008, category{"Local Passenger Ferry"}}, - {1009, category{"Post Boat"}}, - {1010, category{"Train Ferry"}}, - {1011, category{"Road-Link Ferry"}}, - {1012, category{"Airport-Link Ferry"}}, - {1013, category{"Car High-Speed Ferry"}}, - {1014, category{"Passenger High-Speed Ferry"}}, - {1015, category{"Sightseeing Boat"}}, - {1016, category{"School Boat"}}, - {1017, category{"Cable-Drawn Boat"}}, - {1018, category{"River Bus"}}, - {1019, category{"Scheduled Ferry"}}, - {1020, category{"Shuttle Ferry"}}, - {1021, category{"All Water Transports"}}, - {1100, category{"Air"}}, - {1101, category{"International Air"}}, - {1102, category{"Domestic Air"}}, - {1103, category{"Intercontinental Air"}}, - {1104, category{"Domestic Scheduled Air"}}, - {1105, category{"Shuttle Air"}}, - {1106, category{"Intercontinental Charter Air"}}, - {1107, category{"International Charter Air"}}, - {1108, category{"Round-Trip Charter Air"}}, - {1109, category{"Sightseeing Air"}}, - {1110, category{"Helicopter Air"}}, - {1111, category{"Domestic Charter Air"}}, - {1112, category{"Schengen-Area Air"}}, - {1113, category{"Airship"}}, - {1114, category{"All Airs"}}, - {1200, category{"Ferry", 0}}, - {1300, category{"Telecabin"}}, - {1301, category{"Telecabin"}}, - {1302, category{"Cable Car"}}, - {1303, category{"Elevator"}}, - {1304, category{"Chair Lift"}}, - {1305, category{"Drag Lift"}}, - {1306, category{"Small Telecabin"}}, - {1307, category{"All Telecabins"}}, - {1400, category{"Funicular"}}, - {1401, category{"Funicular"}}, - {1402, category{"All Funicular"}}, - {1500, category{"Taxi"}}, - {1501, category{"Communal Taxi"}}, - {1502, category{"Water Taxi"}}, - {1503, category{"Rail Taxi"}}, - {1504, category{"Bike Taxi"}}, - {1505, category{"Licensed Taxi"}}, - {1506, category{"Private Hire Vehicle"}}, - {1507, category{"All Taxis"}}, - {1600, category{"Self Drive"}}, - {1601, category{"Hire Car"}}, - {1602, category{"Hire Van"}}, - {1603, category{"Hire Motorbike"}}, - {1604, category{"Hire Cycle"}}, - {1605, category{"All Self-Drive Vehicles"}}, - {1700, category{"Car train"}}}; - -std::map const route::s_clasz = - std::map{ - {service_class::AIR, 1100}, {service_class::ICE, 101}, - {service_class::IC, 102}, {service_class::COACH, 200}, - {service_class::N, 105}, {service_class::RE, 103}, - {service_class::RB, 106}, {service_class::S, 500}, - {service_class::U, 600}, {service_class::STR, 5}, - {service_class::BUS, 3}, {service_class::SHIP, 1200}, - {service_class::OTHER, 7}}; - -std::optional route::get_category() const { - if (auto const it = s_types.find(type_); it != end(s_types)) { - return it->second; - } else { - return std::nullopt; - } -} - -using gtfs_route = std::tuple; -enum { - route_id, - agency_id, - route_short_name, - route_long_name, - route_desc, - route_type -}; -static const column_mapping columns = { - {"route_id", "agency_id", "route_short_name", "route_long_name", - "route_desc", "route_type"}}; - -route_map read_routes(loaded_file file, agency_map const& agencies) { - motis::logging::scoped_timer const timer{"read routes"}; - - auto const get_type = [](cstr s) { - if (!s.empty() && std::isdigit(s[0]) != 0) { - return utl::parse(s); - } else { - auto const& classes = class_mapping(); - if (auto it = classes.find(s.view()); it != end(classes)) { - return route::s_clasz.at(it->second); - } else { - return route::s_clasz.at(service_class::OTHER); - } - } - }; - - route_map routes; - auto const entries = read(file.content(), columns); - for (auto const& [i, r] : utl::enumerate(entries)) { - auto const agency_it = agencies.find(get(r).to_str()); - auto const agency_ptr = - agency_it == end(agencies) ? nullptr : agency_it->second.get(); - if (agency_ptr == nullptr) { - LOG(logging::warn) << "agency \"" << get(r).view() - << "\" not found (line=" << i << ")"; - } - routes.emplace( - get(r).to_str(), - std::make_unique( - agency_ptr, get(r).to_str(), - get(r).to_str(), get(r).to_str(), - get(r).to_str(), get_type(get(r)))); - } - return routes; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/services.cc b/base/loader/src/gtfs/services.cc deleted file mode 100644 index e2f042556..000000000 --- a/base/loader/src/gtfs/services.cc +++ /dev/null @@ -1,134 +0,0 @@ -#include "motis/loader/gtfs/services.h" - -#include "utl/get_or_create.h" - -#include "motis/core/common/logging.h" - -namespace motis::loader::gtfs { - -enum class bound { first, last }; - -date::sys_days bound_date( - std::map const& base, - std::map> const& exceptions, - bound const b) { - constexpr auto const kMin = date::sys_days::max(); - constexpr auto const kMax = date::sys_days::min(); - - auto const min_base_day = [&]() { - auto const it = - std::min_element(begin(base), end(base), - [](std::pair const& lhs, - std::pair const& rhs) { - return lhs.second.first_day_ < rhs.second.first_day_; - }); - return it == end(base) ? std::pair{"", kMin} - : std::pair{it->first, it->second.first_day_}; - }; - - auto const max_base_day = [&]() { - auto const it = - std::max_element(begin(base), end(base), - [](std::pair const& lhs, - std::pair const& rhs) { - return lhs.second.last_day_ < rhs.second.last_day_; - }); - return it == end(base) ? std::pair{"", kMax} - : std::pair{it->first, it->second.last_day_}; - }; - - switch (b) { - case bound::first: { - auto [min_id, min] = min_base_day(); - for (auto const& [id, dates] : exceptions) { - for (auto const& date : dates) { - if (date.type_ == calendar_date::ADD && date.day_ < min) { - min = date.day_; - min_id = id; - } - } - } - - LOG(logging::info) << "first date " << date::format("%T", min) - << " from service " << min_id; - - return min; - } - case bound::last: { - auto [max_id, max] = max_base_day(); - for (auto const& [id, dates] : exceptions) { - for (auto const& date : dates) { - if (date.type_ == calendar_date::ADD && date.day_ > max) { - max = date.day_; - max_id = id; - } - } - } - - LOG(logging::info) << "last date " << date::format("%T", max) - << " from service " << max_id; - - return max; - } - } - - assert(false); - throw std::runtime_error{"unreachable"}; -} - -bitfield calendar_to_bitfield(std::string const& service_name, - date::sys_days const& start, calendar const& c) { - bitfield traffic_days; - auto bit = (c.first_day_ - start).count(); - for (auto d = c.first_day_; d != c.last_day_ + date::days(1); - d += date::days(1), ++bit) { - if (bit >= traffic_days.size()) { - LOG(logging::error) << "date " << date::format("%T", d) << " for service " - << service_name << " out of range\n"; - continue; - } - auto const weekday_index = - date::year_month_weekday{d}.weekday().c_encoding(); - traffic_days.set(bit, c.week_days_.test(weekday_index)); - } - return traffic_days; -} - -void add_exception(std::string const& service_name, date::sys_days const& start, - calendar_date const& exception, bitfield& b) { - auto const day_idx = (exception.day_ - start).count(); - if (day_idx < 0 || day_idx >= static_cast(b.size())) { - LOG(logging::error) << "date " << date::format("%T", exception.day_) - << " for service " << service_name << " out of range\n"; - return; - } - b.set(day_idx, exception.type_ == calendar_date::ADD); -} - -traffic_days merge_traffic_days( - std::map const& base, - std::map> const& exceptions) { - motis::logging::scoped_timer const timer{"traffic days"}; - - traffic_days s; - s.first_day_ = bound_date(base, exceptions, bound::first); - s.last_day_ = bound_date(base, exceptions, bound::last); - - for (auto const& [service_name, calendar] : base) { - s.traffic_days_[service_name] = std::make_unique( - calendar_to_bitfield(service_name, s.first_day_, calendar)); - } - - for (auto const& [service_name, service_exceptions] : exceptions) { - for (auto const& day : service_exceptions) { - add_exception(service_name, s.first_day_, day, - *utl::get_or_create(s.traffic_days_, service_name, []() { - return std::make_unique(); - })); - } - } - - return s; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/stop.cc b/base/loader/src/gtfs/stop.cc deleted file mode 100755 index 0eccf7aa8..000000000 --- a/base/loader/src/gtfs/stop.cc +++ /dev/null @@ -1,127 +0,0 @@ -#include "motis/loader/gtfs/stop.h" - -#include -#include -#include - -#include "utl/get_or_create.h" -#include "utl/parser/csv.h" - -#include "motis/core/common/logging.h" -#include "motis/hash_map.h" -#include "utl/to_vec.h" - -using namespace utl; -using std::get; - -namespace motis::loader::gtfs { - -enum { stop_id, stop_name, stop_timezone, parent_station, stop_lat, stop_lon }; -using gtfs_stop = std::tuple; -static const column_mapping columns = { - {"stop_id", "stop_name", "stop_timezone", "parent_station", "stop_lat", - "stop_lon"}}; - -void stop::compute_close_stations(geo::point_rtree const& stop_rtree, - unsigned const max_meters) { - if (std::abs(coord_.lat_) < 2.0 && std::abs(coord_.lng_) < 2.0) { - return; - } - close_ = - utl::to_vec(stop_rtree.in_radius(coord_, max_meters), - [](size_t const idx) { return static_cast(idx); }); -} - -std::set stop::get_metas(std::vector const& stops) { - std::set todo, done; - todo.emplace(this); - todo.insert(begin(same_name_), end(same_name_)); - for (auto const& idx : close_) { - todo.insert(stops[idx]); - } - - while (!todo.empty()) { - auto const next = *todo.begin(); - todo.erase(todo.begin()); - done.emplace(next); - - for (auto const& p : next->parents_) { - if (done.find(p) == end(done)) { - todo.emplace(p); - } - } - - for (auto const& p : next->children_) { - if (done.find(p) == end(done)) { - todo.emplace(p); - } - } - } - - for (auto it = begin(done); it != end(done);) { - auto* meta = *it; - auto const is_parent = parents_.find(meta) != end(parents_); - auto const is_child = children_.find(meta) != end(children_); - auto const distance_in_m = geo::distance(meta->coord_, coord_); - if ((distance_in_m > 500 && !is_parent && !is_child) || - distance_in_m > 2000) { - it = done.erase(it); - } else { - ++it; - } - } - - std::set children; - for (auto const& d : done) { - for (auto const& c : d->children_) { - children.emplace(c); - } - } - - done.insert(begin(children), end(children)); - - return done; -} - -stop_map read_stops(loaded_file file) { - motis::logging::scoped_timer const timer{"read stops"}; - - stop_map stops; - mcd::hash_map> equal_names; - for (auto const& s : read(file.content(), columns)) { - auto const new_stop = - utl::get_or_create(stops, get(s).to_str(), [&]() { - return std::make_unique(); - }).get(); - - new_stop->id_ = get(s).to_str(); - new_stop->name_ = get(s).to_str(); - new_stop->coord_ = {parse(get(s).trim()), - parse(get(s).trim())}; - new_stop->timezone_ = get(s).to_str(); - - if (!get(s).trim().empty()) { - auto const parent = - utl::get_or_create(stops, get(s).trim().to_str(), - []() { return std::make_unique(); }) - .get(); - parent->id_ = get(s).trim().to_str(); - parent->children_.emplace(new_stop); - new_stop->parents_.emplace(parent); - } - - equal_names[get(s).view()].emplace_back(new_stop); - } - - for (auto const& [id, s] : stops) { - for (auto const& equal : equal_names[s->name_]) { - if (equal != s.get()) { - s->same_name_.emplace(equal); - } - } - } - - return stops; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/stop_time.cc b/base/loader/src/gtfs/stop_time.cc deleted file mode 100644 index 3d2d58609..000000000 --- a/base/loader/src/gtfs/stop_time.cc +++ /dev/null @@ -1,90 +0,0 @@ -#include "motis/loader/gtfs/stop_time.h" - -#include -#include - -#include "utl/enumerate.h" -#include "utl/parser/arg_parser.h" -#include "utl/parser/csv.h" -#include "utl/progress_tracker.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/gtfs/parse_time.h" -#include "motis/loader/util.h" - -using std::get; -using namespace utl; - -namespace motis::loader::gtfs { - -using gtfs_stop_time = std::tuple; -enum { - trip_id, - arrival_time, - departure_time, - stop_id, - stop_sequence, - stop_headsign, - pickup_type, - drop_off_type -}; - -static const column_mapping stop_time_columns = { - {"trip_id", "arrival_time", "departure_time", "stop_id", "stop_sequence", - "stop_headsign", "pickup_type", "drop_off_type"}}; - -void read_stop_times(loaded_file const& file, trip_map& trips, - stop_map const& stops) { - motis::logging::scoped_timer const timer{"read stop times"}; - std::string last_trip_id; - trip* last_trip = nullptr; - - auto const entries = read(file.content(), stop_time_columns); - - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->status("Parse Stop Times") - .out_bounds(25.F, 60.F) - .in_high(entries.size()); - for (auto const& [i, s] : utl::enumerate(entries)) { - progress_tracker->update(i); - - trip* t = nullptr; - auto t_id = get(s).to_str(); - if (last_trip != nullptr && t_id == last_trip_id) { - t = last_trip; - } else { - if (last_trip != nullptr) { - last_trip->to_line_ = i + 1; - } - - auto const trip_it = trips.find(t_id); - if (trip_it == end(trips)) { - LOG(logging::error) << "trip \"" << t_id << "\" in " << file.name() - << ":" << i << " not found"; - continue; - } - t = trip_it->second.get(); - last_trip_id = t_id; - last_trip = t; - - t->from_line_ = i + 2; - } - - try { - t->stop_times_.emplace( - get(s), stops.at(get(s).to_str()).get(), - get(s).to_str(), // - hhmm_to_min(get(s)), get(s) != 1, - hhmm_to_min(get(s)), get(s) != 1); - } catch (...) { - LOG(logging::warn) << "unknown stop " << get(s).to_str() - << " at " << file.name() << ":" << i; - } - } - - if (last_trip != nullptr) { - last_trip->to_line_ = entries.size() + 1; - } -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/transfers.cc b/base/loader/src/gtfs/transfers.cc deleted file mode 100644 index 654c6034e..000000000 --- a/base/loader/src/gtfs/transfers.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include "motis/loader/gtfs/transfers.h" - -#include -#include - -#include "utl/enumerate.h" -#include "utl/parser/csv.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace flatbuffers64; -using std::get; - -namespace motis::loader::gtfs { - -enum { from_stop_id, to_stop_id, transfer_type, min_transfer_time }; - -using gtfs_transfer = std::tuple; -static const column_mapping columns = { - {"from_stop_id", "to_stop_id", "transfer_type", "min_transfer_time"}}; - -std::map read_transfers(loaded_file f, - stop_map const& stops) { - motis::logging::scoped_timer const timer{"read transfers"}; - std::map transfers; - - if (f.empty()) { - return transfers; - } - - for (auto const& [i, t] : - utl::enumerate(read(f.content(), columns))) { - try { - if (get(t).to_str() != get(t).to_str()) { - transfers.insert(std::make_pair( - std::pair{stops.at(get(t).to_str()).get(), - stops.at(get(t).to_str()).get()}, - transfer(get(t) == transfer::MIN_TRANSFER_TIME - ? get(t) / 60 - : 0, - get(t)))); - } - } catch (std::exception const& e) { - LOG(logging::warn) << "skipping transfer (" << f.name() << ":" << i - << ") between stop pair " - << get(t).to_str() << " - " - << get(t).to_str() << ": " << e.what(); - } - } - return transfers; -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/gtfs/trip.cc b/base/loader/src/gtfs/trip.cc deleted file mode 100644 index f1cbe526c..000000000 --- a/base/loader/src/gtfs/trip.cc +++ /dev/null @@ -1,345 +0,0 @@ -#include "motis/loader/gtfs/trip.h" - -#include -#include -#include -#include - -#include "utl/enumerate.h" -#include "utl/erase_if.h" -#include "utl/get_or_create.h" -#include "utl/pairwise.h" -#include "utl/parser/csv.h" -#include "utl/pipes.h" -#include "utl/progress_tracker.h" -#include "utl/to_vec.h" -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/event_type.h" -#include "motis/core/schedule/time.h" -#include "motis/loader/util.h" - -using namespace utl; -using std::get; - -namespace motis::loader::gtfs { - -std::vector, bitfield>> block::rule_services() { - utl::verify(!trips_.empty(), "empty block not allowed"); - - utl::erase_if(trips_, [](trip const* t) { - auto const is_empty = t->stop_times_.empty(); - if (is_empty) { - LOG(logging::warn) << "trip " << t->id_ << " has no stop times"; - } - return is_empty; - }); - - std::sort(begin(trips_), end(trips_), [](trip const* a, trip const* b) { - return a->stop_times_.front().dep_.time_ < - b->stop_times_.front().dep_.time_; - }); - - struct rule_trip { - trip* trip_; - bitfield traffic_days_; - }; - auto rule_trips = utl::to_vec(trips_, [](auto&& t) { - return rule_trip{t, *t->service_}; - }); - - struct queue_entry { - std::vector::iterator current_it_; - std::vector::iterator> collected_trips_; - bitfield traffic_days_; - }; - - std::vector, bitfield>> combinations; - for (auto start_it = begin(rule_trips); start_it != end(rule_trips); - ++start_it) { - std::stack q; - q.emplace(queue_entry{start_it, {}, start_it->traffic_days_}); - while (!q.empty()) { - auto next = q.top(); - q.pop(); - - auto& [current_it, collected_trips, traffic_days] = next; - collected_trips.emplace_back(current_it); - for (auto succ_it = std::next(current_it); succ_it != end(rule_trips); - ++succ_it) { - if (current_it->trip_->stop_times_.back().stop_ != - succ_it->trip_->stop_times_.front().stop_) { - continue; // prev last stop != next first stop - } - - auto const new_intersection = traffic_days & succ_it->traffic_days_; - traffic_days &= ~succ_it->traffic_days_; - if (new_intersection.any()) { - q.emplace(queue_entry{succ_it, collected_trips, new_intersection}); - } - } - - if (traffic_days.any()) { - for (auto& rt : collected_trips) { - rt->traffic_days_ &= ~traffic_days; - } - combinations.emplace_back( - utl::to_vec(collected_trips, [](auto&& rt) { return rt->trip_; }), - traffic_days); - } - } - } - - return combinations; -} - -stop_time::stop_time() = default; - -stop_time::stop_time(stop* s, std::string headsign, int arr_time, - bool out_allowed, int dep_time, bool in_allowed) - : stop_{s}, - headsign_{std::move(headsign)}, - arr_{arr_time, out_allowed}, - dep_{dep_time, in_allowed} {} - -trip::trip(route const* route, bitfield const* service, block* blk, - std::string id, std::string headsign, std::string short_name) - : route_(route), - service_(service), - block_{blk}, - id_{std::move(id)}, - headsign_(std::move(headsign)), - short_name_(std::move(short_name)) {} - -void trip::interpolate() { - struct bound { - explicit bound(int t) : min_{t}, max_{t} {} - int interpolate(unsigned const idx) const { - auto const p = - static_cast(idx - min_idx_) / (max_idx_ - min_idx_); - return static_cast(min_ + std::round((max_ - min_) * p)); - } - int min_, max_; - int min_idx_{-1}; - int max_idx_{-1}; - }; - auto bounds = std::vector{}; - bounds.reserve(stop_times_.size()); - for (auto const& [i, x] : utl::enumerate(stop_times_)) { - bounds.emplace_back(x.second.arr_.time_); - bounds.emplace_back(x.second.dep_.time_); - } - - auto max = 0; - auto max_idx = 0U; - utl::verify(max != kInterpolate, "last arrival cannot be interpolated"); - for (auto it = bounds.rbegin(); it != bounds.rend(); ++it) { - if (it->max_ == kInterpolate) { - it->max_ = max; - it->max_idx_ = max_idx; - } else { - max = it->max_; - max_idx = static_cast(&(*it) - &bounds.front()) / 2U; - } - } - - auto min = 0; - auto min_idx = 0U; - utl::verify(min != kInterpolate, "first arrival cannot be interpolated"); - for (auto it = bounds.begin(); it != bounds.end(); ++it) { - if (it->min_ == kInterpolate) { - it->min_ = min; - it->min_idx_ = min_idx; - } else { - min = it->max_; - min_idx = static_cast(&(*it) - &bounds.front()) / 2U; - } - } - - for (auto const& [idx, entry] : utl::enumerate(stop_times_)) { - auto& [_, stop_time] = entry; - auto const& arr = bounds[2 * idx]; - auto const& dep = bounds[2 * idx + 1]; - - if (stop_time.arr_.time_ == kInterpolate) { - stop_time.arr_.time_ = arr.interpolate(idx); - } - if (stop_time.dep_.time_ == kInterpolate) { - stop_time.dep_.time_ = dep.interpolate(idx); - } - } -} - -trip::stop_seq trip::stops() const { - return utl::to_vec( - stop_times_, [](flat_map::entry_t const& e) -> stop_identity { - return {e.second.stop_, e.second.arr_.in_out_allowed_, - e.second.dep_.in_out_allowed_}; - }); -} - -trip::stop_seq_numbers trip::seq_numbers() const { - return utl::to_vec(stop_times_, - [](flat_map::entry_t const& e) -> unsigned { - return e.first; - }); -} - -int trip::avg_speed() const { - int travel_time = 0.; // minutes - double travel_distance = 0.; // meters - - for (auto const& [dep_entry, arr_entry] : utl::pairwise(stop_times_)) { - auto const& dep = dep_entry.second; - auto const& arr = arr_entry.second; - if (dep.stop_->timezone_ != arr.stop_->timezone_) { - continue; - } - if (arr.arr_.time_ < dep.dep_.time_) { - continue; - } - - travel_time += arr.arr_.time_ - dep.dep_.time_; - travel_distance += geo::distance(dep.stop_->coord_, arr.stop_->coord_); - } - - return travel_time > 0 ? (travel_distance / 1000.) / (travel_time / 60.) : 0; -} - -int trip::distance() const { - geo::box box; - for (auto const& [_, stop_time] : stop_times_) { - box.extend(stop_time.stop_->coord_); - } - return geo::distance(box.min_, box.max_) / 1000; -} - -void trip::print_stop_times(std::ostream& out, unsigned const indent) const { - for (auto const& t : stop_times_) { - for (auto i = 0U; i != indent; ++i) { - out << " "; - } - out << std::setw(60) << t.second.stop_->name_ << " [" << std::setw(5) - << t.second.stop_->id_ << "]: arr: " << format_time(t.second.arr_.time_) - << ", dep: " << format_time(t.second.dep_.time_) << "\n"; - } -} - -void trip::expand_frequencies( - std::function const& consumer) const { - utl::verify(frequency_.has_value(), "bad call to trip::expand_frequencies"); - - // NOLINTNEXTLINE(bugprone-unchecked-optional-access) - for (auto const& f : frequency_.value()) { - for (auto start = f.start_time_; start < f.end_time_; start += f.headway_) { - trip t{*this}; - - auto const delta = t.stop_times_.front().dep_.time_ - start; - for (auto& stop_time : t.stop_times_) { - stop_time.second.dep_.time_ -= delta; - stop_time.second.arr_.time_ -= delta; - } - consumer(t, f.schedule_relationship_); - } - } -} - -std::pair read_trips(loaded_file file, - route_map const& routes, - traffic_days const& services) { - enum { - route_id, - service_id, - trip_id, - trip_headsign, - trip_short_name, - block_id - }; - using gtfs_trip = std::tuple; - static const column_mapping columns = { - {"route_id", "service_id", "trip_id", "trip_headsign", "trip_short_name", - "block_id"}}; - - motis::logging::scoped_timer const timer{"read trips"}; - - std::pair ret; - auto& [trips, blocks] = ret; - auto const entries = read(file.content(), columns); - - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->status("Trips").out_bounds(5.F, 25.F).in_high( - entries.size()); - for (auto const& [i, t] : utl::enumerate(entries)) { - progress_tracker->update(i); - auto const blk = - get(t).trim().empty() - ? nullptr - : utl::get_or_create(blocks, get(t).trim().to_str(), - []() { return std::make_unique(); }) - .get(); - auto const trp = - trips - .emplace(get(t).to_str(), - std::make_unique( - routes.at(get(t).to_str()).get(), - services.traffic_days_.at(get(t).to_str()) - .get(), - blk, get(t).to_str(), - get(t).to_str(), - get(t).to_str())) - .first->second.get(); - if (blk != nullptr) { - blk->trips_.emplace_back(trp); - } - } - return ret; -} - -void read_frequencies(loaded_file file, trip_map& trips) { - if (file.empty()) { - return; - } - - enum { trip_id, start_time, end_time, headway_secs, exact_times }; - using gtfs_frequency = std::tuple; - static const column_mapping columns = { - {"trip_id", "start_time", "end_time", "headway_secs", "exact_times"}}; - - auto const entries = read(file.content(), columns); - for (auto const& [i, freq] : utl::enumerate(entries)) { - auto const t = std::get(freq).trim(); - auto const trip_it = trips.find(t.to_str()); - if (trip_it == end(trips)) { - LOG(logging::error) << "frequencies.txt:" << (i + 1) - << ": skipping frequency for non-existing trip \"" - << t.view() << "\""; - continue; - } - - auto const headway_secs_str = std::get(freq); - auto const headway_secs = parse(headway_secs_str, -1); - if (headway_secs == -1) { - LOG(logging::error) << "frequencies.txt:" << (i + 1) - << ": skipping frequency with invalid headway_sec=\"" - << headway_secs_str.view() << "\""; - continue; - } - - auto const exact = std::get(freq); - auto const schedule_relationship = exact.view() == "1" - ? ScheduleRelationship_SCHEDULED - : ScheduleRelationship_UNSCHEDULED; - - auto& frequencies = trip_it->second->frequency_; - if (!frequencies.has_value()) { - frequencies = std::vector{}; - } - frequencies->emplace_back(frequency{hhmm_to_min(std::get(freq)), - hhmm_to_min(std::get(freq)), - (headway_secs / 60), - schedule_relationship}); - } -} - -} // namespace motis::loader::gtfs diff --git a/base/loader/src/hrd/builder/attribute_builder.cc b/base/loader/src/hrd/builder/attribute_builder.cc deleted file mode 100644 index 1c1297ca5..000000000 --- a/base/loader/src/hrd/builder/attribute_builder.cc +++ /dev/null @@ -1,59 +0,0 @@ -#include "motis/loader/hrd/builder/attribute_builder.h" - -#include - -#include "utl/get_or_create.h" -#include "utl/to_vec.h" - -#include "utl/verify.h" - -#include "motis/loader/hrd/parse_config.h" - -namespace motis::loader::hrd { - -using namespace utl; -using namespace flatbuffers64; - -attribute_builder::attribute_builder( - std::map hrd_attributes) - : hrd_attributes_(std::move(hrd_attributes)) {} - -Offset>> attribute_builder::create_attributes( - std::vector const& attributes, bitfield_builder& bb, - flatbuffers64::FlatBufferBuilder& fbb) { - return fbb.CreateVector(utl::to_vec(begin(attributes), end(attributes), - [&](hrd_service::attribute const& attr) { - return get_or_create_attribute(attr, bb, - fbb); - })); -} - -Offset attribute_builder::get_or_create_attribute( - hrd_service::attribute const& attr, bitfield_builder& bb, - flatbuffers64::FlatBufferBuilder& fbb) { - auto const attr_info_key = raw_to_int(attr.code_); - auto const attr_key = std::make_pair(attr_info_key, attr.bitfield_num_); - - return utl::get_or_create(fbs_attributes_, attr_key, [&]() { - auto const attr_info = - utl::get_or_create(fbs_attribute_infos_, attr_info_key, [&]() { - auto const stamm_attributes_it = hrd_attributes_.find(attr_info_key); - utl::verify(stamm_attributes_it != end(hrd_attributes_), - "attribute with code {} not found\n", attr.code_.view()); - - auto const fbs_attribute_info = CreateAttributeInfo( - fbb, to_fbs_string(fbb, attr.code_), - to_fbs_string(fbb, stamm_attributes_it->second, ENCODING)); - - fbs_attribute_infos_[attr_info_key] = fbs_attribute_info; - return fbs_attribute_info; - }); - - auto const fbs_attribute = CreateAttribute( - fbb, attr_info, bb.get_or_create_bitfield(attr.bitfield_num_, fbb)); - fbs_attributes_[attr_key] = fbs_attribute; - return fbs_attribute; - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/bitfield_builder.cc b/base/loader/src/hrd/builder/bitfield_builder.cc deleted file mode 100644 index 956660a22..000000000 --- a/base/loader/src/hrd/builder/bitfield_builder.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "motis/loader/hrd/builder/bitfield_builder.h" - -#include "utl/get_or_create.h" -#include "utl/verify.h" - -#include "motis/loader/util.h" - -using namespace flatbuffers64; - -namespace motis::loader::hrd { - -bitfield_builder::bitfield_builder(std::map hrd_bitfields) - : hrd_bitfields_(std::move(hrd_bitfields)) { - // TODO (Felix Guendling) what happens if there is a service such traffic days - bitfield alternating_bits; - for (size_t i = 0; i < alternating_bits.size(); ++i) { - alternating_bits.set(i, (i % 2) == 0); - } -} - -Offset bitfield_builder::get_or_create_bitfield( - int bitfield_num, flatbuffers64::FlatBufferBuilder& fbb) { - auto lookup_it = fbs_bf_lookup_.find(bitfield_num); - if (lookup_it != end(fbs_bf_lookup_)) { - return lookup_it->second; - } - - auto hrd_bitfields_it = hrd_bitfields_.find(bitfield_num); - utl::verify(hrd_bitfields_it != end(hrd_bitfields_), - "bitfield with bitfield number {} not found\n", bitfield_num); - return get_or_create_bitfield(hrd_bitfields_it->second, fbb, bitfield_num); -} - -Offset bitfield_builder::get_or_create_bitfield( - bitfield const& b, flatbuffers64::FlatBufferBuilder& fbb, - int bitfield_num) { - return utl::get_or_create(fbs_bitfields_, b, [&]() { - auto const serialized = fbb.CreateString(serialize_bitset(b)); - if (bitfield_num != kNoBitfield) { - fbs_bf_lookup_.emplace(bitfield_num, serialized); - } - return serialized; - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/category_builder.cc b/base/loader/src/hrd/builder/category_builder.cc deleted file mode 100644 index 87336d1f6..000000000 --- a/base/loader/src/hrd/builder/category_builder.cc +++ /dev/null @@ -1,31 +0,0 @@ -#include "motis/loader/hrd/builder/category_builder.h" - -#include "utl/get_or_create.h" - -#include "utl/verify.h" - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace utl; -using namespace flatbuffers64; - -category_builder::category_builder(std::map hrd_categories) - : hrd_categories_(std::move(hrd_categories)) {} - -Offset category_builder::get_or_create_category( - cstr category_str, flatbuffers64::FlatBufferBuilder& fbb) { - auto const category_key = raw_to_int(category_str); - auto it = hrd_categories_.find(category_key); - utl::verify(it != end(hrd_categories_), "missing category: {}", - category_str.view()); - - return utl::get_or_create(fbs_categories_, category_key, [&]() { - return CreateCategory(fbb, to_fbs_string(fbb, it->second.name_, ENCODING), - it->second.output_rule_); - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/direction_builder.cc b/base/loader/src/hrd/builder/direction_builder.cc deleted file mode 100644 index d06e2bb5d..000000000 --- a/base/loader/src/hrd/builder/direction_builder.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "motis/loader/hrd/builder/direction_builder.h" - -#include "utl/get_or_create.h" - -#include "utl/verify.h" - -#include "motis/loader/hrd/model/hrd_service.h" -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace flatbuffers64; -using namespace utl; - -direction_builder::direction_builder( - std::map hrd_directions) - : hrd_directions_(std::move(hrd_directions)) {} - -Offset direction_builder::get_or_create_direction( - std::vector> const& directions, - station_builder& sb, flatbuffers64::FlatBufferBuilder& fbb) { - if (directions.empty()) { - return 0; - } else { - auto const direction_key = directions[0]; - return utl::get_or_create(fbs_directions_, direction_key.first, [&]() { - switch (direction_key.second) { - case hrd_service::EVA_NUMBER: { - return CreateDirection( - fbb, sb.get_or_create_station(direction_key.first, fbb)); - } - case hrd_service::DIRECTION_CODE: { - auto it = hrd_directions_.find(direction_key.first); - utl::verify(it != end(hrd_directions_), "missing direction info: {}", - direction_key.first); - return CreateDirection(fbb, 0, - to_fbs_string(fbb, it->second, ENCODING)); - } - default: assert(false); return Offset(0); - } - }); - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/footpath_builder.cc b/base/loader/src/hrd/builder/footpath_builder.cc deleted file mode 100644 index 06fec628d..000000000 --- a/base/loader/src/hrd/builder/footpath_builder.cc +++ /dev/null @@ -1,29 +0,0 @@ -#include "motis/loader/hrd/builder/footpath_builder.h" - -#include "motis/core/common/logging.h" - -namespace motis::loader::hrd { - -using namespace flatbuffers64; - -Offset>> create_footpaths( - std::set const& hrd_footpaths, - station_builder& stb, FlatBufferBuilder& fbb) { - std::vector> fbs_footpaths; - for (auto const& f : hrd_footpaths) { - try { - fbs_footpaths.push_back( - CreateFootpath(fbb, // - stb.get_or_create_station(f.from_eva_num_, fbb), - stb.get_or_create_station(f.to_eva_num_, fbb), // - f.duration_)); - } catch (std::runtime_error const&) { - LOG(logging::error) << "skipping footpath " << f.from_eva_num_ << " -> " - << f.to_eva_num_ - << ", could not resolve station(s)\n"; - } - } - return fbb.CreateVector(fbs_footpaths); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/line_builder.cc b/base/loader/src/hrd/builder/line_builder.cc deleted file mode 100644 index f27e7286d..000000000 --- a/base/loader/src/hrd/builder/line_builder.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "motis/loader/hrd/builder/line_builder.h" - -#include "utl/get_or_create.h" - -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace flatbuffers64; -using namespace utl; - -Offset line_builder::get_or_create_line( - std::vector const& lines, FlatBufferBuilder& fbb) { - if (lines.empty()) { - return 0; - } else { - return utl::get_or_create( - fbs_lines_, raw_to_int(lines[0]), - [&]() { return to_fbs_string(fbb, lines[0], "ISO-8859-1"); }); - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/meta_station_builder.cc b/base/loader/src/hrd/builder/meta_station_builder.cc deleted file mode 100644 index 69fed791a..000000000 --- a/base/loader/src/hrd/builder/meta_station_builder.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "motis/loader/hrd/builder/meta_station_builder.h" - -#include - -#include "utl/pipes/all.h" -#include "utl/pipes/remove_if.h" -#include "utl/pipes/transform.h" -#include "utl/pipes/vec.h" -#include "utl/to_vec.h" - -#include "motis/core/common/logging.h" - -using namespace motis::logging; - -namespace motis::loader::hrd { - -using namespace flatbuffers64; - -Offset>> create_meta_stations( - std::set const& hrd_meta_stations, - station_builder& sb, FlatBufferBuilder& fbb) { - using namespace utl; - return fbb.CreateVector( - all(hrd_meta_stations) // - | remove_if([&](auto&& m) { return m.equivalent_.empty(); }) // - | transform([&](station_meta_data::meta_station const& m) - -> std::optional> { - try { - return std::make_optional(CreateMetaStation( - fbb, sb.get_or_create_station(m.eva_, fbb), - fbb.CreateVector(utl::to_vec(m.equivalent_, [&](auto&& e) { - return sb.get_or_create_station(e, fbb); - })))); - } catch (std::exception const& e) { - LOG(error) << "meta station error: " << e.what(); - return std::nullopt; - } - }) // - | remove_if([](auto&& opt) { return !opt.has_value(); }) // - | transform([](auto&& opt) { return *opt; }) // - | vec()); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/provider_builder.cc b/base/loader/src/hrd/builder/provider_builder.cc deleted file mode 100644 index d4bd3096b..000000000 --- a/base/loader/src/hrd/builder/provider_builder.cc +++ /dev/null @@ -1,32 +0,0 @@ -#include "motis/loader/hrd/builder/provider_builder.h" - -#include "utl/get_or_create.h" - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace utl; -using namespace flatbuffers64; - -provider_builder::provider_builder( - std::map hrd_providers) - : hrd_providers_(std::move(hrd_providers)) {} - -Offset provider_builder::get_or_create_provider( - uint64_t admin, FlatBufferBuilder& fbb) { - return utl::get_or_create(fbs_providers_, admin, [&]() -> Offset { - auto it = hrd_providers_.find(admin); - if (it == end(hrd_providers_)) { - return 0; - } else { - return CreateProvider( - fbb, to_fbs_string(fbb, it->second.short_name_, ENCODING), - to_fbs_string(fbb, it->second.long_name_, ENCODING), - to_fbs_string(fbb, it->second.full_name_, ENCODING)); - } - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/route_builder.cc b/base/loader/src/hrd/builder/route_builder.cc deleted file mode 100644 index 940588c64..000000000 --- a/base/loader/src/hrd/builder/route_builder.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "motis/loader/hrd/builder/route_builder.h" - -#include "utl/get_or_create.h" -#include "utl/to_vec.h" - -using namespace utl; -using namespace flatbuffers64; - -namespace motis::loader::hrd { - -Offset route_builder::get_or_create_route( - std::vector const& stops, station_builder& sb, - FlatBufferBuilder& fbb) { - auto events = - utl::to_vec(begin(stops), end(stops), [&](hrd_service::stop const& s) { - return stop_restrictions{s.eva_num_, s.dep_.in_out_allowed_, - s.arr_.in_out_allowed_}; - }); - return utl::get_or_create(routes_, events, [&]() { - return CreateRoute(fbb, - fbb.CreateVector(utl::to_vec( - begin(events), end(events), - [&](stop_restrictions const& sr) { - return sb.get_or_create_station(sr.eva_num_, fbb); - })), - fbb.CreateVector(utl::to_vec( - begin(events), end(events), - [](stop_restrictions const& sr) -> uint8_t { - return sr.entering_allowed_ ? 1 : 0; - })), - fbb.CreateVector(utl::to_vec( - begin(events), end(events), - [](stop_restrictions const& sr) -> uint8_t { - return sr.leaving_allowed_ ? 1 : 0; - }))); - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/rule_service_builder.cc b/base/loader/src/hrd/builder/rule_service_builder.cc deleted file mode 100644 index f971a0c8f..000000000 --- a/base/loader/src/hrd/builder/rule_service_builder.cc +++ /dev/null @@ -1,218 +0,0 @@ -#include "motis/loader/hrd/builder/rule_service_builder.h" - -#include -#include -#include -#include -#include -#include - -#include "utl/erase.h" -#include "utl/erase_if.h" -#include "utl/get_or_create.h" - -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/hrd/model/rules_graph.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace logging; -using namespace flatbuffers64; - -hrd_service* get_or_create( - std::vector>& origin_services, - std::pair& s) { - if (s.second == nullptr) { - origin_services.emplace_back(std::make_unique(*s.first)); - s.second = origin_services.back().get(); - } - return s.second; -} - -void try_apply_rules(std::vector>& origin_services, - std::pair& s, - std::vector>& rules) { - for (auto& r : rules) { - if (auto const info = r->applies(*s.first); info != 0) { - if (s.first->num_repetitions_ == 0) { - r->add(get_or_create(origin_services, s), info); - } else { - LOG(warn) << "suspicious repeated service rule participant: " - << s.first->origin_.filename_ << " [" - << s.first->origin_.line_number_from_ << "," - << s.first->origin_.line_number_to_ << "]"; - } - } - } -} - -bool rule_service_builder::add_service(hrd_service const& s) { - std::pair copied_service; - copied_service.first = &s; // the original service - copied_service.second = nullptr; // pointer to the copy if we need it - - for (auto const& id : s.get_ids()) { - if (auto it = input_rules_.find(id); it != end(input_rules_)) { - try_apply_rules(origin_services_, copied_service, it->second); - } - } - - return copied_service.second != nullptr; -} - -void create_rule_and_service_nodes( - service_rule* r, rules_graph& rg, - std::map& service_to_node) { - for (auto const& comb : r->service_combinations()) { - auto const& s1 = std::get<0>(comb); - auto const& s2 = std::get<1>(comb); - - auto s1_node = reinterpret_cast( - utl::get_or_create(service_to_node, s1, [&]() { - rg.nodes_.emplace_back(std::make_unique(s1)); - return rg.nodes_.back().get(); - })); - auto s2_node = reinterpret_cast( - utl::get_or_create(service_to_node, s2, [&]() { - rg.nodes_.emplace_back(std::make_unique(s2)); - return rg.nodes_.back().get(); - })); - - auto const& rule = std::get<2>(comb); - auto rn = reinterpret_cast( // NOLINT - rg.nodes_ - .emplace_back(std::make_unique(s1_node, s2_node, rule)) - .get()); - - s1_node->rule_nodes_.push_back(rn); - s2_node->rule_nodes_.push_back(rn); - rg.rule_nodes_.push_back(rn); - } -} - -int get_waiting_time(rule_node const* rn) { - assert(rn->rule_.type_ == RuleType_THROUGH); - auto const arr = rn->s1_->service_->stops_.back().arr_.time_ % 1440; - auto const dep = - rn->s2_->service_->event_time( - rn->s2_->service_->get_first_stop_index_at(rn->rule_.eva_num_2_), - event_type::DEP) % - 1440 + - (rn->rule_.day_switch_ ? 1440 : 0); - return dep - arr; -} - -void fix_through_services(rules_graph& rg) { - utl::erase_if(rg.rule_nodes_, [&](rule_node* rn) { - if (rn->rule_.type_ != RuleType_THROUGH) { - return false; - } - auto const ref_waiting_time = get_waiting_time(rn); - if (std::any_of(begin(rn->s1_->rule_nodes_), end(rn->s1_->rule_nodes_), - [&](rule_node* orn) { - return orn != rn && - orn->rule_.type_ == RuleType_THROUGH && - orn->s1_ == rn->s1_ && - get_waiting_time(orn) <= ref_waiting_time; - })) { - utl::erase(rn->s1_->rule_nodes_, rn); - utl::erase(rn->s2_->rule_nodes_, rn); - return true; - } - return false; - }); -} - -void build_graph(service_rules const& rules, rules_graph& rg) { - std::set considered_rules; - std::map service_to_node; - - for (auto const& rule_entry : rules) { - for (auto const& sr : rule_entry.second) { - if (considered_rules.find(sr.get()) == end(considered_rules)) { - considered_rules.insert(sr.get()); - create_rule_and_service_nodes(sr.get(), rg, service_to_node); - } - } - } - - fix_through_services(rg); -} - -void add_rule_service( - std::pair, bitfield> const& component, - std::vector& rule_services) { - std::set s_resolvents; - std::vector sr_resolvents; - - for (auto& rn : component.first) { - rn->resolve_services(component.second, s_resolvents, sr_resolvents); - } - if (!sr_resolvents.empty()) { - rule_services.emplace_back(std::move(sr_resolvents), - std::move(s_resolvents)); - } -} - -void rule_service_builder::resolve_rule_services() { - scoped_timer const timer("resolve service rules"); - - rules_graph rg; - build_graph(input_rules_, rg); - - std::pair, bitfield> component; - for (auto const& rn : rg.rule_nodes_) { - while (!(component = rn->max_component()).first.empty()) { - add_rule_service(component, rule_services_); - } - } -} - -void create_rule_service( - rule_service const& rs, - rule_service_builder::service_builder_fun const& sbf, station_builder& sb, - std::vector>& fbs_rule_services, - FlatBufferBuilder& fbb) { - std::map> services; - for (auto const& s : rs.services_) { - auto const* service = s.service_.get(); - utl::get_or_create(services, service, [&] { - return sbf(std::cref(*service), true, std::ref(fbb)); - }); - } - - std::vector> fbb_rules; - fbb_rules.reserve(rs.rules_.size()); - for (auto const& r : rs.rules_) { - fbb_rules.push_back(CreateRule( - fbb, static_cast(r.rule_info_.type_), services.at(r.s1_), - services.at(r.s2_), - sb.get_or_create_station(r.rule_info_.eva_num_1_, fbb), - sb.get_or_create_station(r.rule_info_.eva_num_2_, fbb), - r.rule_info_.s1_traffic_days_offset_, - r.rule_info_.s2_traffic_days_offset_, r.rule_info_.day_switch_)); - } - fbs_rule_services.push_back( - CreateRuleService(fbb, fbb.CreateVector(fbb_rules))); -} - -void rule_service_builder::create_rule_services(service_builder_fun const& sbf, - station_builder& sb, - FlatBufferBuilder& fbb) { - scoped_timer const timer("create rule and remaining services"); - LOG(info) << "#remaining services: " << origin_services_.size(); - for (auto const& s : origin_services_) { - if (s->traffic_days_.any()) { - sbf(std::cref(*s), false, std::ref(fbb)); - } - } - LOG(info) << "#rule services: " << rule_services_.size(); - for (auto const& rs : rule_services_) { - create_rule_service(rs, sbf, sb, fbs_rule_services_, fbb); - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/service_builder.cc b/base/loader/src/hrd/builder/service_builder.cc deleted file mode 100644 index a7bd304b7..000000000 --- a/base/loader/src/hrd/builder/service_builder.cc +++ /dev/null @@ -1,122 +0,0 @@ -#include "motis/loader/hrd/builder/service_builder.h" - -#include - -#include "utl/get_or_create.h" -#include "utl/to_vec.h" - -#if defined(_WIN32) && defined(CreateService) -#undef CreateService -#endif - -using namespace utl; -using namespace flatbuffers64; - -namespace motis::loader::hrd { - -service_builder::service_builder(track_rules track_rules) - : track_rules_(std::move(track_rules)) {} - -Offset>> create_sections( - std::vector const& sections, category_builder& cb, - provider_builder& pb, line_builder& lb, attribute_builder& ab, - bitfield_builder& bb, direction_builder& db, station_builder& sb, - FlatBufferBuilder& fbb) { - return fbb.CreateVector(utl::to_vec( - begin(sections), end(sections), [&](hrd_service::section const& s) { - return CreateSection( - fbb, cb.get_or_create_category(s.category_[0], fbb), - pb.get_or_create_provider(raw_to_int(s.admin_), fbb), - s.train_num_, lb.get_or_create_line(s.line_information_, fbb), - ab.create_attributes(s.attributes_, bb, fbb), - db.get_or_create_direction(s.directions_, sb, fbb)); - })); -} - -void create_tracks(track_rule_key const& key, int time, - track_rules const& track_rules, bitfield_builder& bb, - std::vector>& tracks, FlatBufferBuilder& fbb) { - auto dep_plr_it = track_rules.find(key); - if (dep_plr_it == end(track_rules)) { - return; - } - - for (auto const& rule : dep_plr_it->second) { - if (rule.time_ == TIME_NOT_SET || time % 1440 == rule.time_) { - tracks.push_back( - CreateTrack(fbb, bb.get_or_create_bitfield(rule.bitfield_num_, fbb), - rule.track_name_)); - } - } -} - -Offset>> create_tracks( - std::vector const& sections, - std::vector const& stops, track_rules const& track_rules, - bitfield_builder& bb, FlatBufferBuilder& fbb) { - struct stop_tracks { - std::vector> dep_tracks_; - std::vector> arr_tracks_; - }; - - std::vector stops_tracks(stops.size()); - for (auto i = 0UL; i < sections.size(); ++i) { - int const section_index = i; - int const from_stop_index = section_index; - int const to_stop_index = from_stop_index + 1; - - auto const& section = sections[section_index]; - auto const& from_stop = stops[from_stop_index]; - auto const& to_stop = stops[to_stop_index]; - - auto dep_event_key = std::make_tuple(from_stop.eva_num_, section.train_num_, - raw_to_int(section.admin_)); - auto arr_event_key = std::make_tuple(to_stop.eva_num_, section.train_num_, - raw_to_int(section.admin_)); - - create_tracks(dep_event_key, from_stop.dep_.time_, track_rules, bb, - stops_tracks[from_stop_index].dep_tracks_, fbb); - create_tracks(arr_event_key, to_stop.arr_.time_, track_rules, bb, - stops_tracks[to_stop_index].arr_tracks_, fbb); - } - - return fbb.CreateVector(utl::to_vec( - begin(stops_tracks), end(stops_tracks), [&](stop_tracks const& sp) { - return CreateTrackRules(fbb, fbb.CreateVector(sp.arr_tracks_), - fbb.CreateVector(sp.dep_tracks_)); - })); -} - -Offset> create_times( - std::vector const& stops, FlatBufferBuilder& fbb) { - std::vector times; - for (auto const& stop : stops) { - times.push_back(stop.arr_.time_); - times.push_back(stop.dep_.time_); - } - return fbb.CreateVector(times); -} - -Offset service_builder::create_service( - hrd_service const& s, route_builder& rb, station_builder& sb, - category_builder& cb, provider_builder& pb, line_builder& lb, - attribute_builder& ab, bitfield_builder& bb, direction_builder& db, - FlatBufferBuilder& fbb, bool is_rule_participant) { - fbs_services_.push_back(CreateService( - fbb, rb.get_or_create_route(s.stops_, sb, fbb), - bb.get_or_create_bitfield(s.traffic_days_, fbb), - create_sections(s.sections_, cb, pb, lb, ab, bb, db, sb, fbb), - create_tracks(s.sections_, s.stops_, track_rules_, bb, fbb), - create_times(s.stops_, fbb), rb.get_or_create_route(s.stops_, sb, fbb).o, - CreateServiceDebugInfo( - fbb, - utl::get_or_create( - filenames_, s.origin_.filename_, - [&fbb, &s]() { return fbb.CreateString(s.origin_.filename_); }), - s.origin_.line_number_from_, s.origin_.line_number_to_), - static_cast(is_rule_participant ? 1U : 0U) != 0U, - s.initial_train_num_)); - return fbs_services_.back(); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/builder/station_builder.cc b/base/loader/src/hrd/builder/station_builder.cc deleted file mode 100644 index 1debf5b97..000000000 --- a/base/loader/src/hrd/builder/station_builder.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include "motis/loader/hrd/builder/station_builder.h" - -#include "utl/get_or_create.h" -#include "utl/to_vec.h" - -#include "motis/loader/hrd/parse_config.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace flatbuffers64; - -station_builder::station_builder( - std::map hrd_stations, timezones tz) - : hrd_stations_(std::move(hrd_stations)), timezones_(std::move(tz)){}; - -Offset station_builder::get_or_create_station(int eva_num, - FlatBufferBuilder& fbb) { - return utl::get_or_create(fbs_stations_, eva_num, [&]() { - auto it = hrd_stations_.find(eva_num); - utl::verify(it != end(hrd_stations_), "missing station: {}", eva_num); - auto tze = timezones_.find(eva_num); - return CreateStation( - fbb, to_fbs_string(fbb, pad_to_7_digits(eva_num)), - to_fbs_string(fbb, it->second.name_, ENCODING), it->second.lat_, - it->second.lng_, it->second.change_time_, - fbb.CreateVector(utl::to_vec( - begin(it->second.ds100_), end(it->second.ds100_), - [&](std::string const& s) { return fbb.CreateString(s); })), - utl::get_or_create( - fbs_timezones_, tze, - [&]() { - return CreateTimezone( - fbb, tze->general_gmt_offset_, - fbb.CreateVectorOfStructs(utl::to_vec( - tze->seasons_, [&](season_entry const& season) { - return Season(season.gmt_offset_, season.first_day_idx_, - season.last_day_idx_, - season.season_begin_time_, - season.season_end_time_); - }))); - }), - 0, it->second.platform_change_time_, - fbb.CreateVector( - utl::to_vec(it->second.platforms_, [&](auto const& platform) { - return CreatePlatform( - fbb, fbb.CreateString(platform.first), - fbb.CreateVector( - utl::to_vec(platform.second, [&](auto const& track) { - return fbb.CreateString(track); - }))); - }))); - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/hrd_parser.cc b/base/loader/src/hrd/hrd_parser.cc deleted file mode 100755 index 13f70b3b2..000000000 --- a/base/loader/src/hrd/hrd_parser.cc +++ /dev/null @@ -1,313 +0,0 @@ -#include "motis/loader/hrd/hrd_parser.h" - -#include "utl/enumerate.h" -#include "utl/erase.h" -#include "utl/progress_tracker.h" - -#include "cista/hash.h" -#include "cista/mmap.h" - -#include "motis/core/common/logging.h" - -#include "motis/schedule-format/Schedule_generated.h" - -#include "motis/loader/hrd/builder/attribute_builder.h" -#include "motis/loader/hrd/builder/bitfield_builder.h" -#include "motis/loader/hrd/builder/category_builder.h" -#include "motis/loader/hrd/builder/direction_builder.h" -#include "motis/loader/hrd/builder/footpath_builder.h" -#include "motis/loader/hrd/builder/line_builder.h" -#include "motis/loader/hrd/builder/meta_station_builder.h" -#include "motis/loader/hrd/builder/provider_builder.h" -#include "motis/loader/hrd/builder/route_builder.h" -#include "motis/loader/hrd/builder/rule_service_builder.h" -#include "motis/loader/hrd/builder/service_builder.h" -#include "motis/loader/hrd/builder/station_builder.h" -#include "motis/loader/hrd/parser/attributes_parser.h" -#include "motis/loader/hrd/parser/basic_info_parser.h" -#include "motis/loader/hrd/parser/bitfields_parser.h" -#include "motis/loader/hrd/parser/categories_parser.h" -#include "motis/loader/hrd/parser/directions_parser.h" -#include "motis/loader/hrd/parser/merge_split_rules_parser.h" -#include "motis/loader/hrd/parser/providers_parser.h" -#include "motis/loader/hrd/parser/service_parser.h" -#include "motis/loader/hrd/parser/stations_parser.h" -#include "motis/loader/hrd/parser/through_services_parser.h" -#include "motis/loader/hrd/parser/timezones_parser.h" -#include "motis/loader/hrd/parser/track_rules_parser.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace flatbuffers64; -using namespace utl; -using namespace motis::logging; -namespace fs = std::filesystem; - -cista::hash_t hash(fs::path const& hrd_root) { - for (auto const& c : configs) { - auto const basic_data_path = hrd_root / c.core_data_ / c.files(BASIC_DATA); - if (fs::is_regular_file(basic_data_path)) { - cista::mmap m{basic_data_path.generic_string().c_str(), - cista::mmap::protection::READ}; - return cista::hash(std::string_view{ - reinterpret_cast(m.begin()), - std::min(static_cast(50 * 1024 * 1024), m.size())}); - } - } - return 0U; -} - -bool hrd_parser::applicable(fs::path const& path) { - return std::any_of(begin(configs), end(configs), - [&](const config& c) { return applicable(path, c); }); -} - -bool hrd_parser::applicable(fs::path const& path, config const& c) { - auto const core_data_root = path / c.core_data_; - auto const core_data_files_available = std::all_of( - begin(c.required_files_), end(c.required_files_), - [&core_data_root](std::vector const& alternatives) { - if (alternatives.empty()) { - return true; - } - return std::any_of( - begin(alternatives), end(alternatives), - [&core_data_root](std::string const& filename) { - return filename.empty() /* file not required */ || - fs::is_regular_file(core_data_root / filename); - }); - }); - auto const services_available = - fs::is_regular_file(path / c.fplan_) || - (fs::is_directory(path / c.fplan_) && - (c.fplan_file_extension_.empty() || - std::any_of(fs::directory_iterator{path / c.fplan_}, - fs::directory_iterator{}, [&](auto&& f) { - return f.path().extension() == c.fplan_file_extension_; - }))); - return core_data_files_available && services_available; -} - -std::vector hrd_parser::missing_files( - fs::path const& hrd_root) const { - for (auto const& c : configs) { - if (fs::is_regular_file(hrd_root / c.core_data_ / c.files(BASIC_DATA))) { - return missing_files(hrd_root, c); - } - } - return {"eckdaten.*"}; -} - -std::vector hrd_parser::missing_files(fs::path const& hrd_root, - config const& c) { - std::vector missing_files; - auto const schedule_data_root = hrd_root / c.fplan_; - if (!fs::exists(schedule_data_root)) { - missing_files.push_back(schedule_data_root.string()); - } - - auto const core_data_root = hrd_root / c.core_data_; - for (auto const& alternatives : c.required_files_) { - std::vector missing_indices; - int pos = 0; - for (auto const& alternative : alternatives) { - if (!fs::is_regular_file(core_data_root / alternative)) { - missing_indices.push_back(pos); - } - ++pos; - } - if (missing_indices.size() < alternatives.size()) { - continue; - } - for (auto const idx : missing_indices) { - missing_files.emplace_back( - (core_data_root / alternatives[idx]).generic_string()); - } - } - - return missing_files; -} - -loaded_file load(fs::path const& root, filename_key k, config const& c) { - if (c.required_files_[k].empty()) { // not available for this HRD version. - return loaded_file{}; - } - - auto it = std::find_if(begin(c.required_files_[k]), end(c.required_files_[k]), - [&root](std::string const& filename) { - return fs::is_regular_file(root / filename); - }); - utl::verify(it != end(c.required_files_[k]), - "unable to load non-regular file(s): filename={}", - c.required_files_[k].at(0)); - return loaded_file(root / *it, c.convert_utf8_); -} - -loaded_file load_optional(fs::path const& root, char const* filename) { - auto const path = root / filename; - if (fs::is_regular_file(path)) { - return loaded_file{path, false}; - } else { - return loaded_file{}; - } -} - -void parse_and_build_services( - fs::path const& hrd_root, std::map const& bitfields, - std::vector>& schedule_data, - std::function const& service_builder_fun, - config const& c) { - std::vector files; - auto const total_bytes = - collect_files(hrd_root / c.fplan_, c.fplan_file_extension_, files); - - auto progress_tracker = utl::get_active_progress_tracker(); - progress_tracker->status("Parse HRD Services") - .out_bounds(0.F, 100.F) - .in_high(total_bytes); - - auto total_consumed = size_t{0ULL}; - auto const progress_update = [&](std::size_t const file_consumed) { - progress_tracker->update(total_consumed + file_consumed); - }; - - for (auto const& [i, file] : utl::enumerate(files)) { - auto const& loaded = schedule_data.emplace_back( - std::make_unique(file, c.convert_utf8_)); - LOG(info) << "parsing " << i << "/" << files.size() << " " - << schedule_data.back()->name(); - - try { - for_each_service(*loaded, bitfields, service_builder_fun, progress_update, - c); - } catch (parser_error const& e) { - LOG(error) << "unable to parse " << e.filename_copy_ << " (error in line " - << e.line_number_ << ")"; - } - - total_consumed += fs::file_size(file); - } -} - -void delete_f_equivalences( - std::set const& hrd_footpaths, - std::set& hrd_meta_stations) { - for (auto const& f : hrd_footpaths) { - if (f.f_equal_) { - auto meta = hrd_meta_stations.find({f.from_eva_num_, {}}); - if (meta == hrd_meta_stations.end()) { - continue; - } - auto meta_copy = *meta; - utl::erase(meta_copy.equivalent_, f.to_eva_num_); - hrd_meta_stations.erase({f.from_eva_num_, {}}); - if (!meta_copy.equivalent_.empty()) { - hrd_meta_stations.emplace(meta_copy); - } - } - } -} - -void hrd_parser::parse(parser_options const&, fs::path const& hrd_root, - FlatBufferBuilder& fbb) { - for (auto const& c : configs) { - if (applicable(hrd_root, c)) { - return parse(hrd_root, fbb, c); - } else { - LOG(info) << (hrd_root / c.core_data_ / c.files(BASIC_DATA)) - << " does not exist"; - } - } - throw std::runtime_error{"no parser was applicable"}; -} - -void hrd_parser::parse(fs::path const& hrd_root, FlatBufferBuilder& fbb, - config const& c) { - LOG(info) << "parsing HRD data version " << c.version_.view(); - - auto const core_data_root = hrd_root / c.core_data_; - auto const bitfields_file = load(core_data_root, BITFIELDS, c); - bitfield_builder bb(parse_bitfields(bitfields_file, c)); - auto const infotext_file = load(core_data_root, INFOTEXT, c); - auto const stations_file = load(core_data_root, STATIONS, c); - auto const coordinates_file = load(core_data_root, COORDINATES, c); - auto const timezones_file = load(core_data_root, TIMEZONES, c); - auto const basic_data_file = load(core_data_root, BASIC_DATA, c); - auto const footp_file_1 = load(core_data_root, FOOTPATHS, c); - auto const footp_file_ext = load(core_data_root, FOOTPATHS_EXT, c); - auto const minct_file = load(core_data_root, MIN_CT_FILE, c); - auto const platform_file = load_optional(core_data_root, "platform.csv"); - station_meta_data metas; - parse_station_meta_data(infotext_file, footp_file_1, footp_file_ext, - minct_file, platform_file, metas, c); - - station_builder stb(parse_stations(stations_file, coordinates_file, metas, c), - parse_timezones(timezones_file, basic_data_file, c)); - - auto const categories_file = load(core_data_root, CATEGORIES, c); - category_builder cb(parse_categories(categories_file, c)); - - auto const providers_file = load(core_data_root, PROVIDERS, c); - provider_builder pb(parse_providers(providers_file, c)); - - auto const attributes_file = load(core_data_root, ATTRIBUTES, c); - attribute_builder ab(parse_attributes(attributes_file, c)); - - auto const directions_file = load(core_data_root, DIRECTIONS, c); - direction_builder db(parse_directions(directions_file, c)); - - auto const tracks_file = load(core_data_root, TRACKS, c); - service_builder sb(parse_track_rules(tracks_file, fbb, c)); - - line_builder lb; - route_builder rb; - - service_rules rules; - auto const ts_file = load(core_data_root, THROUGH_SERVICES, c); - parse_through_service_rules(ts_file, bb.hrd_bitfields_, rules, c); - - auto const ms_file = load(core_data_root, MERGE_SPLIT_SERVICES, c); - parse_merge_split_service_rules(ms_file, bb.hrd_bitfields_, rules, c); - - rule_service_builder rsb(rules); - - // parse and build services - std::vector> schedule_data; - parse_and_build_services( - hrd_root, bb.hrd_bitfields_, schedule_data, - [&](hrd_service const& s) { - if (!rsb.add_service(s)) { - sb.create_service(s, rb, stb, cb, pb, lb, ab, bb, db, fbb, false); - } - }, - c); - - // compute and build rule services - utl::get_active_progress_tracker()->status("Generate Rule Services"); - rsb.resolve_rule_services(); - rsb.create_rule_services( - [&](hrd_service const& s, bool is_rule_service, FlatBufferBuilder& fbb) { - return sb.create_service(s, rb, stb, cb, pb, lb, ab, bb, db, fbb, - is_rule_service); - }, - stb, fbb); - - if (c.version_ == "hrd_5_00_8") { - delete_f_equivalences(metas.footpaths_, metas.meta_stations_); - } - - auto interval = parse_interval(basic_data_file); - auto schedule_name = parse_schedule_name(basic_data_file); - auto footpaths = create_footpaths(metas.footpaths_, stb, fbb); - auto metastations = create_meta_stations(metas.meta_stations_, stb, fbb); - fbb.Finish( - CreateSchedule(fbb, fbb.CreateVectorOfSortedTables(&sb.fbs_services_), - fbb.CreateVector(values(stb.fbs_stations_)), - fbb.CreateVector(values(rb.routes_)), &interval, footpaths, - fbb.CreateVector(rsb.fbs_rule_services_), metastations, - fbb.CreateString(schedule_name), hash(hrd_root))); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/hrd_service.cc b/base/loader/src/hrd/model/hrd_service.cc deleted file mode 100644 index 15f739c66..000000000 --- a/base/loader/src/hrd/model/hrd_service.cc +++ /dev/null @@ -1,180 +0,0 @@ -#include "motis/loader/hrd/model/hrd_service.h" - -#include -#include -#include - -#include "utl/parser/arg_parser.h" -#include "utl/verify.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/core/common/logging.h" -#include "motis/loader/hrd/model/range.h" -#include "motis/loader/util.h" - -using namespace utl; - -namespace motis::loader::hrd { - -hrd_service::stop parse_stop(cstr stop) { - return { - parse(stop.substr(0, size(7))), - {hhmm_to_min(parse(stop.substr(30, size(5)), hrd_service::NOT_SET)), - stop[29] != '-'}, - {hhmm_to_min(parse(stop.substr(37, size(5)), hrd_service::NOT_SET)), - stop[36] != '-'}}; -} - -int initial_train_num(specification const& spec) { - return parse(spec.internal_service_.substr(3, size(5))); -} - -inline cstr stop_train_num(cstr const& stop) { - return stop.substr(43, size(5)).trim(); -} - -inline cstr stop_admin(cstr const& stop) { - return stop.substr(49, size(6)).trim(); -} - -hrd_service::section parse_initial_section(specification const& spec) { - auto const first_stop = spec.stops_.front(); - auto const train_num = stop_train_num(first_stop); - auto const admin = stop_admin(first_stop); - return {train_num.empty() ? initial_train_num(spec) : parse(train_num), - admin.empty() ? spec.internal_service_.substr(9, size(6)) : admin}; -} - -std::vector parse_section( - std::vector sections, cstr stop) { - auto train_num = stop_train_num(stop); - auto admin = stop_admin(stop); - - auto last_section = sections.back(); - sections.emplace_back( - train_num.empty() ? last_section.train_num_ : parse(train_num), - admin.empty() ? last_section.admin_ : admin); - - return sections; -} - -std::vector> compute_ranges( - std::vector const& spec_lines, - std::vector const& stops, - range_parse_information const& parse_info) { - std::vector> parsed(spec_lines.size()); - std::transform( - begin(spec_lines), end(spec_lines), begin(parsed), [&](cstr spec) { - return std::make_pair( - spec, range(stops, spec.substr(parse_info.from_eva_or_idx_), - spec.substr(parse_info.to_eva_or_idx_), - spec.substr(parse_info.from_hhmm_or_idx_), - spec.substr(parse_info.to_hhmm_or_idx_))); - }); - return parsed; -} - -template -void parse_range( - std::vector const& spec_lines, - range_parse_information const& parse_info, - std::vector const& stops, - std::vector& sections, - std::vector hrd_service::section::*member, - TargetInformationParserFun parse_target_info) { - for (auto const& r : compute_ranges(spec_lines, stops, parse_info)) { - TargetInformationType target_info = parse_target_info(r.first, r.second); - for (int i = r.second.from_idx_; i < r.second.to_idx_; ++i) { - (sections[i].*member).push_back(target_info); - } - } -} - -hrd_service::hrd_service(specification const& spec, config const& c) - : origin_(parser_info{spec.filename_, spec.line_number_from_, - spec.line_number_to_}), - num_repetitions_(parse(spec.internal_service_.substr(22, size(3)))), - interval_(parse(spec.internal_service_.substr(26, size(3)))), - stops_(transform(begin(spec.stops_), end(spec.stops_), - parse_stop)), - sections_(std::accumulate( - std::next(begin(spec.stops_)), - std::next(begin(spec.stops_), spec.stops_.size() - 1), - std::vector
({parse_initial_section(spec)}), parse_section)), - initial_train_num_(initial_train_num(spec)) { - parse_range(spec.attributes_, c.attribute_parse_info_, stops_, sections_, - §ion::attributes_, [&c](cstr line, range const&) { - return attribute{parse(line.substr(c.s_info_.att_eva_)), - line.substr(c.s_info_.att_code_)}; - }); - - parse_range(spec.categories_, c.category_parse_info_, stops_, sections_, - §ion::category_, [&c](cstr line, range const&) { - return line.substr(c.s_info_.cat_); - }); - - parse_range(spec.line_information_, c.line_parse_info_, stops_, sections_, - §ion::line_information_, [&c](cstr line, range const&) { - return line.substr(c.s_info_.line_).trim(); - }); - - parse_range(spec.traffic_days_, c.traffic_days_parse_info_, stops_, sections_, - §ion::traffic_days_, [&c](cstr line, range const&) { - return parse(line.substr(c.s_info_.traff_days_)); - }); - - parse_range(spec.directions_, c.direction_parse_info_, stops_, sections_, - §ion::directions_, [&](cstr line, range const& r) { - if (isdigit(line[5]) != 0) { - return std::make_pair( - parse(line.substr(c.s_info_.dir_)), EVA_NUMBER); - } else if (line[5] == ' ') { - return std::make_pair( - static_cast(stops_[r.to_idx_].eva_num_), - EVA_NUMBER); - } else { - return std::make_pair( - raw_to_int(line.substr(c.s_info_.dir_)), - DIRECTION_CODE); - } - }); - - verify_service(); -} - -void hrd_service::verify_service() { - int section_index = 0; - utl::verify(stops_.size() >= 2, "service with less than 2 stops"); - for (auto& section : sections_) { - verify(section.traffic_days_.size() == 1, - "{}:{}:{}: section {} invalid: {} multiple traffic days", - origin_.filename_, origin_.line_number_from_, - origin_.line_number_to_, section_index, - section.traffic_days_.size()); - verify(section.line_information_.size() <= 1, - "{}:{}:{}: section {} invalid: {} line information", - origin_.filename_, origin_.line_number_from_, - origin_.line_number_to_, section_index, - section.line_information_.size()); - verify(section.category_.size() == 1, - "{}:{}:{}: section {} invalid: {} categories", origin_.filename_, - origin_.line_number_from_, origin_.line_number_to_, section_index, - section.category_.size()); - - try { - verify(section.directions_.size() <= 1, - "{}:{}:{}: section {} invalid: {} direction information", - origin_.filename_, origin_.line_number_from_, - origin_.line_number_to_, section_index, - section.directions_.size()); - } catch (std::runtime_error const&) { - LOG(logging::error) << origin_.filename_ << ":" - << origin_.line_number_from_ - << ": quick fixing direction info"; - section.directions_.resize(1); - } - ++section_index; - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/range.cc b/base/loader/src/hrd/model/range.cc deleted file mode 100644 index e265fe93e..000000000 --- a/base/loader/src/hrd/model/range.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include "motis/loader/hrd/model/range.h" - -#include - -#include "utl/parser/arg_parser.h" -#include "utl/verify.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/loader/util.h" - -using namespace utl; - -namespace motis::loader::hrd { - -bool is_index(cstr s) { return s[0] == '#'; } - -int parse_index(cstr s) { return parse(s.substr(1)); } - -int get_index(std::vector const& stops, cstr eva_or_idx, - cstr hhmm_or_idx, bool is_departure_event) { - assert(!eva_or_idx.empty() && !hhmm_or_idx.empty()); - if (is_index(eva_or_idx)) { - // eva_or_idx is an index which is already definite - return parse_index(eva_or_idx); - } else if (is_index(hhmm_or_idx) || hhmm_or_idx.trim().len == 0) { - // eva_or_idx is not an index -> eva_or_idx is an eva number - // hhmm_or_idx is empty -> search for first occurrence - // hhmm_or_idx is an index -> search for nth occurrence - const auto eva_num = parse(eva_or_idx); - const auto n = is_index(hhmm_or_idx) ? parse_index(hhmm_or_idx) + 1 : 1; - const auto it = find_nth( - begin(stops), end(stops), n, - [&](hrd_service::stop const& s) { return s.eva_num_ == eva_num; }); - utl::verify(it != end(stops), "{}th occurrence of eva number {} not found", - n, eva_num); - return static_cast(std::distance(begin(stops), it)); - } else { - // hhmm_or_idx must be a time - // -> return stop where eva number and time matches - const auto eva_num = parse(eva_or_idx); - const auto time = hhmm_to_min(parse(hhmm_or_idx.substr(1))); - const auto it = - std::find_if(begin(stops), end(stops), [&](hrd_service::stop const& s) { - return s.eva_num_ == eva_num && - (is_departure_event ? s.dep_.time_ : s.arr_.time_) == time; - }); - utl::verify(it != end(stops), - "event with time {} at eva number {} not found", time, eva_num); - return static_cast(std::distance(begin(stops), it)); - } -} - -range::range(std::vector const& stops, cstr from_eva_or_idx, - cstr to_eva_or_idx, cstr from_hhmm_or_idx, cstr to_hhmm_or_idx) { - if (from_eva_or_idx.trim().empty() && to_eva_or_idx.trim().empty() && - from_hhmm_or_idx.trim().empty() && to_hhmm_or_idx.trim().empty()) { - from_idx_ = 0; - to_idx_ = stops.size() - 1; - } else { - from_idx_ = get_index(stops, from_eva_or_idx, from_hhmm_or_idx, true); - to_idx_ = get_index(stops, to_eva_or_idx, to_hhmm_or_idx, false); - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/repeat_service.cc b/base/loader/src/hrd/model/repeat_service.cc deleted file mode 100644 index 184900df2..000000000 --- a/base/loader/src/hrd/model/repeat_service.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include "motis/loader/hrd/model/repeat_service.h" - -#include "utl/to_vec.h" - -namespace motis::loader::hrd { - -hrd_service::event update_event(hrd_service::event const& origin, int interval, - int repetition) { - auto const new_time = origin.time_ != hrd_service::NOT_SET - ? origin.time_ + (interval * repetition) - : hrd_service::NOT_SET; - return {new_time, origin.in_out_allowed_}; -} - -hrd_service create_repetition(hrd_service const& origin, int repetition) { - return {origin.origin_, - 0, - 0, - utl::to_vec(begin(origin.stops_), end(origin.stops_), - [&origin, &repetition](hrd_service::stop const& s) { - return hrd_service::stop{ - s.eva_num_, - update_event(s.arr_, origin.interval_, repetition), - update_event(s.dep_, origin.interval_, repetition)}; - }), - origin.sections_, - origin.traffic_days_, - origin.initial_train_num_}; -} - -void expand_repetitions(std::vector& services) { - int const size = services.size(); - services.reserve(services.size() * (services[0].num_repetitions_ + 1)); - for (int service_idx = 0; service_idx < size; ++service_idx) { - auto const& service = services[service_idx]; - for (int repetition = 1; repetition <= service.num_repetitions_; - ++repetition) { - services.push_back(create_repetition(service, repetition)); - } - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/rules_graph.cc b/base/loader/src/hrd/model/rules_graph.cc deleted file mode 100644 index af8c16968..000000000 --- a/base/loader/src/hrd/model/rules_graph.cc +++ /dev/null @@ -1,102 +0,0 @@ -#include "motis/loader/hrd/model/rules_graph.h" -#include "motis/schedule-format/RuleService_generated.h" - -namespace motis::loader::hrd { - -hrd_service* resolve(bitfield const& upper_traffic_days, hrd_service* origin, - std::set& resolved_services) { - auto resolved_it = resolved_services.find(service_resolvent(origin)); - if (resolved_it == end(resolved_services)) { - auto resolved = std::make_unique(*origin); - resolved->traffic_days_ &= upper_traffic_days; - origin->traffic_days_ &= ~upper_traffic_days; - std::tie(resolved_it, std::ignore) = - resolved_services.emplace(std::move(resolved), origin); - } - return resolved_it->service_.get(); -} - -void rule_node::resolve_services( - bitfield const& upper_traffic_days, - std::set& s_resolvents, - std::vector& sr_resolvents) { - if (traffic_days_.any()) { - auto const active_traffic_days = traffic_days_ & upper_traffic_days; - traffic_days_ &= ~active_traffic_days; - auto const s1_traffic_days_offset = - rule_.s1_traffic_days_offset_ + (rule_.day_switch_ ? 1 : 0); - auto const s1_traffic_days = active_traffic_days >> s1_traffic_days_offset; - auto const s2_traffic_days = - active_traffic_days >> rule_.s2_traffic_days_offset_; - sr_resolvents.emplace_back( - rule_, // - resolve(s1_traffic_days, s1_->service_, s_resolvents), - resolve(s2_traffic_days, s2_->service_, s_resolvents)); - } -} - -service_node::service_node(hrd_service* s) : service_(s) {} - -rule_node::rule_node(service_node* s1, service_node* s2, - resolved_rule_info rule_info) - : s1_(s1), s2_(s2), rule_(rule_info) { - switch (rule_.type_) { - case RuleType_MERGE_SPLIT: - rule_.s1_traffic_days_offset_ = s1->service_->traffic_days_offset_at_stop( - s1->service_->get_first_stop_index_at(rule_info.eva_num_1_), - event_type::DEP); - rule_.s2_traffic_days_offset_ = s2->service_->traffic_days_offset_at_stop( - s2->service_->get_first_stop_index_at(rule_info.eva_num_1_), - event_type::DEP); - break; - case RuleType_THROUGH: - rule_.s1_traffic_days_offset_ = s1->service_->traffic_days_offset_at_stop( - s1->service_->stops_.size() - 1, event_type::ARR); - rule_.s2_traffic_days_offset_ = s2->service_->traffic_days_offset_at_stop( - s2->service_->get_first_stop_index_at(rule_info.eva_num_1_), - event_type::DEP); - break; - default: throw std::runtime_error("unknown rule type"); - } - auto const s1_mask_traffic_days_offset = - rule_.s1_traffic_days_offset_ + (rule_.day_switch_ ? 1 : 0); - traffic_days_ = - (s1->service_->traffic_days_ << s1_mask_traffic_days_offset) & - (s2->service_->traffic_days_ << rule_.s2_traffic_days_offset_) & - rule_info.traffic_days_; -} - -std::pair, bitfield> rule_node::max_component() { - std::pair, bitfield> max; - auto& component_nodes = max.first; - auto& component_traffic_days = max.second; - - rule_node* current = nullptr; - std::set queue = {this}; - component_traffic_days = create_uniform_bitfield('1'); - while (!queue.empty()) { - auto first_element = queue.begin(); - current = *first_element; - queue.erase(first_element); - - auto next_traffic_days = component_traffic_days & current->traffic_days_; - if (next_traffic_days.none()) { - continue; - } - component_traffic_days = next_traffic_days; - component_nodes.insert(current); - - for (auto const& link_node : {current->s1_, current->s2_}) { - for (auto const& related_node : link_node->rule_nodes_) { - if (related_node != current && - component_nodes.find(related_node) == end(component_nodes)) { - queue.insert(related_node); - } - } - } - } - - return max; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/specification.cc b/base/loader/src/hrd/model/specification.cc deleted file mode 100644 index b27aa7df3..000000000 --- a/base/loader/src/hrd/model/specification.cc +++ /dev/null @@ -1,85 +0,0 @@ -#include "motis/loader/hrd/model/specification.h" - -#include - -#include "motis/loader/parser_error.h" - -using namespace utl; - -namespace motis::loader::hrd { - -bool specification::is_empty() const { - return internal_service_.str == nullptr || internal_service_.len == 0; -} - -bool specification::valid() const { - return ignore() || (!categories_.empty() && stops_.size() >= 2 && - !traffic_days_.empty() && !is_empty()); -} - -bool specification::ignore() const { - return !is_empty() && !internal_service_.starts_with("*Z"); -} - -void specification::reset() { - internal_service_ = cstr(nullptr, 0); - traffic_days_.clear(); - categories_.clear(); - line_information_.clear(); - attributes_.clear(); - directions_.clear(); - stops_.clear(); -} - -bool specification::read_line(cstr line, char const* filename, - int line_number) { - if (line.len == 0) { - return false; - } - - if (std::isdigit(line[0]) != 0) { - stops_.push_back(line); - return false; - } - - if (line.len < 2 || line[0] != '*') { - throw parser_error(filename, line_number); - } - - // ignore *I, *GR, *SH, *T, *KW, *KWZ - bool potential_kurswagen = false; - switch (line[1]) { - case 'K': potential_kurswagen = true; - /* no break */ - case 'Z': - case 'T': - if (potential_kurswagen && line.len > 3 && line[3] == 'Z') { - // ignore KWZ line - } else if (is_empty()) { - filename_ = filename; - line_number_from_ = line_number; - internal_service_ = line; - } else { - return true; - } - break; - case 'A': - if (line.starts_with("*A VE")) { - traffic_days_.push_back(line); - } else { // *A based on HRD format version 5.00.8 - attributes_.push_back(line); - } - break; - case 'G': - if (!line.starts_with("*GR")) { - categories_.push_back(line); - } - break; - case 'L': line_information_.push_back(line); break; - case 'R': directions_.push_back(line); break; - } - - return false; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/model/split_service.cc b/base/loader/src/hrd/model/split_service.cc deleted file mode 100644 index f097f7927..000000000 --- a/base/loader/src/hrd/model/split_service.cc +++ /dev/null @@ -1,109 +0,0 @@ -#include "motis/loader/hrd/model/split_service.h" - -#include -#include -#include - -#include "utl/verify.h" - -#include "motis/loader/hrd/builder/bitfield_builder.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -auto const all = create_uniform_bitfield('1'); -auto const none = create_uniform_bitfield('0'); - -struct split_info { - bitfield traffic_days_; - int from_section_idx_, to_section_idx_; -}; - -struct splitter { - explicit splitter(std::vector sections) - : sections_(std::move(sections)) {} - - void check_and_remember(int start, int pos, bitfield const& b) { - for (auto const& w : written_) { - utl::verify((b & w.traffic_days_) == none, "invalid bitfields"); - } - written_.push_back({b, start, pos - 1}); - } - - void write_and_remove(unsigned start, unsigned pos, bitfield current) { - if (current != none) { - auto not_current = (~current); - for (unsigned i = start; i < pos; ++i) { - sections_[i] &= not_current; - } - check_and_remember(start, pos, current); - } - } - - void split(unsigned start, unsigned pos, bitfield current) { - if (pos == sections_.size()) { - write_and_remove(start, pos, current); - return; - } - - auto intersection = current & sections_[pos]; - if (intersection == none) { - write_and_remove(start, pos, current); - return; - } - - split(start, pos + 1, intersection); - auto const diff = current & (~intersection); - write_and_remove(start, pos, diff); - } - - std::vector split() { - for (auto pos = 0UL; pos < sections_.size(); ++pos) { - split(pos, pos, sections_[pos]); - } - return written_; - } - - std::vector sections_; - std::vector written_; -}; - -std::vector split(hrd_service const& s, - std::map const& bitfields) { - std::vector section_bitfields; - for (auto const& section : s.sections_) { - auto it = bitfields.find(section.traffic_days_[0]); - utl::verify(it != end(bitfields), "bitfield not found"); - section_bitfields.push_back(it->second); - } - return splitter(section_bitfields).split(); -} - -hrd_service new_service_from_split(split_info const& s, - hrd_service const& origin) { - auto number_of_stops = s.to_section_idx_ - s.from_section_idx_ + 2; - std::vector stops(number_of_stops); - std::copy(std::next(begin(origin.stops_), s.from_section_idx_), - std::next(begin(origin.stops_), s.to_section_idx_ + 2), - begin(stops)); - - auto number_of_sections = s.to_section_idx_ - s.from_section_idx_ + 1; - std::vector sections(number_of_sections); - std::copy(std::next(begin(origin.sections_), s.from_section_idx_), - std::next(begin(origin.sections_), s.to_section_idx_ + 1), - begin(sections)); - - return { - origin.origin_, origin.num_repetitions_, origin.interval_, stops, - sections, s.traffic_days_, origin.initial_train_num_}; -} - -void expand_traffic_days(hrd_service const& service, - std::map const& bitfields, - std::vector& expanded) { - for (auto const& s : split(service, bitfields)) { - expanded.emplace_back(new_service_from_split(s, service)); - } -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/attributes_parser.cc b/base/loader/src/hrd/parser/attributes_parser.cc deleted file mode 100644 index e0ea90954..000000000 --- a/base/loader/src/hrd/parser/attributes_parser.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "motis/loader/hrd/parser/attributes_parser.h" - -#include "utl/parser/cstr.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -bool is_multiple_spaces(cstr line) { - return line.substr(2, size(3)).trim().empty(); -} - -std::map parse_attributes(loaded_file const& file, - config const& c) { - scoped_timer const timer("parsing attributes"); - std::map attributes; - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len == 0 || line.str[0] == '#') { - return; - } else if (line.len < 13 || (is_multiple_spaces(line) && line.len < 22)) { - LOG(warn) << "invalid attribute line - skipping " << file.name() << ":" - << line_number; - return; - } - auto code = line.substr(c.att_.code_); - auto text = is_multiple_spaces(line) ? line.substr(c.att_.text_mul_spaces_) - : line.substr(c.att_.text_normal_); - attributes[raw_to_int(code)] = - std::string(text.str, text.len - 1); - }); - return attributes; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/basic_info_parser.cc b/base/loader/src/hrd/parser/basic_info_parser.cc deleted file mode 100644 index 8c270b7d6..000000000 --- a/base/loader/src/hrd/parser/basic_info_parser.cc +++ /dev/null @@ -1,82 +0,0 @@ -#include "motis/loader/hrd/parser/basic_info_parser.h" - -#include "utl/parser/arg_parser.h" -#include "utl/verify.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/core/common/logging.h" - -using namespace flatbuffers64; -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -void verify_line_format(cstr s) { - utl::verify( - s.len == 10 && - (std::isdigit(s[0]) != 0 && std::isdigit(s[1]) != 0 && s[2] == '.' && - std::isdigit(s[3]) != 0 && std::isdigit(s[4]) != 0 && s[5] == '.' && - std::isdigit(s[6]) != 0 && std::isdigit(s[7]) != 0 && - std::isdigit(s[8]) != 0 && std::isdigit(s[9]) != 0), - "interval boundary [{}] invalid", s.view()); -} - -std::tuple yyyymmdd( - cstr ddmmyyyy) { - return std::make_tuple(parse(ddmmyyyy.substr(6, size(4))), - parse(ddmmyyyy.substr(3, size(2))), - parse(ddmmyyyy.substr(0, size(2)))); -} - -unixtime str_to_unixtime(cstr s) { - int year = 0, month = 0, day = 0; - std::tie(year, month, day) = yyyymmdd(s); - return to_unix_time(year, month, day); -} - -std::pair mask_dates(cstr str) { - cstr from_line, to_line; - - from_line = get_line(str).substr(0, size(10)); - while (from_line.starts_with("%")) { - skip_line(str); - from_line = get_line(str).substr(0, size(10)); - } - - skip_line(str); - - to_line = get_line(str).substr(0, size(10)); - while (to_line.starts_with("%")) { - skip_line(str); - to_line = get_line(str).substr(0, size(10)); - } - - verify_line_format(from_line); - verify_line_format(to_line); - - return std::make_pair(from_line, to_line); -} - -Interval parse_interval(loaded_file const& basic_info_file) { - scoped_timer const timer("parsing schedule interval"); - cstr first_date; - cstr last_date; - std::tie(first_date, last_date) = mask_dates(basic_info_file.content()); - return {str_to_unixtime(first_date), str_to_unixtime(last_date)}; -} - -boost::gregorian::date get_first_schedule_date(loaded_file const& lf) { - std::uint16_t year = 0, month = 0, day = 0; - std::tie(year, month, day) = yyyymmdd(mask_dates(lf.content()).first); - return {year, month, day}; -} - -std::string parse_schedule_name(loaded_file const& basic_info_file) { - cstr str = basic_info_file.content(); - skip_line(str); // from - skip_line(str); // to - return get_line(str).to_str(); // schedule name -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/bitfields_parser.cc b/base/loader/src/hrd/parser/bitfields_parser.cc deleted file mode 100644 index 8b97217da..000000000 --- a/base/loader/src/hrd/parser/bitfields_parser.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include "motis/loader/hrd/parser/bitfields_parser.h" - -#include -#include - -#include "flatbuffers/util.h" - -#include "utl/parser/arg_parser.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -std::string hex_to_string(char c) { - char str[2] = {c, '\0'}; - auto i = flatbuffers64::StringToInt(str, 16); // NOLINT - std::bitset<4> const bits(i); - return bits.to_string(); -} - -template -std::string hex_to_string(T const& char_collection) { - std::string bit_str; - for (auto const& c : char_collection) { - bit_str.append(hex_to_string(c)); - } - return bit_str; -} - -bitfield hex_str_to_bitset(cstr hex, char const* filename, int line_number) { - std::string bit_str = hex_to_string(hex); - auto period_begin = bit_str.find("11"); - auto period_end = bit_str.rfind("11"); - if (period_begin == std::string::npos || period_end == std::string::npos || - period_begin == period_end || period_end - period_begin <= 2) { - throw parser_error(filename, line_number); - } - std::string bitstring(std::next(begin(bit_str), period_begin + 2), - std::next(begin(bit_str), period_end)); - std::reverse(begin(bitstring), end(bitstring)); - return bitfield{bitstring}; -} - -std::map parse_bitfields(loaded_file const& f, config const& c) { - scoped_timer const timer("parsing bitfields"); - - std::map bitfields; - for_each_line_numbered(f.content(), [&](cstr line, int line_number) { - if (line.len == 0 || line.str[0] == '%') { - return; - } else if (line.len < 9) { - throw parser_error(f.name(), line_number); - } - - bitfields[parse(line.substr(c.bf_.index_))] = - hex_str_to_bitset(line.substr(c.bf_.value_), f.name(), line_number); - }); - - bitfields[ALL_DAYS_KEY] = create_uniform_bitfield('1'); - - return bitfields; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/categories_parser.cc b/base/loader/src/hrd/parser/categories_parser.cc deleted file mode 100644 index 3bcd08834..000000000 --- a/base/loader/src/hrd/parser/categories_parser.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "motis/loader/hrd/parser/categories_parser.h" - -#include "utl/parser/arg_parser.h" -#include "utl/parser/cstr.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -std::map parse_categories(loaded_file const& file, - config const& c) { - scoped_timer const timer("parsing categories"); - bool ignore = false; - std::map categories; - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (ignore || line.len <= 1 || line.str[0] == '#' || line.str[0] == '%') { - return; - } else if (line.starts_with("<")) { - ignore = true; - return; - } else if (line.len < 20) { - throw parser_error(file.name(), line_number); - } - - auto const code = raw_to_int(line.substr(c.cat_.code_)); - auto const output_rule = parse(line.substr(c.cat_.output_rule_)); - auto const name = line.substr(c.cat_.name_).trim(); - categories[code] = {std::string(name.c_str(), name.length()), output_rule}; - }); - return categories; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/directions_parser.cc b/base/loader/src/hrd/parser/directions_parser.cc deleted file mode 100644 index 27ff1cfd9..000000000 --- a/base/loader/src/hrd/parser/directions_parser.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "motis/loader/hrd/parser/directions_parser.h" - -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -std::map parse_directions(loaded_file const& file, - config const& c) { - std::map directions; - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.length() < 9 && line[7] == ' ') { - throw parser_error(file.name(), line_number); - } else { - auto const text = line.substr(c.dir_.text_); - directions[raw_to_int(line.substr(c.dir_.eva_))] = - std::string(text.str, text.len); - } - }); - return directions; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/merge_split_rules_parser.cc b/base/loader/src/hrd/parser/merge_split_rules_parser.cc deleted file mode 100755 index 80026929c..000000000 --- a/base/loader/src/hrd/parser/merge_split_rules_parser.cc +++ /dev/null @@ -1,203 +0,0 @@ -#include "motis/loader/hrd/parser/merge_split_rules_parser.h" - -#include -#include - -#include "utl/parser/arg_parser.h" -#include "utl/parser/cstr.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/util.h" -#include "motis/schedule-format/RuleService_generated.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -struct mss_rule : public service_rule { - mss_rule(service_id id_1, service_id id_2, int eva_num_begin, int eva_num_end, - bitfield const& mask) - : service_rule(mask), - id_1_(std::move(id_1)), - id_2_(std::move(id_2)), - eva_num_begin_(eva_num_begin), - eva_num_end_(eva_num_end) {} - - mss_rule(mss_rule const&) = delete; - mss_rule(mss_rule&&) = delete; - mss_rule& operator=(mss_rule const&) = delete; - mss_rule& operator=(mss_rule&&) = delete; - - ~mss_rule() override = default; - - int applies(hrd_service const& s) const override { - // Check for non-empty intersection. - try { - auto const stop_idx = s.find_first_stop_at(eva_num_begin_); - if (stop_idx == hrd_service::NOT_SET) { - return 0; - } - if ((s.traffic_days_at_stop(stop_idx, event_type::DEP) & mask_).none()) { - return 0; - } - } catch (std::runtime_error&) { - return 0; - } - - // Check if first and last stop of the common part are contained with the - // correct service id. - bool begin_found = false, end_found = false; - for (unsigned section_idx = 0; - section_idx < s.sections_.size() && !(begin_found && end_found); - ++section_idx) { - auto const& section = s.sections_[section_idx]; - auto const& from_stop = s.stops_[section_idx]; - auto const& to_stop = s.stops_[section_idx + 1]; - auto service_id = std::make_pair(section.train_num_, - raw_to_int(section.admin_)); - - if (service_id != id_1_ && service_id != id_2_) { - continue; - } - if (!end_found && from_stop.eva_num_ == eva_num_begin_) { - begin_found = true; - } - if (begin_found && to_stop.eva_num_ == eva_num_end_) { - end_found = true; - } - } - return static_cast(begin_found && end_found); - } - - void add(hrd_service* s, int /* info */) override { - participants_.push_back(s); - } - - static std::pair - get_event_time(hrd_service const* s, int eva_num, - hrd_service::event hrd_service::stop::*ev) { - auto stop_it = std::find_if( - begin(s->stops_), end(s->stops_), - [&](hrd_service::stop const& st) { return st.eva_num_ == eva_num; }); - utl::verify(stop_it != end(s->stops_), "merge/split stop not found"); - return std::make_pair(((*stop_it).*ev).time_, - std::distance(begin(s->stops_), stop_it)); - } - - static bool all_ms_events_exist(hrd_service const* s1, hrd_service const* s2, - int mss_begin, int mss_end) { - auto const [merge_time_s1, merge_idx_s1] = - get_event_time(s1, mss_begin, &hrd_service::stop::dep_); - auto const [merge_time_s2, merge_idx_s2] = - get_event_time(s2, mss_begin, &hrd_service::stop::dep_); - - if (merge_time_s1 % 1440 != merge_time_s2 % 1440) { - return false; - } - - auto const day_offset_s1 = merge_time_s1 / 1440; - auto const day_offset_s2 = merge_time_s2 / 1440; - auto const time_offset_s1 = day_offset_s1 * 1440; - auto const time_offset_s2 = day_offset_s2 * 1440; - - auto const [split_time_s1, split_idx_s1] = - get_event_time(s1, mss_end, &hrd_service::stop::arr_); - auto const [split_time_s2, split_idx_s2] = - get_event_time(s2, mss_end, &hrd_service::stop::arr_); - - if (split_time_s1 - time_offset_s1 != split_time_s2 - time_offset_s2 || - split_idx_s1 - merge_idx_s1 != split_idx_s2 - merge_idx_s2) { - return false; - } - - // ensure that all stops between the merge and split match - int const stop_count = split_idx_s1 - merge_idx_s1 + 1; - for (int i = 0; i < stop_count; ++i) { - auto const& stop_s1 = s1->stops_[merge_idx_s1 + i]; - auto const& stop_s2 = s2->stops_[merge_idx_s2 + i]; - if (stop_s1.eva_num_ != stop_s2.eva_num_ || - (i != 0 && (stop_s1.arr_.time_ - time_offset_s1) != - (stop_s2.arr_.time_ - time_offset_s2)) || - (i != stop_count - 1 && (stop_s1.dep_.time_ - time_offset_s1) != - (stop_s2.dep_.time_ - time_offset_s2))) { - return false; - } - } - return true; - } - - std::vector service_combinations() const override { - std::vector unordered_pairs; - std::set> combinations; - for (auto s1 : participants_) { - auto const s1_traffic_days = s1->traffic_days_at_stop( - s1->get_first_stop_index_at(eva_num_begin_), event_type::DEP); - for (auto s2 : participants_) { - if (s1 == s2 || - combinations.find(std::make_pair(s2, s1)) != end(combinations)) { - continue; - } - combinations.emplace(s1, s2); - - auto const s2_traffic_days = s2->traffic_days_at_stop( - s2->get_first_stop_index_at(eva_num_begin_), event_type::DEP); - auto const intersection = s1_traffic_days & s2_traffic_days & mask_; - if (intersection.any() && - all_ms_events_exist(s1, s2, eva_num_begin_, eva_num_end_)) { - unordered_pairs.emplace_back( - s1, s2, - resolved_rule_info{intersection, eva_num_begin_, eva_num_end_, - RuleType_MERGE_SPLIT}); - } - } - } - return unordered_pairs; - } - - resolved_rule_info rule_info() const override { - return resolved_rule_info{mask_, eva_num_begin_, eva_num_end_, - RuleType_MERGE_SPLIT}; - } - - service_id id_1_, id_2_; - int eva_num_begin_, eva_num_end_; - std::vector participants_; -}; - -void parse_merge_split_service_rules( - loaded_file const& file, std::map const& hrd_bitfields, - service_rules& rules, config const& c) { - scoped_timer const timer("parsing merge split rules"); - - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len < c.merge_spl_.line_length_) { - return; - } - - auto const bitfield_idx = - c.merge_spl_.bitfield_.from == std::numeric_limits::max() - ? 0 - : parse(line.substr(c.merge_spl_.bitfield_)); - auto it = hrd_bitfields.find(bitfield_idx); - utl::verify(it != std::end(hrd_bitfields), "missing bitfield: {}:{}", - file.name(), line_number); - - auto key_1 = std::make_pair( - parse(line.substr(c.merge_spl_.key1_nr_)), - raw_to_int(line.substr(c.merge_spl_.key1_admin_).trim())); - auto key_2 = std::make_pair( - parse(line.substr(c.merge_spl_.key2_nr_)), - raw_to_int(line.substr(c.merge_spl_.key2_admin_).trim())); - - auto eva_num_begin = parse(line.substr(c.merge_spl_.eva_begin_)); - auto eva_num_end = parse(line.substr(c.merge_spl_.eva_end_)); - std::shared_ptr const rule( - new mss_rule(key_1, key_2, eva_num_begin, eva_num_end, it->second)); - - rules[key_1].push_back(rule); - rules[key_2].push_back(rule); - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/providers_parser.cc b/base/loader/src/hrd/parser/providers_parser.cc deleted file mode 100644 index 3c072fe41..000000000 --- a/base/loader/src/hrd/parser/providers_parser.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "motis/loader/hrd/parser/providers_parser.h" - -#include "utl/parser/arg_parser.h" -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -void verify_line_format(cstr line, char const* filename, int line_number) { - // Verify that the provider number has 5 digits. - auto provider_number = line.substr(0, size(5)); - utl::verify(std::all_of(begin(provider_number), end(provider_number), - [](char c) { return std::isdigit(c); }), - "provider line format mismatch in {}:{}", filename, line_number); - - utl::verify(line[6] == 'K' || line[6] == ':', - "provider line format mismatch in {}:{}", filename, line_number); -} - -std::string parse_name(cstr s) { - bool const start_is_quote = s[0] == '\'' || s[0] == '\"'; - char const end = start_is_quote ? s[0] : ' '; - int i = start_is_quote ? 1 : 0; - while (s && s[i] != end) { - ++i; - } - auto region = s.substr(start_is_quote ? 1 : 0, size(i - 1)); - return {region.str, region.len}; -} - -provider_info read_provider_names(cstr line, char const* filename, - int line_number) { - provider_info info; - - int const short_name = line.substr_offset(" K "); - int const long_name = line.substr_offset(" L "); - int const full_name = line.substr_offset(" V "); - - utl::verify(short_name != -1 && long_name != -1 && full_name != -1, - "provider line format mismatch in {}:{}", filename, line_number); - - info.short_name_ = parse_name(line.substr(short_name + 3)); - info.long_name_ = parse_name(line.substr(long_name + 3)); - info.full_name_ = parse_name(line.substr(full_name + 3)); - - return info; -} - -std::map parse_providers(loaded_file const& file, - config const& c) { - scoped_timer const timer("parsing providers"); - - std::map providers; - provider_info current_info; - int previous_provider_number = 0; - - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - auto provider_number = parse(line.substr(c.track_.prov_nr_)); - if (line[6] == 'K') { - current_info = read_provider_names(line, file.name(), line_number); - previous_provider_number = provider_number; - } else { - utl::verify(previous_provider_number == provider_number, - "provider line format mismatch in {}:{}", file.name(), - line_number); - for_each_token(line.substr(8), ' ', [&](cstr token) { - providers[raw_to_int(token)] = current_info; - }); - } - }); - - return providers; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/service_parser.cc b/base/loader/src/hrd/parser/service_parser.cc deleted file mode 100644 index 0abb6079d..000000000 --- a/base/loader/src/hrd/parser/service_parser.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include "motis/loader/hrd/parser/service_parser.h" - -#include -#include - -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/hrd/model/repeat_service.h" -#include "motis/loader/hrd/model/split_service.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace flatbuffers64; -using namespace motis::logging; - -namespace motis::loader::hrd { - -void parse_specification(loaded_file const& file, - std::function builder, - std::function bytes_consumed) { - specification spec; - auto last_line = 0U; - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - last_line = line_number; - bytes_consumed(line.c_str() - file.content().c_str()); - - bool const finished = spec.read_line(line, file.name(), line_number); - - if (!finished) { - return; - } else { - spec.line_number_to_ = line_number - 1; - } - - if (!spec.valid()) { - LOG(error) << "skipping bad service at " << file.name() << ":" - << line_number; - } else if (!spec.ignore()) { - // Store if relevant. - try { - builder(spec); - } catch (std::runtime_error const& e) { - LOG(error) << "unable to build service at " << file.name() << ":" - << line_number << ", skipping"; - } - } - - // Next try! Re-read first line of next service. - spec.reset(); - spec.read_line(line, file.name(), line_number); - }); - - if (!spec.is_empty() && spec.valid() && !spec.ignore()) { - spec.line_number_to_ = last_line; - builder(spec); - } -} - -void expand_and_consume( - hrd_service&& non_expanded_service, - std::map const& bitfields, - std::function const& consumer) { - std::vector expanded_services; - expand_traffic_days(non_expanded_service, bitfields, expanded_services); - expand_repetitions(expanded_services); - for (auto const& s : expanded_services) { - consumer(std::cref(s)); - } -} - -void for_each_service(loaded_file const& file, - std::map const& bitfields, - std::function consumer, - std::function bytes_consumed, - config const& c) { - parse_specification( - file, - [&](specification const& spec) { - try { - expand_and_consume(hrd_service(spec, c), bitfields, consumer); - } catch (parser_error const& e) { - LOG(error) << "skipping bad service at " << e.filename_ << ":" - << e.line_number_; - } catch (std::runtime_error const& e) { - LOG(error) << "skipping bad service at " << spec.filename_ << ":" - << spec.line_number_from_ << "-" << spec.line_number_to_ - << ": " << e.what(); - } - }, - std::move(bytes_consumed)); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/station_meta_data_parser.cc b/base/loader/src/hrd/parser/station_meta_data_parser.cc deleted file mode 100644 index 5bce392ca..000000000 --- a/base/loader/src/hrd/parser/station_meta_data_parser.cc +++ /dev/null @@ -1,194 +0,0 @@ -#include "motis/loader/hrd/parser/station_meta_data_parser.h" - -#include -#include -#include -#include -#include - -#include "boost/algorithm/string/trim.hpp" - -#include "utl/parser/cstr.h" -#include "utl/parser/csv.h" -#include "utl/verify.h" - -namespace motis::loader::hrd { - -using namespace utl; - -constexpr int DEFAULT_CHANGE_TIME_LONG_DISTANCE = 5; -constexpr int DEFAULT_CHANGE_TIME_LOCAL_TRANSPORT = 2; - -// 0: -// 1: -// 2: -// * 3: -// * 4: <[RL100-Code 1, ...,RL100-Code N]> -// 5: -// 6: -// 7: -// 8: -// 9: -// 10: -// 11: -// 12: ... -// 13: -void parse_ds100_mappings(loaded_file const& infotext_file, - std::map& ds100_to_eva_number) { - enum { eva_number, ds100_code }; - using entry = std::tuple; - - std::array column_map{}; - std::fill(begin(column_map), end(column_map), NO_COLUMN_IDX); - column_map[3] = 0; - column_map[4] = 1; - - std::vector const entries; - auto next = infotext_file.content(); - while (next) { - next = skip_lines(next, [](cstr const& line) { return line.len < 38; }); - if (!next) { - break; - } - auto row = read_row(next, column_map, 5); - entry e; - read(e, row); - auto const eva_num = std::get(e); - for_each_token(std::get(e), ',', - [&ds100_to_eva_number, &eva_num](cstr token) { - ds100_to_eva_number[token] = eva_num; - }); - } -} - -enum { from_ds100_key, to_ds100_key, duration_key, track_change_time_key }; -using minct = std::tuple; -std::vector load_minct(loaded_file const& minct_file) { - std::array column_map{}; - std::fill(begin(column_map), end(column_map), NO_COLUMN_IDX); - column_map[0] = 0; - column_map[1] = 1; - column_map[2] = 2; - column_map[3] = 3; - cstr minct_content(minct_file.content()); - auto rows = read_rows(minct_content, column_map); - std::vector records; - read(records, rows); - return records; -} - -void load_platforms(loaded_file const& platform_file, - station_meta_data& metas) { - enum { ds100_code, station_name, platform_name, track_name }; - using entry = std::tuple; - - std::vector entries; - auto platform_content = platform_file.content(); - read(platform_content, entries, - {{"ril100", "bahnhof", "Bstg", "Gleis1"}}); - - for (auto const& e : entries) { - auto ds100 = std::get(e).to_str(); - boost::algorithm::trim(ds100); - metas.platforms_[ds100][std::get(e).to_str()].insert( - std::get(e).to_str()); - } -} - -std::pair station_meta_data::get_station_change_time( - int eva_num) const { - auto it = station_change_times_.find(eva_num); - if (it == std::end(station_change_times_)) { - if (eva_num < 1000000) { - return {DEFAULT_CHANGE_TIME_LOCAL_TRANSPORT, 0}; - } else { - return {DEFAULT_CHANGE_TIME_LONG_DISTANCE, 0}; - } - } else { - return it->second; - } -} - -void parse_and_add(loaded_file const& metabhf_file, - std::set& footpaths, - std::set& meta_stations, - config const& c) { - for_each_line(metabhf_file.content(), [&](cstr line) { - if (line.length() < 16 || line[0] == '%' || line[0] == '*') { - return; - } - - if (line[7] == ':') { // equivalent stations - auto const eva = parse(line.substr(c.meta_.meta_stations_.eva_)); - std::vector equivalent; - for_each_token(line.substr(8), ' ', [&c, &equivalent](cstr token) { - if (c.version_ == "hrd_5_20_26" && token.starts_with("F")) { - return; - } - auto const e = parse(token); - if (e != 0) { - equivalent.push_back(e); - } - }); - - if (!equivalent.empty()) { - meta_stations.insert({eva, equivalent}); - } - } else { // footpaths - auto f_equal = false; - if (c.version_ == "hrd_5_00_8") { - f_equal = line.length() > 23 ? line.substr(23, size(1)) == "F" : false; - }; - - auto const fp = station_meta_data::footpath{ - parse(line.substr(c.meta_.footpaths_.from_)), - parse(line.substr(c.meta_.footpaths_.to_)), - parse(line.substr(c.meta_.footpaths_.duration_)), f_equal}; - if (auto const it = footpaths.find(fp); it != end(footpaths)) { - if (it->duration_ > fp.duration_) { - footpaths.erase(it); - footpaths.insert(fp); - } - } else { - footpaths.insert(it, fp); - } - } - }); -} - -void parse_station_meta_data(loaded_file const& infotext_file, - loaded_file const& metabhf_file, - loaded_file const& metabhf_zusatz_file, - loaded_file const& minct_file, - loaded_file const& platform_file, - station_meta_data& metas, config const& config) { - parse_ds100_mappings(infotext_file, metas.ds100_to_eva_num_); - load_platforms(platform_file, metas); - for (auto const& record : load_minct(minct_file)) { - auto const from_ds100 = std::get(record); - auto const to_ds100 = std::get(record); - auto const duration = std::get(record); - auto const platform_interchange = std::get(record); - - if (to_ds100.len == 0) { - auto eva_number_it = metas.ds100_to_eva_num_.find(from_ds100); - if (eva_number_it != end(metas.ds100_to_eva_num_)) { - metas.station_change_times_[eva_number_it->second] = { - duration, platform_interchange}; - } - } else { - auto from_eva_num_it = metas.ds100_to_eva_num_.find(from_ds100); - auto to_eva_num_it = metas.ds100_to_eva_num_.find(to_ds100); - if (from_eva_num_it != end(metas.ds100_to_eva_num_) && - to_eva_num_it != end(metas.ds100_to_eva_num_)) { - metas.footpaths_.insert( - {from_eva_num_it->second, to_eva_num_it->second, duration, false}); - } - } - } - parse_and_add(metabhf_file, metas.footpaths_, metas.meta_stations_, config); - parse_and_add(metabhf_zusatz_file, metas.footpaths_, metas.meta_stations_, - config); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/stations_parser.cc b/base/loader/src/hrd/parser/stations_parser.cc deleted file mode 100644 index 641a1f31e..000000000 --- a/base/loader/src/hrd/parser/stations_parser.cc +++ /dev/null @@ -1,109 +0,0 @@ -#include "motis/loader/hrd/parser/stations_parser.h" - -#include - -#include "utl/parser/arg_parser.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -void parse_station_names(loaded_file const& file, - std::map& stations, - config const& c) { - scoped_timer const timer("parsing station names"); - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len == 0 || line[0] == '%') { - return; - } else if (line.len < 13) { - throw parser_error(file.name(), line_number); - } - - auto eva_num = parse(line.substr(c.st_.names_.eva_)); - auto name = line.substr(c.st_.names_.name_); - - auto it = std::find(begin(name), end(name), '$'); - if (it != end(name)) { - name.len = std::distance(begin(name), it); - } - - stations[eva_num].name_ = std::string(name.str, name.len); - }); -} - -void parse_station_coordinates(loaded_file const& file, - std::map& stations, - config const& c) { - scoped_timer const timer("parsing station coordinates"); - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len == 0 || line[0] == '%') { - return; - } else if (line.len < 30) { - throw parser_error(file.name(), line_number); - } - - auto eva_num = parse(line.substr(c.st_.coords_.eva_)); - auto& station = stations[eva_num]; - - station.lng_ = parse(line.substr(c.st_.coords_.lng_).trim()); - station.lat_ = parse(line.substr(c.st_.coords_.lat_).trim()); - }); -} - -void set_change_times(station_meta_data const& metas, - std::map& stations) { - scoped_timer const timer("set station change times"); - for (auto& station_entry : stations) { - auto const ct = metas.get_station_change_time(station_entry.first); - station_entry.second.change_time_ = ct.first; - station_entry.second.platform_change_time_ = ct.second; - } -} - -void set_ds100(station_meta_data const& metas, - std::map& stations) { - for (auto const& ds100 : metas.ds100_to_eva_num_) { - auto it = stations.find(ds100.second); - if (it != end(stations)) { - it->second.ds100_.push_back(ds100.first.to_str()); - } - } -} - -void set_platforms(station_meta_data const& metas, - std::map& stations) { - for (auto const& platforms : metas.platforms_) { - auto const ds100_it = metas.ds100_to_eva_num_.find(platforms.first.c_str()); - if (ds100_it == end(metas.ds100_to_eva_num_)) { - continue; - } - auto const eva = ds100_it->second; - auto station_it = stations.find(eva); - if (station_it == end(stations)) { - continue; - } - auto& station = station_it->second; - station.platforms_ = platforms.second; - } -} - -std::map parse_stations( - loaded_file const& station_names_file, - loaded_file const& station_coordinates_file, station_meta_data const& metas, - config const& config) { - scoped_timer const timer("parsing stations"); - std::map stations; - parse_station_names(station_names_file, stations, config); - parse_station_coordinates(station_coordinates_file, stations, config); - set_change_times(metas, stations); - set_ds100(metas, stations); - set_platforms(metas, stations); - return stations; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/through_services_parser.cc b/base/loader/src/hrd/parser/through_services_parser.cc deleted file mode 100644 index d8e75530c..000000000 --- a/base/loader/src/hrd/parser/through_services_parser.cc +++ /dev/null @@ -1,156 +0,0 @@ -#include "motis/loader/hrd/parser/through_services_parser.h" - -#include - -#include "utl/parser/arg_parser.h" -#include "utl/parser/cstr.h" - -#include "motis/core/common/logging.h" -#include "motis/loader/util.h" -#include "motis/schedule-format/RuleService_generated.h" - -using namespace utl; -using namespace motis::logging; - -namespace motis::loader::hrd { - -struct ts_rule : public service_rule { - ts_rule(service_id id_1, service_id id_2, int eva_num, bitfield const& mask) - : service_rule(mask), - id_1_(std::move(id_1)), - id_2_(std::move(id_2)), - eva_num_(eva_num) {} - - ~ts_rule() override = default; - - ts_rule(ts_rule const&) = delete; - ts_rule(ts_rule&&) = delete; - ts_rule& operator=(ts_rule const&) = delete; - ts_rule& operator=(ts_rule&&) = delete; - - int applies(hrd_service const& s) const override { - // Check for non-empty intersection. - - if ((s.traffic_days_at_stop(s.stops_.size() - 1, event_type::ARR) & mask_) - .any()) { - // Assuming s is service (1): Check last stop. - auto last_stop = s.stops_.back(); - auto last_section = s.sections_.back(); - if (last_stop.eva_num_ == eva_num_ && - last_section.train_num_ == id_1_.first && - raw_to_int(last_section.admin_) == id_1_.second) { - return 1; - } - } - - // Assuming s is service (2). - for (auto section_idx = 0UL; section_idx < s.sections_.size(); - ++section_idx) { - auto from_stop = s.stops_[section_idx]; - auto section = s.sections_[section_idx]; - - if (from_stop.eva_num_ == eva_num_ && section.train_num_ == id_2_.first && - raw_to_int(section.admin_) == id_2_.second && - (s.traffic_days_at_stop(section_idx, event_type::DEP) & mask_) - .any()) { - return 2; - } - } - - // No match. - return 0; - } - - void add(hrd_service* s, int info) override { - if (info == 1) { - participants_1_.push_back(s); - } else { - participants_2_.push_back(s); - } - } - - std::vector service_combinations() const override { - std::vector comb; - for (auto const& s1 : participants_1_) { - auto const s1_stop_index = static_cast(s1->stops_.size()) - 1; - auto const s1_traffic_days = - s1->traffic_days_at_stop(s1_stop_index, event_type::ARR); - - std::optional combination; - auto min_time_diff = 1440; - - for (auto const& s2 : participants_2_) { - auto const s2_stop_index = s2->get_first_stop_index_at(eva_num_); - auto const s2_traffic_days = - s2->traffic_days_at_stop(s2_stop_index, event_type::DEP); - - auto const arr_time = - s1->event_time(s1_stop_index, event_type::ARR) % 1440; - auto const dep_time = - s2->event_time(s2_stop_index, event_type::DEP) % 1440; - auto const day_switch = dep_time < arr_time; - auto const time_diff = (dep_time + (day_switch ? 1440 : 0)) - arr_time; - - if (time_diff > min_time_diff) { - continue; - } - - auto const intersection = - day_switch ? (s1_traffic_days << 1) & s2_traffic_days & mask_ - : s1_traffic_days & s2_traffic_days & mask_; - - if (intersection.any()) { - combination = {s1, s2, - resolved_rule_info{intersection, eva_num_, eva_num_, - RuleType_THROUGH, day_switch}}; - min_time_diff = time_diff; - } - } - - if (combination) { - comb.push_back(combination.value()); - } - } - - return comb; - } - - resolved_rule_info rule_info() const override { - return resolved_rule_info{mask_, eva_num_, eva_num_, RuleType_THROUGH}; - } - - service_id id_1_, id_2_; - int eva_num_; - std::vector participants_1_; - std::vector participants_2_; -}; - -void parse_through_service_rules(loaded_file const& file, - std::map const& hrd_bitfields, - service_rules& rules, config const& c) { - scoped_timer const timer("parsing through trains"); - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len < 40) { - return; - } - - auto it = hrd_bitfields.find(parse(line.substr(c.th_s_.bitfield_))); - - utl::verify(it != std::end(hrd_bitfields), "missing bitfield: {}:{}", - file.name(), line_number); - - auto key_1 = - std::make_pair(parse(line.substr(c.th_s_.key1_nr_)), - raw_to_int(line.substr(c.th_s_.key1_admin_))); - auto key_2 = - std::make_pair(parse(line.substr(c.th_s_.key2_nr_)), - raw_to_int(line.substr(c.th_s_.key2_admin_))); - std::shared_ptr const rule(new ts_rule( - key_1, key_2, parse(line.substr(c.th_s_.eva_)), it->second)); - - rules[key_1].push_back(rule); - rules[key_2].push_back(rule); - }); -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/timezones_parser.cc b/base/loader/src/hrd/parser/timezones_parser.cc deleted file mode 100644 index 7cb1487e2..000000000 --- a/base/loader/src/hrd/parser/timezones_parser.cc +++ /dev/null @@ -1,101 +0,0 @@ -#include "motis/loader/hrd/parser/timezones_parser.h" - -#include "boost/date_time/gregorian/gregorian_types.hpp" - -#include "utl/parser/arg_parser.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/loader/hrd/parser/basic_info_parser.h" -#include "motis/loader/util.h" - -namespace motis::loader::hrd { - -using namespace boost::gregorian; -using namespace utl; - -int bitfield_idx(cstr ddmmyyyy, - boost::gregorian::date const& first_schedule_date) { - boost::gregorian::date const season_begin_date( - parse(ddmmyyyy.substr(4, size(4))), - parse(ddmmyyyy.substr(2, size(2))), - parse(ddmmyyyy.substr(0, size(2)))); - return (season_begin_date - first_schedule_date).days(); -} - -int eva_number(cstr str) { return parse(str); } - -int distance_to_midnight(cstr hhmm) { return hhmm_to_min(parse(hhmm)); } - -std::vector parse_seasons( - cstr const line, boost::gregorian::date const& schedule_begin) { - enum state { - kSeasonOffset, - kSeasonBeginDate, - kSeasonBeginHour, - kSeasonEndDate, - kSeasonEndHour, - kNumStates - } s{kSeasonOffset}; - std::vector seasons; - auto e = season_entry{}; - for_each_token(line, ' ', [&](cstr const t) { - switch (s) { - case kSeasonOffset: e.gmt_offset_ = hhmm_to_min(parse(t)); break; - case kSeasonBeginDate: - e.first_day_idx_ = bitfield_idx(t, schedule_begin); - break; - case kSeasonBeginHour: - e.season_begin_time_ = hhmm_to_min(parse(t)); - break; - case kSeasonEndDate: - e.last_day_idx_ = bitfield_idx(t, schedule_begin); - break; - case kSeasonEndHour: - e.season_end_time_ = hhmm_to_min(parse(t)); - seasons.push_back(e); - break; - default:; - } - s = static_cast((s + 1) % kNumStates); - }); - return seasons; -} - -timezones parse_timezones(loaded_file const& timezones_file, - loaded_file const& basic_data_file, config const& c) { - auto const first_schedule_date = get_first_schedule_date(basic_data_file); - - timezones tz; - for_each_line(timezones_file.content(), [&](cstr line) { - if (auto const comment_start = line.view().find('%'); - comment_start != std::string::npos) { - line = line.substr(0, comment_start); - } - - if (line.length() == 15) { - auto first_valid_eva_number = - eva_number(line.substr(c.tz_.type1_first_valid_eva_)); - auto it = tz.eva_to_tze_.find(first_valid_eva_number); - utl::verify(it != end(tz.eva_to_tze_), - "missing timezone information for eva number: {}", - first_valid_eva_number); - - tz.eva_to_tze_[eva_number(line.substr(c.tz_.type1_eva_))] = it->second; - return; - } - - if ((isdigit(line[0]) != 0) && line.length() >= 47) { - tz.timezone_entries_.emplace_back(std::make_unique( - distance_to_midnight(line.substr(c.tz_.type2_dst_to_midnight_)), - line.substr(14, size(33)).trim().empty() - ? std::vector{} - : parse_seasons(line.substr(14), first_schedule_date))); - tz.eva_to_tze_[eva_number(line.substr(c.tz_.type2_eva_))] = - tz.timezone_entries_.back().get(); - } - }); - - return tz; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/hrd/parser/track_rules_parser.cc b/base/loader/src/hrd/parser/track_rules_parser.cc deleted file mode 100644 index 877419099..000000000 --- a/base/loader/src/hrd/parser/track_rules_parser.cc +++ /dev/null @@ -1,56 +0,0 @@ -#include "motis/loader/hrd/parser/track_rules_parser.h" - -#include "utl/parser/arg_parser.h" -#include "utl/parser/cstr.h" - -#include "motis/core/common/date_time_util.h" -#include "motis/core/common/logging.h" -#include "motis/loader/hrd/parser/bitfields_parser.h" -#include "motis/loader/parser_error.h" -#include "motis/loader/util.h" - -using namespace utl; -using namespace flatbuffers64; -using namespace motis::logging; - -namespace motis::loader::hrd { - -track_rules parse_track_rules(loaded_file const& file, - flatbuffers64::FlatBufferBuilder& b, - config const& c) { - scoped_timer const timer("parsing track rules"); - track_rules prs; - std::map> track_names; - - for_each_line_numbered(file.content(), [&](cstr line, int line_number) { - if (line.len == 0 || line.starts_with("%")) { - return; - } else if (line.len < c.track_rul_.min_line_length_) { - throw parser_error(file.name(), line_number); - } - - auto eva_num = parse(line.substr(c.track_rul_.eva_num_)); - auto train_num = parse(line.substr(c.track_rul_.train_num_)); - auto train_admin = - raw_to_int(line.substr(c.track_rul_.train_admin_)); - auto track_name_str = line.substr(c.track_rul_.track_name_).trim(); - auto track_name = raw_to_int(track_name_str); - auto time = hhmm_to_min( - parse(line.substr(c.track_rul_.time_).trim(), TIME_NOT_SET)); - auto bitfield = - parse(line.substr(c.track_rul_.bitfield_).trim(), ALL_DAYS_KEY); - - // Resolve track name (create it if not found) - auto track_name_it = track_names.find(track_name); - if (track_name_it == end(track_names)) { - std::tie(track_name_it, std::ignore) = track_names.insert(std::make_pair( - track_name, to_fbs_string(b, track_name_str, "ISO-8859-1"))); - } - - prs[std::make_tuple(eva_num, train_num, train_admin)].push_back( - {track_name_it->second, bitfield, time}); - }); - return prs; -} - -} // namespace motis::loader::hrd diff --git a/base/loader/src/interval_util.cc b/base/loader/src/interval_util.cc deleted file mode 100644 index dd2f8b202..000000000 --- a/base/loader/src/interval_util.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "motis/loader/interval_util.h" - -#include - -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/schedule.h" -#include "motis/schedule-format/Schedule_generated.h" - -#include "date/date.h" - -namespace motis::loader { - -std::string format_date(time_t const t, char const* format = "%Y-%m-%d") { - return date::format( - format, std::chrono::system_clock::time_point{std::chrono::seconds{t}}); -} - -std::pair first_last_days(schedule const& sched, - size_t const src_index, - Interval const* interval) { - auto first_day = static_cast((sched.schedule_begin_ - interval->from()) / - SECONDS_A_DAY); - auto last_day = static_cast( - (sched.schedule_end_ - interval->from()) / SECONDS_A_DAY - 1); - - utl::verify(interval->from() <= interval->to() && - sched.schedule_begin_ < sched.schedule_end_, - "invalid schedule range settings {} - {}, {}schedule.raw {} {}", - sched.schedule_begin_, sched.schedule_end_, - sched.prefixes_.at(src_index), interval->from(), interval->to()); - - if (interval->from() > sched.schedule_end_ || - interval->to() < sched.schedule_begin_) { - logging::l(logging::log_level::warn, - "schedule {} (from={}, to={}) out of interval (from={}, to={}), " - "fbs: {} - {}, sched: {} - {}", - sched.prefixes_.empty() ? "" : sched.prefixes_.at(src_index), - format_date(interval->from()), format_date(interval->to()), - format_date(sched.schedule_begin_), - format_date(sched.schedule_end_), interval->from(), - interval->to(), sched.schedule_begin_, sched.schedule_end_); - } - - return {first_day, last_day}; -} - -} // namespace motis::loader diff --git a/base/loader/src/loaded_file.cc b/base/loader/src/loaded_file.cc deleted file mode 100755 index a36b453a9..000000000 --- a/base/loader/src/loaded_file.cc +++ /dev/null @@ -1,111 +0,0 @@ -#include "motis/loader/loaded_file.h" - -#include "motis/core/common/logging.h" - -#include "utl/parser/file.h" -#include "utl/verify.h" - -namespace motis::loader { - -// Inplace version of -// https://stackoverflow.com/a/23690194 -void convert_utf8_to_iso_8859_1(std::string& s, std::string_view filename) { - auto line = 1; - auto column = 1; - auto code_point = unsigned{}; - auto out = s.data(); - auto in = reinterpret_cast(s.data()); - - auto to_go = s.size(); - while (to_go != 0) { - auto const ch = static_cast(*in); - if (ch == '\n') { - column = 1; - ++line; - } - - if (ch <= 0x7f) { - code_point = ch; - } else if (ch <= 0xbf) { - code_point = (code_point << 6U) | (ch & 0x3fU); - } else if (ch <= 0xdf) { - code_point = ch & 0x1fU; - } else if (ch <= 0xef) { - code_point = ch & 0x0fU; - } else { - code_point = ch & 0x07U; - } - - ++in; - - if (((*in & 0xc0U) != 0x80U) && (code_point <= 0x10ffff)) { - if (code_point > 255) { - LOG(logging::error) << "invalid unicode at " << filename << ":" << line - << ":" << column; - } - *out = static_cast(code_point); - ++out; - ++column; - } - --to_go; - } - - s.resize(out - s.data()); -} - -loaded_file::loaded_file() = default; - -loaded_file::loaded_file(char const* filename, char const* str, - bool convert_utf8) - : name_(filename), buf_(str) { - if (convert_utf8) { - convert_utf8_to_iso_8859_1(buf_, filename); - } -} - -loaded_file::loaded_file(char const* filename, std::string&& buf, - bool convert_utf8) - : name_(filename), buf_(std::move(buf)) { - if (convert_utf8) { - convert_utf8_to_iso_8859_1(buf_, filename); - } -} - -loaded_file::loaded_file(std::filesystem::path const& p, bool convert_utf8) - : name_(p.filename().string()), - buf_(utl::file(p.string().c_str(), "r").content_str()) { - if (convert_utf8) { - convert_utf8_to_iso_8859_1(buf_, p.generic_string()); - } -} - -loaded_file::loaded_file(loaded_file&& o) noexcept - : name_{std::move(o.name_)}, buf_{std::move(o.buf_)} {} - -loaded_file::~loaded_file() = default; - -loaded_file& loaded_file::operator=(loaded_file&& o) noexcept { - name_ = std::move(o.name_); - buf_ = std::move(o.buf_); - return *this; -} - -char const* loaded_file::name() const { return name_.c_str(); } - -utl::cstr loaded_file::content() const { - auto const offset = contains_utf8_bom() ? 3 : 0; - return {reinterpret_cast(buf_.data() + offset), - buf_.size() - offset}; -} - -bool loaded_file::empty() const { return buf_.empty(); } - -bool loaded_file::contains_utf8_bom() const { - auto const data = - reinterpret_cast(buf_.data()); // NOLINT - return buf_.size() >= 3 && - (static_cast(data[0]) == 239 && - static_cast(data[1]) == 187 && static_cast(data[2]) == 191); -} - -} // namespace motis::loader diff --git a/base/loader/src/loader.cc b/base/loader/src/loader.cc deleted file mode 100644 index cc174a759..000000000 --- a/base/loader/src/loader.cc +++ /dev/null @@ -1,200 +0,0 @@ -#include "motis/loader/loader.h" - -#include -#include -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include - -#include "flatbuffers/flatbuffers.h" - -#include "cista/mmap.h" - -#include "utl/enumerate.h" -#include "utl/overloaded.h" -#include "utl/parser/file.h" -#include "utl/progress_tracker.h" -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/core/common/typed_flatbuffer.h" -#include "motis/core/schedule/serialization.h" - -#include "motis/loader/build_graph.h" -#include "motis/loader/gtfs/gtfs_parser.h" -#include "motis/loader/hrd/hrd_parser.h" - -#include "motis/schedule-format/Schedule_generated.h" - -namespace fs = std::filesystem; -namespace ml = motis::logging; - -namespace motis::loader { - -std::vector> parsers() { - std::vector> p; - p.emplace_back(std::make_unique()); - p.emplace_back(std::make_unique()); - return p; -} - -using dataset_mem_t = std::variant>; - -schedule_ptr load_schedule_impl(loader_options const& loader_opt, - cista::memory_holder& schedule_buf, - std::string const& data_dir) { - ml::scoped_timer const time("loading schedule"); - - // ensure there is an active progress tracker (e.g. for test cases) - utl::get_active_progress_tracker_or_activate("schedule"); - - auto const graph_path = loader_opt.graph_path(data_dir); - auto enable_read_graph = loader_opt.read_graph_; - auto enable_write_graph = loader_opt.write_graph_; - if (loader_opt.cache_graph_) { - enable_read_graph = fs::is_regular_file(graph_path); - enable_write_graph = true; - } - if (enable_read_graph) { - utl::verify(fs::is_regular_file(graph_path), "graph not found: {}", - graph_path); - LOG(ml::info) << "reading graph: " << graph_path; - try { - return read_graph(graph_path, schedule_buf, loader_opt.read_graph_mmap_); - } catch (std::runtime_error const& err) { - if (loader_opt.cache_graph_) { - LOG(ml::info) << "could not load existing graph, updating cache (" - << err.what() << ")"; - } else { - throw err; - } - } - } - - utl::verify(!loader_opt.dataset_.empty(), - "load_schedule: loader_opt.dataset_.empty()"); - utl::verify( - loader_opt.dataset_.size() == 1 || - loader_opt.dataset_.size() == loader_opt.dataset_prefix_.size(), - "load_schedule: dataset/prefix size mismatch"); - - std::vector mem; - mem.reserve(loader_opt.dataset_.size()); - for (auto const& [i, path] : utl::enumerate(loader_opt.dataset_)) { - auto const binary_schedule_file = loader_opt.fbs_schedule_path(data_dir, i); - if (fs::is_regular_file(binary_schedule_file)) { - mem.emplace_back(cista::mmap{binary_schedule_file.c_str(), - cista::mmap::protection::READ}); - continue; - } - - auto const all_parsers = parsers(); - auto const it = std::find_if( - begin(all_parsers), end(all_parsers), - [&p = path](auto const& parser) { return parser->applicable(p); }); - - if (it == end(all_parsers)) { - for (auto const& parser : parsers()) { - std::clog << "missing files:\n"; - for (auto const& file : parser->missing_files(path)) { - std::clog << " " << file << "\n"; - } - } - throw utl::fail("no parser for dataset {}", path); - } - - auto progress_tracker = utl::activate_progress_tracker( - loader_opt.dataset_prefix_.empty() || - loader_opt.dataset_prefix_[i].empty() - ? fmt::format("parse {}", i) - : fmt::format("parse {}", loader_opt.dataset_prefix_[i])); - - flatbuffers64::FlatBufferBuilder builder; - try { - (**it).parse({loader_opt.link_stop_distance_}, path, builder); - progress_tracker->status("FINISHED").show_progress(false); - } catch (std::exception const& e) { - progress_tracker->status(fmt::format("ERROR: {}", e.what())) - .show_progress(false); - throw; - } catch (...) { - progress_tracker->status("ERROR: UNKNOWN EXCEPTION").show_progress(false); - throw; - } - - if (loader_opt.write_serialized_) { - auto const schedule_dir = fs::path{binary_schedule_file}.parent_path(); - if (!schedule_dir.empty()) { - fs::create_directories(schedule_dir); - } - utl::file(binary_schedule_file.c_str(), "w+") - .write(builder.GetBufferPointer(), builder.GetSize()); - } - - mem.emplace_back(typed_flatbuffer{std::move(builder)}); - } - - auto const datasets = utl::to_vec(mem, [&](dataset_mem_t const& v) { - return std::visit( - utl::overloaded{[](cista::mmap const& m) -> Schedule const* { - return GetSchedule(m.data()); - }, - [](typed_flatbuffer const& m) - -> Schedule const* { return m.get(); }}, - v); - }); - - utl::activate_progress_tracker("schedule"); - auto sched = build_graph(datasets, loader_opt); - if (enable_write_graph) { - LOG(ml::info) << "writing graph: " << graph_path; - auto const graph_dir = fs::path{graph_path}.parent_path(); - if (!graph_dir.empty()) { - fs::create_directories(graph_dir); - } - write_graph(graph_path, *sched); - } - return sched; -} - -#ifdef _WIN32 -bool load_schedule_checked(loader_options const& opt, - cista::memory_holder& schedule_buf, - std::string const& data_dir, schedule_ptr& ptr) { - __try { - [&]() { ptr = load_schedule_impl(opt, schedule_buf, data_dir); }(); - return true; - } __except (GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR - ? EXCEPTION_EXECUTE_HANDLER - : EXCEPTION_CONTINUE_SEARCH) { - return false; - } -} -#endif - -schedule_ptr load_schedule(loader_options const& loader_opt, - cista::memory_holder& schedule_buf, - std::string const& data_dir) { -#ifdef _WIN32 - auto ptr = schedule_ptr{}; - utl::verify(load_schedule_checked(loader_opt, schedule_buf, data_dir, ptr), - "load_schedule: file access error: EXCEPTION_IN_PAGE_ERROR"); - return ptr; -#else - return load_schedule_impl(loader_opt, schedule_buf, data_dir); -#endif -} - -schedule_ptr load_schedule(loader_options const& loader_opt) { - utl::verify(!loader_opt.read_graph_, - "load_schedule: read_graph requires buffer"); - cista::memory_holder buf{}; - return load_schedule(loader_opt, buf, ""); -} - -} // namespace motis::loader diff --git a/base/loader/src/loader_options.cc b/base/loader/src/loader_options.cc deleted file mode 100644 index bd34dd8f2..000000000 --- a/base/loader/src/loader_options.cc +++ /dev/null @@ -1,55 +0,0 @@ -#include "motis/loader/loader_options.h" - -#include -#include - -#include "boost/date_time/local_time/local_time.hpp" - -#include "motis/core/common/date_time_util.h" - -namespace fs = std::filesystem; - -namespace motis::loader { - -std::pair loader_options::interval() const { - std::pair interval; - - if (schedule_begin_ == "TODAY") { - auto now = boost::posix_time::second_clock::universal_time().date(); - interval.first = to_unix_time(now.year(), now.month(), now.day()); - } else { - interval.first = to_unix_time(std::stoi(schedule_begin_.substr(0, 4)), - std::stoi(schedule_begin_.substr(4, 2)), - std::stoi(schedule_begin_.substr(6, 2))); - } - - interval.second = interval.first + num_days_ * 24 * 3600; - - return interval; -} - -std::string loader_options::graph_path(std::string const& data_dir) const { - if (graph_path_ == "default") { - auto const [from, to] = interval(); - std::stringstream ss; - ss << "graph_" << from << "-" << to << "af" << adjust_footpaths_ << "ar" - << apply_rules_ << "ef" << expand_footpaths_ << "ptd" - << planned_transfer_delta_ << "nlt" << no_local_transport_ << ".raw"; - return (fs::path{data_dir} / "schedule" / ss.str()).generic_string(); - } else { - return graph_path_; - } -} - -std::string loader_options::fbs_schedule_path(std::string const& data_dir, - size_t const id) const { - if (dataset_prefix_.empty()) { - return (fs::path{data_dir} / "schedule" / "schedule.raw").generic_string(); - } else { - return (fs::path{data_dir} / "schedule" / - (dataset_prefix_.at(id) + "_schedule.raw")) - .generic_string(); - } -} - -} // namespace motis::loader diff --git a/base/loader/src/rule_route_builder.cc b/base/loader/src/rule_route_builder.cc deleted file mode 100644 index 5ee7bb1c9..000000000 --- a/base/loader/src/rule_route_builder.cc +++ /dev/null @@ -1,216 +0,0 @@ -#include "motis/loader/rule_route_builder.h" - -#include "motis/vector.h" - -#include - -#include "utl/get_or_create.h" - -using namespace flatbuffers64; - -namespace motis::loader { - -struct rule_node; - -struct service_node { - explicit service_node(Service const* service, bitfield&& traffic_days) - : service_(service), traffic_days_(traffic_days) {} - - std::vector rule_nodes_; - Service const* service_{nullptr}; - bitfield traffic_days_; -}; - -struct rule_node { - rule_node(service_node* s1, service_node* s2, Rule const* rule) - : s1_(s1), s2_(s2), rule_(rule) {} - - service_node *s1_, *s2_; - Rule const* rule_; -}; - -struct rules_graph { - std::vector> service_nodes_; - std::vector> rule_nodes_; -}; - -struct rule_node_cmp { - bool operator()(rule_node const* lhs, rule_node const* rhs) const { - return lhs->rule_ < rhs->rule_; - } -}; - -struct rule_route_builder { - rule_route_builder(graph_builder& gb, bitfield const& traffic_days_mask) - : gb_(gb), schedule_traffic_days_mask_(traffic_days_mask) {} - - void build(RuleService const* rs) { - build_rules_graph(rs); - build_routes(); - } - -private: - void build_rules_graph(RuleService const* rs) { - std::map service_to_node; - for (auto const r : *rs->rules()) { - if (skip_rule(r)) { - continue; - } - auto s1_node = utl::get_or_create(service_to_node, r->service1(), [&]() { - return rg_.service_nodes_ - .emplace_back(std::make_unique( - r->service1(), get_bitfield(r->service1()))) - .get(); - }); - auto s2_node = utl::get_or_create(service_to_node, r->service2(), [&]() { - return rg_.service_nodes_ - .emplace_back(std::make_unique( - r->service2(), get_bitfield(r->service2()))) - .get(); - }); - auto rn = - rg_.rule_nodes_ - .emplace_back(std::make_unique(s1_node, s2_node, r)) - .get(); - s1_node->rule_nodes_.push_back(rn); - s2_node->rule_nodes_.push_back(rn); - } - } - - inline bitfield get_bitfield(Service const* service) { - return deserialize_bitset( - {service->traffic_days()->c_str(), - static_cast(service->traffic_days()->size())}) & - schedule_traffic_days_mask_; - } - - void build_routes() { - for (auto& rn : rg_.rule_nodes_) { - while (build_routes(rn.get())) { - } - } - for (auto& sn : rg_.service_nodes_) { - if (sn->traffic_days_.any()) { - single_services_.emplace_back(sn->service_, sn->traffic_days_); - } - } - } - - bool build_routes(rule_node* ref_rn) { - if (ref_rn->s1_->traffic_days_.none() || - ref_rn->s2_->traffic_days_.none()) { - return false; - } - auto const ref_sn = ref_rn->s1_; - auto ref_traffic_days = ref_sn->traffic_days_; - - std::queue> queue; - std::set route_rules; - std::map traffic_day_offsets; - queue.emplace(ref_rn, ref_sn, 0); - traffic_day_offsets[ref_sn] = 0; - while (!queue.empty()) { - auto const qe = queue.front(); - auto const [qrn, from, offset] = qe; - queue.pop(); - - auto const to = qrn->s1_ == from ? qrn->s2_ : qrn->s1_; - auto const day_switch = qrn->rule_->day_switch(); - auto const delta_offset = - qrn->s1_ == from ? static_cast(qrn->rule_->day_offset2()) - - static_cast(qrn->rule_->day_offset1()) - - (day_switch ? 1 : 0) - : static_cast(qrn->rule_->day_offset1()) - - static_cast(qrn->rule_->day_offset2()) + - (day_switch ? 1 : 0); - auto const new_offset = offset + delta_offset; - auto const new_traffic_days = - ref_traffic_days & shifted_bitfield(to->traffic_days_, new_offset) & - schedule_traffic_days_mask_; - - if (new_traffic_days.none()) { - continue; - } - ref_traffic_days = new_traffic_days; - route_rules.insert(qrn); - traffic_day_offsets[to] = new_offset; - - for (auto sn : {qrn->s1_, qrn->s2_}) { - for (auto rn : sn->rule_nodes_) { - if (rn == qrn || route_rules.find(rn) != end(route_rules)) { - continue; - } - auto const target_offset = sn == from ? offset : new_offset; - if (rn->s1_ == sn) { - queue.emplace(rn, rn->s1_, target_offset); - } else if (rn->s2_ == sn) { - queue.emplace(rn, rn->s2_, target_offset); - } - } - } - } - - if (ref_traffic_days.none() || route_rules.empty()) { - return false; - } - - auto& route = rule_routes_.emplace_back(); - for (auto const [sn, offset] : traffic_day_offsets) { - auto const service_traffic_days = - shifted_bitfield(ref_traffic_days, -offset) & - schedule_traffic_days_mask_; - route.traffic_days_[sn->service_] = service_traffic_days; - sn->traffic_days_ &= ~service_traffic_days; - } - route.first_day_ = static_cast(gb_.first_day_); - route.last_day_ = static_cast(gb_.last_day_); - for (auto const& rn : route_rules) { - route.rules_.push_back(rn->rule_); - } - return true; - } - - static inline bitfield shifted_bitfield(bitfield const& orig, int offset) { - return offset > 0 ? orig << static_cast(offset) - : orig >> static_cast(-offset); - } - - inline bool skip_rule(Rule const* rule) const { - return gb_.no_local_transport_ && - (gb_.skip_route(rule->service1()->route()) || - gb_.skip_route(rule->service2()->route())); - } - -public: - graph_builder& gb_; - rules_graph rg_; - bitfield const& schedule_traffic_days_mask_; - std::vector> single_services_; - mcd::vector rule_routes_; -}; - -void build_rule_routes(graph_builder& gb, - Vector> const* rule_services) { - auto schedule_traffic_days_mask = create_uniform_bitfield('0'); - for (auto day_idx = gb.first_day_; day_idx <= gb.last_day_; ++day_idx) { - if (day_idx >= schedule_traffic_days_mask.size()) { - continue; - } - schedule_traffic_days_mask.set(static_cast(day_idx), true); - } - - rule_service_graph_builder rsgb(gb); - - for (auto const& rs : *rule_services) { - rule_route_builder rrb(gb, schedule_traffic_days_mask); - rrb.build(rs); - - for (auto const& [service, traffic_days] : rrb.single_services_) { - gb.add_route_services({std::make_pair(service, traffic_days)}); - } - - rsgb.add_rule_services(rrb.rule_routes_); - } -} - -} // namespace motis::loader diff --git a/base/loader/src/rule_service_graph_builder.cc b/base/loader/src/rule_service_graph_builder.cc deleted file mode 100644 index 7ee7350c1..000000000 --- a/base/loader/src/rule_service_graph_builder.cc +++ /dev/null @@ -1,701 +0,0 @@ -#include "motis/loader/rule_service_graph_builder.h" - -#include -#include -#include -#include -#include - -#include "utl/get_or_create.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/price.h" -#include "motis/core/schedule/trip.h" -#include "motis/core/access/connection_access.h" -#include "motis/core/access/trip_iterator.h" -#include "motis/loader/util.h" - -#include "motis/schedule-format/Schedule_generated.h" - -namespace motis::loader { - -using namespace flatbuffers64; -using namespace motis::logging; - -using neighbor = std::pair; - -struct service_section { - route_section route_section_; - mcd::vector participants_; - bool in_allowed_from_ = false; - bool out_allowed_from_ = false; - bool in_allowed_to_ = false; - bool out_allowed_to_ = false; -}; - -struct rule_service_section_builder { - rule_service_section_builder(graph_builder& gb, rule_route const& rs) - : gb_(gb), - neighbors_(build_neighbors(rs)), - sections_(build_empty_sections(rs)) {} - - static std::map> build_neighbors( - rule_route const& rs) { - std::map> neighbors; - for (auto const& r : rs.rules_) { - if (r->type() != RuleType_THROUGH) { - neighbors[r->service1()].emplace_back(r->service2(), r); - neighbors[r->service2()].emplace_back(r->service1(), r); - } - } - return neighbors; - } - - static std::map> - build_empty_sections(rule_route const& rs) { - std::map> sections; - for (auto const& r : rs.rules_) { - sections.emplace( - r->service1(), - mcd::vector( - static_cast::size_type>( - r->service1()->sections()->size()))); - sections.emplace( - r->service2(), - mcd::vector( - static_cast::size_type>( - r->service2()->sections()->size()))); - } - return sections; - } - - static unsigned stop_index_of(Service const* s, Station const* station) { - auto const& stations = *s->route()->stations(); - auto it = std::find(std::begin(stations), std::end(stations), station); - utl::verify(it != std::end(stations), "rule station not found"); - return static_cast(std::distance(std::begin(stations), it)); - } - - void build_sections(rule_route const& rs) { - std::set built; - for (auto const& r : rs.rules_) { - for (auto const& s : {r->service1(), r->service2()}) { - if (built.insert(s).second) { - add_service(s); - } - } - } - } - - void add_service(Service const* service) { - add_service(service, 0, static_cast(service->sections()->size()), - 0, static_cast(service->sections()->size()), - sections_[service], std::set()); - } - - void add_service(Service const* service, // - unsigned from_idx, unsigned to_idx, // - unsigned src_from_idx, unsigned src_to_idx, // - mcd::vector& sections, - std::set visited) { - visited.emplace(service); - - // Recursive add_service call for each neighbor. - for (auto const& neighbor : neighbors_[service]) { - Rule const* rule = neighbor.second; - Service const* neighbor_service = neighbor.first; - - if (visited.find(neighbor_service) != end(visited)) { - continue; - } - - auto rule_service_from = stop_index_of(service, rule->from()); - auto rule_service_to = stop_index_of(service, rule->to()); - auto rule_neighbor_from = stop_index_of(neighbor_service, rule->from()); - auto rule_neighbor_to = stop_index_of(neighbor_service, rule->to()); - - auto new_service_from_idx = std::max(rule_service_from, from_idx); - auto new_service_to_idx = std::min(rule_service_to, to_idx); - - if (new_service_from_idx >= new_service_to_idx) { - continue; - } - - auto neighbor_from = - rule_neighbor_from + (new_service_from_idx - rule_service_from); - auto neighbor_to = - rule_neighbor_to + (new_service_to_idx - rule_service_to); - - auto src_from = src_from_idx + (new_service_from_idx - from_idx); - auto src_to = src_to_idx + (new_service_to_idx - to_idx); - - if (src_from < src_to) { - add_service(neighbor_service, neighbor_from, neighbor_to, src_from, - src_to, sections, visited); - } - } - - // Add service as participant to the specified sections. - for (unsigned src_section_idx = src_from_idx, - service_section_idx = from_idx; - src_section_idx < src_to_idx; - ++src_section_idx, ++service_section_idx) { - if (sections[src_section_idx] == nullptr) { - section_mem_.emplace_back(std::make_unique()); - sections[src_section_idx] = section_mem_.back().get(); - } - sections_[service][service_section_idx] = sections[src_section_idx]; - - auto& section_participants = sections[src_section_idx]->participants_; - auto not_already_added = - std::find_if(begin(section_participants), end(section_participants), - [&service](participant const& p) { - return p.service_ == service; - }) == end(section_participants); - - if (not_already_added) { - section_participants.emplace_back(service, service_section_idx); - - auto& ss = sections_[service][service_section_idx]; - ss->in_allowed_from_ |= - service->route()->in_allowed()->Get(service_section_idx) != 0U; - ss->out_allowed_from_ |= - service->route()->out_allowed()->Get(service_section_idx) != 0U; - ss->in_allowed_to_ |= - service->route()->in_allowed()->Get(service_section_idx + 1) != 0U; - ss->out_allowed_to_ |= - service->route()->out_allowed()->Get(service_section_idx + 1) != 0U; - } - } - } - - graph_builder& gb_; - std::map> neighbors_; - std::map> sections_; - mcd::vector> section_mem_; -}; - -struct lcon_time_adjuster { - static void adjust(edge* prev_edge, edge* e) { - auto& prev_lcons = prev_edge->m_.route_edge_.conns_; - auto& curr_lcons = e->m_.route_edge_.conns_; - - for (auto lcon_idx = lcon_idx_t{}; - lcon_idx < static_cast(prev_lcons.size()); ++lcon_idx) { - auto& prev_lcon = prev_lcons[lcon_idx]; - auto& curr_lcon = curr_lcons[lcon_idx]; - - auto& last_arr = prev_lcon.a_time_; - auto& curr_dep = curr_lcon.d_time_; - auto& curr_arr = curr_lcon.a_time_; - - if (last_arr > curr_dep) { - curr_dep += 60; - } - - if (curr_dep > curr_arr) { - curr_arr += 60; - } - - assert(last_arr <= curr_dep && curr_dep <= curr_arr); - } - } - - void process_following_route_edges(edge* e, edge* pred) { - for (auto& following : e->to_->edges_) { - if (!following.empty()) { - adjust(pred == nullptr ? e : pred, &following); - queue_.emplace(&following, nullptr); - } else if (following.type() == edge::THROUGH_EDGE) { - queue_.emplace(&following, e); - } - } - } - - void adjust_times(node* first_route_node) { - for (auto& following : first_route_node->edges_) { - queue_.emplace(&following, nullptr); - } - - while (!queue_.empty()) { - auto el = queue_.front(); - queue_.pop(); - process_following_route_edges(el.first, el.second); - } - } - - std::queue> queue_; -}; - -struct node_id_cmp { - bool operator()(node const* lhs, node const* rhs) const { - return lhs->id_ < rhs->id_; - } -}; - -struct rule_service_route_builder { - rule_service_route_builder( - graph_builder& gb, // - unsigned first_day, unsigned last_day, - std::map>& sections, - unsigned route_id, rule_route const& rs) - : gb_(gb), - first_day_(first_day), - last_day_(last_day), - sections_(sections), - route_id_(route_id), - traffic_days_(rs.traffic_days_) {} - - void build_routes() { - for (auto& entry : sections_) { - build_route(entry.first, entry.second); - } - - for (auto& entry : sections_) { - write_trip_info(entry.first, entry.second); - utl::verify( - [&entry] { - node const* pred_to = nullptr; - for (auto const& s : entry.second) { - if (pred_to != nullptr && - pred_to != s->route_section_.from_route_node_) { - return false; - } - pred_to = s->route_section_.to_route_node_; - } - return true; - }(), - "rule service: route node ordering"); - } - } - - void adjust_times() { - for (auto& entry : sections_) { - lcon_time_adjuster().adjust_times( - entry.second[0]->route_section_.from_route_node_); - } - } - - static services_key get_services_key( - std::array const& services, int day_idx) { - services_key k; - k.day_idx_ = day_idx; - auto const ref_day_offset = - services[0].service_->times()->Get(services[0].section_idx_ * 2 + 1) / - 1440; - for (auto const& s : services) { - if (s.service_ == nullptr) { - break; - } - auto const s_day_offset = - s.service_->times()->Get(s.section_idx_ * 2 + 1) / 1440; - k.services_.insert({s.service_, ref_day_offset - s_day_offset}); - } - return k; - } - - merged_trips_idx get_or_create_trips( - std::array const& services, int day_idx) { - auto k = get_services_key(services, day_idx); - return utl::get_or_create(trips_, k, [&]() { - return static_cast(push_mem( - gb_.sched_.merged_trips_, - mcd::to_vec(begin(k.services_), end(k.services_), - [&](service_with_day_offset sp) { - auto const s_day_idx = day_idx + sp.day_offset_; - return ptr{utl::get_or_create( - single_trips_, - std::make_pair(sp.service_, s_day_idx), [&]() { - // TODO(pablo): handle duplicate trip id - return gb_.register_service(sp.service_, - s_day_idx, true); - })}; - }))); - }); - } - - mcd::vector build_connections( - service_section const& section) { - auto participants = section.participants_; - std::sort(begin(participants), end(participants)); - - std::array services; - std::copy(begin(participants), end(participants), begin(services)); - - assert(!participants.empty()); - - mcd::vector lcons; - bool adjusted = false; - auto const& traffic_days = traffic_days_.at(services[0].service_); - for (unsigned day_idx = first_day_; day_idx <= last_day_; ++day_idx) { - if (traffic_days.test(day_idx)) { - lcons.push_back( - gb_.section_to_connection(get_or_create_trips(services, day_idx), - services, day_idx, 0, adjusted)); - adjusted = false; - } - } - return lcons; - } - - node* find_to(std::set& visited, - mcd::vector const& sections, int i) const { - if (i >= static_cast(sections.size()) || i < 0 || - visited.find(sections[i]) != end(visited)) { - return nullptr; - } - - auto const& s = sections[i]; - visited.emplace(s); - - if (s->route_section_.to_route_node_ != nullptr) { - return s->route_section_.to_route_node_; - } - - auto const succ_from = find_from(visited, sections, i + 1); - if (succ_from != nullptr) { - return succ_from; - } - - for (participant const& p : s->participants_) { - auto const& p_sections = sections_.at(p.service_); - auto const p_succ_from = - find_from(visited, p_sections, p.section_idx_ + 1); - if (p_succ_from != nullptr) { - return p_succ_from; - } - } - - return nullptr; - } - - node* find_from(std::set& visited, - mcd::vector const& sections, int i) const { - if (i >= static_cast(sections.size()) || i < 0 || - visited.find(sections[i]) != end(visited)) { - return nullptr; - } - - auto const& s = sections[i]; - visited.emplace(s); - - if (s->route_section_.from_route_node_ != nullptr) { - return s->route_section_.from_route_node_; - } - - auto const pred_to = find_to(visited, sections, i - 1); - if (pred_to != nullptr) { - return pred_to; - } - - for (participant const& p : s->participants_) { - auto const& p_sections = sections_.at(p.service_); - auto const p_pred_to = find_to(visited, p_sections, p.section_idx_ - 1); - if (p_pred_to != nullptr) { - return p_pred_to; - } - } - - return nullptr; - } - - void build_route(Service const* s, mcd::vector& sections) { - utl::verify(s->sections()->size() == sections.size(), - "section count mismatch"); - utl::verify(std::none_of(begin(sections), end(sections), - [](service_section* ss) { return ss == nullptr; }), - "every section created"); - utl::verify(std::all_of(begin(sections), end(sections), - [&s](service_section const* ss) { - auto is_curr = [&s](participant const& p) { - return p.service_ == s; - }; - auto contains_curr = - std::find_if(begin(ss->participants_), - end(ss->participants_), - is_curr) != - end(ss->participants_); - return contains_curr; - }), - "every section contains participant"); - utl::verify( - std::all_of(begin(sections), end(sections), - [](service_section const* ss) { - auto const get_from_to = [](participant const& p) { - auto const stations = p.service_->route()->stations(); - auto const from = stations->Get(p.section_idx_); - auto const to = stations->Get(p.section_idx_ + 1); - return std::make_pair(from, to); - }; - - auto const ref = get_from_to(ss->participants_.front()); - return std::all_of( - begin(ss->participants_), end(ss->participants_), - [&get_from_to, &ref](participant const& p) { - return get_from_to(p) == ref; - }); - }), - "service section station mismatch"); - - auto const& r = s->route(); - auto const& stops = r->stations(); - for (auto i = 0UL; i < stops->size() - 1; ++i) { - auto section_idx = i; - if (sections[section_idx]->route_section_.is_valid()) { - continue; - } - - auto from = section_idx; - auto to = section_idx + 1; - - std::set v_from, v_to; // visited sets - auto const from_route_node = find_from(v_from, sections, section_idx); - auto const to_route_node = find_to(v_to, sections, section_idx); - - sections[section_idx]->route_section_ = gb_.add_route_section( - route_id_, build_connections(*sections[section_idx]), - stops->Get(from), // - sections[section_idx]->in_allowed_from_, // - sections[section_idx]->out_allowed_from_, - stops->Get(to), // - sections[section_idx]->in_allowed_to_, // - sections[section_idx]->out_allowed_to_, // - from_route_node, to_route_node); - } - - utl::verify( - std::all_of(begin(sections), end(sections), - [](auto&& s) { return s->route_section_.is_valid(); }), - "all built sections are valid"); - utl::verify( - [§ions]() { - for (auto i = 0UL; i < sections.size() - 1; ++i) { - if (sections[i]->route_section_.to_route_node_ != - sections[i + 1]->route_section_.from_route_node_) { - return false; - } - } - return true; - }(), - "all sections: s[i].to = s[i + 1].from"); - } - - void write_trip_info(Service const* s, - mcd::vector const& sections) { - push_mem( - gb_.sched_.trip_edges_, - mcd::to_vec( - begin(sections), end(sections), [](service_section* section) { - return trip::route_edge(section->route_section_.get_route_edge()); - })); - - auto const& traffic_days = traffic_days_.at(s); - auto edges = gb_.sched_.trip_edges_.back().get(); - auto lcon_idx = lcon_idx_t{}; - for (unsigned day_idx = first_day_; day_idx <= last_day_; ++day_idx) { - if (traffic_days.test(day_idx)) { - auto trp = single_trips_.at(std::make_pair(s, day_idx)); - trp->edges_ = edges; - trp->lcon_idx_ = lcon_idx; - if (!edges->empty()) { - auto const& first_lcon = - edges->front()->m_.route_edge_.conns_.at(lcon_idx); - trp->original_first_connection_info_ = - &access::get_connection_info(gb_.sched_, first_lcon, trp); - trp->original_first_clasz_ = first_lcon.full_con_->clasz_; - } - ++lcon_idx; - } - } - } - - void connect_through_services(rule_route const& rs) { - for (auto const& r : rs.rules_) { - if (r->type() == RuleType_THROUGH) { - connect_route_nodes(r); - } - } - } - - node* get_through_route_node(Service const* service, Station const* station, - bool source) { - auto get_node = [source](service_section const* s) { - return source ? s->route_section_.to_route_node_ - : s->route_section_.from_route_node_; - }; - - auto station_it = gb_.stations_.find(station); - utl::verify(station_it != end(gb_.stations_), "through station not found"); - auto station_node = station_it->second; - - auto& sections = sections_.at(service); - if (source) { - utl::verify(!sections.empty(), - "through station not found (sections empty)"); - auto const n = get_node(sections.back()); - utl::verify(n->get_station() == station_node, - "through station not found (last station does not match)"); - return n; - } else { - auto it = std::find_if( - begin(sections), end(sections), [&](service_section const* s) { - return get_node(s)->get_station() == station_node; - }); - utl::verify(it != end(sections), "through station not found"); - return get_node(*it); - } - } - - void connect_route_nodes(Rule const* r) { - auto s1_node = get_through_route_node(r->service1(), r->from(), true); - auto s2_node = get_through_route_node(r->service2(), r->from(), false); - for (auto const& e : s1_node->edges_) { - if (e.type() == edge::THROUGH_EDGE && e.to_ == s2_node) { - return; - } - } - if (std::find_if(begin(s1_node->edges_), end(s1_node->edges_), - [](edge const& e) { - return e.type() == edge::THROUGH_EDGE; - }) != end(s1_node->edges_)) { - auto const s1_debug = r->service1()->debug(); - auto const s2_debug = r->service2()->debug(); - LOG(warn) << "multiple outgoing through edges: " - << s1_debug->file()->view() << " lines " - << s1_debug->line_from() << "-" << s1_debug->line_to() << " -> " - << s2_debug->file()->view() << " lines " - << s2_debug->line_from() << "-" << s2_debug->line_to() - << " at station " << r->from()->id()->view() << " " - << r->from()->name()->view(); - } - s1_node->edges_.push_back(make_through_edge(s1_node, s2_node)); - through_target_nodes_.insert(s2_node); - } - - void expand_trips() { - for (auto& entry : sections_) { - start_nodes_.insert(entry.second[0]->route_section_.from_route_node_); - } - for (auto const& entry : sections_) { - for (auto const* section : entry.second) { - auto const* rn = section->route_section_.to_route_node_; - start_nodes_.erase(rn); - } - } - for (auto const& n : through_target_nodes_) { - start_nodes_.erase(n); - } - - for (auto const* rn : start_nodes_) { - expand_trips(rn); - } - } - - void expand_trips(node const* start_node) { expand_trips(start_node, {}); } - - void expand_trips(node const* start_node, - mcd::vector&& prefix) { - mcd::vector path(std::move(prefix)); - auto n = start_node; - while (n != nullptr) { - mcd::vector route_edges; - add_outgoing_route_edges(route_edges, n); - if (route_edges.size() > 1) { - for (auto const* re : route_edges) { - auto new_prefix = path; - new_prefix.emplace_back(re); - expand_trips(re->to_, std::move(new_prefix)); - } - return; - } else if (route_edges.size() == 1) { - auto const* re = route_edges[0]; - path.emplace_back(re); - n = re->to_; - } else { - n = nullptr; - } - } - make_expanded_trips(path); - } - - void add_outgoing_route_edges(mcd::vector& route_edges, - node const* n) { - for (auto const& e : n->edges_) { - if (e.type() == edge::ROUTE_EDGE) { - route_edges.push_back(&e); - } else if (e.type() == edge::THROUGH_EDGE && e.to_ != n) { - add_outgoing_route_edges(route_edges, e.to_); - } - } - } - - void make_expanded_trips(mcd::vector& route_edges) { - if (route_edges.empty()) { - return; - } - auto const lc_count = route_edges.front()->m_.route_edge_.conns_.size(); - - push_mem(gb_.sched_.trip_edges_, route_edges); - auto const edges_ptr = gb_.sched_.trip_edges_.back().get(); - - auto route_trips = gb_.sched_.expanded_trips_.emplace_back(); - for (auto lcon_idx = 0U; lcon_idx < lc_count; ++lcon_idx) { - full_trip_id const ftid; - push_mem(gb_.sched_.trip_mem_, ftid, "", edges_ptr, lcon_idx, - static_cast(gb_.sched_.trip_mem_.size()), - trip_debug{}, mcd::vector{}); - auto trip_ptr = gb_.sched_.trip_mem_.back().get(); - - auto const& first_lcon = - route_edges.front()->m_.route_edge_.conns_.at(lcon_idx); - trip_ptr->original_first_connection_info_ = - first_lcon.full_con_->con_info_; - trip_ptr->original_first_clasz_ = first_lcon.full_con_->clasz_; - - if (gb_.check_trip(trip_ptr)) { - route_trips.push_back(trip_ptr); - } - } - if (!route_trips.empty()) { - gb_.sched_.route_to_expanded_routes_[route_id_].emplace_back( - route_trips.index()); - } - } - - graph_builder& gb_; - unsigned first_day_, last_day_; - std::map>& sections_; - std::map, trip*> single_trips_; - std::map trips_; - unsigned route_id_; - std::set start_nodes_; - std::set through_target_nodes_; - std::map const& traffic_days_; -}; - -rule_service_graph_builder::rule_service_graph_builder(graph_builder& gb) - : gb_(gb) {} - -void rule_service_graph_builder::add_rule_services( - mcd::vector const& rule_services) { - if (rule_services.empty()) { - return; - } - - for (auto const& rule_service : rule_services) { - auto route_id = gb_.next_route_index_++; - - rule_service_section_builder section_builder(gb_, rule_service); - section_builder.build_sections(rule_service); - - rule_service_route_builder route_builder( - gb_, rule_service.first_day_, rule_service.last_day_, - section_builder.sections_, route_id, rule_service); - route_builder.build_routes(); - route_builder.connect_through_services(rule_service); - - route_builder.expand_trips(); - } -} - -} // namespace motis::loader diff --git a/base/loader/src/timezone_util.cc b/base/loader/src/timezone_util.cc deleted file mode 100644 index 5d0d7f244..000000000 --- a/base/loader/src/timezone_util.cc +++ /dev/null @@ -1,206 +0,0 @@ -#include "motis/loader/timezone_util.h" - -#include -#include - -#include "flatbuffers/flatbuffers.h" - -#include "utl/get_or_create.h" -#include "utl/pipes.h" -#include "utl/verify.h" - -#include "motis/core/common/logging.h" -#include "motis/core/schedule/time.h" -#include "motis/core/schedule/timezone.h" - -using namespace motis::logging; - -namespace motis::loader { - -timezone_name_idx tz_cache::lookup_name(std::string_view timezone_name) { - if (prev_name_ == timezone_name) { - return prev_name_idx_; - } else { - prev_name_ = timezone_name; - return prev_name_idx_ = - utl::get_or_create(timezone_name_idx_, timezone_name, [&]() { - return static_cast( - timezone_name_idx_.size()); - }); - } -} - -int day_idx(int day_idx_schedule_first_day, int day_idx_schedule_last_day, - int day_idx_season_event_day) { - return std::max( - std::min(day_idx_schedule_last_day, day_idx_season_event_day) - - day_idx_schedule_first_day, - 0); -} - -timezone create_timezone(int general_offset, int day_idx_schedule_first_day, - int day_idx_schedule_last_day, - std::vector const& seasons) { - return {general_offset, - utl::all(seasons) // - | utl::remove_if([&](Season const& s) { - return s.day_idx_last_day() < day_idx_schedule_first_day || - day_idx_schedule_last_day < s.day_idx_first_day(); - }) // - | - utl::transform([&](Season const& s) { - time season_begin = 0; - if (day_idx_schedule_first_day <= s.day_idx_first_day()) { - season_begin = to_motis_time( - day_idx(day_idx_schedule_first_day, - day_idx_schedule_last_day, s.day_idx_first_day()), - s.minutes_after_midnight_first_day() - general_offset); - } - - time season_end = INVALID_TIME - s.offset(); - if (s.day_idx_last_day() <= day_idx_schedule_last_day) { - season_end = to_motis_time( - day_idx(day_idx_schedule_first_day, - day_idx_schedule_last_day, s.day_idx_last_day()), - s.minutes_after_midnight_last_day() - s.offset()); - } - - return season{s.offset(), season_begin, season_end}; - }) // - | utl::emplace_back_to>()}; -} - -time get_event_time(tz_cache& cache, std::time_t const schedule_begin, - int day_idx, int local_time, timezone const* tz, - char const* stop_tz, char const* provider_tz) { - if (tz != nullptr) { - return tz->to_motis_time(day_idx, local_time); - } else if (stop_tz != nullptr || provider_tz != nullptr) { - try { - auto const tz = stop_tz != nullptr ? stop_tz : provider_tz; - return utl::get_or_create( - cache.cache_, - tz_cache_key{cache.lookup_name(tz), static_cast(day_idx), - static_cast