✨ Internal train network structure
- Defines Network, StopArea, StopPoints and JourneySections - Loads them from json using the build_from_json method
This commit is contained in:
parent
27c5a55400
commit
61aec3d856
9 changed files with 1877 additions and 0 deletions
|
|
@ -2,6 +2,17 @@ cmake_minimum_required(VERSION 4.0)
|
||||||
|
|
||||||
project(Trenesis)
|
project(Trenesis)
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
add_subdirectory(ext/json)
|
||||||
|
|
||||||
include_directories(lib)
|
include_directories(lib)
|
||||||
|
add_library(trenesis)
|
||||||
|
|
||||||
|
target_sources(trenesis
|
||||||
|
PRIVATE
|
||||||
|
lib/trenesis/geojson.cpp
|
||||||
|
lib/trenesis/network/graph.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(trenesis PUBLIC nlohmann_json::nlohmann_json)
|
||||||
|
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
|
|
|
||||||
7
ext/json/CMakeLists.txt
Normal file
7
ext/json/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
json
|
||||||
|
URL https://github.com/nlohmann/json/releases/download/v3.12.0/json.tar.xz
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(json)
|
||||||
7
lib/trenesis/geojson.cpp
Normal file
7
lib/trenesis/geojson.cpp
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "geojson.h"
|
||||||
|
|
||||||
|
namespace trenesis {
|
||||||
|
Point::Point(double longitude, double latitude)
|
||||||
|
: longitude(longitude), latitude(latitude) {
|
||||||
|
}
|
||||||
|
}
|
||||||
10
lib/trenesis/geojson.h
Normal file
10
lib/trenesis/geojson.h
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace trenesis {
|
||||||
|
struct Point {
|
||||||
|
double longitude;
|
||||||
|
double latitude;
|
||||||
|
|
||||||
|
Point(double longitude, double latitude);
|
||||||
|
};
|
||||||
|
}
|
||||||
112
lib/trenesis/network/graph.cpp
Normal file
112
lib/trenesis/network/graph.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
#include "graph.h"
|
||||||
|
|
||||||
|
namespace trenesis {
|
||||||
|
|
||||||
|
StopArea::StopArea(std::string id, std::string label, std::string name, Point coord)
|
||||||
|
: id(id), label(label), name(name), coord(coord) {
|
||||||
|
}
|
||||||
|
|
||||||
|
StopPoint::StopPoint(
|
||||||
|
std::string id,
|
||||||
|
std::string label,
|
||||||
|
std::string name,
|
||||||
|
Point coord,
|
||||||
|
StopArea* stop_area
|
||||||
|
) : id(id), label(label), name(name), coord(coord), stop_area(stop_area) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Network Network::build_from_json(const json& vehicle_journeys, const json& stop_points) {
|
||||||
|
Network graph;
|
||||||
|
auto _vehicle_journeys = vehicle_journeys["vehicle_journeys"];
|
||||||
|
auto _stop_points = stop_points["stop_points"];
|
||||||
|
std::unordered_map<std::string, std::string> spoint_to_sarea;
|
||||||
|
|
||||||
|
for(auto v = _stop_points.begin(); v != _stop_points.end(); ++v) {
|
||||||
|
auto stop_point = *v;
|
||||||
|
auto stop_area = stop_point["stop_area"];
|
||||||
|
|
||||||
|
auto stop_area_id = stop_area["id"];
|
||||||
|
auto& stop_area_in_map = graph.stop_areas.try_emplace(
|
||||||
|
stop_area_id,
|
||||||
|
new StopArea(
|
||||||
|
stop_area_id,
|
||||||
|
stop_area["label"],
|
||||||
|
stop_area["name"],
|
||||||
|
Point(
|
||||||
|
std::stod((std::string) stop_area["coord"]["lon"]),
|
||||||
|
std::stod((std::string) stop_area["coord"]["lat"])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).first->second;
|
||||||
|
|
||||||
|
auto stop_point_id = stop_point["id"];
|
||||||
|
spoint_to_sarea[stop_point_id] = stop_area_id;
|
||||||
|
|
||||||
|
stop_area_in_map->stop_points.try_emplace(
|
||||||
|
stop_point_id,
|
||||||
|
new StopPoint(
|
||||||
|
stop_point_id,
|
||||||
|
stop_point["label"],
|
||||||
|
stop_point["name"],
|
||||||
|
Point(
|
||||||
|
std::stod((std::string) stop_point["coord"]["lon"]),
|
||||||
|
std::stod((std::string) stop_point["coord"]["lat"])
|
||||||
|
),
|
||||||
|
stop_area_in_map.get()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto v = _vehicle_journeys.begin(); v != _vehicle_journeys.end(); ++v) {
|
||||||
|
std::map<std::string, JourneySection> journey;
|
||||||
|
auto stop_times = (*v)["stop_times"];
|
||||||
|
for(auto t = stop_times.begin(); t < stop_times.end(); ++t) {
|
||||||
|
auto stop_point_id = (*t)["stop_point"]["id"];
|
||||||
|
auto& stop_area = graph.stop_areas.at(
|
||||||
|
spoint_to_sarea.at(stop_point_id)
|
||||||
|
);
|
||||||
|
JourneySection js;
|
||||||
|
js.departure_time = (*t)["departure_time"];
|
||||||
|
js.arrival_time = (*t)["arrival_time"];
|
||||||
|
js.origin = stop_area->stop_points[stop_point_id].get();
|
||||||
|
|
||||||
|
journey[js.departure_time] = js;
|
||||||
|
}
|
||||||
|
if(journey.size() > 1) {
|
||||||
|
for(auto js = journey.begin(); js != --journey.end(); ++js) {
|
||||||
|
auto js_cpy = js;
|
||||||
|
++js_cpy;
|
||||||
|
auto next_section = *js_cpy;
|
||||||
|
js->second.destination = next_section.second.origin;
|
||||||
|
js->second.arrival_time = next_section.second.arrival_time;
|
||||||
|
auto& stop_area = graph.stop_areas.at(
|
||||||
|
spoint_to_sarea.at(js->second.origin->id)
|
||||||
|
);
|
||||||
|
stop_area->stop_points[js->second.origin->id]->departures
|
||||||
|
.push_back(js->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//auto node_in_map =
|
||||||
|
//graph.stop_areas.emplace(std::make_pair(
|
||||||
|
//node_id,
|
||||||
|
//new StopArea
|
||||||
|
//));
|
||||||
|
//if (node_in_map.second) {
|
||||||
|
//auto& network_node = node_in_map.first->second;
|
||||||
|
|
||||||
|
//network_node->id = node_id;
|
||||||
|
//network_node->name = stop_point["name"];
|
||||||
|
//network_node->label = stop_point["label"];
|
||||||
|
//network_node->coord.latitude = std::stod(
|
||||||
|
//(std::string) stop_point["coord"]["lat"]
|
||||||
|
//);
|
||||||
|
//network_node->coord.longitude = std::stod(
|
||||||
|
//(std::string) stop_point["coord"]["lon"]
|
||||||
|
//);
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
lib/trenesis/network/graph.h
Normal file
54
lib/trenesis/network/graph.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include "trenesis/geojson.h"
|
||||||
|
|
||||||
|
namespace trenesis {
|
||||||
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
struct StopPoint;
|
||||||
|
|
||||||
|
struct StopArea {
|
||||||
|
std::string id;
|
||||||
|
std::string label;
|
||||||
|
std::string name;
|
||||||
|
Point coord;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<StopPoint>> stop_points;
|
||||||
|
|
||||||
|
StopArea(std::string id, std::string label, std::string name, Point coord);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JourneySection {
|
||||||
|
StopPoint* origin;
|
||||||
|
StopPoint* destination;
|
||||||
|
// TODO: use real types for times
|
||||||
|
std::string departure_time;
|
||||||
|
std::string arrival_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StopPoint {
|
||||||
|
std::string id;
|
||||||
|
std::string label;
|
||||||
|
std::string name;
|
||||||
|
Point coord;
|
||||||
|
StopArea* stop_area;
|
||||||
|
|
||||||
|
std::vector<JourneySection> departures;
|
||||||
|
|
||||||
|
StopPoint(
|
||||||
|
std::string id,
|
||||||
|
std::string label,
|
||||||
|
std::string name,
|
||||||
|
Point coord,
|
||||||
|
StopArea* stop_area
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Network {
|
||||||
|
std::unordered_map<std::string, std::unique_ptr<StopArea>> stop_areas;
|
||||||
|
|
||||||
|
static Network build_from_json(const json& vehicle_journeys, const json& stop_points);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,11 +3,18 @@ add_subdirectory(googletest)
|
||||||
add_executable(
|
add_executable(
|
||||||
test_trenesis
|
test_trenesis
|
||||||
trenesis/test.cpp
|
trenesis/test.cpp
|
||||||
|
trenesis/network/graph.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
test_trenesis
|
test_trenesis
|
||||||
|
trenesis
|
||||||
GTest::gtest_main
|
GTest::gtest_main
|
||||||
|
GTest::gmock_main
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
assets
|
||||||
)
|
)
|
||||||
|
|
||||||
include(GoogleTest)
|
include(GoogleTest)
|
||||||
|
|
|
||||||
994
tests/assets/trenesis/network/graph_assets.h
Normal file
994
tests/assets/trenesis/network/graph_assets.h
Normal file
|
|
@ -0,0 +1,994 @@
|
||||||
|
|
||||||
|
constexpr auto single_node_stop_points =
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"stop_points": [
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713040",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto single_node_journey =
|
||||||
|
// This is a simplified extract from /coverage/sncf/vehicle_journeys
|
||||||
|
// representing the line Dijon -> Cercy -> Nevers
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"vehicle_journeys": [
|
||||||
|
{
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "081200",
|
||||||
|
"utc_arrival_time": "071200",
|
||||||
|
"departure_time": "081200",
|
||||||
|
"utc_departure_time": "071200",
|
||||||
|
"headsign": "893009",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": false,
|
||||||
|
"skipped_stop": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto dijon_cercy_nevers_stop_points =
|
||||||
|
// This is a simplified extract from /coverage/sncf/stop_points
|
||||||
|
// representing stations Dijon, Cercy, Nevers
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"stop_points": [
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713040",
|
||||||
|
"name": "Dijon",
|
||||||
|
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87696492:Train",
|
||||||
|
"name": "Cercy-la-Tour",
|
||||||
|
"label": "Cercy-la-Tour (Cercy-la-Tour)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.645084",
|
||||||
|
"lat": "46.85793"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87696492",
|
||||||
|
"name": "Cercy-la-Tour",
|
||||||
|
"label": "Cercy-la-Tour (Cercy-la-Tour)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.645084",
|
||||||
|
"lat": "46.85793"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87696005:Train",
|
||||||
|
"name": "Nevers",
|
||||||
|
"label": "Nevers (Nevers)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.150743",
|
||||||
|
"lat": "46.987282"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87696005",
|
||||||
|
"name": "Nevers",
|
||||||
|
"label": "Nevers (Nevers)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.150743",
|
||||||
|
"lat": "46.987282"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto dijon_cercy_nevers_journey =
|
||||||
|
// This is a simplified extract from /coverage/sncf/vehicle_journeys
|
||||||
|
// representing the line Dijon -> Cercy -> Nevers
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"vehicle_journeys": [
|
||||||
|
{
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "081200",
|
||||||
|
"utc_arrival_time": "071200",
|
||||||
|
"departure_time": "081200",
|
||||||
|
"utc_departure_time": "071200",
|
||||||
|
"headsign": "893009",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "095300",
|
||||||
|
"utc_arrival_time": "085300",
|
||||||
|
"departure_time": "095400",
|
||||||
|
"utc_departure_time": "085400",
|
||||||
|
"headsign": "893009",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87696492:Train",
|
||||||
|
"name": "Cercy-la-Tour",
|
||||||
|
"label": "Cercy-la-Tour (Cercy-la-Tour)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.645084",
|
||||||
|
"lat": "46.85793"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "102900",
|
||||||
|
"utc_arrival_time": "092900",
|
||||||
|
"departure_time": "102900",
|
||||||
|
"utc_departure_time": "092900",
|
||||||
|
"headsign": "893009",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87696005:Train",
|
||||||
|
"name": "Nevers",
|
||||||
|
"label": "Nevers (Nevers)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "3.150743",
|
||||||
|
"lat": "46.987282"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto besancon_dijon_lons_train_only_stop_points =
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"stop_points": [
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718007:Train",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718007",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713412",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713040",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718841:Train",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718841",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718833:Train",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718833",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87715003:Train",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87715003",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718239:Train",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718239",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto besancon_dijon_lons_train_only_journeys =
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"vehicle_journeys": [
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2026-01-05:894210:1187:Train",
|
||||||
|
"name": "894210",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1817",
|
||||||
|
"name": "journey_pattern:1817"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "105600",
|
||||||
|
"utc_arrival_time": "095600",
|
||||||
|
"departure_time": "105600",
|
||||||
|
"utc_departure_time": "095600",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718007:Train",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "112000",
|
||||||
|
"utc_arrival_time": "102000",
|
||||||
|
"departure_time": "112200",
|
||||||
|
"utc_departure_time": "102200",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "115200",
|
||||||
|
"utc_arrival_time": "105200",
|
||||||
|
"departure_time": "115200",
|
||||||
|
"utc_departure_time": "105200",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2025-12-25:895705:1187:Train",
|
||||||
|
"name": "895705",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1982",
|
||||||
|
"name": "journey_pattern:1982"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "111400",
|
||||||
|
"utc_arrival_time": "101400",
|
||||||
|
"departure_time": "111400",
|
||||||
|
"utc_departure_time": "101400",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "113200",
|
||||||
|
"utc_arrival_time": "103200",
|
||||||
|
"departure_time": "113300",
|
||||||
|
"utc_departure_time": "103300",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718841:Train",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "113900",
|
||||||
|
"utc_arrival_time": "103900",
|
||||||
|
"departure_time": "114200",
|
||||||
|
"utc_departure_time": "104200",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718833:Train",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "123700",
|
||||||
|
"utc_arrival_time": "113700",
|
||||||
|
"departure_time": "123700",
|
||||||
|
"utc_departure_time": "113700",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87715003:Train",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2025-12-30:895857:1187:Train",
|
||||||
|
"name": "895857",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1899",
|
||||||
|
"name": "journey_pattern:1899"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "164700",
|
||||||
|
"utc_arrival_time": "154700",
|
||||||
|
"departure_time": "165200",
|
||||||
|
"utc_departure_time": "155200",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718007:Train",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "171500",
|
||||||
|
"utc_arrival_time": "161500",
|
||||||
|
"departure_time": "171600",
|
||||||
|
"utc_departure_time": "161600",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718841:Train",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "172100",
|
||||||
|
"utc_arrival_time": "162100",
|
||||||
|
"departure_time": "172200",
|
||||||
|
"utc_departure_time": "162200",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718833:Train",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "175900",
|
||||||
|
"utc_arrival_time": "165900",
|
||||||
|
"departure_time": "180100",
|
||||||
|
"utc_departure_time": "170100",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718239:Train",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
|
||||||
|
constexpr auto besancon_dijon_lons_stop_points =
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"stop_points": [
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718007:Train",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718007",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713412",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87713040",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718841:Train",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718841",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718833:Train",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718833",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87715003:Train",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87715003",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718007:LongDistanceTrain",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718007",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718841:LongDistanceTrain",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718841",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718833:LongDistanceTrain",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718833",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "stop_point:SNCF:87718239:LongDistanceTrain",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
},
|
||||||
|
"stop_area": {
|
||||||
|
"id": "stop_area:SNCF:87718239",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
|
|
||||||
|
constexpr auto besancon_dijon_lons_journeys =
|
||||||
|
R"-(
|
||||||
|
{
|
||||||
|
"vehicle_journeys": [
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2026-01-05:894210:1187:Train",
|
||||||
|
"name": "894210",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1817",
|
||||||
|
"name": "journey_pattern:1817"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "105600",
|
||||||
|
"utc_arrival_time": "095600",
|
||||||
|
"departure_time": "105600",
|
||||||
|
"utc_departure_time": "095600",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718007:Train",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": false,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "112000",
|
||||||
|
"utc_arrival_time": "102000",
|
||||||
|
"departure_time": "112200",
|
||||||
|
"utc_departure_time": "102200",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "115200",
|
||||||
|
"utc_arrival_time": "105200",
|
||||||
|
"departure_time": "115200",
|
||||||
|
"utc_departure_time": "105200",
|
||||||
|
"headsign": "894210",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713040:Train",
|
||||||
|
"name": "Dijon",
|
||||||
|
"label": "Dijon (Dijon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.027256",
|
||||||
|
"lat": "47.323411"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": false,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2025-12-25:895705:1187:Train",
|
||||||
|
"name": "895705",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1982",
|
||||||
|
"name": "journey_pattern:1982"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "111400",
|
||||||
|
"utc_arrival_time": "101400",
|
||||||
|
"departure_time": "111400",
|
||||||
|
"utc_departure_time": "101400",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87713412:Train",
|
||||||
|
"name": "Dole-Ville",
|
||||||
|
"label": "Dole-Ville (Dole)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.48806",
|
||||||
|
"lat": "47.09615"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": false,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "113200",
|
||||||
|
"utc_arrival_time": "103200",
|
||||||
|
"departure_time": "113300",
|
||||||
|
"utc_departure_time": "103300",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718841:Train",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "113900",
|
||||||
|
"utc_arrival_time": "103900",
|
||||||
|
"departure_time": "114200",
|
||||||
|
"utc_departure_time": "104200",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718833:Train",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "123700",
|
||||||
|
"utc_arrival_time": "113700",
|
||||||
|
"departure_time": "123700",
|
||||||
|
"utc_departure_time": "113700",
|
||||||
|
"headsign": "895705",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87715003:Train",
|
||||||
|
"name": "Pontarlier",
|
||||||
|
"label": "Pontarlier (Pontarlier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.353418",
|
||||||
|
"lat": "46.900988"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": false,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "vehicle_journey:SNCF:2025-12-30:895857:1187:LongDistanceTrain",
|
||||||
|
"name": "895857",
|
||||||
|
"journey_pattern": {
|
||||||
|
"id": "journey_pattern:1899",
|
||||||
|
"name": "journey_pattern:1899"
|
||||||
|
},
|
||||||
|
"stop_times": [
|
||||||
|
{
|
||||||
|
"arrival_time": "164700",
|
||||||
|
"utc_arrival_time": "154700",
|
||||||
|
"departure_time": "165200",
|
||||||
|
"utc_departure_time": "155200",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718007:LongDistanceTrain",
|
||||||
|
"name": "Besançon Viotte",
|
||||||
|
"label": "Besançon Viotte (Besançon)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "6.021943",
|
||||||
|
"lat": "47.247049"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "171500",
|
||||||
|
"utc_arrival_time": "161500",
|
||||||
|
"departure_time": "171600",
|
||||||
|
"utc_departure_time": "161600",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718841:LongDistanceTrain",
|
||||||
|
"name": "Arc-et-Senans",
|
||||||
|
"label": "Arc-et-Senans (Arc-et-Senans)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.77683",
|
||||||
|
"lat": "47.030473"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "172100",
|
||||||
|
"utc_arrival_time": "162100",
|
||||||
|
"departure_time": "172200",
|
||||||
|
"utc_departure_time": "162200",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718833:LongDistanceTrain",
|
||||||
|
"name": "Mouchard",
|
||||||
|
"label": "Mouchard (Mouchard)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.799698",
|
||||||
|
"lat": "46.976865"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"arrival_time": "175900",
|
||||||
|
"utc_arrival_time": "165900",
|
||||||
|
"departure_time": "180100",
|
||||||
|
"utc_departure_time": "170100",
|
||||||
|
"headsign": "895857",
|
||||||
|
"stop_point": {
|
||||||
|
"id": "stop_point:SNCF:87718239:LongDistanceTrain",
|
||||||
|
"name": "Lons-le-Saunier",
|
||||||
|
"label": "Lons-le-Saunier (Lons-le-Saunier)",
|
||||||
|
"coord": {
|
||||||
|
"lon": "5.551108",
|
||||||
|
"lat": "46.66858"
|
||||||
|
},
|
||||||
|
"links": [],
|
||||||
|
"equipments": []
|
||||||
|
},
|
||||||
|
"pickup_allowed": true,
|
||||||
|
"drop_off_allowed": true,
|
||||||
|
"skipped_stop": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)-";
|
||||||
675
tests/trenesis/network/graph.cpp
Normal file
675
tests/trenesis/network/graph.cpp
Normal file
|
|
@ -0,0 +1,675 @@
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
#include "trenesis/network/graph.h"
|
||||||
|
#include "trenesis/network/graph_assets.h"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
|
||||||
|
namespace trenesis {
|
||||||
|
using stop_area_pair = decltype(trenesis::Network::stop_areas)::value_type;
|
||||||
|
using stop_point_pair = decltype(trenesis::StopArea::stop_points)::value_type;
|
||||||
|
|
||||||
|
namespace matchers {
|
||||||
|
template<class... StopPoints>
|
||||||
|
auto StopArea(const char* stop_area_id, StopPoints... stop_points) {
|
||||||
|
return AllOf(
|
||||||
|
Field(
|
||||||
|
"key", &stop_area_pair::first, stop_area_id
|
||||||
|
),
|
||||||
|
Field(
|
||||||
|
"value",
|
||||||
|
&stop_area_pair::second,
|
||||||
|
Pointee(Field("stop_points", &StopArea::stop_points, UnorderedElementsAre(
|
||||||
|
Field(
|
||||||
|
"key", &stop_point_pair::first, stop_points // Dijon
|
||||||
|
)...
|
||||||
|
)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Departure(
|
||||||
|
const Network& graph,
|
||||||
|
const char* origin_stop_area,
|
||||||
|
const char* origin_stop_point,
|
||||||
|
const char* destination_stop_area,
|
||||||
|
const char* destination_stop_point,
|
||||||
|
const char* departure_time,
|
||||||
|
const char* arrival_time
|
||||||
|
) {
|
||||||
|
return AllOf(
|
||||||
|
Field(
|
||||||
|
"origin", &JourneySection::origin,
|
||||||
|
graph.stop_areas.at(origin_stop_area)->stop_points.at(origin_stop_point).get()
|
||||||
|
),
|
||||||
|
Field(
|
||||||
|
"destination", &JourneySection::destination,
|
||||||
|
graph.stop_areas.at(destination_stop_area)->stop_points.at(destination_stop_point).get()
|
||||||
|
),
|
||||||
|
Field(
|
||||||
|
"departure_time", &JourneySection::departure_time, departure_time
|
||||||
|
),
|
||||||
|
Field(
|
||||||
|
"arrival_time", &JourneySection::arrival_time, arrival_time
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... Departures>
|
||||||
|
auto DeparturesFromStopPoint(Departures... departures) {
|
||||||
|
return Field(
|
||||||
|
"value",
|
||||||
|
&stop_point_pair::second,
|
||||||
|
Pointee(
|
||||||
|
Field(
|
||||||
|
"departures", &StopPoint::departures, UnorderedElementsAre(
|
||||||
|
departures...
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class... DeparturesFromStopPoint>
|
||||||
|
auto DeparturesFromStopArea(
|
||||||
|
DeparturesFromStopPoint... departures_from_stop_point
|
||||||
|
) {
|
||||||
|
return Pointer(
|
||||||
|
Field("stop_points", &StopArea::stop_points, UnorderedElementsAre(
|
||||||
|
departures_from_stop_point...
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace trenesis;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds a graph with a single node to test node parsing.
|
||||||
|
*/
|
||||||
|
TEST(Network, build_simple_node) {
|
||||||
|
const auto graph = trenesis::Network::build_from_json(
|
||||||
|
json::parse(single_node_journey),
|
||||||
|
json::parse(single_node_stop_points)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Complete stop areas matching is only performed in this test. For the
|
||||||
|
// rest of the test, only the structure of the network (i.e. stop points and
|
||||||
|
// departures) are tested.
|
||||||
|
EXPECT_THAT(graph.stop_areas, UnorderedElementsAre(
|
||||||
|
AllOf(
|
||||||
|
Field(
|
||||||
|
"key",
|
||||||
|
&stop_area_pair::first,
|
||||||
|
"stop_area:SNCF:87713040"
|
||||||
|
),
|
||||||
|
Field(
|
||||||
|
"value",
|
||||||
|
&stop_area_pair::second,
|
||||||
|
Pointer(AllOf(
|
||||||
|
Field(&trenesis::StopArea::id, "stop_area:SNCF:87713040"),
|
||||||
|
Field(&trenesis::StopArea::name, "Dijon"),
|
||||||
|
Field(&trenesis::StopArea::label, "Dijon (Dijon)"),
|
||||||
|
Field(
|
||||||
|
&trenesis::StopArea::coord,
|
||||||
|
AllOf(
|
||||||
|
Field(&trenesis::Point::longitude, 5.027256),
|
||||||
|
Field(&trenesis::Point::latitude, 47.323411)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
Field(&trenesis::StopArea::stop_points, UnorderedElementsAre(
|
||||||
|
AllOf(
|
||||||
|
Field("key", &stop_point_pair::first, "stop_point:SNCF:87713040:Train"),
|
||||||
|
Field(
|
||||||
|
"value",
|
||||||
|
&stop_point_pair::second,
|
||||||
|
Pointer(AllOf(
|
||||||
|
Field(&trenesis::StopPoint::id, "stop_point:SNCF:87713040:Train"),
|
||||||
|
Field(&trenesis::StopPoint::name, "Dijon"),
|
||||||
|
Field(&trenesis::StopPoint::label, "Dijon (Dijon)"),
|
||||||
|
Field(
|
||||||
|
&trenesis::StopPoint::coord,
|
||||||
|
AllOf(
|
||||||
|
Field(&trenesis::Point::longitude, 5.027256),
|
||||||
|
Field(&trenesis::Point::latitude, 47.323411)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds a linear graph with 3 nodes
|
||||||
|
*/
|
||||||
|
TEST(Network, build_simple_graph) {
|
||||||
|
const auto graph = trenesis::Network::build_from_json(
|
||||||
|
json::parse(dijon_cercy_nevers_journey),
|
||||||
|
json::parse(dijon_cercy_nevers_stop_points)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check stop_areas
|
||||||
|
EXPECT_THAT(graph.stop_areas, UnorderedElementsAre(
|
||||||
|
matchers::StopArea(
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Cercy
|
||||||
|
"stop_area:SNCF:87696492", "stop_point:SNCF:87696492:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Nevers
|
||||||
|
"stop_area:SNCF:87696005", "stop_point:SNCF:87696005:Train"
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
// Check departures
|
||||||
|
|
||||||
|
// Dijon
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040",
|
||||||
|
"stop_point:SNCF:87713040:Train",
|
||||||
|
// Cercy
|
||||||
|
"stop_area:SNCF:87696492",
|
||||||
|
"stop_point:SNCF:87696492:Train",
|
||||||
|
// Departure
|
||||||
|
"081200",
|
||||||
|
// Arrival
|
||||||
|
"095300")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Cercy
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87696492"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Cercy
|
||||||
|
"stop_area:SNCF:87696492",
|
||||||
|
"stop_point:SNCF:87696492:Train",
|
||||||
|
// Nevers
|
||||||
|
"stop_area:SNCF:87696005",
|
||||||
|
"stop_point:SNCF:87696005:Train",
|
||||||
|
// Departure
|
||||||
|
"095400",
|
||||||
|
// Arrival
|
||||||
|
"102900"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Nevers
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87696005"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds a graph with 4 nodes and the following shape:
|
||||||
|
*
|
||||||
|
* Besançon -- Dole -- Dijon
|
||||||
|
* \ /
|
||||||
|
* Arc-et-Senans
|
||||||
|
* |
|
||||||
|
* --Mouchard
|
||||||
|
* / |
|
||||||
|
* / Pontarlier
|
||||||
|
* |
|
||||||
|
* Lons-le-Saunier
|
||||||
|
*/
|
||||||
|
TEST(Network, build_complex_graph) {
|
||||||
|
const auto graph = trenesis::Network::build_from_json(
|
||||||
|
// This is a simplified extract from /coverage/sncf/vehicle_journeys
|
||||||
|
json::parse(besancon_dijon_lons_train_only_journeys),
|
||||||
|
json::parse(besancon_dijon_lons_train_only_stop_points)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check stop_areas
|
||||||
|
EXPECT_THAT(graph.stop_areas, UnorderedElementsAre(
|
||||||
|
matchers::StopArea(
|
||||||
|
// Besançon Viotte
|
||||||
|
"stop_area:SNCF:87718007","stop_point:SNCF:87718007:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Arc-et-senans
|
||||||
|
"stop_area:SNCF:87718841", "stop_point:SNCF:87718841:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833", "stop_point:SNCF:87718833:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Pontarlier
|
||||||
|
"stop_area:SNCF:87715003","stop_point:SNCF:87715003:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Lons-le-Saunier
|
||||||
|
"stop_area:SNCF:87718239", "stop_point:SNCF:87718239:Train"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check departures
|
||||||
|
|
||||||
|
// Besançon Viotte
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718007"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Besançon
|
||||||
|
"stop_area:SNCF:87718007",
|
||||||
|
"stop_point:SNCF:87718007:Train",
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Departure
|
||||||
|
"105600",
|
||||||
|
// Arrival
|
||||||
|
"112000"
|
||||||
|
),
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Besançon
|
||||||
|
"stop_area:SNCF:87718007",
|
||||||
|
"stop_point:SNCF:87718007:Train",
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Departure
|
||||||
|
"165200",
|
||||||
|
// Arrival
|
||||||
|
"171500"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dole
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713412"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040",
|
||||||
|
"stop_point:SNCF:87713040:Train",
|
||||||
|
// Departure
|
||||||
|
"112200",
|
||||||
|
// Arrival
|
||||||
|
"115200"
|
||||||
|
),
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Departure
|
||||||
|
"111400",
|
||||||
|
// Arrival
|
||||||
|
"113200"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dijon
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Arc-et-Senans
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718841"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Departure
|
||||||
|
"113300",
|
||||||
|
// Arrival
|
||||||
|
"113900"
|
||||||
|
),
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Departure
|
||||||
|
"171600",
|
||||||
|
// Arrival
|
||||||
|
"172100"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mouchard
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718833"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Pontarlier
|
||||||
|
"stop_area:SNCF:87715003",
|
||||||
|
"stop_point:SNCF:87715003:Train",
|
||||||
|
// Departure
|
||||||
|
"114200",
|
||||||
|
// Arrival
|
||||||
|
"123700"
|
||||||
|
),
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Lons-le-Saunier
|
||||||
|
"stop_area:SNCF:87718239",
|
||||||
|
"stop_point:SNCF:87718239:Train",
|
||||||
|
// Departure
|
||||||
|
"172200",
|
||||||
|
// Arrival
|
||||||
|
"175900"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pontarlier
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87715003"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Lons-le-Saunier
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718239"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builds a graph with 4 nodes and the following shape:
|
||||||
|
*
|
||||||
|
* Besançon -- Dole -- Dijon
|
||||||
|
* \ /
|
||||||
|
* Arc-et-Senans
|
||||||
|
* | |
|
||||||
|
* --Mouchard
|
||||||
|
* / |
|
||||||
|
* / Pontarlier
|
||||||
|
* |
|
||||||
|
* Lons-le-Saunier
|
||||||
|
*/
|
||||||
|
TEST(Network, build_complex_graph_with_long_distance_train) {
|
||||||
|
const auto graph = trenesis::Network::build_from_json(
|
||||||
|
json::parse(besancon_dijon_lons_journeys),
|
||||||
|
json::parse(besancon_dijon_lons_stop_points)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check stop_areas
|
||||||
|
EXPECT_THAT(graph.stop_areas, UnorderedElementsAre(
|
||||||
|
matchers::StopArea(
|
||||||
|
// Besançon Viotte
|
||||||
|
"stop_area:SNCF:87718007",
|
||||||
|
"stop_point:SNCF:87718007:Train", "stop_point:SNCF:87718007:LongDistanceTrain"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412", "stop_point:SNCF:87713412:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040", "stop_point:SNCF:87713040:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Arc-et-senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train", "stop_point:SNCF:87718841:LongDistanceTrain"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train", "stop_point:SNCF:87718833:LongDistanceTrain"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Pontarlier
|
||||||
|
"stop_area:SNCF:87715003","stop_point:SNCF:87715003:Train"
|
||||||
|
),
|
||||||
|
matchers::StopArea(
|
||||||
|
// Lons-le-Saunier
|
||||||
|
"stop_area:SNCF:87718239",
|
||||||
|
"stop_point:SNCF:87718239:LongDistanceTrain"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check departures
|
||||||
|
|
||||||
|
// Besançon Viotte
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718007"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Besançon
|
||||||
|
"stop_area:SNCF:87718007",
|
||||||
|
"stop_point:SNCF:87718007:Train",
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Departure
|
||||||
|
"105600",
|
||||||
|
// Arrival
|
||||||
|
"112000"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Besançon
|
||||||
|
"stop_area:SNCF:87718007",
|
||||||
|
"stop_point:SNCF:87718007:LongDistanceTrain",
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:LongDistanceTrain",
|
||||||
|
// Departure
|
||||||
|
"165200",
|
||||||
|
// Arrival
|
||||||
|
"171500"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dole
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713412"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Dijon
|
||||||
|
"stop_area:SNCF:87713040",
|
||||||
|
"stop_point:SNCF:87713040:Train",
|
||||||
|
// Departure
|
||||||
|
"112200",
|
||||||
|
// Arrival
|
||||||
|
"115200"
|
||||||
|
),
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Dole
|
||||||
|
"stop_area:SNCF:87713412",
|
||||||
|
"stop_point:SNCF:87713412:Train",
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Departure
|
||||||
|
"111400",
|
||||||
|
// Arrival
|
||||||
|
"113200"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dijon
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87713040"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Arc-et-Senans
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718841"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:Train",
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Departure
|
||||||
|
"113300",
|
||||||
|
// Arrival
|
||||||
|
"113900"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Arc-et-Senans
|
||||||
|
"stop_area:SNCF:87718841",
|
||||||
|
"stop_point:SNCF:87718841:LongDistanceTrain",
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:LongDistanceTrain",
|
||||||
|
// Departure
|
||||||
|
"171600",
|
||||||
|
// Arrival
|
||||||
|
"172100"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mouchard
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718833"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:Train",
|
||||||
|
// Pontarlier
|
||||||
|
"stop_area:SNCF:87715003",
|
||||||
|
"stop_point:SNCF:87715003:Train",
|
||||||
|
// Departure
|
||||||
|
"114200",
|
||||||
|
// Arrival
|
||||||
|
"123700"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
matchers::Departure(
|
||||||
|
graph,
|
||||||
|
// Mouchard
|
||||||
|
"stop_area:SNCF:87718833",
|
||||||
|
"stop_point:SNCF:87718833:LongDistanceTrain",
|
||||||
|
// Lons-le-Saunier
|
||||||
|
"stop_area:SNCF:87718239",
|
||||||
|
"stop_point:SNCF:87718239:LongDistanceTrain",
|
||||||
|
// Departure
|
||||||
|
"172200",
|
||||||
|
// Arrival
|
||||||
|
"175900"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pontarlier
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87715003"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Lons-le-Saunier
|
||||||
|
EXPECT_THAT(graph.stop_areas.at("stop_area:SNCF:87718239"),
|
||||||
|
matchers::DeparturesFromStopArea(
|
||||||
|
matchers::DeparturesFromStopPoint(
|
||||||
|
// None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue