Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
38
libs/routing/routing_integration_tests/CMakeLists.txt
Normal file
38
libs/routing/routing_integration_tests/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# This subproject implements integration tests.
|
||||
# This tests are launched on the whole world dataset.
|
||||
|
||||
# It is recommended to place tests here in the following cases:
|
||||
# - tests are written to be launch on the whole world dataset;
|
||||
# - tests covers significant number of subsystems;
|
||||
|
||||
project(routing_integration_tests)
|
||||
|
||||
set(SRC
|
||||
absent_regions_finder_tests.cpp
|
||||
archival_reporter_tests.cpp
|
||||
bicycle_route_test.cpp
|
||||
bicycle_turn_test.cpp
|
||||
concurrent_feature_parsing_test.cpp
|
||||
cross_country_routing_tests.cpp
|
||||
get_altitude_test.cpp
|
||||
guides_tests.cpp
|
||||
pedestrian_route_test.cpp
|
||||
road_graph_tests.cpp
|
||||
roundabouts_tests.cpp
|
||||
route_test.cpp
|
||||
routing_test_tools.cpp
|
||||
routing_test_tools.hpp
|
||||
small_routes.cpp
|
||||
speed_camera_notifications_tests.cpp
|
||||
street_names_test.cpp
|
||||
transit_route_test.cpp
|
||||
turn_test.cpp
|
||||
)
|
||||
|
||||
omim_add_test(${PROJECT_NAME} ${SRC} REQUIRE_SERVER)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
tracking
|
||||
routing
|
||||
map
|
||||
)
|
||||
|
|
@ -0,0 +1,305 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "map/framework.hpp"
|
||||
#include "map/routing_manager.hpp"
|
||||
|
||||
#include "storage/routing_helpers.hpp"
|
||||
#include "storage/storage.hpp"
|
||||
|
||||
#include "routing_common/num_mwm_id.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace absent_regions_finder_tests
|
||||
{
|
||||
using namespace routing;
|
||||
|
||||
class TestAbsentRegionsFinder
|
||||
{
|
||||
public:
|
||||
TestAbsentRegionsFinder();
|
||||
|
||||
void TestRegions(Checkpoints const & checkpoints, std::set<std::string> const & planRegions);
|
||||
|
||||
protected:
|
||||
std::set<std::string> GetRegions(Checkpoints const & checkpoints);
|
||||
|
||||
FrameworkParams m_frameworkParams;
|
||||
Framework m_framework;
|
||||
RoutingManager & m_manager;
|
||||
RoutingManager::Callbacks & m_callbacks;
|
||||
std::shared_ptr<NumMwmIds> m_numMwmIds;
|
||||
CountryFileGetterFn m_countryFileGetter;
|
||||
LocalFileCheckerFn m_localFileChecker;
|
||||
};
|
||||
|
||||
TestAbsentRegionsFinder::TestAbsentRegionsFinder()
|
||||
: m_framework(m_frameworkParams)
|
||||
, m_manager(m_framework.GetRoutingManager())
|
||||
, m_callbacks(m_manager.GetCallbacksForTests())
|
||||
{
|
||||
m_numMwmIds = CreateNumMwmIds(m_framework.GetStorage());
|
||||
|
||||
m_countryFileGetter = [this](m2::PointD const & p) -> std::string
|
||||
{ return m_callbacks.m_countryInfoGetter().GetRegionCountryId(p); };
|
||||
|
||||
m_localFileChecker = [&](std::string const & countryFile)
|
||||
{
|
||||
MwmSet::MwmId const mwmId =
|
||||
m_callbacks.m_dataSourceGetter().GetMwmIdByCountryFile(platform::CountryFile(countryFile));
|
||||
return mwmId.IsAlive();
|
||||
};
|
||||
}
|
||||
|
||||
void TestAbsentRegionsFinder::TestRegions(Checkpoints const & checkpoints, std::set<std::string> const & planRegions)
|
||||
{
|
||||
std::set<std::string> const & factRegions = GetRegions(checkpoints);
|
||||
TEST_EQUAL(planRegions, factRegions, ());
|
||||
}
|
||||
|
||||
std::set<std::string> TestAbsentRegionsFinder::GetRegions(Checkpoints const & checkpoints)
|
||||
{
|
||||
AbsentRegionsFinder finder(m_countryFileGetter, m_localFileChecker, m_numMwmIds, m_callbacks.m_dataSourceGetter());
|
||||
RouterDelegate delegate;
|
||||
|
||||
finder.GenerateAbsentRegions(checkpoints, delegate);
|
||||
|
||||
std::set<std::string> regions;
|
||||
finder.GetAllRegions(regions);
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
||||
// From "Russia_Republic of Karelia_South" to "Russia_Krasnodar Krai".
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=61.759%2C34.452%3B45.070%2C38.940#map=5/54.869/40.210
|
||||
/**
|
||||
* @todo Current test set and Organic set differ from OSRM route. Need to make deep investigation here.
|
||||
* OSRM wants Novgorod, Tver, Moscow (looks good).
|
||||
* Organic wants Vologda, Tver, Moscow East, Ryazan (also may be good).
|
||||
* Current test set doesn't have Tver (obvious error).
|
||||
* Ukraine_Luhansk Oblast is not a good idea for both variants.
|
||||
*/
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Karelia_Krasnodar)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(61.76, 34.45), mercator::FromLatLon(45.07, 38.94)};
|
||||
|
||||
// Current test set.
|
||||
/*
|
||||
std::set<std::string> const planRegions{"Russia_Krasnodar Krai",
|
||||
"Russia_Leningradskaya Oblast_Southeast",
|
||||
"Russia_Lipetsk Oblast",
|
||||
"Russia_Moscow",
|
||||
"Russia_Moscow Oblast_East",
|
||||
"Russia_Moscow Oblast_West",
|
||||
"Russia_Republic of Karelia_South",
|
||||
"Russia_Rostov Oblast",
|
||||
"Russia_Tula Oblast",
|
||||
"Russia_Vologda Oblast",
|
||||
"Russia_Voronezh Oblast",
|
||||
"Ukraine_Luhansk Oblast"};
|
||||
*/
|
||||
|
||||
// Organic test set.
|
||||
std::set<std::string> const planRegions{"Russia_Krasnodar Krai",
|
||||
"Russia_Leningradskaya Oblast_Southeast",
|
||||
"Russia_Lipetsk Oblast",
|
||||
"Russia_Moscow Oblast_East",
|
||||
"Russia_Republic of Karelia_South",
|
||||
"Russia_Rostov Oblast",
|
||||
"Russia_Ryazan Oblast",
|
||||
"Russia_Tula Oblast",
|
||||
"Russia_Tver Oblast",
|
||||
"Russia_Vologda Oblast",
|
||||
"Russia_Voronezh Oblast",
|
||||
"Ukraine_Luhansk Oblast"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Canada_Ontario_Kingston" to "US_Maryland_and_DC".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Kingston_DC)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(45.38, -75.69), mercator::FromLatLon(38.91, -77.031)};
|
||||
|
||||
std::set<std::string> const planRegions{"Canada_Ontario_Kingston", "US_Maryland_Baltimore", "US_Maryland_and_DC",
|
||||
"US_New York_North", "US_New York_West", "US_Pennsylvania_Central",
|
||||
"US_Pennsylvania_Scranton"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "US_Colorado_Aspen" to "Canada_Saskatchewan_Saskatoon".
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=39.95763%2C-106.79994%3B49.92034%2C-106.99302
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Colorado_Saskatchewan)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(39.95763, -106.79994), mercator::FromLatLon(49.92034, -106.99302)};
|
||||
|
||||
std::set<std::string> const planRegions{"Canada_Saskatchewan_Saskatoon", "US_Colorado_Aspen", "US_Montana_East",
|
||||
"US_Wyoming"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Belgium_Flemish Brabant" to "Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen".
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=50.87763%2C4.44676%3B50.76935%2C6.42488
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Belgium_Germany)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(50.87763, 4.44676), mercator::FromLatLon(50.76935, 6.42488)};
|
||||
|
||||
// OSRM, Valhalla with E40.
|
||||
std::set<std::string> const expected1 = {
|
||||
"Belgium_Flemish Brabant",
|
||||
"Belgium_Walloon Brabant",
|
||||
"Belgium_Liege",
|
||||
"Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen",
|
||||
};
|
||||
|
||||
// GraphHopper with E314.
|
||||
std::set<std::string> const expected2 = {
|
||||
"Belgium_Flemish Brabant",
|
||||
"Belgium_Limburg",
|
||||
"Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen",
|
||||
"Netherlands_Limburg",
|
||||
};
|
||||
|
||||
auto const actual = GetRegions(checkpoints);
|
||||
TEST(actual == expected1 || actual == expected2, (actual));
|
||||
}
|
||||
|
||||
// From "Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen" to "Belgium_Flemish Brabant".
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=50.76935%2C6.42488%3B50.78285%2C4.46508
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Germany_Belgium)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(50.76935, 6.42488), mercator::FromLatLon(50.78285, 4.46508)};
|
||||
|
||||
// Valhalla with E40.
|
||||
std::set<std::string> const expected1 = {"Belgium_Flemish Brabant", "Belgium_Walloon Brabant", "Belgium_Liege",
|
||||
"Belgium_Limburg",
|
||||
"Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen"};
|
||||
|
||||
// OSRM, GraphHopper with E314.
|
||||
std::set<std::string> const expected2 = {
|
||||
"Belgium_Flemish Brabant",
|
||||
"Belgium_Limburg",
|
||||
"Germany_North Rhine-Westphalia_Regierungsbezirk Koln_Aachen",
|
||||
"Netherlands_Limburg",
|
||||
};
|
||||
|
||||
auto const actual = GetRegions(checkpoints);
|
||||
TEST(actual == expected1 || actual == expected2, (actual));
|
||||
}
|
||||
|
||||
// From "Kazakhstan_South" to "Mongolia".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Kazakhstan_Mongolia)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(46.12223, 79.28636), mercator::FromLatLon(47.04792, 97.74559)};
|
||||
|
||||
std::set<std::string> const planRegions{"Kazakhstan_South", "China_Xinjiang", "Mongolia"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Bolivia_North" to "Brazil_North Region_East".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Bolivia_Brazil)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(-16.54128, -60.83588), mercator::FromLatLon(-7.38744, -51.29514)};
|
||||
|
||||
std::set<std::string> const planRegions{"Bolivia_North", "Brazil_Mato Grosso", "Brazil_North Region_East"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Egypt" to "Sudan_West".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Egypt_Sudan)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(25.84571, 30.34731), mercator::FromLatLon(19.82398, 30.20142)};
|
||||
|
||||
std::set<std::string> const planRegions{"Egypt", "Sudan_West"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Sudan_West" to "Chad".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Sudan_Chad)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(12.91113, 25.01158), mercator::FromLatLon(13.44014, 20.23824)};
|
||||
|
||||
std::set<std::string> const planRegions{"Sudan_West", "Chad"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Australia_Sydney" to "Australia_Victoria".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Sydney_Victoria)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(-35.08077, 148.45423), mercator::FromLatLon(-36.81267, 145.74843)};
|
||||
|
||||
std::set<std::string> const planRegions{"Australia_Sydney", "Australia_Victoria"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// From "Thailand_South" to "Cambodia".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Thailand_Cambodia)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(7.89, 98.30), mercator::FromLatLon(11.56, 104.86)};
|
||||
|
||||
std::set<std::string> const planRegions{"Thailand_South", "Cambodia"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// Inside "China_Sichuan". If the route is inside single mwm we expect empty result from
|
||||
// RegionsRouter.
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, China)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(30.78611, 102.55829), mercator::FromLatLon(27.54127, 102.02502)};
|
||||
|
||||
TestRegions(checkpoints, {});
|
||||
}
|
||||
|
||||
// Inside "Finland_Eastern Finland_North".
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Finland)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(63.54162, 28.71141), mercator::FromLatLon(64.6790, 28.73029)};
|
||||
|
||||
TestRegions(checkpoints, {});
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/980
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, BC_Alberta)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(49.2608724, -123.1139529),
|
||||
mercator::FromLatLon(53.5354110, -113.5079960)};
|
||||
|
||||
std::set<std::string> const planRegions{"Canada_Alberta_Edmonton", "Canada_Alberta_South",
|
||||
"Canada_British Columbia_Southeast", "Canada_British Columbia_Vancouver"};
|
||||
|
||||
TestRegions(checkpoints, planRegions);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1721
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Germany_Cologne_Croatia_Zagreb)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(50.924, 6.943), mercator::FromLatLon(45.806, 15.963)};
|
||||
|
||||
/// @todo Optimal route should include Graz-Maribor-Zagreb.
|
||||
auto const & rgns = GetRegions(checkpoints);
|
||||
TEST(rgns.count("Austria_Styria_Graz") > 0, ());
|
||||
}
|
||||
|
||||
UNIT_CLASS_TEST(TestAbsentRegionsFinder, Russia_SPB_Pechory)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(59.9387323, 30.3162295),
|
||||
mercator::FromLatLon(57.8133044, 27.6081855)};
|
||||
|
||||
/// @todo Optimal should not include Estonia.
|
||||
for (auto const & rgn : GetRegions(checkpoints))
|
||||
TEST(!rgn.starts_with("Estonia"), ());
|
||||
}
|
||||
|
||||
} // namespace absent_regions_finder_tests
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "tracking/archival_manager.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "map/framework.hpp"
|
||||
#include "map/routing_manager.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "coding/file_writer.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/file_name_utils.hpp"
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
/// @obsolete https://github.com/organicmaps/organicmaps/commit/04bc294c851bdfe3189d04391f7c3a7d6e601835
|
||||
|
||||
/*
|
||||
namespace
|
||||
{
|
||||
void UpdateLocationForArchiving(location::GpsInfo & point) { point.m_timestamp += 3; }
|
||||
|
||||
size_t GetFilesCount(std::string const & path,
|
||||
std::string const & extension = ARCHIVE_TRACKS_FILE_EXTENSION)
|
||||
{
|
||||
Platform::FilesList files;
|
||||
Platform::GetFilesByExt(path, extension, files);
|
||||
return files.size();
|
||||
}
|
||||
|
||||
void FillArchive(RoutingManager & manager, size_t count)
|
||||
{
|
||||
location::GpsInfo point;
|
||||
point.m_horizontalAccuracy = 10.0;
|
||||
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
{
|
||||
UpdateLocationForArchiving(point);
|
||||
manager.OnLocationUpdate(point);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
}
|
||||
|
||||
void CreateEmptyFile(std::string const & path, std::string const & fileName)
|
||||
{
|
||||
FileWriter fw(base::JoinPath(path, fileName));
|
||||
}
|
||||
|
||||
void TestFilesExistence(size_t newestIndex, size_t fileCount, std::string const & fileExtension,
|
||||
std::string const & dir)
|
||||
{
|
||||
CHECK_GREATER(newestIndex, fileCount, ());
|
||||
for (size_t i = newestIndex; i > newestIndex - fileCount; --i)
|
||||
{
|
||||
TEST(Platform::IsFileExistsByFullPath(base::JoinPath(dir, std::to_string(i) + fileExtension)),
|
||||
());
|
||||
}
|
||||
}
|
||||
|
||||
TRouteResult GetRouteResult()
|
||||
{
|
||||
return integration::CalculateRoute(integration::GetVehicleComponents(routing::VehicleType::Car),
|
||||
mercator::FromLatLon(55.7607268, 37.5801099), m2::PointD::Zero(),
|
||||
mercator::FromLatLon(55.75718, 37.63156));
|
||||
}
|
||||
|
||||
size_t GetInitialTimestamp()
|
||||
{
|
||||
auto const now = std::chrono::system_clock::now();
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
|
||||
}
|
||||
|
||||
class TestArchivalReporter
|
||||
{
|
||||
public:
|
||||
TestArchivalReporter()
|
||||
: m_framework(m_frameworkParams)
|
||||
, m_manager(m_framework.GetRoutingManager())
|
||||
, m_session(m_manager.RoutingSession())
|
||||
, m_routeResult(GetRouteResult())
|
||||
, m_route(*m_routeResult.first)
|
||||
, m_tracksDir(tracking::GetTracksDirectory())
|
||||
{
|
||||
RouterResultCode const result = m_routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
m_manager.SetRouter(routing::RouterType::Vehicle);
|
||||
m_session.SetState(routing::SessionState::OnRoute);
|
||||
m_session.EnableFollowMode();
|
||||
|
||||
m_session.SetRoutingSettings(routing::GetRoutingSettings(routing::VehicleType::Car));
|
||||
m_session.AssignRouteForTesting(std::make_shared<Route>(m_route), m_routeResult.second);
|
||||
}
|
||||
|
||||
~TestArchivalReporter() { Platform::RmDirRecursively(m_tracksDir); }
|
||||
|
||||
protected:
|
||||
FrameworkParams m_frameworkParams;
|
||||
Framework m_framework;
|
||||
RoutingManager & m_manager;
|
||||
routing::RoutingSession & m_session;
|
||||
TRouteResult m_routeResult;
|
||||
Route & m_route;
|
||||
std::string m_tracksDir;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
// Ordinary ArchivalReporter pipeline: periodically dump files.
|
||||
UNIT_CLASS_TEST(TestArchivalReporter, StraightPipeline)
|
||||
{
|
||||
TEST_EQUAL(GetFilesCount(m_tracksDir), 0, ());
|
||||
for (size_t iter = 1; iter < 4; ++iter)
|
||||
{
|
||||
FillArchive(m_manager, tracking::kItemsForDump);
|
||||
TEST_EQUAL(GetFilesCount(m_tracksDir), iter, ());
|
||||
}
|
||||
}
|
||||
|
||||
// Startup of ArchivalReporter: if there are too many files they need to be removed.
|
||||
UNIT_TEST(TestArchivalReporter_DeleteOldData)
|
||||
{
|
||||
tracking::ArchivingSettings const settings;
|
||||
std::string const tracksDir = tracking::GetTracksDirectory();
|
||||
CHECK(Platform::MkDirChecked(tracksDir), ());
|
||||
size_t const maxFilesCount = std::max(settings.m_maxFilesToSave, settings.m_maxArchivesToSave);
|
||||
size_t const tsStart = GetInitialTimestamp();
|
||||
size_t newestFileIndex = maxFilesCount * 2;
|
||||
|
||||
// Create files before the AchivalReporter initialization.
|
||||
for (size_t i = 0, ts = tsStart; i <= newestFileIndex; ++i, ++ts)
|
||||
{
|
||||
auto const name = std::to_string(ts);
|
||||
CreateEmptyFile(tracksDir, name + ARCHIVE_TRACKS_FILE_EXTENSION);
|
||||
CreateEmptyFile(tracksDir, name + ARCHIVE_TRACKS_ZIPPED_FILE_EXTENSION);
|
||||
TEST_EQUAL(GetFilesCount(tracksDir, ARCHIVE_TRACKS_FILE_EXTENSION), i + 1, ());
|
||||
TEST_EQUAL(GetFilesCount(tracksDir, ARCHIVE_TRACKS_ZIPPED_FILE_EXTENSION), i + 1, ());
|
||||
}
|
||||
|
||||
// Create the ArchivalReporter instance. It will remove the oldest files on startup.
|
||||
TestArchivalReporter testReporter;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
// Check that the files count equals to the maximum count.
|
||||
TEST_EQUAL(GetFilesCount(tracksDir, ARCHIVE_TRACKS_FILE_EXTENSION), settings.m_maxFilesToSave,
|
||||
());
|
||||
TEST_EQUAL(GetFilesCount(tracksDir, ARCHIVE_TRACKS_ZIPPED_FILE_EXTENSION),
|
||||
settings.m_maxArchivesToSave, ());
|
||||
// Check that the oldest files are removed and the newest ones are not.
|
||||
newestFileIndex += tsStart;
|
||||
TestFilesExistence(newestFileIndex, settings.m_maxFilesToSave, ARCHIVE_TRACKS_FILE_EXTENSION,
|
||||
tracksDir);
|
||||
TestFilesExistence(newestFileIndex, settings.m_maxArchivesToSave,
|
||||
ARCHIVE_TRACKS_ZIPPED_FILE_EXTENSION, tracksDir);
|
||||
}
|
||||
|
||||
// ArchivalReporter pipeline with no dumping.
|
||||
// Checks behaviour if there is no free space on device.
|
||||
UNIT_CLASS_TEST(TestArchivalReporter, FreeSpaceOnDisk)
|
||||
{
|
||||
tracking::ArchivingSettings settings;
|
||||
settings.m_minFreeSpaceOnDiskBytes = std::numeric_limits<size_t>::max();
|
||||
m_manager.ConfigureArchivalReporter(settings);
|
||||
|
||||
TEST_EQUAL(GetFilesCount(m_tracksDir), 0, ());
|
||||
for (size_t iter = 1; iter < 4; ++iter)
|
||||
{
|
||||
FillArchive(m_manager, tracking::kItemsForDump);
|
||||
TEST_EQUAL(GetFilesCount(m_tracksDir), 0, ());
|
||||
}
|
||||
}
|
||||
*/
|
||||
449
libs/routing/routing_integration_tests/bicycle_route_test.cpp
Normal file
449
libs/routing/routing_integration_tests/bicycle_route_test.cpp
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
namespace bicycle_route_test
|
||||
{
|
||||
using namespace integration;
|
||||
using namespace routing;
|
||||
using namespace routing::turns;
|
||||
|
||||
UNIT_TEST(RussiaMoscowSevTushinoParkPreferingBicycleWay)
|
||||
{
|
||||
// Prefer a good quality dedicated cycleway over bad quality path + footway.
|
||||
/// @todo: replace with a better case that prefers a longer cycleway to e.g. shorter track of same quality.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.87445, 37.43711),
|
||||
{0., 0.}, mercator::FromLatLon(55.87203, 37.44274), 460.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowNahimovskyLongRoute)
|
||||
{
|
||||
// Get onto a secondary and follow it. Same as GraphHopper.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.66151, 37.63320),
|
||||
{0., 0.}, mercator::FromLatLon(55.67695, 37.56220), 5670.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UseSteps)
|
||||
{
|
||||
// Use the steps as the detour is way too long.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.4403114, 37.7740223), {0., 0.},
|
||||
mercator::FromLatLon(55.439703, 37.7725059), 139.058);
|
||||
}
|
||||
|
||||
UNIT_TEST(Italy_AvoidSteps)
|
||||
{
|
||||
// 690m detour instead of taking a 120m shortcut via steps.
|
||||
// Same as Valhalla. But GraphHopper prefers steps.
|
||||
// https://github.com/organicmaps/organicmaps/issues/2253
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(42.4631, 14.21342),
|
||||
{0., 0.}, mercator::FromLatLon(42.46343, 14.2125), 687.788);
|
||||
}
|
||||
|
||||
UNIT_TEST(SwedenStockholmCyclewayPriority)
|
||||
{
|
||||
/// @todo(pastk): DELETE: the cycleway is the shortest and the only obvious option here anyway, what's the value of
|
||||
/// this test?
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(59.33151, 18.09347),
|
||||
{0., 0.}, mercator::FromLatLon(59.33052, 18.09391), 113.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(Poland_PreferCyclewayDetour)
|
||||
{
|
||||
// Prefer a longer cycleway route with a little uphill
|
||||
// rather than a 130m shorter route via a residential.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(50.043813, 20.016456), {0., 0.},
|
||||
mercator::FromLatLon(50.047522, 20.029986), 1354.04);
|
||||
}
|
||||
|
||||
UNIT_TEST(Poland_PreferCycleway_AvoidPrimary)
|
||||
{
|
||||
// Prefer a 180m longer and a little uphill cycleway detour to avoid a straight primary road.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(50.031478, 19.948912), {0., 0.},
|
||||
mercator::FromLatLon(50.036289, 19.941198), 993.818);
|
||||
}
|
||||
|
||||
UNIT_TEST(NetherlandsAmsterdamBicycleNo)
|
||||
{
|
||||
// Snap start/finish point to the closest suitable road.
|
||||
// The closest road here has a bicycle=no tag so its ignored and the next closest cycleway is used.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.32716, 5.05932),
|
||||
{0., 0.}, mercator::FromLatLon(52.32587, 5.06121), 338.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(NetherlandsAmsterdamBicycleYes)
|
||||
{
|
||||
// Test that a highway=unclassified gets a significant boost due to presence of bicycle=yes tag.
|
||||
/// @todo(pastk): it shouldn't as there is no cycling infra (cycleway:both=no
|
||||
/// https://www.openstreetmap.org/way/214196820) and bicycle=yes means "its legal", not "its fast", see
|
||||
/// https://github.com/organicmaps/organicmaps/issues/9593
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.32872, 5.07527), {0.0, 0.0},
|
||||
mercator::FromLatLon(52.33853, 5.08941));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TestRouteTime(*routeResult.first, 284.38);
|
||||
}
|
||||
|
||||
UNIT_TEST(Netherlands_Amsterdam_OnewaySt_CyclewayOpposite)
|
||||
{
|
||||
// Bicycles can go against the car traffic on oneway=yes roads if there is a cycleway=opposite tag.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(52.37571, 4.88591),
|
||||
{0., 0.}, mercator::FromLatLon(52.37736, 4.88744), 212.8);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowKashirskoe16ToCapLongRoute)
|
||||
{
|
||||
// There is no dedicated bicycle infra, except short end part. All OSM routers give different results,
|
||||
// OM yields a short and logical route shortcutting via some service roads and footways (allowed in Russia).
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.66230, 37.63214),
|
||||
{0., 0.}, mercator::FromLatLon(55.68927, 37.70356), 6968.64);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_UseServiceCountrysideRoads)
|
||||
{
|
||||
/// @todo(pastk): long service countryside roads is a mismapping probably.
|
||||
/// https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1850558462
|
||||
// Goes by smaller roads, including service ones. Also avoids extra 60m uphill
|
||||
// of the secondary road route. Most similar to Valhalla, but 2km shorter.
|
||||
// https://github.com/organicmaps/organicmaps/issues/6027
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(49.1423, 10.068),
|
||||
{0., 0.}, mercator::FromLatLon(49.3023, 10.5738), 47769.2);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowServicePassThrough)
|
||||
{
|
||||
// Passing through living_street and service is allowed in Russia.
|
||||
TRouteResult route = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.79649, 37.53738), {0., 0.},
|
||||
mercator::FromLatLon(55.79618, 37.54071));
|
||||
TEST_EQUAL(route.second, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_UseAllowedFootways)
|
||||
{
|
||||
// Shortcut via footways if its allowed in the country.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.6572884, 37.6142816), {0., 0.},
|
||||
mercator::FromLatLon(55.6576455, 37.6164412), 182.766);
|
||||
}
|
||||
|
||||
UNIT_TEST(Spain_Barcelona_UsePedestrianAndLivingStreet)
|
||||
{
|
||||
// Don't make long detours to avoid pedestrian and living streets.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(41.40080, 2.16026),
|
||||
{0.0, 0.0}, mercator::FromLatLon(41.39937, 2.15735),
|
||||
516.14 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Poland_UseLivingStreet)
|
||||
{
|
||||
// Don't make a long detour via an uphill residential to avoid a living street.
|
||||
// https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1851446320
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(50.006085, 19.962158), {0.0, 0.0},
|
||||
mercator::FromLatLon(50.006664, 19.957639), 335.978 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Poland_UseLivingStreet2)
|
||||
{
|
||||
// Don't make a long detour via service and residential to avoid a living street.
|
||||
// (a more strict and longer test than above)
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(50.096027, 19.90433), {0.0, 0.0},
|
||||
mercator::FromLatLon(50.099875, 19.889867), 1124.7 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaKerchStraitFerryRoute)
|
||||
{
|
||||
// Use a cross-mwm ferry.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(45.4167, 36.7658),
|
||||
{0.0, 0.0}, mercator::FromLatLon(45.3653, 36.6161), 17151.4);
|
||||
}
|
||||
|
||||
UNIT_TEST(SwedenStockholmBicyclePastFerry)
|
||||
{
|
||||
// Several consecutive ferries.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(59.4725, 18.51355),
|
||||
{0.0, 0.0}, mercator::FromLatLon(59.42533, 18.35991), 14338.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(CrossMwmKaliningradRegionToLiepaja)
|
||||
{
|
||||
// A cross mwm route (3 regions). Includes a ferry.
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(54.63519, 21.80749), {0., 0.},
|
||||
mercator::FromLatLon(56.51119, 21.01847), 266992);
|
||||
}
|
||||
|
||||
UNIT_TEST(Lithuania_Avoid_Ferry_Long_Route)
|
||||
{
|
||||
// Avoid ferry Dreverna-Juodkrantė-Klaipėda.
|
||||
RoutingOptionSetter optionsGuard(RoutingOptions::Ferry);
|
||||
|
||||
// GraphHopper makes a detour (via unpaved), OSRM goes straight with highway=primary,
|
||||
// Valhalla uses a part of the primary. A user says that GraphHopper is the best option.
|
||||
// https://www.openstreetmap.org/directions?engine=graphhopper_bicycle&route=55.340%2C21.459%3B55.715%2C21.135
|
||||
// OM uses a much shorter (56km vs 64km) route with bicycle=yes tracks and a short path section.
|
||||
/// @todo(pastk): the route goes through a landuse=military briefly and OM doesn't account for that.
|
||||
/// And too much preference is given to bicycle=yes track, see https://github.com/organicmaps/organicmaps/issues/9593
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.3405073, 21.4595925), {0., 0.},
|
||||
mercator::FromLatLon(55.7140174, 21.1365445), 56243.2);
|
||||
}
|
||||
|
||||
UNIT_TEST(SpainTenerifeAdejeVilaflor)
|
||||
{
|
||||
// Test on riding up from Adeje (sea level) to Vilaflor (altitude 1400 meters).
|
||||
// A long ETA due to going uphill.
|
||||
TRouteResult const res =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(28.11984, -16.72592), {0., 0.},
|
||||
mercator::FromLatLon(28.15865, -16.63704));
|
||||
TEST_EQUAL(res.second, RouterResultCode::NoError, ());
|
||||
|
||||
TestRouteLength(*res.first, 26401);
|
||||
TestRouteTime(*res.first, 10716);
|
||||
}
|
||||
|
||||
UNIT_TEST(SpainTenerifeVilaflorAdeje)
|
||||
{
|
||||
// Test on riding down from Vilaflor (altitude 1400 meters) to Adeje (sea level).
|
||||
// A short ETA going downhill.
|
||||
TRouteResult const res =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(28.15865, -16.63704), {0., 0.},
|
||||
mercator::FromLatLon(28.11984, -16.72592));
|
||||
TEST_EQUAL(res.second, RouterResultCode::NoError, ());
|
||||
|
||||
TestRouteLength(*res.first, 24582);
|
||||
TestRouteTime(*res.first, 4459);
|
||||
}
|
||||
|
||||
// Two tests on not building route against traffic on road with oneway:bicycle=yes.
|
||||
UNIT_TEST(Munich_OnewayBicycle1)
|
||||
{
|
||||
/// @todo Should combine TurnSlightLeft, TurnLeft, TurnLeft into UTurnLeft?
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(48.1601673, 11.5630245), {0.0, 0.0},
|
||||
mercator::FromLatLon(48.1606349, 11.5631699), 264.042 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Munich_OnewayBicycle2)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(48.17819, 11.57286),
|
||||
{0.0, 0.0}, mercator::FromLatLon(48.17867, 11.57303),
|
||||
201.532 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(London_GreenwichTunnel)
|
||||
{
|
||||
// Use the bicycle=dismount foot tunnel https://www.openstreetmap.org/way/4358990
|
||||
// as a detour is way too long.
|
||||
// https://github.com/organicmaps/organicmaps/issues/8028
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(51.4817397, -0.0100070258), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.4883739, -0.00809729298), 1183.12 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Batumi_AvoidServiceDetour)
|
||||
{
|
||||
// Go straight via a residential without a short detour via service road.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(41.6380014, 41.6269446), {0.0, 0.0},
|
||||
mercator::FromLatLon(41.6392113, 41.6260084), 160.157 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Gdansk_AvoidLongCyclewayDetour)
|
||||
{
|
||||
/// @todo(pastk): DELETE: the preferred route goes by a shared cycleway also - replace with a better case (the next
|
||||
/// one!)
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(54.2632738, 18.6771661), {0.0, 0.0},
|
||||
mercator::FromLatLon(54.2698882, 18.6765837), 760.749 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Netherlands_AvoidLongCyclewayDetour)
|
||||
{
|
||||
// Same as GraphHopper.
|
||||
// The first sample from https://github.com/organicmaps/organicmaps/issues/1772
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(52.253405, 6.182288), {0.0, 0.0},
|
||||
mercator::FromLatLon(52.247599, 6.197973), 1440.8 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Poland_AvoidDetourAndExtraCrossings)
|
||||
{
|
||||
// Avoid making a longer cycleway detour which involves extra road crossings.
|
||||
// Same as GraphHopper. Valhalla suggests going by the road (worse for cyclists
|
||||
// really preferring to avoid cars whenever possible, may be preferred
|
||||
// for more aggressive ones depending on light phase to go through one traffic light only).
|
||||
// https://github.com/organicmaps/organicmaps/issues/7954
|
||||
// https://github.com/organicmaps/organicmaps/pull/9692#discussion_r1849627559
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(50.08227, 20.03348),
|
||||
{0.0, 0.0}, mercator::FromLatLon(50.08253, 20.03191),
|
||||
157.7 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_DontAvoidNocyclewayResidential)
|
||||
{
|
||||
// No strange detours to avoid a nocycleway residential. Same as GraphHopper.
|
||||
// https://github.com/organicmaps/organicmaps/issues/4059#issuecomment-1399338757
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(51.33772, 12.41432),
|
||||
{0.0, 0.0}, mercator::FromLatLon(51.33837, 12.40958),
|
||||
359.495 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(UK_UseNocyclewayTertiary)
|
||||
{
|
||||
// A preferred route is through nocycleway tertiary roads. Same as all OSM routers.
|
||||
// The detour is via a shared cycleway and with 130m less alt gain, but is 4km longer.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(51.3826906, -2.3481788), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.3615095, -2.3114138), 4468.83 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_UseResidential)
|
||||
{
|
||||
// No long detour to avoid a short residential.
|
||||
// https://github.com/organicmaps/organicmaps/issues/9330
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(48.1464472, 11.5589919), {0.0, 0.0},
|
||||
mercator::FromLatLon(48.1418297, 11.5602123), 614.963 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Belarus_StraightFootway)
|
||||
{
|
||||
// Prefer footways over roads in Belarus due to local laws.
|
||||
// https://github.com/organicmaps/organicmaps/issues/4145
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(53.8670285, 30.3162749), {0.0, 0.0},
|
||||
mercator::FromLatLon(53.876436, 30.3348084), 1613.34 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Spain_Madrid_DedicatedCycleway)
|
||||
{
|
||||
// Check that OM uses dedicated "Carril bici del Paseo de la Castellana".
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(40.459616, -3.690031), {0.0, 0.0},
|
||||
mercator::FromLatLon(40.4403523, -3.69267444), 2283.89 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Seoul_ElevationDetour)
|
||||
{
|
||||
// The longer 664m route has less uphill Ascent: 25 Descent: 17
|
||||
// vs Ascent: 37 Descent: 29n of the shorter 545m route.
|
||||
// Valhalla and GraphHopper prefer a longer route also.
|
||||
// https://github.com/organicmaps/organicmaps/issues/7047
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(37.510519, 127.101251), {0.0, 0.0},
|
||||
mercator::FromLatLon(37.513874, 127.099234), 663.547 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Spain_Zaragoza_Fancy_NoBicycle_Crossings)
|
||||
{
|
||||
// A highway=crossing node https://www.openstreetmap.org/node/258776322 on the way
|
||||
// has bicycle=no, which doesn't prevent routing along this road.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(41.6523561, -0.881151311), {0.0, 0.0},
|
||||
mercator::FromLatLon(41.6476614, -0.885694674), 649.855 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_Use_Bicycle_Track)
|
||||
{
|
||||
// Avoid primary and prefer smaller roads and tracks with bicycle=yes.
|
||||
/// @todo Still prefers a no-cycling-infra but bicycle=yes secondary rather than a paved track,
|
||||
/// see https://github.com/organicmaps/organicmaps/issues/1201#issuecomment-946042937
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(48.420723, 9.90350146), {0.0, 0.0},
|
||||
mercator::FromLatLon(48.4080367, 9.86597073), 3778.41 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Finland_Use_Tertiary_LowTraffic)
|
||||
{
|
||||
// Detour via a tertiary to avoid a secondary.
|
||||
// https://github.com/orgs/organicmaps/discussions/5158#discussioncomment-5938807
|
||||
/// @todo(pastk): prefer roads with lower maxspeed.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(61.5445696, 23.9394003), {0.0, 0.0},
|
||||
mercator::FromLatLon(61.6153965, 23.876755), 9876.65 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Belarus_Stolbcy_Use_Unpaved)
|
||||
{
|
||||
// Goes by a track, unpaved and paved streets and an unpaved_bad track in the end.
|
||||
// Closer as GraphHopper. Valhalla detours the unpaved street.
|
||||
// OSRM shortcuts through paths and a ford.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(53.471389, 26.7422186), {0.0, 0.0},
|
||||
mercator::FromLatLon(53.454082, 26.7560061), 4620.81 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UseTrunk_Long)
|
||||
{
|
||||
// Prefer riding via a straight trunk road instead of taking a long +30% detour via smaller roads.
|
||||
/// @todo(pastk): DELETE: This test is controversial as this route has sections with longer relative trunk-avoiding
|
||||
/// detours e.g. from 67.9651692,32.8685132 to 68.022093,32.9654391 its +40% longer via a teriary and its OK?
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(66.271, 33.048),
|
||||
{0.0, 0.0}, mercator::FromLatLon(68.95, 33.045), 404262 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
/// @todo(pastk): find a good "avoid trunk" test case where trunk allows cycling.
|
||||
UNIT_TEST(Russia_UseTrunk)
|
||||
{
|
||||
// Prefer riding via a straight trunk road instead of taking weird detours via smaller roads
|
||||
// (651m via a tertiaty + service in this case).
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(68.0192918, 32.9576269), {0.0, 0.0},
|
||||
mercator::FromLatLon(68.0212968, 32.9632167), 323.951 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UseTrunk_AvoidGasStationsDetours)
|
||||
{
|
||||
/// @todo(pastk): still OM detours into many petrol stations along the trunk.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.9132468, 39.1453188), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.9146268, 39.153307), 613.721 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Netherlands_IgnoreCycleBarrier_WithoutAccess)
|
||||
{
|
||||
// There is a barrier=cycle_barrier in the beginning of the route
|
||||
// and it doesn't affect routing as there is no explicit bicycle=no.
|
||||
// https://github.com/organicmaps/organicmaps/issues/3920
|
||||
/// @todo(pastk): such barrier should have a small penalty in routing
|
||||
/// as it slows down a cyclist.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(51.9960994, 5.67350176), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.9996861, 5.67299133), 428.801);
|
||||
}
|
||||
|
||||
UNIT_TEST(UK_ForbidGates_WithoutAccess)
|
||||
{
|
||||
// A barrier=gate without explicit access leads to a long detour.
|
||||
// https://www.openstreetmap.org/node/6993853766
|
||||
/// @todo OSRM/Valhalla/GraphHopper ignore such gates,
|
||||
/// see
|
||||
/// https://www.openstreetmap.org/directions?engine=fossgis_valhalla_bicycle&route=51.3579329%2C-2.3137701%3B51.3574666%2C-2.3152644
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(51.3579329, -2.3137701), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.3574666, -2.31526436), 1149.28);
|
||||
}
|
||||
|
||||
UNIT_TEST(UK_Canterbury_AvoidDismount)
|
||||
{
|
||||
/// @todo(pastk): the case is controversial, a user emailed "All cyclists in our town use this particular footway"
|
||||
/// but we don't know if cyclists dismount there or just cycle through (ignoring the UK rules).
|
||||
// A shortcut via a footway is 305 meters, ETAs are similar, but cyclists prefer to ride!
|
||||
// Check the London_GreenwichTunnel case for when dismounting is reasonable as the detour is way too long.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(51.2794435, 1.05627788), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.2818863, 1.05725286), 976);
|
||||
}
|
||||
|
||||
} // namespace bicycle_route_test
|
||||
274
libs/routing/routing_integration_tests/bicycle_turn_test.cpp
Normal file
274
libs/routing/routing_integration_tests/bicycle_turn_test.cpp
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "routing/route.hpp"
|
||||
|
||||
namespace bicycle_turn_test
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace routing::turns;
|
||||
|
||||
UNIT_TEST(RussiaMoscowSevTushinoParkBicycleWayTurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.87467, 37.43658), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.8719, 37.4464));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 3 /* expectedTurnCount */);
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnSlightRight);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnSlightRight);
|
||||
|
||||
integration::TestRouteLength(route, 753.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(SpainTenerifeSlightTurnMain_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(28.09214, -16.73121), {0.0, 0.0},
|
||||
mercator::FromLatLon(28.09227, -16.7303));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 1 /* expectedTurnCount */);
|
||||
// Turn is needed because the route goes to the one of symmetric ways.
|
||||
// It's complicated since route way has tag tertiary and alternative way - residential.
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnSlightRight);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowGerPanfilovtsev22BicycleWayTurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.85630, 37.41004), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.85717, 37.41052));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 2 /* expectedTurnCount */);
|
||||
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_SalameiNerisPossibleTurnCorrectionBicycleWay_TurnTest)
|
||||
{
|
||||
using namespace integration;
|
||||
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.85854, 37.36795),
|
||||
{0.0, 0.0}, mercator::FromLatLon(55.85364, 37.37318));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
/// @todo This route goes not as expected after transforming path -> footway.
|
||||
TestRouteLength(route, 741);
|
||||
|
||||
TestTurnCount(route, 3 /* expectedTurnCount */);
|
||||
GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnSlightLeft);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_SalameiNerisNoUTurnBicycleWay_TurnTest)
|
||||
{
|
||||
using namespace integration;
|
||||
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.85854, 37.36795), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.85765, 37.36793));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
/// @todo This route goes not as expected after adding surface=ground into nearby paths.
|
||||
TestRouteLength(route, 252.735);
|
||||
|
||||
// Expected 1.
|
||||
/*
|
||||
TestTurnCount(route, 3);
|
||||
GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
*/
|
||||
|
||||
// Expected 2.
|
||||
/*
|
||||
TestTurnCount(route, 2);
|
||||
GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
*/
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowSevTushinoParkBicycleOnePointOnewayRoadTurnTest)
|
||||
{
|
||||
m2::PointD const point = mercator::FromLatLon(55.8719, 37.4464);
|
||||
TRouteResult const routeResult =
|
||||
integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle), point, {0.0, 0.0}, point);
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowSevTushinoParkBicycleOnePointTwowayRoadTurnTest)
|
||||
{
|
||||
m2::PointD const point = mercator::FromLatLon(55.87102, 37.44222);
|
||||
TRouteResult const routeResult =
|
||||
integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle), point, {0.0, 0.0}, point);
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_TatishchevaOnewayCarRoad_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.71566, 37.61568), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.71519, 37.61566));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 4 /* expectedTurnCount */);
|
||||
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 3).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
|
||||
integration::TestRouteLength(route, 320.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_SvobodiOnewayBicycleWay_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.87277, 37.44002), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.87362, 37.43853));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 5 /* expectedTurnCount */);
|
||||
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnSlightRight);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestOneOfDirections(
|
||||
{CarDirection::TurnSlightLeft, CarDirection::TurnLeft});
|
||||
integration::GetNthTurn(route, 3).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 4).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
|
||||
integration::TestRouteLength(route, 768.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(TurnsNearAltufievskoeShosseLongFakeSegmentTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.91569, 37.58972), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.9162315, 37.5861694));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestTurnCount(route, 5 /* expectedTurnCount */);
|
||||
|
||||
// Complicated case.
|
||||
// RoutingEngineResult::GetPossibleTurns at (turn_m_index == 3)
|
||||
// return nodes with isCandidatesAngleValid and 2 candidates with m_angle == 0
|
||||
// In fact they are -90 and +90, but we don't know it.
|
||||
// But this should not prevent from proper directions.
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 3).TestValid().TestDirection(CarDirection::TurnSlightLeft);
|
||||
integration::GetNthTurn(route, 4).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
|
||||
integration::TestRouteLength(route, 268.783);
|
||||
}
|
||||
|
||||
UNIT_TEST(TurnsNearMoscowRiverShortFakeSegmentTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.71484, 37.54868), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.71586, 37.54594));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
// Closest snapping road is a footway on East, and there are 2 turns, obviously.
|
||||
integration::TestTurnCount(route, 3 /* expectedTurnCount */);
|
||||
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
|
||||
integration::TestRouteLength(route, 401.2);
|
||||
}
|
||||
|
||||
UNIT_TEST(TurnsNearMKAD85kmShortFakeSegmentTest)
|
||||
{
|
||||
using namespace integration;
|
||||
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Bicycle), mercator::FromLatLon(55.91788, 37.58603), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.91684, 37.57884));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TestRouteLength(route, 1685.31);
|
||||
|
||||
TestTurnCount(route, 10);
|
||||
GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnSlightLeft);
|
||||
GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnSlightLeft);
|
||||
GetNthTurn(route, 3).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 4).TestValid().TestDirection(CarDirection::EnterRoundAbout);
|
||||
GetNthTurn(route, 5).TestValid().TestDirection(CarDirection::LeaveRoundAbout);
|
||||
GetNthTurn(route, 6).TestValid().TestDirection(CarDirection::EnterRoundAbout);
|
||||
GetNthTurn(route, 7).TestValid().TestDirection(CarDirection::LeaveRoundAbout);
|
||||
GetNthTurn(route, 8).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
GetNthTurn(route, 9).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
|
||||
/// @todo Should fix this small segment.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.9164523, 37.5867809), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.914489, 37.5850912), 260.482, 0.005);
|
||||
}
|
||||
|
||||
UNIT_TEST(TurnsNearKhladkombinatTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Bicycle),
|
||||
mercator::FromLatLon(55.86973, 37.45825), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.87020, 37.46011));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(route, 478.295);
|
||||
|
||||
integration::TestTurnCount(route, 3 /* expectedTurnCount */);
|
||||
|
||||
integration::GetNthTurn(route, 0).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
integration::GetNthTurn(route, 1).TestValid().TestDirection(CarDirection::TurnLeft);
|
||||
integration::GetNthTurn(route, 2).TestValid().TestDirection(CarDirection::TurnRight);
|
||||
}
|
||||
} // namespace bicycle_turn_test
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
namespace concurrent_feature_parsing_test
|
||||
{
|
||||
using namespace platform;
|
||||
using namespace std;
|
||||
|
||||
void TestConcurrentAccessToFeatures(string const & mwm)
|
||||
{
|
||||
FrozenDataSource dataSource;
|
||||
|
||||
auto const & countryFile = CountryFile(mwm);
|
||||
auto const & local = integration::GetLocalCountryFileByCountryId(countryFile);
|
||||
TEST_NOT_EQUAL(local, LocalCountryFile(), ());
|
||||
TEST(local.HasFiles(), (local));
|
||||
|
||||
auto const mwmIdAndRegResult = dataSource.RegisterMap(local);
|
||||
TEST_EQUAL(mwmIdAndRegResult.second, MwmSet::RegResult::Success, (local));
|
||||
TEST(mwmIdAndRegResult.first.IsAlive(), (local));
|
||||
|
||||
auto const handle = dataSource.GetMwmHandleByCountryFile(countryFile);
|
||||
TEST(handle.IsAlive(), (local));
|
||||
|
||||
auto const featureNumber = handle.GetValue()->m_ftTable->size();
|
||||
// Note. If hardware_concurrency() returns 0 it means that number of core is not defined.
|
||||
// If hardware_concurrency() returns 1 it means that only one core is available.
|
||||
// In the both cases 2 threads should be used for this test.
|
||||
auto const threadNumber = max(thread::hardware_concurrency(), static_cast<unsigned int>(2));
|
||||
LOG(LINFO, ("Parsing geometry of", featureNumber, "features in", threadNumber, "threads simultaneously.", local));
|
||||
|
||||
mutex guardCtorMtx;
|
||||
auto parseGeometries = [&](vector<m2::PointD> & points)
|
||||
{
|
||||
unique_lock<mutex> guardCtor(guardCtorMtx);
|
||||
FeaturesLoaderGuard guard(dataSource, handle.GetId());
|
||||
guardCtor.unlock();
|
||||
|
||||
for (uint32_t i = 0; i < featureNumber; ++i)
|
||||
{
|
||||
auto feature = guard.GetFeatureByIndex(i);
|
||||
TEST(feature, ("Feature id:", i, "is not found in", local));
|
||||
|
||||
feature->ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
for (size_t i = 0; i < feature->GetPointsCount(); ++i)
|
||||
points.push_back(feature->GetPoint(i));
|
||||
}
|
||||
};
|
||||
|
||||
vector<future<void>> futures;
|
||||
futures.reserve(threadNumber);
|
||||
vector<vector<m2::PointD>> pointsByThreads;
|
||||
pointsByThreads.resize(threadNumber);
|
||||
for (size_t i = 0; i + 1 < threadNumber; ++i)
|
||||
futures.push_back(async(launch::async, parseGeometries, ref(pointsByThreads[i])));
|
||||
parseGeometries(pointsByThreads[threadNumber - 1]);
|
||||
|
||||
for (auto const & fut : futures)
|
||||
fut.wait();
|
||||
|
||||
// Checking that all geometry points are equal after parsing in different threads.
|
||||
CHECK_GREATER_OR_EQUAL(pointsByThreads.size(), 2, ());
|
||||
for (size_t i = 1; i < pointsByThreads.size(); ++i)
|
||||
{
|
||||
TEST_EQUAL(pointsByThreads[i].size(), pointsByThreads[0].size(), (i));
|
||||
for (size_t j = 0; j < pointsByThreads[i].size(); ++j)
|
||||
TEST_EQUAL(pointsByThreads[i][j], pointsByThreads[0][j], (i, j));
|
||||
}
|
||||
|
||||
LOG(LINFO, ("Parsing is done."));
|
||||
}
|
||||
|
||||
// This test on availability of parsing FeatureType in several threads.
|
||||
UNIT_TEST(ConcurrentFeatureParsingTest)
|
||||
{
|
||||
classificator::Load();
|
||||
|
||||
vector<string> const mwms = {"Russia_Moscow", "Nepal_Kathmandu", "Netherlands_North Holland_Amsterdam"};
|
||||
|
||||
for (auto const & mwm : mwms)
|
||||
TestConcurrentAccessToFeatures(mwm);
|
||||
}
|
||||
} // namespace concurrent_feature_parsing_test
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
using namespace routing;
|
||||
|
||||
// In this case the shortest way from Austria, Morzg to Austria, Unken is through Germany. We don't
|
||||
// add penalty for crossing the Schengen Area borders so the route runs through Germany.
|
||||
UNIT_TEST(CrossCountry_Schengen_Borders_Austria_to_Austria_through_Germany)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car),
|
||||
mercator::FromLatLon(47.7707543, 13.0557409) /* startPoint */, {0.0, 0.0} /* startDirection */,
|
||||
mercator::FromLatLon(47.6500734, 12.7291784) /* finalPoint */, 41126.6 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
// In this case the shortest way from Russian Federation, Smolensk Oblast to Russian Federation,
|
||||
// Bryansk Oblast is through Belarus. We don't add penalty for crossing the Eurasian Economic Union
|
||||
// borders so the route runs through Belarus.
|
||||
UNIT_TEST(CrossCountry_EAEU_Borders_Russia_to_Russia_through_Belarus)
|
||||
{
|
||||
/// @todo Uses tertiary instead of longer (7km) primary. Can't say fo sure is it ok or not, but looks good.
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(53.83281, 32.47602) /* startPoint */,
|
||||
{0.0, 0.0} /* startDirection */, mercator::FromLatLon(52.79681, 32.98167) /* finalPoint */,
|
||||
188'085 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UsePrimaryDetour_NotSecondaryTown)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Car),
|
||||
mercator::FromLatLon(50.215143, 39.4498585), {0.0, 0.0},
|
||||
mercator::FromLatLon(49.9025281, 40.5213712), 123949);
|
||||
|
||||
/// @todo Should prefer trunk detour with maxspeed=90 than secondary with maxspeed=60.
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Car),
|
||||
mercator::FromLatLon(45.2849983, 38.2432247), {0.0, 0.0},
|
||||
mercator::FromLatLon(45.237346, 38.0046459), 28534.8);
|
||||
}
|
||||
|
||||
// In this case the shortest way from Belgorod oblast to Crimea is through Ukraine. But we add
|
||||
// |kCrossCountryPenaltyS| penalty for crossing borders between Russian Federation and Ukraine,
|
||||
// between Ukraine and Crimea, and between Crimea and Russian Federation, because Crimea is a
|
||||
// territorial dispute. So the route should run directly from Russian Federation to Crimea.
|
||||
UNIT_TEST(CrossCountry_Russia_Belgorod_Oblast_to_Crimea)
|
||||
{
|
||||
// This routes go via Russia only.
|
||||
// Some subroutes are checked in Russia_UsePrimaryDetour_NotSecondaryTown.
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(50.39589, 38.83377) /* startPoint */,
|
||||
{0.0, 0.0} /* startDirection */, mercator::FromLatLon(45.06336, 34.48566) /* finalPoint */, 1'144'970);
|
||||
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(50.39589, 38.83377) /* startPoint */,
|
||||
{0.0, 0.0} /* startDirection */, mercator::FromLatLon(45.1048391, 35.1297058) /* finalPoint */, 1'096'360);
|
||||
}
|
||||
|
||||
// In this case the shortest way from Lithuania to Poland is through Russia, Kaliningrad Oblast. But
|
||||
// we add cross-country penalty for entering Kaliningrad and don't add it for crossing mutual
|
||||
// borders of the Schengen Area countries. So the route should run directly from Lithuania to Poland.
|
||||
UNIT_TEST(CrossCountry_Lithuania_to_Poland)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(55.10055, 22.30228) /* startPoint */,
|
||||
{0.0, 0.0} /* startDirection */, mercator::FromLatLon(54.27745, 22.33767) /* finalPoint */,
|
||||
191'963 /* expectedRouteMeters */);
|
||||
}
|
||||
|
||||
// In this case the shortest way from Hungary to Slovakia is through Ukraine. But we add penalty for
|
||||
// crossing cross-country borders if both countries are not in the Schengen Area or Eurasian
|
||||
// Economic Union. So the route should run directly from Hungary to Slovakia.
|
||||
UNIT_TEST(CrossCountry_Hungary_to_Slovakia)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(
|
||||
integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(48.39107, 22.18352) /* startPoint */,
|
||||
{0.0, 0.0} /* startDirection */, mercator::FromLatLon(48.69826, 22.23454) /* finalPoint */,
|
||||
100'015 /* expectedRouteMeters */);
|
||||
}
|
||||
142
libs/routing/routing_integration_tests/get_altitude_test.cpp
Normal file
142
libs/routing/routing_integration_tests/get_altitude_test.cpp
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "indexer/altitude_loader.hpp"
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature_algo.hpp"
|
||||
#include "indexer/feature_altitude.hpp"
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/feature_processor.hpp"
|
||||
|
||||
#include "routing/routing_helpers.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "base/math.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace get_altitude_tests
|
||||
{
|
||||
using namespace feature;
|
||||
using namespace geometry;
|
||||
using namespace platform;
|
||||
using namespace std;
|
||||
|
||||
class FeaturesGuard
|
||||
{
|
||||
public:
|
||||
FrozenDataSource m_dataSource;
|
||||
MwmSet::MwmHandle m_handle;
|
||||
unique_ptr<AltitudeLoaderCached> m_altitudes;
|
||||
|
||||
explicit FeaturesGuard(string const & countryId)
|
||||
{
|
||||
LocalCountryFile const country = integration::GetLocalCountryFileByCountryId(CountryFile(countryId));
|
||||
TEST_NOT_EQUAL(country, LocalCountryFile(), ());
|
||||
TEST(country.HasFiles(), (country));
|
||||
|
||||
pair<MwmSet::MwmId, MwmSet::RegResult> const res = m_dataSource.RegisterMap(country);
|
||||
TEST_EQUAL(res.second, MwmSet::RegResult::Success, ());
|
||||
m_handle = m_dataSource.GetMwmHandleById(res.first);
|
||||
TEST(m_handle.IsAlive(), ());
|
||||
TEST(GetValue(), ());
|
||||
|
||||
m_altitudes = make_unique<AltitudeLoaderCached>(*GetValue());
|
||||
}
|
||||
|
||||
MwmValue const * GetValue() { return m_handle.GetValue(); }
|
||||
};
|
||||
|
||||
void TestAltitudeOfAllMwmFeatures(string const & countryId, Altitude const altitudeLowerBoundMeters,
|
||||
Altitude const altitudeUpperBoundMeters)
|
||||
{
|
||||
FeaturesGuard features(countryId);
|
||||
|
||||
ForEachFeature(features.GetValue()->m_cont, [&](FeatureType & f, uint32_t const & id)
|
||||
{
|
||||
if (!routing::IsRoad(TypesHolder(f)))
|
||||
return;
|
||||
|
||||
f.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
size_t const pointsCount = f.GetPointsCount();
|
||||
if (pointsCount == 0)
|
||||
return;
|
||||
|
||||
auto const & altitudes = features.m_altitudes->GetAltitudes(id, pointsCount);
|
||||
TEST(!altitudes.empty(),
|
||||
("Empty altitude vector. MWM:", countryId, ", feature id:", id, ", altitudes:", altitudes));
|
||||
|
||||
for (auto const altitude : altitudes)
|
||||
{
|
||||
TEST_EQUAL(math::Clamp(altitude, altitudeLowerBoundMeters, altitudeUpperBoundMeters), altitude,
|
||||
("Unexpected altitude. MWM:", countryId, ", feature id:", id, ", altitudes:", altitudes));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
UNIT_TEST(GetAltitude_AllMwmFeaturesTest)
|
||||
{
|
||||
classificator::Load();
|
||||
|
||||
TestAltitudeOfAllMwmFeatures("Russia_Moscow", 50 /* altitudeLowerBoundMeters */, 300 /* altitudeUpperBoundMeters */);
|
||||
TestAltitudeOfAllMwmFeatures("Nepal_Kathmandu", 250 /* altitudeLowerBoundMeters */,
|
||||
6000 /* altitudeUpperBoundMeters */);
|
||||
TestAltitudeOfAllMwmFeatures("Netherlands_North Holland_Amsterdam", -25 /* altitudeLowerBoundMeters */,
|
||||
50 /* altitudeUpperBoundMeters */);
|
||||
}
|
||||
|
||||
/*
|
||||
void PrintGeometryAndAltitude(std::string const & countryID, ms::LatLon const & ll, double distM)
|
||||
{
|
||||
FeaturesGuard features(countryID);
|
||||
auto const point = mercator::FromLatLon(ll);
|
||||
m2::RectD const rect = mercator::RectByCenterXYAndSizeInMeters(point, distM);
|
||||
|
||||
features.m_dataSource.ForEachInRect([&](FeatureType & ft)
|
||||
{
|
||||
if (!routing::IsRoad(TypesHolder(ft)))
|
||||
return;
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
size_t const pointsCount = ft.GetPointsCount();
|
||||
if (pointsCount == 0)
|
||||
return;
|
||||
|
||||
if (GetMinDistanceMeters(ft, point) > distM)
|
||||
return;
|
||||
|
||||
stringstream geomSS;
|
||||
geomSS.precision(20);
|
||||
for (size_t i = 0; i < pointsCount; ++i)
|
||||
{
|
||||
auto const ll = mercator::ToLatLon(ft.GetPoint(i));
|
||||
geomSS << "{ " << ll.m_lat << ", " << ll.m_lon << " }, ";
|
||||
}
|
||||
LOG(LINFO, (geomSS.str()));
|
||||
|
||||
auto const & altitudes = features.m_altitudes->GetAltitudes(ft.GetID().m_index, pointsCount);
|
||||
LOG(LINFO, (ft.GetName(StringUtf8Multilang::kDefaultCode), altitudes));
|
||||
|
||||
}, rect, scales::GetUpperScale());
|
||||
}
|
||||
|
||||
UNIT_TEST(GetAltitude_SamplesTest)
|
||||
{
|
||||
classificator::Load();
|
||||
|
||||
PrintGeometryAndAltitude("Italy_Lazio", {41.8998667, 12.4985937}, 15.0);
|
||||
PrintGeometryAndAltitude("Crimea", { 44.7598876, 34.3160482 }, 5.0);
|
||||
}
|
||||
*/
|
||||
|
||||
} // namespace get_altitude_tests
|
||||
106
libs/routing/routing_integration_tests/guides_tests.cpp
Normal file
106
libs/routing/routing_integration_tests/guides_tests.cpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace guides_tests
|
||||
{
|
||||
using namespace routing;
|
||||
|
||||
// Test guide track is laid crosswise the OSM road graph. It doesn't match the OSM roads so we
|
||||
// can test route length, time and points number and it is enough to guarantee that the route
|
||||
// built during the test is the route through the guide which we expect.
|
||||
GuidesTracks GetTestGuides()
|
||||
{
|
||||
// Guide with single track.
|
||||
GuidesTracks guides;
|
||||
guides[10] = {{{mercator::FromLatLon(48.13999, 11.56873), 10},
|
||||
{mercator::FromLatLon(48.14096, 11.57246), 10},
|
||||
{mercator::FromLatLon(48.14487, 11.57259), 10}}};
|
||||
return guides;
|
||||
}
|
||||
|
||||
void TestGuideRoute(Checkpoints const & checkpoints, double expectedDistM, double expectedTimeS,
|
||||
size_t expectedPointsCount)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), checkpoints, GetTestGuides());
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, expectedDistM);
|
||||
integration::TestRouteTime(*routeResult.first, expectedTimeS);
|
||||
integration::TestRoutePointsNumber(*routeResult.first, expectedPointsCount);
|
||||
}
|
||||
|
||||
void ReverseCheckpoints(Checkpoints const & checkpoints)
|
||||
{
|
||||
auto points = checkpoints.GetPoints();
|
||||
std::reverse(points.begin(), points.end());
|
||||
}
|
||||
|
||||
// Start and finish checkpoints are connected to the track via single fake edge.
|
||||
UNIT_TEST(Guides_TwoPointsOnTrack)
|
||||
{
|
||||
// Checkpoints lie on the track.
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(48.14367, 11.57257), mercator::FromLatLon(48.13999, 11.56873)};
|
||||
|
||||
double const expectedDistM = 600.8;
|
||||
double const expectedTimeS = 721.0;
|
||||
size_t const expectedPointsCount = 7;
|
||||
|
||||
TestGuideRoute(checkpoints, expectedDistM, expectedTimeS, expectedPointsCount);
|
||||
ReverseCheckpoints(checkpoints);
|
||||
TestGuideRoute(checkpoints, expectedDistM, expectedTimeS, expectedPointsCount);
|
||||
}
|
||||
|
||||
// One checkpoint is connected to the track projection via OSM,
|
||||
// other checkpoint is connected to the track projection via single fake edge.
|
||||
UNIT_TEST(Guides_TwoPointsOnTrackOneViaOsm)
|
||||
{
|
||||
// Start is further from track then |kEqDistToTrackPointM|, but finish is closer.
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(48.13998, 11.56982), mercator::FromLatLon(48.14448, 11.57259)};
|
||||
|
||||
double const expectedDistM = 788.681;
|
||||
double const expectedTimeS = 903.3;
|
||||
size_t const expectedPointsCount = 13;
|
||||
|
||||
TestGuideRoute(checkpoints, expectedDistM, expectedTimeS, expectedPointsCount);
|
||||
ReverseCheckpoints(checkpoints);
|
||||
TestGuideRoute(checkpoints, expectedDistM, expectedTimeS, expectedPointsCount);
|
||||
}
|
||||
|
||||
// Start checkpoint is far away from the track, finish checkpoint lies in meters from
|
||||
// the middle of the track. We build the first part of the route from start to the terminal
|
||||
// track point, second part - from the terminal point to the finish.
|
||||
UNIT_TEST(Guides_FinishPointOnTrack)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(48.1394659, 11.575924),
|
||||
mercator::FromLatLon(48.1407632, 11.5716992)};
|
||||
|
||||
TestGuideRoute(checkpoints, 840.1 /* expectedDistM */, 736.279 /* expectedTimeS */, 37 /* expectedPointsCount */);
|
||||
}
|
||||
|
||||
// Start checkpoint is on the track, finish checkpoint is far away. We build the first part of the
|
||||
// route through the track and the second part - through the OSM roads.
|
||||
UNIT_TEST(Guides_StartPointOnTrack)
|
||||
{
|
||||
Checkpoints const checkpoints{mercator::FromLatLon(48.14168, 11.57244), mercator::FromLatLon(48.13741, 11.56095)};
|
||||
|
||||
TestGuideRoute(checkpoints, 1200.45 /* expectedDistM */, 1056.45 /* expectedTimeS */, 52 /* expectedPointsCount */);
|
||||
}
|
||||
|
||||
// Start and finish lie on the track; 3 intermediate points are far away from the track.
|
||||
UNIT_TEST(Guides_MultipleIntermediatePoints)
|
||||
{
|
||||
Checkpoints const checkpoints({mercator::FromLatLon(48.14403, 11.57259), mercator::FromLatLon(48.14439, 11.57480),
|
||||
mercator::FromLatLon(48.14192, 11.57548), mercator::FromLatLon(48.14106, 11.57279),
|
||||
mercator::FromLatLon(48.14044, 11.57061)});
|
||||
|
||||
TestGuideRoute(checkpoints, 1231.91 /* expectedDistM */, 1042.65 /* expectedTimeS */, 67 /* expectedPointsCount */);
|
||||
}
|
||||
} // namespace guides_tests
|
||||
674
libs/routing/routing_integration_tests/pedestrian_route_test.cpp
Normal file
674
libs/routing/routing_integration_tests/pedestrian_route_test.cpp
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
namespace pedestrian_route_test
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace routing::turns;
|
||||
using namespace integration;
|
||||
using mercator::FromLatLon;
|
||||
|
||||
UNIT_TEST(GermanyBremenJunctionToCycleway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(52.41947, 10.75148), {0., 0.},
|
||||
mercator::FromLatLon(52.41868, 10.75274), 137.);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad424aTo1207)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9963, 37.2036), {0., 0.},
|
||||
mercator::FromLatLon(55.9955, 37.1948), 659.213);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad924aTo418)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9844, 37.1808), {0., 0.},
|
||||
mercator::FromLatLon(55.9999, 37.2021), 2447.75);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad924aToFilaretovskyChurch)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9844, 37.1808), {0., 0.},
|
||||
mercator::FromLatLon(55.9915, 37.1808), 1194.84);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad924aTo1145)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9844, 37.1808), {0., 0.},
|
||||
mercator::FromLatLon(55.9924, 37.1853), 1162.74);
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowMuzeonToLebedinoeOzeroGorkyPark)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.7348, 37.606), {0., 0.},
|
||||
mercator::FromLatLon(55.724, 37.5956), 1640.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad315parkingToMusicSchoolBus_BadRoute)
|
||||
{
|
||||
/// @todo Bad route, goes through a highway-tertiary and fake edge.
|
||||
// integration::CalculateRouteAndTestRouteLength(
|
||||
// integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
// mercator::FromLatLon(55.9996, 37.2174), {0., 0.},
|
||||
// mercator::FromLatLon(55.999963, 37.2179159), 164.);
|
||||
|
||||
// A bit far end point and the route is ok.
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9996, 37.2174), {0., 0.},
|
||||
mercator::FromLatLon(55.9999757, 37.217925), 165.423);
|
||||
}
|
||||
|
||||
UNIT_TEST(Zgrad924aToKrukovo)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.9844, 37.1808), {0., 0.},
|
||||
mercator::FromLatLon(55.9802, 37.1736), 1030);
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowMailRuStarbucksToPetrovskoRazumovskyAlley)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.7971, 37.5376), {0., 0.},
|
||||
mercator::FromLatLon(55.7953, 37.5597), 1802.31);
|
||||
}
|
||||
|
||||
UNIT_TEST(AustraliaMelburn_AvoidMotorway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(-37.7936, 144.985), {0., 0.},
|
||||
mercator::FromLatLon(-37.7896, 145.025), 4659.5);
|
||||
}
|
||||
|
||||
UNIT_TEST(AustriaWein_AvoidTrunk)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(48.233, 16.3562), {0., 0.},
|
||||
mercator::FromLatLon(48.2458, 16.3704), 2172.23);
|
||||
}
|
||||
|
||||
UNIT_TEST(FranceParis_AvoidBridleway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(48.859, 2.25452), {0., 0.},
|
||||
mercator::FromLatLon(48.8634, 2.24315), 1049.);
|
||||
}
|
||||
|
||||
UNIT_TEST(HungaryBudapest_AvoidMotorway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.56566, 19.14942), {0., 0.},
|
||||
mercator::FromLatLon(47.593, 19.24018), 10179.6);
|
||||
}
|
||||
|
||||
UNIT_TEST(PolandWarshaw_AvoidCycleway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(52.2487, 21.0173), {0., 0.},
|
||||
mercator::FromLatLon(52.25, 21.0164), 182.);
|
||||
}
|
||||
|
||||
UNIT_TEST(SwedenStockholmSlussenHiltonToMaritimeMuseum)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.32046, 18.06924), {0.0, 0.0},
|
||||
mercator::FromLatLon(59.32751, 18.09092), 3445.22);
|
||||
}
|
||||
|
||||
UNIT_TEST(SwedenStockholmSlussenHiltonToAfChapmanHostel)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.32045, 18.06928), {0., 0.},
|
||||
mercator::FromLatLon(59.3254, 18.08022), 2170.87);
|
||||
}
|
||||
|
||||
UNIT_TEST(EstoniaTallinnRadissonHiltonToCatherdalChurch)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.4362, 24.7682), {0., 0.},
|
||||
mercator::FromLatLon(59.437, 24.7392), 1972.54);
|
||||
}
|
||||
|
||||
UNIT_TEST(EstoniaTallinnRadissonHiltonToSkypeOffice)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.4362, 24.7682), {0., 0.},
|
||||
mercator::FromLatLon(59.3971, 24.661), 8673.);
|
||||
}
|
||||
|
||||
UNIT_TEST(BelarusMinksHotelYubileyniToChurchSaintsSimonAndHelen)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(53.9112, 27.5466), {0., 0.},
|
||||
mercator::FromLatLon(53.8965, 27.5476), 2151.28);
|
||||
}
|
||||
|
||||
UNIT_TEST(BelarusMinksBarURatushiToMoscowBusStation)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(53.9045, 27.5569), {0., 0.},
|
||||
mercator::FromLatLon(53.889, 27.5466), 2395.3);
|
||||
}
|
||||
|
||||
UNIT_TEST(BelarusBobruisk50LetVlksmToSanatoryShinnik)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(53.1638, 29.1804), {0., 0.},
|
||||
mercator::FromLatLon(53.179, 29.1682), 2400.);
|
||||
}
|
||||
|
||||
UNIT_TEST(BelarusBobruisk50LetVlksmToArena)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(53.1638, 29.1804), {0., 0.},
|
||||
mercator::FromLatLon(53.1424, 29.2467), 6123.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogSyzranov10k3ToSoftech)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2183, 38.8634), {0., 0.},
|
||||
mercator::FromLatLon(47.2, 38.8878), 3752.68);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogSyzranov10k3ToTruseE)
|
||||
{
|
||||
// In the end prefers longer footway instead of secondary (no other tags).
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2183, 38.8634), {0., 0.},
|
||||
mercator::FromLatLon(47.2048, 38.9441), 7536.52);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogSyzranov10k3ToLazo5k2)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2183, 38.8634), {0., 0.},
|
||||
mercator::FromLatLon(47.2584, 38.9128), 7563.05);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogJukova2ToBolBulvarnaya8)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2768, 38.9282), {0., 0.},
|
||||
mercator::FromLatLon(47.2412, 38.8902), 6239.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogCheckhova267k2ToKotlostroy33)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2200, 38.8906), {0., 0.},
|
||||
mercator::FromLatLon(47.2459, 38.8937), 3485.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTaganrogCheckhova267k2ToBolBulvarnaya8)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2200, 38.8906), {0., 0.},
|
||||
mercator::FromLatLon(47.2412, 38.8902), 2834.47);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaRostovOnDonPrKosmonavtovToDneprovsky120b)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.2811, 39.7178), {0., 0.},
|
||||
mercator::FromLatLon(47.2875, 39.759), 4300.);
|
||||
}
|
||||
|
||||
UNIT_TEST(TurkeyKemerPalmetResortToYachtClub)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(36.6143, 30.5572), {0., 0.},
|
||||
mercator::FromLatLon(36.6004, 30.576), 2992.);
|
||||
}
|
||||
|
||||
UNIT_TEST(CzechPragueNode5ToHilton)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(50.0653, 14.4031), {0., 0.},
|
||||
mercator::FromLatLon(50.0933, 14.4397), 5106.);
|
||||
}
|
||||
|
||||
/// @todo Here maybe some +-100m differencies. OM workd like OSRM here.
|
||||
/// @{
|
||||
UNIT_TEST(CzechPragueHiltonToKarlovMost)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(50.0933, 14.4397), {0., 0.},
|
||||
mercator::FromLatLon(50.0864, 14.4124), 2483);
|
||||
}
|
||||
|
||||
UNIT_TEST(CzechPragueHiltonToNicholasChurch)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(50.0933, 14.4397), {0., 0.},
|
||||
mercator::FromLatLon(50.088, 14.4032), 3196);
|
||||
}
|
||||
/// @}
|
||||
|
||||
UNIT_TEST(CzechPragueHiltonToKvetniceViewpoint)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(50.0933, 14.4397), {0., 0.},
|
||||
mercator::FromLatLon(50.0806, 14.3973), 4649.68);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaSaintPetersburgMoyka93ToAlexanderColumn)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.9241, 30.323), {0., 0.},
|
||||
mercator::FromLatLon(59.939, 30.3159), 2307.17);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaSaintPetersburgMoyka93ToMarsovoPole)
|
||||
{
|
||||
// OM follows left bank of Griboedova, while can keep right bank and make a small detour around church.
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.9241, 30.323), {0., 0.},
|
||||
mercator::FromLatLon(59.9436, 30.3318), 2755);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaSaintPetersburgMoyka93ToAvrora)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.9241, 30.323), {0., 0.},
|
||||
mercator::FromLatLon(59.9554, 30.3378), 4614.66);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaSaintPetersburgPetrPaulChurchToDolphins)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.9502, 30.3165), {0., 0.},
|
||||
mercator::FromLatLon(59.973, 30.2702), 4507.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaPetergofEntranceToErmitagePalace)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.8806, 29.904), {0., 0.},
|
||||
mercator::FromLatLon(59.8889, 29.9034), 1073.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaPetergofMarlyPalaceToTrainStation)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(59.8887, 29.8963), {0., 0.},
|
||||
mercator::FromLatLon(59.8648, 29.9251), 3885.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowMailRuToTsarCannon)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.79703, 37.53761), {0., 0.},
|
||||
mercator::FromLatLon(55.75146, 37.61792), 7989.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowHovrinoStationToKasperskyLab)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.8701, 37.50833), {0., 0.},
|
||||
mercator::FromLatLon(55.83715, 37.48132), 5162.);
|
||||
}
|
||||
|
||||
UNIT_TEST(ItalyRome_WalkOverStreetWithSidewalkBoth)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(41.9052, 12.4106), {0., 0.},
|
||||
mercator::FromLatLon(41.9226, 12.4216), 2413.);
|
||||
}
|
||||
|
||||
UNIT_TEST(USARedlandsEsriHQToRedlandsCommunity)
|
||||
{
|
||||
// OM makes like OSRM with footway.
|
||||
// Valhalla uses shorter South San Mateo + West Olive.
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(34.0556, -117.19567), {0., 0.},
|
||||
mercator::FromLatLon(34.03682, -117.20649), 3212.65);
|
||||
}
|
||||
|
||||
UNIT_TEST(USANewYorkEmpireStateBuildingToUnitedNations)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(40.74844, -73.98566), {0., 0.},
|
||||
mercator::FromLatLon(40.75047, -73.96759), 2265.);
|
||||
}
|
||||
|
||||
// Test on walking around a ford on an mwm border.
|
||||
UNIT_TEST(CrossMwmRussiaPStaiToBelarusDrazdy)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.014, 30.95552), {0., 0.},
|
||||
mercator::FromLatLon(55.01437, 30.8858), 4835.76);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_ZgradPanfilovskyUndergroundCrossing_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(55.98401, 37.17979), {0., 0.},
|
||||
mercator::FromLatLon(55.98419, 37.17938));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(route, 151.0);
|
||||
|
||||
std::vector<turns::TurnItem> t;
|
||||
route.GetTurnsForTesting(t);
|
||||
TEST_EQUAL(t.size(), 3, ());
|
||||
|
||||
TEST_EQUAL(t[0].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[1].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[2].m_pedestrianTurn, PedestrianDirection::ReachedYourDestination, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_HydroprojectBridgeCrossing_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(55.80867, 37.50575), {0., 0.},
|
||||
mercator::FromLatLon(55.80884, 37.50668));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
// I don't see any bad routing sections here. Make actual value.
|
||||
integration::TestRouteLength(route, 352.09);
|
||||
|
||||
std::vector<turns::TurnItem> t;
|
||||
route.GetTurnsForTesting(t);
|
||||
TEST_EQUAL(t.size(), 5, ());
|
||||
|
||||
TEST_EQUAL(t[0].m_pedestrianTurn, PedestrianDirection::TurnLeft, ());
|
||||
TEST_EQUAL(t[1].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[2].m_pedestrianTurn, PedestrianDirection::TurnLeft, ());
|
||||
TEST_EQUAL(t[3].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[4].m_pedestrianTurn, PedestrianDirection::ReachedYourDestination, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Belarus_Minsk_RenaissanceHotelUndergroundCross_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(53.89296, 27.52775), {0., 0.},
|
||||
mercator::FromLatLon(53.89262, 27.52838));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(route, 127.0);
|
||||
|
||||
std::vector<turns::TurnItem> t;
|
||||
route.GetTurnsForTesting(t);
|
||||
TEST_EQUAL(t.size(), 5, ());
|
||||
|
||||
TEST_EQUAL(t[0].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[1].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[2].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[3].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[4].m_pedestrianTurn, PedestrianDirection::ReachedYourDestination, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowVodnyStadiumHighwayPlatform)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.83955, 37.48692), {0., 0.},
|
||||
mercator::FromLatLon(55.84061, 37.48636), 136.115);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_SevTushinoParkPedestrianOnePoint_TurnTest)
|
||||
{
|
||||
m2::PointD const point = mercator::FromLatLon(55.8719, 37.4464);
|
||||
TRouteResult const routeResult =
|
||||
integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Pedestrian), point, {0.0, 0.0}, point);
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(route, 0.0);
|
||||
|
||||
integration::TestTurnCount(route, 0 /* expectedTurnCount */);
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowKashirskoe16ToVorobeviGori)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.66230, 37.63214), {0., 0.},
|
||||
mercator::FromLatLon(55.70934, 37.54232), 9232.81);
|
||||
}
|
||||
|
||||
// Test on building pedestrian route past ferry.
|
||||
UNIT_TEST(SwitzerlandSaintBlaisePedestrianPastFerry)
|
||||
{
|
||||
// New value has bigger ditance (+100 meters), but better ETA (-1 minute).
|
||||
// Check with intermediate point {47.0098, 6.9770}
|
||||
|
||||
/// @todo After reducing GetFerryLandingPenalty, the app takes ferry here (1184 meters, 708 seconds).
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(47.010336, 6.982954), {0.0, 0.0},
|
||||
mercator::FromLatLon(47.005817, 6.970227), 1662.43);
|
||||
}
|
||||
|
||||
// Test on building pedestrian route past ferry.
|
||||
UNIT_TEST(NetherlandsAmsterdamPedestrianPastFerry)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(52.38075, 4.89938), {0.0, 0.0},
|
||||
mercator::FromLatLon(52.40194, 4.89038), 2553.18);
|
||||
}
|
||||
|
||||
// Test on building pedestrian route past ferry.
|
||||
UNIT_TEST(ItalyVenicePedestrianPastFerry)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(45.4375, 12.33549), {0.0, 0.0},
|
||||
mercator::FromLatLon(45.44057, 12.33393), 725.4);
|
||||
}
|
||||
|
||||
// Test on climbing from Priut11 to Elbrus mountain.
|
||||
UNIT_TEST(RussiaPriut11Elbrus)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteTime(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(43.31475, 42.46035), {0., 0.},
|
||||
mercator::FromLatLon(43.35254, 42.43788), 37753.4 /* expectedTimeSeconds */);
|
||||
}
|
||||
|
||||
// Test on going down from Elbrus mountain to Priut11.
|
||||
UNIT_TEST(RussiaElbrusPriut11)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteTime(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(43.35254, 42.43788), {0., 0.},
|
||||
mercator::FromLatLon(43.31475, 42.46035), 15878.9 /* expectedTimeSeconds */);
|
||||
}
|
||||
|
||||
// Test on going straight forward on primary road.
|
||||
UNIT_TEST(BudvaPrimaryRoad)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(42.2884527, 18.8456794), {0., 0.},
|
||||
mercator::FromLatLon(42.2880575, 18.8492896), 412.66);
|
||||
}
|
||||
|
||||
// Test on start and finish route which lies on a feature crossed by a mwm border and a ford.
|
||||
UNIT_TEST(RussiaSmolenskAriaFeatureCrossingBorderWithFord)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(55.01727, 30.91566), {0., 0.},
|
||||
mercator::FromLatLon(55.01867, 30.91285), 298.6);
|
||||
}
|
||||
|
||||
UNIT_TEST(NoTurnOnForkingRoad_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(55.67505, 37.51851), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.6748507, 37.5177359));
|
||||
|
||||
Route const & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(route, 64.655);
|
||||
|
||||
/// @todo t[1].m_pedestrianTurn, PedestrianDirection::TurnRight is redundant here.
|
||||
std::vector<turns::TurnItem> t;
|
||||
route.GetTurnsForTesting(t);
|
||||
TEST_EQUAL(t.size(), 2, ());
|
||||
TEST_EQUAL(t[0].m_pedestrianTurn, PedestrianDirection::TurnLeft, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(NoTurnOnForkingRoad2_TurnTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(VehicleType::Pedestrian), mercator::FromLatLon(55.68336, 37.49492), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.68488, 37.49789));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
integration::TestRouteLength(route, 300.0);
|
||||
|
||||
// Unfortunatelly, we don't have SlightRight for pedestrians, but current turns are OK.
|
||||
// https://www.openstreetmap.org/directions?engine=graphhopper_foot&route=55.68336%2C37.49492%3B55.68488%2C37.49789
|
||||
std::vector<turns::TurnItem> t;
|
||||
route.GetTurnsForTesting(t);
|
||||
TEST_EQUAL(t.size(), 3, (t));
|
||||
|
||||
TEST_EQUAL(t[0].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
TEST_EQUAL(t[1].m_pedestrianTurn, PedestrianDirection::TurnRight, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Hungary_UseFootways)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(45.8587043, 18.2863972), {0., 0.},
|
||||
mercator::FromLatLon(45.858625, 18.285348), 95.7657);
|
||||
}
|
||||
|
||||
UNIT_TEST(France_Uphill_Downlhill)
|
||||
{
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_foot&route=45.3211%2C3.6954%3B45.2353%2C3.8575
|
||||
// Same as OSRM.
|
||||
|
||||
double timeDownhill, timeUphill;
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(45.32111, 3.69535), {0., 0.},
|
||||
FromLatLon(45.235327, 3.857533));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
TestRouteLength(route, 19771);
|
||||
timeDownhill = route.GetTotalTimeSec();
|
||||
TEST_GREATER(timeDownhill, 4 * 3600, ());
|
||||
}
|
||||
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(45.235327, 3.857533), {0., 0.},
|
||||
FromLatLon(45.32111, 3.69535));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
TestRouteLength(route, 19771);
|
||||
timeUphill = route.GetTotalTimeSec();
|
||||
TEST_GREATER(timeUphill, 4 * 3600, ());
|
||||
}
|
||||
|
||||
TEST_GREATER(timeUphill - timeDownhill, 1000, ());
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1342
|
||||
UNIT_TEST(Crimea_Altitude_Mountains)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(44.7600296, 34.3247698), {0., 0.},
|
||||
mercator::FromLatLon(44.7632754, 34.313077), 1303.43);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/2803
|
||||
UNIT_TEST(Italy_Rome_Altitude_Footway)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(41.899384, 12.4980887), {0., 0.},
|
||||
mercator::FromLatLon(41.9007759, 12.4994956), 203.861);
|
||||
}
|
||||
|
||||
UNIT_TEST(Romania_Mountains_ETA)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Pedestrian),
|
||||
FromLatLon(45.5450, 25.2584), {0., 0.}, FromLatLon(45.5223, 25.2806));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
TestRouteLength(route, 4712.19);
|
||||
route.GetTotalTimeSec();
|
||||
TEST_LESS(route.GetTotalTimeSec(), 2.5 * 3600, ());
|
||||
}
|
||||
|
||||
// Check piligrim routes here: www santiago.nl/downloads/
|
||||
UNIT_TEST(Spain_N634_Piligrim_Road)
|
||||
{
|
||||
integration::CalculateRouteAndTestRouteLength(integration::GetVehicleComponents(VehicleType::Pedestrian),
|
||||
mercator::FromLatLon(43.5488528, -6.4696861), {0., 0.},
|
||||
mercator::FromLatLon(43.5435194, -6.5340694), 7217.93);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/5410
|
||||
UNIT_TEST(Australia_Mountains_Downlhill)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(-33.7374217, 150.283098), {0., 0.},
|
||||
FromLatLon(-33.7375399, 150.283358));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
TestRouteLength(route, 27.4434);
|
||||
// Altitudes diff is (914 -> 798).
|
||||
double const eta = route.GetTotalTimeSec();
|
||||
TEST(8 * 60 < eta && eta < 11 * 60, (eta));
|
||||
}
|
||||
|
||||
UNIT_TEST(Turkey_UsePrimary)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(38.7352697, 35.516104),
|
||||
{0., 0.}, FromLatLon(38.7398797, 35.5170627), 679.702);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(38.7168708, 35.4903164),
|
||||
{0., 0.}, FromLatLon(38.7207386, 35.4811178), 1050.39);
|
||||
}
|
||||
|
||||
UNIT_TEST(Georgia_UsePrimary)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Pedestrian), FromLatLon(42.7175722, 42.0496444), {0., 0.},
|
||||
FromLatLon(43.0451, 42.3742778));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
TestRouteLength(route, 68595);
|
||||
double const eta = route.GetTotalTimeSec();
|
||||
TEST(22 * 3600 < eta && eta < 24 * 3600, (eta));
|
||||
}
|
||||
|
||||
} // namespace pedestrian_route_test
|
||||
54
libs/routing/routing_integration_tests/road_graph_tests.cpp
Normal file
54
libs/routing/routing_integration_tests/road_graph_tests.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/data_source.hpp"
|
||||
#include "indexer/feature_altitude.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "routing/features_road_graph.hpp"
|
||||
#include "routing/road_graph.hpp"
|
||||
#include "routing_common/car_model.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/point_with_altitude.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace routing;
|
||||
using namespace integration;
|
||||
|
||||
// The test on combinatorial explosion of number of fake edges at FeaturesRoadGraph.
|
||||
// It might happen when a lot of roads intersect at one point. For example,
|
||||
// https://www.openstreetmap.org/#map=19/50.73197/-1.21295
|
||||
UNIT_TEST(FakeEdgesCombinatorialExplosion)
|
||||
{
|
||||
classificator::Load();
|
||||
|
||||
std::vector<LocalCountryFile> localFiles;
|
||||
GetAllLocalFiles(localFiles);
|
||||
TEST(!localFiles.empty(), ());
|
||||
|
||||
FrozenDataSource dataSource;
|
||||
for (auto const & file : localFiles)
|
||||
dataSource.Register(file);
|
||||
|
||||
MwmDataSource routingSource(dataSource, nullptr /* numMwmIDs */);
|
||||
FeaturesRoadGraph graph(routingSource, IRoadGraph::Mode::ObeyOnewayTag,
|
||||
std::make_shared<CarModelFactory>(CountryParentNameGetterFn()));
|
||||
geometry::PointWithAltitude const j(m2::PointD(mercator::FromLatLon(50.73208, -1.21279)),
|
||||
geometry::kDefaultAltitudeMeters);
|
||||
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> sourceVicinity;
|
||||
graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(j.GetPoint(), FeaturesRoadGraph::kClosestEdgesRadiusM),
|
||||
20 /* count */, sourceVicinity);
|
||||
// In case of the combinatorial explosion mentioned above all the memory was consumed for
|
||||
// FeaturesRoadGraph::m_fakeIngoingEdges and FeaturesRoadGraph::m_fakeOutgoingEdges fields.
|
||||
graph.AddFakeEdges(j, sourceVicinity);
|
||||
}
|
||||
41
libs/routing/routing_integration_tests/roundabouts_tests.cpp
Normal file
41
libs/routing/routing_integration_tests/roundabouts_tests.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "geometry/latlon.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace routing;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct RouteData
|
||||
{
|
||||
ms::LatLon m_start;
|
||||
ms::LatLon m_finish;
|
||||
double m_routeLengthM;
|
||||
};
|
||||
|
||||
UNIT_TEST(MiniRoundabout_CalculateRoute)
|
||||
{
|
||||
std::vector<RouteData> const routesWithMiniRoundabouts{{{51.45609, 0.05974}, {51.45562, 0.06005}, 61.3},
|
||||
{{51.49746, -0.40027}, {51.49746, -0.40111}, 65.64},
|
||||
{{55.98700, -3.38256}, {55.98665, -3.38260}, 43.6},
|
||||
{{52.22163, 21.09296}, {52.22189, 21.09286}, 41.5}};
|
||||
|
||||
for (auto const & route : routesWithMiniRoundabouts)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car),
|
||||
mercator::FromLatLon(route.m_start), {0.0, 0.0},
|
||||
mercator::FromLatLon(route.m_finish));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, route.m_routeLengthM);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
918
libs/routing/routing_integration_tests/route_test.cpp
Normal file
918
libs/routing/routing_integration_tests/route_test.cpp
Normal file
|
|
@ -0,0 +1,918 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
#include "routing/routing_options.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace route_test
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace integration;
|
||||
using mercator::FromLatLon;
|
||||
|
||||
UNIT_TEST(StrangeCaseInAfrica)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(19.20789, 30.50663), {0., 0.},
|
||||
FromLatLon(19.17289, 30.47315), 7645.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowKashirskoeShosseCrossing)
|
||||
{
|
||||
// OSRM agrees here:
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=55.66216%2C37.63259%3B55.66237%2C37.63560
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.66216, 37.63259), {0., 0.},
|
||||
FromLatLon(55.66237, 37.63560), 2877.81);
|
||||
}
|
||||
|
||||
UNIT_TEST(MoscowToSVOAirport)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.75100, 37.61790), {0.0, 0.0},
|
||||
FromLatLon(55.97310, 37.41460), 36070.1);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.97310, 37.41460), {0.0, 0.0},
|
||||
FromLatLon(55.75100, 37.61790), 39129.8);
|
||||
}
|
||||
|
||||
// Restrictions tests. Check restrictions generation, if there are any errors.
|
||||
UNIT_TEST(RestrictionTestNeatBaumanAndTTK)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.77398, 37.68469), {0., 0.},
|
||||
FromLatLon(55.77201, 37.68789), 1032.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RestrictionTestNearMetroShodnenskaya)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.85043, 37.43824), {0., 0.},
|
||||
FromLatLon(55.85191, 37.43910), 525.601);
|
||||
}
|
||||
|
||||
// Strange asserts near Cupertino test
|
||||
UNIT_TEST(CaliforniaCupertinoFindPhantomAssertTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(37.33409, -122.03458), {0., 0.},
|
||||
FromLatLon(37.33498, -122.03575), 1471.96);
|
||||
}
|
||||
|
||||
// Path in the last map through the other map.
|
||||
UNIT_TEST(RussiaUfaToUstKatavTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(54.7304, 55.9554), {0., 0.},
|
||||
FromLatLon(54.9228, 58.1469), 160565);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowNoServiceCrossing)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.77787, 37.70405), {0., 0.},
|
||||
FromLatLon(55.77682, 37.70391), 3140.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowShortWayToService)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.77787, 37.70405), {0., 0.},
|
||||
FromLatLon(55.77691, 37.70428), 171.);
|
||||
}
|
||||
|
||||
UNIT_TEST(PriceIslandLoadCrossGeometryTest)
|
||||
{
|
||||
size_t constexpr kExpectedPointsNumber = 56;
|
||||
// Forward
|
||||
TRouteResult route = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(46.16255, -63.81643), {0., 0.},
|
||||
FromLatLon(46.25401, -63.70213));
|
||||
TEST_EQUAL(route.second, RouterResultCode::NoError, ());
|
||||
TEST(route.first, ());
|
||||
TestRoutePointsNumber(*route.first, kExpectedPointsNumber);
|
||||
|
||||
// And backward case
|
||||
route = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(46.25401, -63.70213), {0., 0.},
|
||||
FromLatLon(46.16255, -63.81643));
|
||||
TEST_EQUAL(route.second, RouterResultCode::NoError, ());
|
||||
TEST(route.first, ());
|
||||
TestRoutePointsNumber(*route.first, kExpectedPointsNumber);
|
||||
}
|
||||
|
||||
UNIT_TEST(NederlandLeeuwardenToDenOeverTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(53.2076, 5.7082), {0., 0.},
|
||||
FromLatLon(52.9337, 5.0308), 59500.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowGerPanfilovtsev22SolodchaPravdiRouteTest)
|
||||
{
|
||||
// OSRM agrees here to use motorways instead of city roads.
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=55.858%2C37.410%3B54.794%2C39.837
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.85792, 37.40992), {0., 0.},
|
||||
FromLatLon(54.79390, 39.83656), 263920.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowBelarusMinsk)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.750650, 37.617673), {0., 0.},
|
||||
FromLatLon(53.902114, 27.562020), 712649.0);
|
||||
}
|
||||
|
||||
UNIT_TEST(UKRugbyStIvesRouteTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(52.37076, -1.26530), {0., 0.},
|
||||
FromLatLon(50.21480, -5.47994), 455902.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscow_ItalySienaCenter_SplittedMotorway)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.79690, 37.53759), {0., 0.},
|
||||
FromLatLon(43.32677, 11.32792), 2870710.);
|
||||
}
|
||||
|
||||
UNIT_TEST(PeruSingleRoadTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(-14.22061, -73.35969), {0., 0.},
|
||||
FromLatLon(-14.22389, -73.44281), 15900.);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowFranceParisCenterRouteTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.75271, 37.62618), {0., 0.},
|
||||
FromLatLon(48.86123, 2.34129), 2840940.);
|
||||
}
|
||||
|
||||
UNIT_TEST(EnglandToFranceRouteLeMansTest)
|
||||
{
|
||||
TRouteResult const res = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(51.09276, 1.11369),
|
||||
{0., 0.}, FromLatLon(50.93317, 1.82737));
|
||||
|
||||
TestRouteLength(*res.first, 63877.4);
|
||||
// LeMans shuttle duration is 35 min.
|
||||
TEST_LESS(res.first->GetTotalTimeSec(), 3200, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaMoscowRegionToBelarusBorder)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.464182, 35.943947), {0.0, 0.0},
|
||||
FromLatLon(52.442467, 31.609642), 554000.);
|
||||
}
|
||||
|
||||
UNIT_TEST(GermanyToTallinCrossMwmRoute)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(48.397416, 16.515289), {0.0, 0.0},
|
||||
FromLatLon(59.437214, 24.745355), 1650000.);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_Leningradskiy39RepublicOfSouthAfricaCapeTownCenterRouteTest)
|
||||
{
|
||||
/// @todo Interesting numbers here
|
||||
/// - GraphHopper: 13703 km, 153 h
|
||||
/// - Google: 15289 km, 198 h (via Europe?!)
|
||||
/// - OM: 14486 km, 185 h
|
||||
/// - OSRM, Valhalla are failed
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.79721, 37.53786), {0., 0.},
|
||||
FromLatLon(-33.9286, 18.41837), 14'493'000);
|
||||
}
|
||||
|
||||
UNIT_TEST(AlbaniaToMontenegroCrossTest)
|
||||
{
|
||||
// Road from Albania to Montenegro. Test turnaround finding at border (when start/stop
|
||||
// points are inside borders and one of segments has outside points).
|
||||
// Forward
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(42.01535, 19.40044), {0., 0.},
|
||||
FromLatLon(42.01201, 19.36286), 3749);
|
||||
|
||||
// And backward case
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(42.01201, 19.36286), {0., 0.},
|
||||
FromLatLon(42.01535, 19.40044), 3753);
|
||||
}
|
||||
|
||||
UNIT_TEST(CanadaBridgeCrossToEdwardIsland)
|
||||
{
|
||||
// Forward
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.13418, -63.84656), {0., 0.},
|
||||
FromLatLon(46.26739, -63.63907), 23000.);
|
||||
|
||||
// And backward case
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.26739, -63.63907), {0., 0.},
|
||||
FromLatLon(46.13418, -63.84656), 23000.);
|
||||
}
|
||||
|
||||
UNIT_TEST(ParisCrossDestinationInForwardHeapCase)
|
||||
{
|
||||
// Forward.
|
||||
// Updated after fixing primary/trunk factors. Route looks good, but it differs from Valhalla.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(49.85015, 2.24296), {0., 0.},
|
||||
FromLatLon(48.85458, 2.36291), 132906);
|
||||
|
||||
// Backward.
|
||||
// OM makes the same as GraphHopper and Valhalla. OSRM makes a bit shorter route.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(48.85458, 2.36291), {0., 0.},
|
||||
FromLatLon(49.85027, 2.24283), 136653);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaSmolenskRussiaMoscowTimeTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(54.7998, 32.05489),
|
||||
{0., 0.}, FromLatLon(55.753, 37.60169));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TestRouteLength(route, 391699);
|
||||
|
||||
// https://www.openstreetmap.org/directions?engine=graphhopper_car&route=54.800%2C32.055%3B55.753%2C37.602
|
||||
// Middle between GraphHopper and OSRM
|
||||
TestRouteTime(route, 19079.5);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_Leningradskiy39GeroevPanfilovtsev22TimeTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(55.7971, 37.53804),
|
||||
{0., 0.}, FromLatLon(55.8579, 37.40990));
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TestRouteLength(route, 14276.3);
|
||||
TestRouteTime(route, 1163.63);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_Moscow_Leningradskiy39GeroevPanfilovtsev22SubrouteTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(55.7971, 37.53804),
|
||||
{0., 0.}, FromLatLon(55.8579, 37.40990));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TEST_EQUAL(route.GetSubrouteCount(), 1, ());
|
||||
std::vector<RouteSegment> info;
|
||||
route.GetSubrouteInfo(0, info);
|
||||
TEST_EQUAL(route.GetPoly().GetSize(), info.size() + 1, ());
|
||||
size_t constexpr kExpectedPointsNumber = 335;
|
||||
TestRoutePointsNumber(route, kExpectedPointsNumber);
|
||||
}
|
||||
|
||||
UNIT_TEST(USALosAnglesAriaTwentyninePalmsHighwayTimeTest)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(34.0739, -115.3212), {0.0, 0.0},
|
||||
FromLatLon(34.0928, -115.5930));
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TEST_LESS(route.GetTotalTimeSec(), std::numeric_limits<double>::max() / 2.0, ());
|
||||
}
|
||||
|
||||
// Test on routing along features with tag man_made:pier.
|
||||
UNIT_TEST(CanadaVictoriaVancouverTest)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(48.47831, -123.32749), {0.0, 0.0},
|
||||
FromLatLon(49.26242, -123.11553));
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
// Test on the route with the finish near zero length edge.
|
||||
UNIT_TEST(BelarusSlonimFinishNearZeroEdgeTest)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(53.08279, 25.30036), {0.0, 0.0},
|
||||
FromLatLon(53.09443, 25.34356));
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
// Test on the route with the start near zero length edge.
|
||||
UNIT_TEST(BelarusSlonimStartNearZeroEdgeTest)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(53.09422, 25.34411), {0.0, 0.0},
|
||||
FromLatLon(53.09271, 25.3467));
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
// Test on roads with tag maxspeed=none.
|
||||
UNIT_TEST(GermanyBerlinMunichTimeTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(
|
||||
GetVehicleComponents(VehicleType::Car), FromLatLon(52.51172, 13.39468), {0., 0.}, FromLatLon(48.13294, 11.60352));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
/// @todo New time is closer to GraphHopper timing, but still very optimistic. Compare maxspeed=none defaults.
|
||||
// https://www.openstreetmap.org/directions?engine=graphhopper_car&route=52.51172%2C13.39468%3B48.13294%2C11.60352
|
||||
// TODO: w/ penalties PR: Route length: 585244 meters. ETA: 19436 seconds.
|
||||
TestRouteLength(route, 584960);
|
||||
TestRouteTime(route, 19173.3);
|
||||
}
|
||||
|
||||
// Test on roads with tag route=shuttle_train. This train has defined maxspeed=100.
|
||||
UNIT_TEST(GermanyShuttleTrainTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(54.78370, 8.83528),
|
||||
{0., 0.}, FromLatLon(54.91681, 8.31346));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
// TODO: w/ penalties PR: Route length: 44520.5 meters. ETA: 2732.48 seconds.
|
||||
TestRouteLength(route, 44517.4);
|
||||
TestRouteTime(route, 2619.62);
|
||||
}
|
||||
|
||||
UNIT_TEST(TolyattiFeatureThatCrossSeveralMwmsTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(
|
||||
GetVehicleComponents(VehicleType::Car), FromLatLon(52.67316, 48.22478), {0., 0.}, FromLatLon(53.49143, 49.52386));
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
|
||||
// GraphHopper and Valhalla agree here, but OSRM makes a short route via Syzran.
|
||||
TestRouteLength(route, 155734);
|
||||
TestRouteTime(route, 7958.85);
|
||||
}
|
||||
|
||||
// Test on removing speed cameras from the route for maps from Jan 2019,
|
||||
// and on the absence of speed cameras in maps for later maps for Switzerland.
|
||||
UNIT_TEST(SwitzerlandNoSpeedCamerasInRouteTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(47.5194, 8.73093),
|
||||
{0., 0.}, FromLatLon(46.80592, 7.13724));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
auto const & routeSegments = route.GetRouteSegments();
|
||||
for (auto const & routeSegment : routeSegments)
|
||||
TEST(routeSegment.GetSpeedCams().empty(), (routeSegment.GetSegment()));
|
||||
}
|
||||
|
||||
// Test on warning about speed cameras for countries where speed cameras partly prohibited.
|
||||
UNIT_TEST(GermanyWarningAboutSpeedCamerasTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(
|
||||
GetVehicleComponents(VehicleType::Car), FromLatLon(52.38465, 13.41906), {0., 0.}, FromLatLon(52.67564, 13.27453));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TEST(route.CrossMwmsPartlyProhibitedForSpeedCams(), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Spain_RestirctionOnlyMany)
|
||||
{
|
||||
// This relation https://www.openstreetmap.org/relation/7610329
|
||||
// See also Valhalla engine.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(43.38234, -5.67648), {0.0, 0.0},
|
||||
FromLatLon(43.38222, -5.69083), 8289.15);
|
||||
}
|
||||
|
||||
// TODO: w/ penalties PR: Route length: 2409.19 meters. ETA: 189.409 second
|
||||
// i.e. prefers to take a longer highway detour instead of service roads many turns - seems good!
|
||||
// (current test: Route length: 895.203 meters. ETA: 196.768 seconds.)
|
||||
UNIT_TEST(Russia_Moscow_RestirctionOnlyMany)
|
||||
{
|
||||
// This relation https://www.openstreetmap.org/relation/581743
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.991986, 37.2131072),
|
||||
{0.0, 0.0}, FromLatLon(55.9918083, 37.215531), 894.853);
|
||||
}
|
||||
|
||||
// Test that fake segments are not built from start to roads with hwtag=nocar for car routing.
|
||||
UNIT_TEST(SpainBilbaoAirportNoCarTest)
|
||||
{
|
||||
TRouteResult const routeResult = CalculateRoute(
|
||||
GetVehicleComponents(VehicleType::Car), FromLatLon(43.29969, -2.91312), {0., 0.}, FromLatLon(43.29904, -2.9108));
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *(routeResult.first);
|
||||
std::vector<RouteSegment> const & routeSegments = route.GetRouteSegments();
|
||||
TEST_GREATER(routeSegments.size(), 2, ());
|
||||
|
||||
// Note. routeSegments[0] is a start segment(point). routeSegments[1] is a fake segment
|
||||
// which goes from the route start to a segment of the road graph.
|
||||
// routeSegments[1].GetDistFromBeginningMeters() is the length of the first fake segment.
|
||||
// Start point is located near a road with hwtag=no.
|
||||
// So if routeSegments[1].GetDistFromBeginningMeters() is long enough the segment
|
||||
// with hwtag=no is no used.
|
||||
TEST_GREATER(routeSegments[1].GetDistFromBeginningMeters(), 20.0, ());
|
||||
}
|
||||
|
||||
// Test when start is located near mwm border. In that case it's possible that one of
|
||||
// closest edges is a dead end within one mwm. The end of this dead end should
|
||||
// be taken into account in |IndexGraphStarterJoints<Graph>::FindFirstJoints()|.
|
||||
UNIT_TEST(EnglandLondonStartNearMwmBorderTest)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(51.603582, 0.266995), {0., 0.},
|
||||
FromLatLon(51.606785, 0.264055), 416.8);
|
||||
}
|
||||
|
||||
// Test that toll road is not crossed by a fake edge if RouingOptions are set to Road::Toll.
|
||||
// Test on necessity calling RectCoversPolyline() after DataSource::ForEachInRect() while looking for fake edges.
|
||||
UNIT_TEST(RussiaMoscowNotCrossingTollRoadTest)
|
||||
{
|
||||
auto & vehicleComponents = GetVehicleComponents(VehicleType::Car);
|
||||
|
||||
auto const start = FromLatLon(55.93934, 37.406);
|
||||
m2::PointD finish[] = {FromLatLon(55.9414245, 37.4489627), FromLatLon(55.9421391, 37.4484832)};
|
||||
|
||||
{
|
||||
// Avoid motorway toll road and build route through minor residential roads (short but slow).
|
||||
RoutingOptionSetter optionsGuard(RoutingOptions::Toll);
|
||||
|
||||
// 1. End point is near the motorway toll road, but choose a minor track as end segment.
|
||||
CalculateRouteAndTestRouteLength(vehicleComponents, start, {0.0, 0.0}, finish[0], 8427.71);
|
||||
|
||||
// 2. End point is near the service road via the motorway toll road, but choose a minor track as end segment.
|
||||
CalculateRouteAndTestRouteLength(vehicleComponents, start, {0.0, 0.0}, finish[1], 8361.27);
|
||||
}
|
||||
|
||||
{
|
||||
// Normal route via the motorway toll road - long but fast (like Graphopper).
|
||||
// - 20595.4 is OK (Graphopper)
|
||||
// - 19203.7 is OK (OSRM)
|
||||
// - 21930.7 is OK (Valhalla)
|
||||
CalculateRouteAndTestRouteLength(vehicleComponents, start, {0.0, 0.0}, finish[0], 21930.7);
|
||||
CalculateRouteAndTestRouteLength(vehicleComponents, start, {0.0, 0.0}, finish[1], 22015.4);
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(NoCrash_RioGrandeCosmopolis)
|
||||
{
|
||||
TRouteResult const route = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(-32.17641, -52.16350),
|
||||
{0., 0.}, FromLatLon(-22.64374, -47.19720));
|
||||
|
||||
TEST_EQUAL(route.second, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(AreMwmsNear_HelsinkiPiter)
|
||||
{
|
||||
TRouteResult const route = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(60.87083, 26.53612),
|
||||
{0., 0.}, FromLatLon(60.95360, 28.53979));
|
||||
|
||||
TEST_EQUAL(route.second, RouterResultCode::NoError, ());
|
||||
}
|
||||
|
||||
// Test RussiaShorterFakeEdges1 and RussiaShorterFakeEdges2 are on reducing
|
||||
// |kSpeedOffroadKMpH| for car routing. This lets us make
|
||||
// fake edges shorter that prevent crossing lakes, forests and so on.
|
||||
UNIT_TEST(RussiaBlackLakeShorterFakeEdges1)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.62466, 39.71385), {0., 0.},
|
||||
FromLatLon(55.63114, 39.70979), 1469.54);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaShorterFakeEdges2)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.31103, 38.80954), {0., 0.},
|
||||
FromLatLon(55.31155, 38.8217), 2489.8);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1788
|
||||
UNIT_TEST(Germany_ShortRouteWithPassThroughChanges)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(49.512076, 8.284476), {0., 0.},
|
||||
FromLatLon(49.523783, 8.288701), 2014.);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/821
|
||||
UNIT_TEST(Ukraine_UmanOdessa)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(48.7498, 30.2203), {0., 0.},
|
||||
FromLatLon(46.4859, 30.6837), 265163.);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1736
|
||||
UNIT_TEST(Belgium_LiegeBrugge)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(50.645205, 5.573507), {0., 0.},
|
||||
FromLatLon(51.208479, 3.225558), 193436.);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1627
|
||||
UNIT_TEST(Spain_MadridSevilla)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(40.415322, -3.703517), {0., 0.},
|
||||
FromLatLon(37.388667, -5.995355), 528667.);
|
||||
}
|
||||
|
||||
UNIT_TEST(Belarus_Lithuania_MinskVilnius)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(53.902837, 27.562144), {0., 0.},
|
||||
FromLatLon(54.686821, 25.283189), 183231.);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/338
|
||||
UNIT_TEST(Russia_MendeleevoReutov)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(56.036866, 37.232630), {0., 0.},
|
||||
FromLatLon(55.762128, 37.856665), 66261.9);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1721
|
||||
UNIT_TEST(Austria_Croatia_SalzburgZagreb)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(47.795928, 13.047597), {0., 0.},
|
||||
FromLatLon(45.812822, 15.977049), 414275);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1071
|
||||
// TODO: w/ penalties PR: Route length: 348417 meters. ETA: 17740.4 seconds.
|
||||
// The route seems to be logical, so looks like an improvement?!
|
||||
UNIT_TEST(Russia_MoscowDesnogorsk)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.715208, 37.396528), {0., 0.},
|
||||
FromLatLon(54.151853, 33.287128), 355887);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1271
|
||||
UNIT_TEST(USA_DontLeaveHighway)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(34.1801345, -118.885005),
|
||||
{0., 0.}, FromLatLon(34.1767471, -118.869327), 1523);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/2085
|
||||
UNIT_TEST(USA_NorthCarolina_CrossMWMs)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(35.6233244, -78.3917262),
|
||||
{0., 0.}, FromLatLon(36.0081839, -81.5245347), 333425);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1565
|
||||
UNIT_TEST(Cyprus_NoUTurnFromFake)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(34.70639, 33.1184951), {0., 0.},
|
||||
FromLatLon(34.7065239, 33.1184222), 384.238);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(34.7068976, 33.1199084), {0., 0.},
|
||||
FromLatLon(34.7070505, 33.1198391), 670.077);
|
||||
}
|
||||
|
||||
UNIT_TEST(Crimea_UseGravelTertiary)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(45.362591, 36.471533), {0., 0.},
|
||||
FromLatLon(45.475055, 36.341766), 18815.6);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(45.470764, 36.331289), {0., 0.},
|
||||
FromLatLon(45.424964, 36.080336), 55220.2);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/2475
|
||||
UNIT_TEST(Spain_LinksJunction)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(38.8031, 0.0383), {0., 0.},
|
||||
FromLatLon(38.8228, 0.0357), 3479.63);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1773
|
||||
UNIT_TEST(Netherlands_CrossMwm_A15)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(51.847656, 4.089189), {0., 0.},
|
||||
FromLatLon(51.651632, 4.725924), 70596.3);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/2494
|
||||
UNIT_TEST(Netherlands_CrossMwm_GoudaToApenheul)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(52.0181, 4.7111), {0., 0.},
|
||||
FromLatLon(52.2153, 5.9187), 103576);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/2285
|
||||
UNIT_TEST(Hawaii_KeepH1)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(21.277841, -157.779314), {0., 0.},
|
||||
FromLatLon(21.296098, -157.823823), 5289.31);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1668
|
||||
UNIT_TEST(Russia_Moscow_KeepPrimary)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.7083688, 37.6213856), {0., 0.},
|
||||
FromLatLon(55.724623, 37.62588), 1921.88);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/1727
|
||||
// https://github.com/organicmaps/organicmaps/issues/2020
|
||||
// https://github.com/organicmaps/organicmaps/issues/2057
|
||||
UNIT_TEST(DontUseLinksWhenRidingOnMotorway)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(32.16881, 34.90656), {0., 0.},
|
||||
FromLatLon(32.1588823, 34.9330855), 2847.33);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(43.587808, 1.495385), {0., 0.},
|
||||
FromLatLon(43.600145, 1.490489), 1457.16);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(34.0175371, -84.3272339),
|
||||
{0., 0.}, FromLatLon(34.0298011, -84.3182477), 1609.76);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UseDonMotorway)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(54.5775321, 38.2206224), {0., 0.},
|
||||
FromLatLon(49.9315563, 40.5529881), 608031);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_Italy_Malcesine)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(48.4101446, 11.5892265), {0., 0.},
|
||||
FromLatLon(45.7662964, 10.8111554), 427135);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(45.7662964, 10.8111554), {0., 0.},
|
||||
FromLatLon(48.4101446, 11.5892265), 431341);
|
||||
|
||||
/// @todo Again strange detour (near finish) on a long route.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(50.8499365, 12.4662169), {0., 0.},
|
||||
FromLatLon(45.7662964, 10.8111554), 776000);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/3363
|
||||
UNIT_TEST(Belarus_UseP27_PastawyBraslaw)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.1187744, 26.8460319), {0., 0.},
|
||||
FromLatLon(55.6190911, 27.0938092), 86239.8);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/3257
|
||||
UNIT_TEST(Turkey_AvoidMountainsSecondary)
|
||||
{
|
||||
TRouteResult const res = CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(41.0027, 27.6752),
|
||||
{0., 0.}, FromLatLon(40.6119, 27.1136));
|
||||
|
||||
// GraphHopper and OSRM make a short route via the mountain secondary.
|
||||
// Valhalla makes a long route. I think it is correct.
|
||||
/// @todo Should "split" ways for better inCity/outCity classification. Now long ways are detected as outCity (wrong).
|
||||
TestRouteLength(*res.first, 100399);
|
||||
TestRouteTime(*res.first, 5319.01);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/4110
|
||||
// TODO: w/ penalties PR: Route length: 162712 meters. ETA: 6478.54 seconds
|
||||
// a strange looking detour is added in the end of the route compared to screenshot in OM #4110
|
||||
// Adding intermediate 45.255047, 13.6235211 fixes it:
|
||||
// Route length: 156291 meters. ETA: 6469.42 seconds (both shorter and tad faster!)
|
||||
UNIT_TEST(Slovenia_Croatia_CrossBorderPenalty)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.038579, 14.469414), {0., 0.},
|
||||
FromLatLon(45.22718, 13.596334), 156285);
|
||||
}
|
||||
|
||||
UNIT_TEST(USA_Birmingham_AL_KeyWest_FL_NoMotorway)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(28.9666499, -82.127271), {0., 0.},
|
||||
FromLatLon(25.8633542, -80.3878891), 457734);
|
||||
|
||||
/// @note These tests works good on release server, my desktop release skips MWM Florida_Orlando ...
|
||||
/// 15 vs 8 cross-mwm candidates.
|
||||
|
||||
auto const start = FromLatLon(33.5209837, -86.807945);
|
||||
auto const finish = FromLatLon(24.5534713, -81.7932587);
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), start, {0., 0.}, finish, 1'471'410);
|
||||
|
||||
RoutingOptionSetter optionsGuard(RoutingOptions::Motorway);
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), start, {0., 0.}, finish, 1'495'860);
|
||||
}
|
||||
|
||||
UNIT_TEST(Turkey_Salarialaca_Sanliurfa)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(38.8244409, 34.0979749), {0., 0.},
|
||||
FromLatLon(37.159585, 38.7919353));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TestRouteLength(route, 656891);
|
||||
// Should be less than 6 hours (6 * 3600), between Valhalla and GraphHopper.
|
||||
TestRouteTime(route, 20453.5);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/4924
|
||||
// https://github.com/organicmaps/organicmaps/issues/4996
|
||||
UNIT_TEST(UK_MiniRoundabout)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(50.4155631, -4.17201038),
|
||||
{0., 0.}, FromLatLon(50.4161337, -4.17226314), 114.957);
|
||||
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(50.4173675, -4.14913092),
|
||||
{0., 0.}, FromLatLon(50.4170013, -4.1471226), 153.223);
|
||||
|
||||
/// @todo Fancy case, changing start/end point a little and the route is OK. Also check m_exitNum.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(51.5686491, -0.00590868183),
|
||||
{0., 0.}, FromLatLon(51.5684408, -0.00596725822), 40);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/5069
|
||||
UNIT_TEST(Germany_Netherlands_AvoidLoops)
|
||||
{
|
||||
// https://www.openstreetmap.org/directions?engine=fossgis_osrm_car&route=51.682%2C10.220%3B51.919%2C5.845
|
||||
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(51.6823791, 10.2197113), {0., 0.},
|
||||
FromLatLon(51.9187916, 5.8452563));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
// TODO: w/ penalties PR: Route length: 405391 meters. ETA: 14249.4 seconds.
|
||||
TestRouteLength(route, 405058);
|
||||
TestRouteTime(route, 13965.2);
|
||||
}
|
||||
|
||||
UNIT_TEST(Germany_Cologne_Croatia_Zagreb)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(50.924, 6.943), {0., 0.},
|
||||
FromLatLon(45.806, 15.963), 1074730);
|
||||
}
|
||||
|
||||
UNIT_TEST(Finland_Avoid_CompactedUnclassified)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(61.4677, 24.0025), {0., 0.},
|
||||
FromLatLon(61.4577, 24.035), 3128.31);
|
||||
}
|
||||
|
||||
// https://github.com/orgs/organicmaps/discussions/5158#discussioncomment-5938807
|
||||
UNIT_TEST(Greece_Crete_Use_EO94)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(35.5170594, 24.0938699), {0., 0.},
|
||||
FromLatLon(35.5446109, 24.1312439), 6333.82);
|
||||
}
|
||||
|
||||
UNIT_TEST(Bulgaria_Rosenovo_Dobrich)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(43.6650649, 27.7826578), {0., 0.},
|
||||
FromLatLon(43.5690961, 27.8307318), 16556.3);
|
||||
}
|
||||
|
||||
UNIT_TEST(Russia_UseGravelPrimary_Not_DefaultTertiary)
|
||||
{
|
||||
/// @todo Actually, tertiary should be tagged as surface=unpaved.
|
||||
/// There is an idea to detect and update route if we have leave-enter for the same ref (named) >= primary road:
|
||||
/// {80K-004, some tertiary, 80K-004} in a reasonable distance. This is a signal that "some tertiary"
|
||||
/// in a middle is an error.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.8466967, 57.303653), {0., 0.},
|
||||
FromLatLon(55.8260004, 57.0367732), 19910);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/5695
|
||||
UNIT_TEST(Russia_Yekaterinburg_NChelny)
|
||||
{
|
||||
// Make sense without Chelyabinsk and Izhevsk. Thus we can check really fancy cases.
|
||||
// Otherwise, good routes will be through Perm-Izhevsk or Chelyabinsk-Ufa
|
||||
auto components = CreateAllMapsComponents(VehicleType::Car, {"Russia_Chelyabinsk Oblast", "Russia_Udmurt Republic"});
|
||||
|
||||
auto const start = FromLatLon(56.8382242, 60.6308866);
|
||||
auto const finish = FromLatLon(55.7341111, 52.4156012);
|
||||
|
||||
{
|
||||
RoutingOptionSetter optionsGuard(RoutingOptions::Dirty | RoutingOptions::Ferry);
|
||||
// forward
|
||||
CalculateRouteAndTestRouteLength(*components, start, {0., 0.}, finish, 767702);
|
||||
// backward
|
||||
CalculateRouteAndTestRouteLength(*components, finish, {0., 0.}, start, 766226);
|
||||
}
|
||||
|
||||
// OSRM, GraphHopper uses gravel, Valhalla makes a route like above.
|
||||
|
||||
/// @todo Should use tertiary + gravel + villages (46km) here and below instead of primary (86km)?
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(55.9315, 58.202), {0., 0.},
|
||||
FromLatLon(55.7555, 57.8348), 45788);
|
||||
// forward
|
||||
CalculateRouteAndTestRouteLength(*components, start, {0., 0.}, finish, 757109);
|
||||
// backward
|
||||
CalculateRouteAndTestRouteLength(*components, finish, {0., 0.}, start, 755851);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/5695
|
||||
UNIT_TEST(Russia_CrossMwm_Ferry)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
CalculateRoute(GetVehicleComponents(VehicleType::Car), FromLatLon(55.7840398, 54.0815156), {0., 0.},
|
||||
FromLatLon(55.7726245, 54.0752932));
|
||||
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
Route const & route = *routeResult.first;
|
||||
TestRouteLength(route, 1453);
|
||||
// 2 hours duration (https://www.openstreetmap.org/way/426120647) + 20 minutes ferry landing penalty.
|
||||
/// @todo Not working now, @see SingleVehicleWorldGraph::CalculateETA.
|
||||
TEST_GREATER(route.GetTotalTimeSec(), 7200 + 20 * 60, ());
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/6035
|
||||
UNIT_TEST(Netherlands_CrossMwm_Ferry)
|
||||
{
|
||||
/// @todo Should work after reducing ferry landing penalty, but nope ..
|
||||
/// Can't realize what is going on here, maybe penalty is aggregated 2 times?
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(52.3855418, 6.12969591), {0., 0.},
|
||||
FromLatLon(52.3924362, 6.12166998), 1322);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/6278
|
||||
// TODO: w/ penalties PR: Route length: 4629.08 meters. ETA: 750.719 seconds.
|
||||
// The new route looks alright.
|
||||
UNIT_TEST(Turkey_PreferSecondary_NotResidential)
|
||||
{
|
||||
/// @todo Now the app wrongly takes tertiary (no limits) vs primary/secondary (with maxspeed = 30) - fixed?
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(41.0529, 28.9201), {0., 0.},
|
||||
FromLatLon(41.0731, 28.9407), 4783.85);
|
||||
}
|
||||
|
||||
UNIT_TEST(Ireland_NorthernIreland_NoBorderPenalty)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(53.9909441, -7.36035861),
|
||||
{0., 0.}, FromLatLon(54.9517424, -7.73625795), 138655);
|
||||
}
|
||||
|
||||
UNIT_TEST(Israel_Jerusalem_Palestine_NoBorderPenalty)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(31.4694833, 35.394899), {0., 0.},
|
||||
FromLatLon(31.7776832, 35.2236876), 76133);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/6510
|
||||
UNIT_TEST(EqualMaxSpeeds_PreferPrimary_NotResidential)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.5239, 5.6187), {0., 0.},
|
||||
FromLatLon(46.5240, 5.6096), 1123);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/3033#issuecomment-1798343531
|
||||
UNIT_TEST(Spain_NoMaxSpeeds_KeepTrunk_NotTrunkLink)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(43.3773971, -3.43177355),
|
||||
{0., 0.}, FromLatLon(43.3685773, -3.42580007), 1116.79);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/8823
|
||||
UNIT_TEST(LATAM_UsePrimary_NotTrunkDetour)
|
||||
{
|
||||
// 10247 or less should be here.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(4.737768, -74.077599), {0., 0.},
|
||||
FromLatLon(4.684999, -74.046393), 10247.3);
|
||||
|
||||
/// @todo Still have the strange detour at the end. Due to the 20/30 km/h assignment for the primary_link.
|
||||
/// Looks like it is bad to assign maxspeed for _all_ connected links if it is defined for the middle one.
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/8729
|
||||
UNIT_TEST(USA_UseDirt_WithMaxspeed)
|
||||
{
|
||||
// Route length: 20907.2 meters. ETA: 1847.97 seconds.
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.5361985, -111.943183),
|
||||
{0., 0.}, FromLatLon(46.4925409, -112.105446), 20906.5);
|
||||
|
||||
// TODO: w/ penalties PR: Route length: 3324.62 meters. ETA: 1377.89 seconds.
|
||||
// The new route is shorter and less turns!
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(46.7336967, -111.926), {0., 0.},
|
||||
FromLatLon(46.7467037, -111.917147), 3527.79);
|
||||
|
||||
// Albania https://github.com/organicmaps/organicmaps/issues/8541
|
||||
// 247.14 meters. ETA: 370.356 seconds
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(42.3889581, 19.7812567), {0., 0.},
|
||||
FromLatLon(42.3878106, 19.7831402), 247.139);
|
||||
}
|
||||
|
||||
// https://codeberg.org/comaps/comaps/issues/304
|
||||
UNIT_TEST(Norway_FauxOneway_MotorVehicleBackward_No)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(59.919189, 10.759355), {0., 0.},
|
||||
FromLatLon(59.921042, 10.759302), 410);
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Bicycle), FromLatLon(59.919189, 10.759355),
|
||||
{0., 0.}, FromLatLon(59.921042, 10.759302), 210);
|
||||
}
|
||||
|
||||
// https://github.com/organicmaps/organicmaps/issues/9620
|
||||
UNIT_TEST(Germany_Avoid_Agricultural)
|
||||
{
|
||||
CalculateRouteAndTestRouteLength(GetVehicleComponents(VehicleType::Car), FromLatLon(47.6584463, 11.038139), {0., 0.},
|
||||
FromLatLon(47.6580109, 11.0432625), 1096.11);
|
||||
}
|
||||
|
||||
} // namespace route_test
|
||||
340
libs/routing/routing_integration_tests/routing_test_tools.cpp
Normal file
340
libs/routing/routing_integration_tests/routing_test_tools.cpp
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "routing/routing_tests/index_graph_tools.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "map/features_fetcher.hpp"
|
||||
|
||||
#include "routing/index_router.hpp"
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/router_delegate.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "storage/country_parent_getter.hpp"
|
||||
#include "storage/routing_helpers.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
#include "platform/platform_tests_support/helpers.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "geometry/distance_on_sphere.hpp"
|
||||
|
||||
#include "base/math.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
namespace integration
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace routing_test;
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
double constexpr kErrorMeters = 1.0;
|
||||
double constexpr kErrorSeconds = 1.0;
|
||||
} // namespace
|
||||
|
||||
shared_ptr<FeaturesFetcher> CreateFeaturesFetcher(vector<LocalCountryFile> const & localFiles)
|
||||
{
|
||||
size_t const maxOpenFileNumber = 4096;
|
||||
platform::tests_support::ChangeMaxNumberOfOpenFiles(maxOpenFileNumber);
|
||||
shared_ptr<FeaturesFetcher> featuresFetcher(new FeaturesFetcher);
|
||||
featuresFetcher->InitClassificator();
|
||||
|
||||
for (LocalCountryFile const & localFile : localFiles)
|
||||
featuresFetcher->RegisterMap(localFile);
|
||||
|
||||
return featuresFetcher;
|
||||
}
|
||||
|
||||
unique_ptr<storage::CountryInfoGetter> CreateCountryInfoGetter()
|
||||
{
|
||||
Platform const & platform = GetPlatform();
|
||||
return storage::CountryInfoReader::CreateCountryInfoGetter(platform);
|
||||
}
|
||||
|
||||
unique_ptr<IndexRouter> CreateVehicleRouter(DataSource & dataSource, storage::CountryInfoGetter const & infoGetter,
|
||||
traffic::TrafficCache const & trafficCache,
|
||||
vector<LocalCountryFile> const & localFiles, VehicleType vehicleType)
|
||||
{
|
||||
auto const countryFileGetter = [&infoGetter](m2::PointD const & pt) { return infoGetter.GetRegionCountryId(pt); };
|
||||
|
||||
auto const getMwmRectByName = [&infoGetter](string const & countryId) -> m2::RectD
|
||||
{ return infoGetter.GetLimitRectForLeaf(countryId); };
|
||||
|
||||
auto countryParentGetter = std::make_unique<storage::CountryParentGetter>();
|
||||
CHECK(countryParentGetter, ());
|
||||
|
||||
auto numMwmIds = make_shared<NumMwmIds>();
|
||||
for (auto const & f : localFiles)
|
||||
{
|
||||
auto const & countryFile = f.GetCountryFile();
|
||||
auto const mwmId = dataSource.GetMwmIdByCountryFile(countryFile);
|
||||
|
||||
if (!mwmId.IsAlive())
|
||||
continue;
|
||||
|
||||
if (countryParentGetter->GetStorageForTesting().IsLeaf(countryFile.GetName()))
|
||||
numMwmIds->RegisterFile(countryFile);
|
||||
}
|
||||
|
||||
// You should have at least one country file to make further tests.
|
||||
TEST(!numMwmIds->IsEmpty(), ());
|
||||
|
||||
bool const loadAltitudes = vehicleType != VehicleType::Car;
|
||||
auto indexRouter =
|
||||
make_unique<IndexRouter>(vehicleType, loadAltitudes, *countryParentGetter, countryFileGetter, getMwmRectByName,
|
||||
numMwmIds, MakeNumMwmTree(*numMwmIds, infoGetter), trafficCache, dataSource);
|
||||
|
||||
return indexRouter;
|
||||
}
|
||||
|
||||
void GetAllLocalFiles(vector<LocalCountryFile> & localFiles)
|
||||
{
|
||||
platform::FindAllLocalMapsAndCleanup(numeric_limits<int64_t>::max() /* latestVersion */, localFiles);
|
||||
|
||||
// Leave only real country files for routing test.
|
||||
localFiles.erase(std::remove_if(localFiles.begin(), localFiles.end(),
|
||||
[](LocalCountryFile const & file)
|
||||
{
|
||||
auto const & name = file.GetCountryName();
|
||||
return name == WORLD_FILE_NAME || name == WORLD_COASTS_FILE_NAME;
|
||||
}),
|
||||
localFiles.end());
|
||||
|
||||
for (auto & file : localFiles)
|
||||
file.SyncWithDisk();
|
||||
}
|
||||
|
||||
shared_ptr<VehicleRouterComponents> CreateAllMapsComponents(VehicleType vehicleType,
|
||||
std::set<std::string> const & skipMaps)
|
||||
{
|
||||
vector<LocalCountryFile> localFiles;
|
||||
GetAllLocalFiles(localFiles);
|
||||
base::EraseIf(localFiles,
|
||||
[&skipMaps](LocalCountryFile const & cf) { return skipMaps.count(cf.GetCountryName()) > 0; });
|
||||
TEST(!localFiles.empty(), ());
|
||||
|
||||
return make_shared<VehicleRouterComponents>(localFiles, vehicleType);
|
||||
}
|
||||
|
||||
IRouterComponents & GetVehicleComponents(VehicleType vehicleType)
|
||||
{
|
||||
static map<VehicleType, shared_ptr<VehicleRouterComponents>> kVehicleComponents;
|
||||
|
||||
auto it = kVehicleComponents.find(vehicleType);
|
||||
if (it == kVehicleComponents.end())
|
||||
tie(it, ignore) = kVehicleComponents.emplace(vehicleType, CreateAllMapsComponents(vehicleType, {}));
|
||||
|
||||
CHECK(it->second, ());
|
||||
return *(it->second);
|
||||
}
|
||||
|
||||
TRouteResult CalculateRoute(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint)
|
||||
{
|
||||
RouterDelegate delegate;
|
||||
shared_ptr<Route> route = make_shared<Route>("mapsme", 0 /* route id */);
|
||||
RouterResultCode result = routerComponents.GetRouter().CalculateRoute(
|
||||
Checkpoints(startPoint, finalPoint), startDirection, false /* adjust */, delegate, *route);
|
||||
ASSERT(route, ());
|
||||
routerComponents.GetRouter().SetGuides({});
|
||||
return TRouteResult(route, result);
|
||||
}
|
||||
|
||||
TRouteResult CalculateRoute(IRouterComponents const & routerComponents, Checkpoints const & checkpoints,
|
||||
GuidesTracks && guides)
|
||||
{
|
||||
RouterDelegate delegate;
|
||||
shared_ptr<Route> route = make_shared<Route>("mapsme", 0 /* route id */);
|
||||
routerComponents.GetRouter().SetGuides(std::move(guides));
|
||||
RouterResultCode result = routerComponents.GetRouter().CalculateRoute(
|
||||
checkpoints, m2::PointD::Zero() /* startDirection */, false /* adjust */, delegate, *route);
|
||||
ASSERT(route, ());
|
||||
routerComponents.GetRouter().SetGuides({});
|
||||
return TRouteResult(route, result);
|
||||
}
|
||||
|
||||
void TestTurnCount(routing::Route const & route, uint32_t expectedTurnCount)
|
||||
{
|
||||
// We use -1 for ignoring the "ReachedYourDestination" turn record.
|
||||
vector<turns::TurnItem> turns;
|
||||
route.GetTurnsForTesting(turns);
|
||||
TEST_EQUAL(turns.size() - 1, expectedTurnCount, ());
|
||||
}
|
||||
|
||||
void TestTurns(Route const & route, vector<CarDirection> const & expectedTurns)
|
||||
{
|
||||
vector<turns::TurnItem> turns;
|
||||
route.GetTurnsForTesting(turns);
|
||||
TEST_EQUAL(turns.size() - 1, expectedTurns.size(), ());
|
||||
|
||||
for (size_t i = 0; i < expectedTurns.size(); ++i)
|
||||
TEST_EQUAL(turns[i].m_turn, expectedTurns[i], ());
|
||||
}
|
||||
|
||||
void TestCurrentStreetName(Route const & route, string const & expectedStreetName)
|
||||
{
|
||||
RouteSegment::RoadNameInfo roadNameInfo;
|
||||
route.GetCurrentStreetName(roadNameInfo);
|
||||
TEST_EQUAL(roadNameInfo.m_name, expectedStreetName, ());
|
||||
}
|
||||
|
||||
void TestNextStreetName(Route const & route, string const & expectedStreetName)
|
||||
{
|
||||
RouteSegment::RoadNameInfo roadNameInfo;
|
||||
route.GetNextTurnStreetName(roadNameInfo);
|
||||
TEST_EQUAL(roadNameInfo.m_name, expectedStreetName, ());
|
||||
}
|
||||
|
||||
void TestRouteLength(Route const & route, double expectedRouteMeters, double relativeError)
|
||||
{
|
||||
double const delta = max(expectedRouteMeters * relativeError, kErrorMeters);
|
||||
double const routeMeters = route.GetTotalDistanceMeters();
|
||||
TEST(AlmostEqualAbs(routeMeters, expectedRouteMeters, delta),
|
||||
("Route length test failed. Expected:", expectedRouteMeters, "have:", routeMeters, "delta:", delta));
|
||||
}
|
||||
|
||||
void TestRouteTime(Route const & route, double expectedRouteSeconds, double relativeError)
|
||||
{
|
||||
double const delta = max(expectedRouteSeconds * relativeError, kErrorSeconds);
|
||||
double const routeSeconds = route.GetTotalTimeSec();
|
||||
TEST(AlmostEqualAbs(routeSeconds, expectedRouteSeconds, delta),
|
||||
("Route time test failed. Expected:", expectedRouteSeconds, "have:", routeSeconds, "delta:", delta));
|
||||
}
|
||||
|
||||
void TestRoutePointsNumber(Route const & route, size_t expectedPointsNumber, double relativeError)
|
||||
{
|
||||
CHECK_GREATER_OR_EQUAL(relativeError, 0.0, ());
|
||||
size_t const routePoints = route.GetPoly().GetSize();
|
||||
TEST(AlmostEqualRel(static_cast<double>(routePoints), static_cast<double>(expectedPointsNumber), relativeError),
|
||||
("Route points test failed. Expected:", expectedPointsNumber, "have:", routePoints,
|
||||
"relative error:", relativeError));
|
||||
}
|
||||
|
||||
void CalculateRouteAndTestRouteLength(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint,
|
||||
double expectedRouteMeters, double relativeError /* = 0.02 */)
|
||||
{
|
||||
TRouteResult routeResult = CalculateRoute(routerComponents, startPoint, startDirection, finalPoint);
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
CHECK(routeResult.first, ());
|
||||
TestRouteLength(*routeResult.first, expectedRouteMeters, relativeError);
|
||||
}
|
||||
|
||||
void CalculateRouteAndTestRouteTime(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint,
|
||||
double expectedTimeSeconds, double relativeError /* = 0.07 */)
|
||||
{
|
||||
TRouteResult routeResult = CalculateRoute(routerComponents, startPoint, startDirection, finalPoint);
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
CHECK(routeResult.first, ());
|
||||
TestRouteTime(*routeResult.first, expectedTimeSeconds, relativeError);
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestValid() const
|
||||
{
|
||||
TEST(m_isValid, ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestNotValid() const
|
||||
{
|
||||
TEST(!m_isValid, ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestPoint(m2::PointD const & expectedPoint, double inaccuracyMeters) const
|
||||
{
|
||||
double const distanceMeters = ms::DistanceOnEarth(expectedPoint.y, expectedPoint.x, m_point.y, m_point.x);
|
||||
TEST_LESS(distanceMeters, inaccuracyMeters, ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestDirection(routing::turns::CarDirection expectedDirection) const
|
||||
{
|
||||
TEST_EQUAL(m_direction, expectedDirection, ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestOneOfDirections(set<routing::turns::CarDirection> const & expectedDirections) const
|
||||
{
|
||||
TEST(expectedDirections.find(m_direction) != expectedDirections.cend(), (m_direction));
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn const & TestTurn::TestRoundAboutExitNum(uint32_t expectedRoundAboutExitNum) const
|
||||
{
|
||||
TEST_EQUAL(m_roundAboutExitNum, expectedRoundAboutExitNum, ());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TestTurn GetNthTurn(routing::Route const & route, uint32_t turnNumber)
|
||||
{
|
||||
vector<turns::TurnItem> turns;
|
||||
route.GetTurnsForTesting(turns);
|
||||
if (turnNumber >= turns.size())
|
||||
{
|
||||
ASSERT(false, ());
|
||||
return TestTurn();
|
||||
}
|
||||
|
||||
TurnItem const & turn = turns[turnNumber];
|
||||
return TestTurn(route.GetPoly().GetPoint(turn.m_index), turn.m_turn, turn.m_exitNum);
|
||||
}
|
||||
|
||||
bool IsSubwayExists(Route const & route)
|
||||
{
|
||||
auto const & routeSegments = route.GetRouteSegments();
|
||||
bool intoSubway = false;
|
||||
|
||||
for (auto const & routeSegment : routeSegments)
|
||||
{
|
||||
if (!routeSegment.HasTransitInfo())
|
||||
{
|
||||
intoSubway = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (routeSegment.GetTransitInfo().GetType() != TransitInfo::Type::Gate)
|
||||
continue;
|
||||
|
||||
if (intoSubway)
|
||||
return true;
|
||||
|
||||
intoSubway = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CheckSubwayAbsent(Route const & route)
|
||||
{
|
||||
bool wasSubway = IsSubwayExists(route);
|
||||
TEST(!wasSubway, ("Find subway subpath into route."));
|
||||
}
|
||||
|
||||
void CheckSubwayExistence(Route const & route)
|
||||
{
|
||||
bool wasSubway = IsSubwayExists(route);
|
||||
TEST(wasSubway, ("Can not find subway subpath into route."));
|
||||
}
|
||||
|
||||
LocalCountryFile GetLocalCountryFileByCountryId(platform::CountryFile const & country)
|
||||
{
|
||||
vector<LocalCountryFile> localFiles;
|
||||
GetAllLocalFiles(localFiles);
|
||||
|
||||
for (auto const & lf : localFiles)
|
||||
if (lf.GetCountryFile() == country)
|
||||
return lf;
|
||||
return {};
|
||||
}
|
||||
} // namespace integration
|
||||
173
libs/routing/routing_integration_tests/routing_test_tools.hpp
Normal file
173
libs/routing/routing_integration_tests/routing_test_tools.hpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/index_router.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "traffic/traffic_cache.hpp"
|
||||
|
||||
#include "storage/country_info_getter.hpp"
|
||||
|
||||
#include "map/features_fetcher.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/*
|
||||
* These tests are developed to simplify routing integration tests writing.
|
||||
* You can use the interface bellow however you want but there are some hints.
|
||||
* 1. Most likely you want to use GetCarComponents() or GetPedestrianComponents() without parameter
|
||||
* to get a reference to IRouterComponents.
|
||||
* It loads all the maps from directories Platform::WritableDir()
|
||||
* and Platform::ResourcesDir() only once and then reuse it.
|
||||
* Use GetCarComponents() or GetPedestrianComponents() with vector of maps parameter
|
||||
* only if you want to test something on a special map set.
|
||||
* 2. Loading maps and calculating routes is a time consuming process.
|
||||
* Do this only if you really need it.
|
||||
* 3. If you want to check that a turn is absent - use TestTurnCount.
|
||||
* 4. The easiest way to gather all the information for writing an integration test is
|
||||
* - to put a break point in CalculateRoute() method;
|
||||
* - to make a route with the desktop application;
|
||||
* - to get all necessary parameters and result of the route calculation;
|
||||
* - to place them into the test you're writing.
|
||||
* 5. The recommended way for naming tests for a route from one place to another one is
|
||||
* <Country><City><Street1><House1><Street2><House2><Test time. TurnTest or RouteTest for the
|
||||
* time being>
|
||||
* 6. Add a comment to describe what this particular test is testing (e.g. "respect the bicycle=no tag").
|
||||
* And add a ref to a Github issue if applicable.
|
||||
* 7. It's a good idea to use short routes for testing turns. The thing is geometry of long routes
|
||||
* could be changed from one dataset to another. The shorter the route the less is the chance it's changed.
|
||||
*/
|
||||
|
||||
typedef std::pair<std::shared_ptr<routing::Route>, routing::RouterResultCode> TRouteResult;
|
||||
|
||||
namespace integration
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace turns;
|
||||
using platform::LocalCountryFile;
|
||||
|
||||
std::shared_ptr<FeaturesFetcher> CreateFeaturesFetcher(std::vector<LocalCountryFile> const & localFiles);
|
||||
|
||||
std::unique_ptr<storage::CountryInfoGetter> CreateCountryInfoGetter();
|
||||
|
||||
std::unique_ptr<IndexRouter> CreateVehicleRouter(DataSource & dataSource, storage::CountryInfoGetter const & infoGetter,
|
||||
traffic::TrafficCache const & trafficCache,
|
||||
std::vector<LocalCountryFile> const & localFiles,
|
||||
VehicleType vehicleType);
|
||||
|
||||
class IRouterComponents
|
||||
{
|
||||
public:
|
||||
IRouterComponents(std::vector<LocalCountryFile> const & localFiles)
|
||||
: m_featuresFetcher(CreateFeaturesFetcher(localFiles))
|
||||
, m_infoGetter(CreateCountryInfoGetter())
|
||||
{}
|
||||
|
||||
virtual ~IRouterComponents() = default;
|
||||
|
||||
virtual IRouter & GetRouter() const = 0;
|
||||
|
||||
storage::CountryInfoGetter const & GetCountryInfoGetter() const noexcept { return *m_infoGetter; }
|
||||
|
||||
protected:
|
||||
std::shared_ptr<FeaturesFetcher> m_featuresFetcher;
|
||||
std::unique_ptr<storage::CountryInfoGetter> m_infoGetter;
|
||||
};
|
||||
|
||||
class VehicleRouterComponents : public IRouterComponents
|
||||
{
|
||||
public:
|
||||
VehicleRouterComponents(std::vector<LocalCountryFile> const & localFiles, VehicleType vehicleType)
|
||||
: IRouterComponents(localFiles)
|
||||
, m_indexRouter(CreateVehicleRouter(m_featuresFetcher->GetDataSource(), *m_infoGetter, m_trafficCache, localFiles,
|
||||
vehicleType))
|
||||
{}
|
||||
|
||||
IRouter & GetRouter() const override { return *m_indexRouter; }
|
||||
|
||||
private:
|
||||
traffic::TrafficCache m_trafficCache;
|
||||
std::unique_ptr<IndexRouter> m_indexRouter;
|
||||
};
|
||||
|
||||
void GetAllLocalFiles(std::vector<LocalCountryFile> & localFiles);
|
||||
void TestOnlineCrosses(ms::LatLon const & startPoint, ms::LatLon const & finalPoint,
|
||||
std::vector<std::string> const & expected, IRouterComponents & routerComponents);
|
||||
void TestOnlineFetcher(ms::LatLon const & startPoint, ms::LatLon const & finalPoint,
|
||||
std::vector<std::string> const & expected, IRouterComponents & routerComponents);
|
||||
|
||||
std::shared_ptr<VehicleRouterComponents> CreateAllMapsComponents(VehicleType vehicleType,
|
||||
std::set<std::string> const & skipMaps);
|
||||
|
||||
IRouterComponents & GetVehicleComponents(VehicleType vehicleType);
|
||||
|
||||
TRouteResult CalculateRoute(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint);
|
||||
|
||||
TRouteResult CalculateRoute(IRouterComponents const & routerComponents, Checkpoints const & checkpoints,
|
||||
GuidesTracks && guides);
|
||||
|
||||
void TestTurnCount(Route const & route, uint32_t expectedTurnCount);
|
||||
void TestTurns(Route const & route, std::vector<CarDirection> const & expectedTurns);
|
||||
|
||||
/// Testing route length.
|
||||
/// It is used for checking if routes have expected(sample) length.
|
||||
/// A created route will pass the test iff
|
||||
/// expectedRouteMeters - expectedRouteMeters * relativeError <= route->GetDistance()
|
||||
/// && expectedRouteMeters + expectedRouteMeters * relativeError >= route->GetDistance()
|
||||
void TestRouteLength(Route const & route, double expectedRouteMeters, double relativeError = 0.01);
|
||||
void TestRouteTime(Route const & route, double expectedRouteSeconds, double relativeError = 0.01);
|
||||
void TestRoutePointsNumber(Route const & route, size_t expectedPointsNumber, double relativeError = 0.1);
|
||||
|
||||
void CalculateRouteAndTestRouteLength(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint,
|
||||
double expectedRouteMeters, double relativeError = 0.02);
|
||||
|
||||
void CalculateRouteAndTestRouteTime(IRouterComponents const & routerComponents, m2::PointD const & startPoint,
|
||||
m2::PointD const & startDirection, m2::PointD const & finalPoint,
|
||||
double expectedTimeSeconds, double relativeError = 0.07);
|
||||
|
||||
void CheckSubwayExistence(Route const & route);
|
||||
void CheckSubwayAbsent(Route const & route);
|
||||
|
||||
class TestTurn
|
||||
{
|
||||
friend TestTurn GetNthTurn(Route const & route, uint32_t turnNumber);
|
||||
|
||||
m2::PointD const m_point;
|
||||
CarDirection const m_direction;
|
||||
uint32_t const m_roundAboutExitNum;
|
||||
bool const m_isValid;
|
||||
|
||||
TestTurn() : m_point({0.0, 0.0}), m_direction(CarDirection::None), m_roundAboutExitNum(0), m_isValid(false) {}
|
||||
TestTurn(m2::PointD const & pnt, CarDirection direction, uint32_t roundAboutExitNum)
|
||||
: m_point(pnt)
|
||||
, m_direction(direction)
|
||||
, m_roundAboutExitNum(roundAboutExitNum)
|
||||
, m_isValid(true)
|
||||
{}
|
||||
|
||||
public:
|
||||
TestTurn const & TestValid() const;
|
||||
TestTurn const & TestNotValid() const;
|
||||
TestTurn const & TestPoint(m2::PointD const & expectedPoint, double inaccuracyMeters = 3.) const;
|
||||
TestTurn const & TestDirection(CarDirection expectedDirection) const;
|
||||
TestTurn const & TestOneOfDirections(std::set<CarDirection> const & expectedDirections) const;
|
||||
TestTurn const & TestRoundAboutExitNum(uint32_t expectedRoundAboutExitNum) const;
|
||||
};
|
||||
|
||||
/// Extracting appropriate TestTurn if any. If not TestTurn::isValid() returns false.
|
||||
/// inaccuracy is set in meters.
|
||||
TestTurn GetNthTurn(Route const & route, uint32_t turnNumber);
|
||||
|
||||
void TestCurrentStreetName(routing::Route const & route, std::string const & expectedStreetName);
|
||||
|
||||
void TestNextStreetName(routing::Route const & route, std::string const & expectedStreetName);
|
||||
|
||||
LocalCountryFile GetLocalCountryFileByCountryId(platform::CountryFile const & country);
|
||||
} // namespace integration
|
||||
160
libs/routing/routing_integration_tests/small_routes.cpp
Normal file
160
libs/routing/routing_integration_tests/small_routes.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/vehicle_mask.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
using namespace routing;
|
||||
|
||||
namespace
|
||||
{
|
||||
// This is set of small routes was received from users' crashes.
|
||||
// It crashed into astar_algorithm.hpp in CHECK() about A* invariant
|
||||
// for bidirectional algo.
|
||||
// These tests should just passed without any crash.
|
||||
UNIT_TEST(SmallRoutes_JustNoError)
|
||||
{
|
||||
// Do not touch the coords here! It's must be written in this format.
|
||||
// In other case, some tests become not crashable.
|
||||
std::vector<std::tuple<ms::LatLon, ms::LatLon, VehicleType>> routes = {
|
||||
{{12.087755, -68.898342}, {12.086652, -68.899154}, VehicleType::Car}, // 1
|
||||
{{-20.104568, 57.580254}, {-20.106874, 57.580414}, VehicleType::Car}, // 2
|
||||
{{-0.756955, -90.315459}, {-0.757317, -90.314971}, VehicleType::Pedestrian}, // 3
|
||||
{{-13.527445, -71.983072}, {-13.527530, -71.983102}, VehicleType::Car}, // 4
|
||||
{{-22.205002, 166.472641}, {-22.205165, 166.473012}, VehicleType::Car}, // 5
|
||||
{{-33.640811, 115.023226}, {-33.640719, 115.022691}, VehicleType::Car}, // 6
|
||||
{{-37.731474, 176.132243}, {-37.731238, 176.132445}, VehicleType::Car}, // 7
|
||||
{{-37.950809, 176.993992}, {-37.951158, 176.994054}, VehicleType::Car}, // 8
|
||||
{{-38.122103, 176.307336}, {-38.122196, 176.307424}, VehicleType::Car}, // 9
|
||||
{{-44.384889, 171.245860}, {-44.384856, 171.246203}, VehicleType::Car}, // 10
|
||||
{{-8.352453, 116.039122}, {-8.352394, 116.038901}, VehicleType::Pedestrian}, // 11
|
||||
{{-8.690502, 115.432713}, {-8.690827, 115.433297}, VehicleType::Pedestrian}, // 12
|
||||
{{-8.840441, 115.180369}, {-8.840584, 115.180666}, VehicleType::Car}, // 13
|
||||
{{10.766800, 106.691260}, {10.766686, 106.691217}, VehicleType::Car}, // 14
|
||||
{{12.089446, -68.863145}, {12.089641, -68.863023}, VehicleType::Car}, // 15
|
||||
{{12.168143, -68.285843}, {12.168203, -68.285999}, VehicleType::Car}, // 16
|
||||
{{12.490231, -69.966714}, {12.489738, -69.966762}, VehicleType::Car}, // 17
|
||||
{{12.529459, -69.989523}, {12.529752, -69.989532}, VehicleType::Car}, // 18
|
||||
{{12.545208, -70.052132}, {12.545086, -70.051987}, VehicleType::Car}, // 19
|
||||
{{14.623702, 121.015163}, {14.623624, 121.015058}, VehicleType::Car}, // 20
|
||||
{{27.614768, -82.735309}, {27.615303, -82.735014}, VehicleType::Car}, // 21
|
||||
{{30.647048, 104.071743}, {30.647142, 104.071331}, VehicleType::Pedestrian}, // 22
|
||||
{{31.308356, 120.629667}, {31.308911, 120.629565}, VehicleType::Pedestrian}, // 23
|
||||
{{31.624363, -7.985198}, {31.624537, -7.985214}, VehicleType::Pedestrian}, // 24
|
||||
{{31.624519, -7.985267}, {31.624537, -7.985214}, VehicleType::Pedestrian}, // 25
|
||||
{{31.656752, 34.555609}, {31.656685, 34.555488}, VehicleType::Car}, // 26
|
||||
{{34.907010, 33.620845}, {34.906048, 33.620263}, VehicleType::Car}, // 27
|
||||
{{34.921187, 32.625802}, {34.921086, 32.625805}, VehicleType::Car}, // 28
|
||||
{{34.979258, 33.937110}, {34.979098, 33.937177}, VehicleType::Car}, // 29
|
||||
{{35.018181, 34.046807}, {35.018514, 34.046997}, VehicleType::Car}, // 30
|
||||
{{35.514115, 23.912056}, {35.514230, 23.912168}, VehicleType::Car}, // 31
|
||||
{{35.581194, 45.424180}, {35.581028, 45.424491}, VehicleType::Pedestrian}, // 32
|
||||
{{36.230656, 28.134475}, {36.230385, 28.134924}, VehicleType::Car}, // 33
|
||||
{{36.358085, 25.444976}, {36.358666, 25.445164}, VehicleType::Pedestrian}, // 34
|
||||
{{36.694829, 31.598065}, {36.694798, 31.597773}, VehicleType::Car}, // 35
|
||||
{{37.090061, -8.413102}, {37.089739, -8.412828}, VehicleType::Pedestrian}, // 36
|
||||
{{40.166637, 44.442915}, {40.166747, 44.442915}, VehicleType::Car}, // 37
|
||||
{{40.166670, 44.442903}, {40.166744, 44.442910}, VehicleType::Car}, // 38
|
||||
{{40.171230, 44.539676}, {40.171196, 44.539501}, VehicleType::Car}, // 39
|
||||
{{40.546780, 14.243017}, {40.546760, 14.242680}, VehicleType::Pedestrian}, // 40
|
||||
{{41.384478, 2.161366}, {41.384550, 2.161269}, VehicleType::Car}, // 41
|
||||
{{42.966040, -9.039394}, {42.965825, -9.038590}, VehicleType::Pedestrian}, // 42
|
||||
{{43.705792, -79.422995}, {43.705667, -79.422915}, VehicleType::Car}, // 43
|
||||
{{43.856909, 18.384329}, {43.857161, 18.384610}, VehicleType::Car}, // 44
|
||||
{{43.973927, 3.134214}, {43.973684, 3.134444}, VehicleType::Car}, // 45
|
||||
{{44.413185, 12.206472}, {44.413859, 12.206783}, VehicleType::Car}, // 46
|
||||
{{44.420630, 26.161473}, {44.420488, 26.161505}, VehicleType::Car}, // 47
|
||||
{{44.599012, 33.460076}, {44.598730, 33.460236}, VehicleType::Car}, // 48
|
||||
{{45.249033, 19.799025}, {45.249157, 19.798848}, VehicleType::Car}, // 49
|
||||
{{46.144412, -62.467054}, {46.144296, -62.466491}, VehicleType::Car}, // 50
|
||||
{{46.171920, 21.350128}, {46.172083, 21.350218}, VehicleType::Car}, // 51
|
||||
{{47.033895, 28.843783}, {47.033992, 28.843885}, VehicleType::Car}, // 52
|
||||
{{47.169674, 11.385885}, {47.169627, 11.385719}, VehicleType::Car}, // 53
|
||||
{{47.921071, 106.880479}, {47.920870, 106.880295}, VehicleType::Car}, // 54
|
||||
{{48.390422, 24.501536}, {48.390864, 24.499478}, VehicleType::Car}, // 55
|
||||
{{48.631019, 25.740152}, {48.631189, 25.739863}, VehicleType::Car}, // 56
|
||||
{{48.867584, 2.353219}, {48.867617, 2.353077}, VehicleType::Pedestrian}, // 57
|
||||
{{48.868294, 2.323534}, {48.868426, 2.323615}, VehicleType::Pedestrian}, // 58
|
||||
{{48.872028, 2.359879}, {48.872093, 2.360042}, VehicleType::Car}, // 59
|
||||
{{49.550927, 25.593832}, {49.551146, 25.593766}, VehicleType::Car}, // 60
|
||||
{{49.564538, 25.633862}, {49.564365, 25.634210}, VehicleType::Car}, // 61
|
||||
{{49.675343, -125.010402}, {49.675095, -125.010445}, VehicleType::Car}, // 62
|
||||
{{50.128494, 5.342730}, {50.128312, 5.342838}, VehicleType::Pedestrian}, // 63
|
||||
{{50.293157, 57.153277}, {50.292945, 57.153430}, VehicleType::Car}, // 64
|
||||
{{50.424169, 30.543769}, {50.424075, 30.543552}, VehicleType::Car}, // 65
|
||||
{{50.456769, 3.699087}, {50.456896, 3.698898}, VehicleType::Car}, // 66
|
||||
{{50.513276, 30.493644}, {50.513395, 30.493749}, VehicleType::Pedestrian}, // 67
|
||||
{{50.948447, 6.943709}, {50.948523, 6.943618}, VehicleType::Pedestrian}, // 68
|
||||
{{51.070450, 13.690914}, {51.070186, 13.690486}, VehicleType::Car}, // 69
|
||||
{{51.442925, 5.475704}, {51.442785, 5.475484}, VehicleType::Bicycle}, // 70
|
||||
{{52.210605, 104.301558}, {52.210766, 104.299210}, VehicleType::Pedestrian}, // 71
|
||||
{{53.132201, 17.992780}, {53.132109, 17.992736}, VehicleType::Pedestrian}, // 72
|
||||
{{53.450367, 26.471001}, {53.451092, 26.473267}, VehicleType::Car}, // 73
|
||||
{{53.544199, 9.942703}, {53.544226, 9.943041}, VehicleType::Pedestrian}, // 74
|
||||
{{53.663670, 23.809416}, {53.663587, 23.809148}, VehicleType::Car}, // 75
|
||||
{{53.688767, 23.840653}, {53.688625, 23.840767}, VehicleType::Car}, // 76
|
||||
{{53.705198, 23.799942}, {53.705020, 23.799729}, VehicleType::Car}, // 78
|
||||
{{53.721229, 23.853621}, {53.721089, 23.853499}, VehicleType::Car}, // 79
|
||||
{{53.908905, 27.492089}, {53.908688, 27.492657}, VehicleType::Car}, // 80
|
||||
{{53.915279, 27.497204}, {53.915298, 27.497692}, VehicleType::Car}, // 81
|
||||
{{54.708002, 20.588852}, {54.709596, 20.589344}, VehicleType::Pedestrian}, // 82
|
||||
{{56.328089, 43.780187}, {56.329598, 43.779347}, VehicleType::Pedestrian}, // 83
|
||||
{{56.328148, 43.780259}, {56.329598, 43.779347}, VehicleType::Pedestrian}, // 84
|
||||
{{60.601636, 27.840518}, {60.601707, 27.841084}, VehicleType::Car}, // 85
|
||||
{{60.602799, 27.838590}, {60.602779, 27.839252}, VehicleType::Car}, // 86
|
||||
{{61.002506, 72.586208}, {61.002588, 72.586563}, VehicleType::Car}, // 87
|
||||
{{61.311170, 63.318459}, {61.310999, 63.318328}, VehicleType::Car}, // 88
|
||||
{{61.460908, 76.638827}, {61.460768, 76.639447}, VehicleType::Car}, // 89
|
||||
{{63.370116, 10.360256}, {63.370199, 10.360618}, VehicleType::Car}, // 90
|
||||
{{63.975020, -22.575718}, {63.975126, -22.576316}, VehicleType::Car}, // 91
|
||||
{{64.538104, -21.926846}, {64.538149, -21.927736}, VehicleType::Car}, // 92
|
||||
{{64.538306, 40.520611}, {64.538233, 40.520327}, VehicleType::Car}, // 93
|
||||
{{9.625079, 123.805457}, {9.625084, 123.805655}, VehicleType::Car}, // 94
|
||||
};
|
||||
|
||||
std::vector<std::tuple<ms::LatLon, ms::LatLon, m2::PointD, VehicleType>> routesWithDir = {
|
||||
{{-45.433213, -72.739150},
|
||||
{-45.434484, -72.738892},
|
||||
{-1.3387623880589671899e-06, -4.2558102819612031453e-07},
|
||||
VehicleType::Car}, // 1
|
||||
};
|
||||
|
||||
size_t number = 0;
|
||||
for (auto const & route : routes)
|
||||
{
|
||||
++number;
|
||||
ms::LatLon start;
|
||||
ms::LatLon finish;
|
||||
VehicleType type;
|
||||
std::tie(start, finish, type) = route;
|
||||
|
||||
LOG(LINFO, ("Start test without direction, number:", number));
|
||||
TRouteResult result = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(type), mercator::FromLatLon(start), {0., 0.}, mercator::FromLatLon(finish));
|
||||
TEST_EQUAL(result.second, RouterResultCode::NoError, (std::get<0>(route), std::get<1>(route), std::get<2>(route)));
|
||||
}
|
||||
|
||||
number = 0;
|
||||
for (auto const & route : routesWithDir)
|
||||
{
|
||||
++number;
|
||||
ms::LatLon start;
|
||||
ms::LatLon finish;
|
||||
VehicleType type;
|
||||
m2::PointD direction;
|
||||
std::tie(start, finish, direction, type) = route;
|
||||
|
||||
LOG(LINFO, ("Start test with direction, number:", number));
|
||||
TRouteResult result = integration::CalculateRoute(
|
||||
integration::GetVehicleComponents(type), mercator::FromLatLon(start), direction, mercator::FromLatLon(finish));
|
||||
TEST_EQUAL(result.second, RouterResultCode::NoError, ());
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
|
@ -0,0 +1,460 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "routing/routing_tests/tools.hpp"
|
||||
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
#include "routing/routing_helpers.hpp"
|
||||
#include "routing/routing_session.hpp"
|
||||
#include "routing/speed_camera_manager.hpp"
|
||||
|
||||
#include "platform/location.hpp"
|
||||
#include "platform/measurement_utils.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace speed_camera_notifications_tests
|
||||
{
|
||||
using namespace routing;
|
||||
using namespace routing::turns;
|
||||
using namespace std;
|
||||
|
||||
string const kCameraOnTheWay = "Speed camera on the way";
|
||||
|
||||
location::GpsInfo MoveTo(ms::LatLon const & coords, double speed = -1)
|
||||
{
|
||||
static auto constexpr kGpsAccuracy = 0.01;
|
||||
|
||||
location::GpsInfo info;
|
||||
info.m_horizontalAccuracy = kGpsAccuracy;
|
||||
info.m_verticalAccuracy = kGpsAccuracy;
|
||||
info.m_latitude = coords.m_lat;
|
||||
info.m_longitude = coords.m_lon;
|
||||
info.m_speed = speed;
|
||||
return info;
|
||||
}
|
||||
|
||||
void ChangePosition(ms::LatLon const & coords, double speedKmPH, RoutingSession & routingSession)
|
||||
{
|
||||
routingSession.OnLocationPositionChanged(
|
||||
MoveTo({coords.m_lat, coords.m_lon}, measurement_utils::KmphToMps(speedKmPH)));
|
||||
}
|
||||
|
||||
void InitRoutingSession(ms::LatLon const & from, ms::LatLon const & to, RoutingSession & routingSession,
|
||||
SpeedCameraManagerMode mode = SpeedCameraManagerMode::Auto)
|
||||
{
|
||||
TRouteResult const routeResult =
|
||||
integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car), mercator::FromLatLon(from),
|
||||
m2::PointD::Zero(), mercator::FromLatLon(to));
|
||||
|
||||
Route & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
routingSession.Init(nullptr /* PointCheckCallback */);
|
||||
routingSession.SetRoutingSettings(routing::GetRoutingSettings(routing::VehicleType::Car));
|
||||
routingSession.AssignRouteForTesting(make_shared<Route>(route), result);
|
||||
routingSession.SetTurnNotificationsUnits(measurement_utils::Units::Metric);
|
||||
routingSession.GetSpeedCamManager().SetMode(mode);
|
||||
string const engShortJson = R"(
|
||||
{
|
||||
"unknown_camera": ")" + kCameraOnTheWay +
|
||||
R"("
|
||||
}
|
||||
)";
|
||||
routingSession.SetLocaleWithJsonForTesting(engShortJson, "en");
|
||||
}
|
||||
|
||||
bool CheckVoiceNotification(RoutingSession & routingSession)
|
||||
{
|
||||
vector<string> notifications;
|
||||
routingSession.GenerateNotifications(notifications, false);
|
||||
return any_of(notifications.begin(), notifications.end(), [](auto const & item) { return item == kCameraOnTheWay; });
|
||||
}
|
||||
|
||||
bool CheckBeepSignal(RoutingSession & routingSession)
|
||||
{
|
||||
return routingSession.GetSpeedCamManager().ShouldPlayBeepSignal();
|
||||
}
|
||||
|
||||
SpeedCameraManager::Interval CheckZone(RoutingSession const & routingSession, double speedKmPH)
|
||||
{
|
||||
SpeedCameraOnRoute const & closestCamera = routingSession.GetSpeedCamManager().GetClosestCamForTests();
|
||||
TEST(closestCamera.IsValid(), ("No speed camera found."));
|
||||
|
||||
double const speedMpS = measurement_utils::KmphToMps(speedKmPH);
|
||||
double const passedDist = routingSession.GetRouteForTests()->GetCurrentDistanceFromBeginMeters();
|
||||
double const distToCamera = closestCamera.m_distFromBeginMeters - passedDist;
|
||||
|
||||
return SpeedCameraManager::GetIntervalByDistToCam(distToCamera, speedMpS);
|
||||
}
|
||||
|
||||
bool NoCameraFound(RoutingSession & routingSession)
|
||||
{
|
||||
SpeedCameraOnRoute const & closestCamera = routingSession.GetSpeedCamManager().GetClosestCamForTests();
|
||||
return !closestCamera.IsValid();
|
||||
}
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____Notification___|___beep____|_____(exceed speed limit here) Impact camera zone_____|
|
||||
// Expected: Beep signal.
|
||||
/* Camera was (temporary) removed from OSM.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_1)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.67931, 37.53268}, {55.68764, 37.54508},
|
||||
routingSession, mode);
|
||||
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.68126, 37.53551}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::ImpactZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____Notification___|___beep____|_____(exceed speed limit here) Impact camera zone_____|
|
||||
// Expected: Beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_2)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.74070, 37.61681} /* from */, {55.74885, 37.61036} /* to */, routingSession, mode);
|
||||
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.74505, 37.61384}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::ImpactZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____Notification___|___(exceed speed limit here) beep____|_____Impact camera zone_____|
|
||||
// Expected: Beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_3)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession, mode);
|
||||
|
||||
// No danger here.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76766, 37.59260}, speedKmPH, routingSession);
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// Exceed speed limit in beep zone.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76589, 37.58999}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::BeepSignalZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Next tests about camera which is not part of way in OSM.
|
||||
// This link (camera and way) was found by geometry index.
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____Notification___|___beep____|_____(exceed speed limit here) Impact camera zone_____|
|
||||
// Expected: Beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_4)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.65601, 37.53822} /* from */, {55.65760, 37.52312} /* to */, routingSession, mode);
|
||||
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.65647, 37.53643}, speedKmPH, routingSession);
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.65671, 37.53236}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::ImpactZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____(exceed speed limit here) Notification___|___beep____|_____Impact camera zone_____|
|
||||
// Expected: Voice notification.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_5)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession, mode);
|
||||
|
||||
// No danger here.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76766, 37.59260}, speedKmPH, routingSession);
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// Exceed speed limit before beep zone.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76605, 37.59078}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ____(exceed speed limit here) Notification___|___(and here) beep____|_____Impact camera zone_____|
|
||||
// Expected: Voice notification, after it beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_6)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession, mode);
|
||||
|
||||
// Exceed speed limit before beep zone.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76605, 37.59078}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// Exceed speed limit in beep zone.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76560, 37.59015}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::BeepSignalZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Auto/Always
|
||||
// ___(exceed speed limit here) Notification___|___(not exceed speed limit here) beep____|____Impact camera zone____|
|
||||
// We must hear beep signal after voice notification, no matter whether we exceed speed limit or not.
|
||||
// Expected: Voice notification, after it beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_7)
|
||||
{
|
||||
vector<SpeedCameraManagerMode> modes = {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always};
|
||||
for (auto const mode : modes)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession, mode);
|
||||
|
||||
// Exceed speed limit before beep zone.
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76655, 37.59146}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// Intermediate Move for correct calculating of passedDistance.
|
||||
{
|
||||
double const speedKmPH = 40.0;
|
||||
ChangePosition({55.76602, 37.59074}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// Intermediate Move for correct calculating of passedDistance.
|
||||
{
|
||||
double const speedKmPH = 20.0;
|
||||
ChangePosition({55.76559, 37.59016}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
// No exceed speed limit in beep zone, but we did VoiceNotification earlier,
|
||||
// so now we make BeedSignal.
|
||||
{
|
||||
double const speedKmPH = 40.0;
|
||||
ChangePosition({55.76573, 37.59030}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::BeepSignalZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Always/Auto
|
||||
// ____Notification___|___beep____|_____Impact camera zone_____|
|
||||
// ----------------^ | - We are here. Exceed speed limit.
|
||||
// | In case Always/Auto mode we should hear voice notification.
|
||||
// -----------------^ | - Then we are here. Exceed speed limit.
|
||||
// | But it's soon to make beep signal.
|
||||
// ---------------------^ - Than we are here. Exceed speed limit.
|
||||
// We should here beep signal.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoAlwaysMode_8)
|
||||
{
|
||||
for (auto const mode : {SpeedCameraManagerMode::Auto, SpeedCameraManagerMode::Always})
|
||||
{
|
||||
// On "Leningradskiy" from East to West direction.
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.6755737, 37.5264126}, // from
|
||||
{55.67052, 37.51893}, // to
|
||||
routingSession, mode);
|
||||
|
||||
{
|
||||
double const speedKmPH = 180.0;
|
||||
ChangePosition({55.67533, 37.5264}, speedKmPH, routingSession);
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
{
|
||||
double const speedKmPH = 180.0;
|
||||
ChangePosition({55.67515, 37.52577}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
{
|
||||
double const speedKmPH = 180.0;
|
||||
ChangePosition({55.67515, 37.52577}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::VoiceNotificationZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
{
|
||||
double const speedKmPH = 180.0;
|
||||
ChangePosition({55.67505, 37.52542}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::BeepSignalZone, ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Always
|
||||
// ____Notification___|___beep____|_____Impact camera zone_____|
|
||||
// --------------------------------^ - We are here. No exceed speed limit.
|
||||
// In case |Always| mode we should hear voice notification.
|
||||
// Expected: Voice notification in |Always| mode.
|
||||
UNIT_TEST(SpeedCameraNotification_AlwaysMode_1)
|
||||
{
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession,
|
||||
SpeedCameraManagerMode::Always);
|
||||
|
||||
{
|
||||
double const speedKmPH = 40.0;
|
||||
ChangePosition({55.76476, 37.58905}, speedKmPH, routingSession);
|
||||
TEST_EQUAL(CheckZone(routingSession, speedKmPH), SpeedCameraManager::Interval::ImpactZone, ());
|
||||
TEST(CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mode: Auto
|
||||
// ____Notification___|___beep____|_____Impact camera zone_____|
|
||||
// --------------------------------^ - We are here. No exceed speed limit.
|
||||
// In case |Auto| mode we should hear nothing.
|
||||
// Expected: and nothing in mode: |Auto|.
|
||||
UNIT_TEST(SpeedCameraNotification_AutoMode_1)
|
||||
{
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession,
|
||||
SpeedCameraManagerMode::Auto);
|
||||
|
||||
{
|
||||
double const speedKmPH = 40.0;
|
||||
ChangePosition({55.76476, 37.58905}, speedKmPH, routingSession);
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST(SpeedCameraNotification_NeverMode_1)
|
||||
{
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({55.76801, 37.59363} /* from */, {55.75947, 37.58484} /* to */, routingSession,
|
||||
SpeedCameraManagerMode::Never);
|
||||
|
||||
{
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({55.76476, 37.58905}, speedKmPH, routingSession);
|
||||
TEST(!NoCameraFound(routingSession), ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
{
|
||||
double const speedKmPH = 200.0;
|
||||
ChangePosition({55.76441, 37.58865}, speedKmPH, routingSession);
|
||||
TEST(!NoCameraFound(routingSession), ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
|
||||
{
|
||||
double const speedKmPH = 300.0;
|
||||
ChangePosition({55.76335, 37.58767}, speedKmPH, routingSession);
|
||||
TEST(!NoCameraFound(routingSession), ());
|
||||
TEST(!CheckVoiceNotification(routingSession), ());
|
||||
TEST(!CheckBeepSignal(routingSession), ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test on case when a feature is split by a mini_roundabout or by a turning_loop and
|
||||
// contains a speed camera. The thing is to pass this test it's necessary to process
|
||||
// fake road feature ids correctly while speed cameras generation process.
|
||||
UNIT_TEST(SpeedCameraNotification_CameraOnMiniRoundabout)
|
||||
{
|
||||
RoutingSession routingSession;
|
||||
InitRoutingSession({41.201998, 69.109587} /* from */, {41.200358, 69.107051} /* to */, routingSession,
|
||||
SpeedCameraManagerMode::Never);
|
||||
double const speedKmPH = 100.0;
|
||||
ChangePosition({41.201998, 69.109587}, speedKmPH, routingSession);
|
||||
TEST(!NoCameraFound(routingSession), ());
|
||||
}
|
||||
} // namespace speed_camera_notifications_tests
|
||||
64
libs/routing/routing_integration_tests/street_names_test.cpp
Normal file
64
libs/routing/routing_integration_tests/street_names_test.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "routing/route.hpp"
|
||||
#include "routing/routing_callbacks.hpp"
|
||||
|
||||
#include "platform/location.hpp"
|
||||
|
||||
using namespace routing;
|
||||
using namespace routing::turns;
|
||||
|
||||
void MoveRoute(Route & route, ms::LatLon const & coords)
|
||||
{
|
||||
location::GpsInfo info;
|
||||
info.m_horizontalAccuracy = 0.01;
|
||||
info.m_verticalAccuracy = 0.01;
|
||||
info.m_longitude = coords.m_lon;
|
||||
info.m_latitude = coords.m_lat;
|
||||
route.MoveIterator(info);
|
||||
}
|
||||
|
||||
UNIT_TEST(RussiaTulskayaToPaveletskayaStreetNamesTest)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Car),
|
||||
mercator::FromLatLon(55.70839, 37.62145), {0., 0.},
|
||||
mercator::FromLatLon(55.73198, 37.63945));
|
||||
|
||||
Route & route = *routeResult.first;
|
||||
RouterResultCode const result = routeResult.second;
|
||||
TEST_EQUAL(result, RouterResultCode::NoError, ());
|
||||
|
||||
/// @todo https://github.com/organicmaps/organicmaps/issues/1668
|
||||
integration::TestCurrentStreetName(route, "Большая Тульская улица");
|
||||
integration::TestNextStreetName(route, "Подольское шоссе");
|
||||
|
||||
MoveRoute(route, ms::LatLon(55.71398, 37.62443));
|
||||
|
||||
integration::TestCurrentStreetName(route, "Подольское шоссе");
|
||||
integration::TestNextStreetName(route, "Валовая улица");
|
||||
|
||||
MoveRoute(route, ms::LatLon(55.72059, 37.62766));
|
||||
|
||||
integration::TestCurrentStreetName(route, "Павловская улица");
|
||||
integration::TestNextStreetName(route, "Валовая улица");
|
||||
|
||||
MoveRoute(route, ms::LatLon(55.72469, 37.62624));
|
||||
|
||||
integration::TestCurrentStreetName(route, "Большая Серпуховская улица");
|
||||
integration::TestNextStreetName(route, "Валовая улица");
|
||||
|
||||
MoveRoute(route, ms::LatLon(55.73034, 37.63099));
|
||||
|
||||
// No more extra last turn, so TestNextStreetName returns "".
|
||||
integration::TestCurrentStreetName(route, "Валовая улица");
|
||||
// integration::TestNextStreetName(route, "улица Зацепский Вал");
|
||||
|
||||
MoveRoute(route, ms::LatLon(55.730912, 37.636191));
|
||||
|
||||
integration::TestCurrentStreetName(route, "улица Зацепский Вал");
|
||||
integration::TestNextStreetName(route, "");
|
||||
|
||||
integration::TestRouteLength(route, 3390.);
|
||||
}
|
||||
171
libs/routing/routing_integration_tests/transit_route_test.cpp
Normal file
171
libs/routing/routing_integration_tests/transit_route_test.cpp
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "routing/routing_integration_tests/routing_test_tools.hpp"
|
||||
|
||||
#include "geometry/mercator.hpp"
|
||||
|
||||
namespace transit_route_test
|
||||
{
|
||||
using namespace routing;
|
||||
|
||||
UNIT_TEST(Transit_Moscow_CenterToKotelniki_CrossMwm)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(55.75018, 37.60971), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.67245, 37.86130));
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, 22968.6);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Moscow_DubrovkaToTrtykovskya)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(55.71813, 37.67756), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.74089, 37.62831));
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, 7622.19);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Moscow_NoSubwayTest)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(55.73893, 37.62438), {0.0, 0.0},
|
||||
mercator::FromLatLon(55.73470, 37.62617));
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, 604.86);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayAbsent(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Piter_FrunzenskyaToPlochadVosstaniya)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(59.90511, 30.31425), {0.0, 0.0},
|
||||
mercator::FromLatLon(59.93096, 30.35872));
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
/// @todo Check https://github.com/organicmaps/organicmaps/issues/1669 for details.
|
||||
integration::TestRouteLength(*routeResult.first, 5837.21);
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Piter_TooLongPedestrian)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(59.90511, 30.31425), {0.0, 0.0},
|
||||
mercator::FromLatLon(59.78014, 30.50036));
|
||||
|
||||
/// @todo Returns valid route now with long pedestrian part in the end, I don't see problems here.
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
auto const & route = *routeResult.first;
|
||||
|
||||
integration::CheckSubwayExistence(route);
|
||||
integration::TestRouteLength(route, 23521.9);
|
||||
TEST_LESS(route.GetTotalTimeSec(), 3600 * 3, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Vatikan_NotEnoughGraphDataAtThenEnd)
|
||||
{
|
||||
TRouteResult const routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(41.89543, 12.41481), {0.0, 0.0},
|
||||
mercator::FromLatLon(41.89203, 12.46263));
|
||||
|
||||
/// @todo Returns valid route now with long pedestrian part in the end, I don't see problems here.
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
TEST(routeResult.first, ());
|
||||
auto const & route = *routeResult.first;
|
||||
|
||||
integration::CheckSubwayExistence(route);
|
||||
integration::TestRouteLength(route, 7703.56);
|
||||
TEST_LESS(route.GetTotalTimeSec(), 4000, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Vatikan_CorneliaToOttaviano)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(41.90052, 12.42642), {0.0, 0.0},
|
||||
mercator::FromLatLon(41.90414, 12.45640));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
// I don't see any bad routing sections here. Make actual value.
|
||||
integration::TestRouteLength(*routeResult.first, 4316.61);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_London_PoplarToOval)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(51.50818, -0.01634), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.48041, -0.10843));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
integration::TestRouteLength(*routeResult.first, 9421.72);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_London_DeptfordBridgeToCyprus)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(51.47149, -0.030558), {0.0, 0.0},
|
||||
mercator::FromLatLon(51.51242, 0.07101));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
// I don't see any bad routing sections here. Make actual value.
|
||||
integration::TestRouteLength(*routeResult.first, 12882.2);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_Washington_FoggyToShaw)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(38.89582, -77.04934), {0.0, 0.0},
|
||||
mercator::FromLatLon(38.91516, -77.01513));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
// I don't see any bad routing sections here. Make actual value.
|
||||
integration::TestRouteLength(*routeResult.first, 5685.82);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
|
||||
UNIT_TEST(Transit_NewYork_GrassmereToPleasantPlains)
|
||||
{
|
||||
TRouteResult routeResult = integration::CalculateRoute(integration::GetVehicleComponents(VehicleType::Transit),
|
||||
mercator::FromLatLon(40.60536, -74.07736), {0.0, 0.0},
|
||||
mercator::FromLatLon(40.53015, -74.21559));
|
||||
|
||||
TEST_EQUAL(routeResult.second, RouterResultCode::NoError, ());
|
||||
|
||||
// I don't see any bad routing sections here. Make actual value.
|
||||
integration::TestRouteLength(*routeResult.first, 17433.7);
|
||||
|
||||
CHECK(routeResult.first, ());
|
||||
integration::CheckSubwayExistence(*routeResult.first);
|
||||
}
|
||||
} // namespace transit_route_test
|
||||
1347
libs/routing/routing_integration_tests/turn_test.cpp
Normal file
1347
libs/routing/routing_integration_tests/turn_test.cpp
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue