Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:58:55 +01:00
parent 4af19165ec
commit 68073add76
12458 changed files with 12350765 additions and 2 deletions

View file

@ -0,0 +1,18 @@
project(routing_benchmarks)
set(SRC
../routing_integration_tests/routing_test_tools.cpp
../routing_integration_tests/routing_test_tools.hpp
bicycle_routing_tests.cpp
car_routing_tests.cpp
helpers.cpp
helpers.hpp
pedestrian_routing_tests.cpp
)
omim_add_test(${PROJECT_NAME} ${SRC})
target_link_libraries(${PROJECT_NAME}
routing
map
)

View file

@ -0,0 +1,48 @@
#include "testing/testing.hpp"
#include "routing/routing_benchmarks/helpers.hpp"
#include "routing/car_directions.hpp"
#include "routing/road_graph.hpp"
#include "routing_common/bicycle_model.hpp"
#include "geometry/mercator.hpp"
#include <memory>
#include <set>
#include <string>
namespace
{
// Test preconditions: files from the kBicycleMapFiles set with '.mwm'
// extension must be placed in omim/data folder.
std::set<std::string> const kBicycleMapFiles = {"Russia_Moscow"};
class BicycleTest : public RoutingTest
{
public:
BicycleTest() : RoutingTest(routing::IRoadGraph::Mode::ObeyOnewayTag, routing::VehicleType::Bicycle, kBicycleMapFiles)
{}
protected:
std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
{
return std::make_unique<SimplifiedModelFactory<routing::BicycleModel>>();
}
};
UNIT_CLASS_TEST(BicycleTest, Smoke)
{
m2::PointD const start = mercator::FromLatLon(55.79181, 37.56513);
m2::PointD const final = mercator::FromLatLon(55.79369, 37.56054);
TestRouters(start, final);
}
UNIT_CLASS_TEST(BicycleTest, RussiaMoscow_Test1)
{
m2::PointD const start = mercator::FromLatLon(55.79828, 37.53710);
m2::PointD const final = mercator::FromLatLon(55.79956, 37.54115);
TestRouters(start, final);
}
} // namespace

View file

@ -0,0 +1,64 @@
#include "testing/testing.hpp"
#include "routing/routing_benchmarks/helpers.hpp"
#include "routing/car_directions.hpp"
#include "routing/road_graph.hpp"
#include "routing_common/car_model.hpp"
#include "geometry/latlon.hpp"
#include "geometry/mercator.hpp"
#include <memory>
#include <set>
#include <string>
namespace
{
std::set<std::string> const kCarMapFiles = {"Russia_Moscow"};
class CarTest : public RoutingTest
{
public:
CarTest() : RoutingTest(routing::IRoadGraph::Mode::ObeyOnewayTag, routing::VehicleType::Car, kCarMapFiles) {}
void TestCarRouter(ms::LatLon const & start, ms::LatLon const & final, size_t reiterations)
{
routing::Route routeFoundByAstarBidirectional("", 0 /* route id */);
auto router = CreateRouter("test-astar-bidirectional");
m2::PointD const startMerc = mercator::FromLatLon(start);
m2::PointD const finalMerc = mercator::FromLatLon(final);
for (size_t i = 0; i < reiterations; ++i)
TestRouter(*router, startMerc, finalMerc, routeFoundByAstarBidirectional);
}
protected:
std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
{
return std::make_unique<SimplifiedModelFactory<routing::CarModel>>();
}
};
// Benchmarks below are on profiling looking for the best segments of routes.
// So short routes are used to focus on time needed for finding the best segments.
// Start and finish are located in a city with dense road network.
UNIT_CLASS_TEST(CarTest, InCity)
{
TestCarRouter(ms::LatLon(55.75785, 37.58267), ms::LatLon(55.76082, 37.58492), 30);
}
// Start and finish are located near a big road.
UNIT_CLASS_TEST(CarTest, BigRoad)
{
TestCarRouter(ms::LatLon(55.75826, 37.39476), ms::LatLon(55.7605, 37.39003), 30);
}
// Start are located near an airport center. It's far from road network.
UNIT_CLASS_TEST(CarTest, InAirport)
{
TestCarRouter(ms::LatLon(55.97285, 37.41275), ms::LatLon(55.96396, 37.41922), 30);
}
} // namespace

View file

@ -0,0 +1,165 @@
#include "routing/routing_benchmarks/helpers.hpp"
#include "testing/testing.hpp"
#include "routing/features_road_graph.hpp"
#include "routing/router_delegate.hpp"
#include "routing/routing_integration_tests/routing_test_tools.hpp"
#include "indexer/classificator_loader.hpp"
#include "indexer/mwm_set.hpp"
#include "platform/local_country_file.hpp"
#include "platform/local_country_file_utils.hpp"
#include "platform/platform.hpp"
#include "coding/point_coding.hpp"
#include "geometry/mercator.hpp"
#include "geometry/point_with_altitude.hpp"
#include "geometry/polyline2d.hpp"
#include "base/logging.hpp"
#include "base/math.hpp"
#include "base/timer.hpp"
#include <limits>
#include <memory>
namespace
{
m2::PointD GetPointOnEdge(routing::Edge const & e, double posAlong)
{
if (posAlong <= 0.0)
return e.GetStartJunction().GetPoint();
if (posAlong >= 1.0)
return e.GetEndJunction().GetPoint();
m2::PointD const d = e.GetEndJunction().GetPoint() - e.GetStartJunction().GetPoint();
return e.GetStartJunction().GetPoint() + d * posAlong;
}
} // namespace
RoutingTest::RoutingTest(routing::IRoadGraph::Mode mode, routing::VehicleType type,
std::set<std::string> const & neededMaps)
: m_mode(mode)
, m_type(type)
, m_neededMaps(neededMaps)
, m_numMwmIds(std::make_unique<routing::NumMwmIds>())
{
classificator::Load();
Platform & platform = GetPlatform();
m_cig = storage::CountryInfoReader::CreateCountryInfoGetter(platform);
platform::FindAllLocalMapsAndCleanup(std::numeric_limits<int64_t>::max(), m_localFiles);
std::set<std::string> registeredMaps;
for (auto const & localFile : m_localFiles)
{
m_numMwmIds->RegisterFile(localFile.GetCountryFile());
auto const & name = localFile.GetCountryName();
if (m_neededMaps.count(name) == 0)
continue;
UNUSED_VALUE(m_dataSource.RegisterMap(localFile));
auto const & countryFile = localFile.GetCountryFile();
TEST(m_dataSource.IsLoaded(countryFile), ());
MwmSet::MwmId const id = m_dataSource.GetMwmIdByCountryFile(countryFile);
TEST(id.IsAlive(), ());
registeredMaps.insert(name);
}
if (registeredMaps != m_neededMaps)
{
for (auto const & file : m_neededMaps)
if (registeredMaps.count(file) == 0)
LOG(LERROR, ("Can't find map:", file));
TEST(false, ("Some maps can't be found. See error messages above."));
}
}
void RoutingTest::TestRouters(m2::PointD const & startPos, m2::PointD const & finalPos)
{
// Find route by A*-bidirectional algorithm.
routing::Route routeFoundByAstarBidirectional("", 0 /* route id */);
{
auto router = CreateRouter("test-astar-bidirectional");
TestRouter(*router, startPos, finalPos, routeFoundByAstarBidirectional);
}
// Find route by A* algorithm.
routing::Route routeFoundByAstar("", 0 /* route id */);
{
auto router = CreateRouter("test-astar");
TestRouter(*router, startPos, finalPos, routeFoundByAstar);
}
double constexpr kEpsilon = 1e-6;
TEST(AlmostEqualAbs(routeFoundByAstar.GetTotalDistanceMeters(),
routeFoundByAstarBidirectional.GetTotalDistanceMeters(), kEpsilon),
());
}
void RoutingTest::TestTwoPointsOnFeature(m2::PointD const & startPos, m2::PointD const & finalPos)
{
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> startEdges;
GetNearestEdges(startPos, startEdges);
TEST(!startEdges.empty(), ());
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> finalEdges;
GetNearestEdges(finalPos, finalEdges);
TEST(!finalEdges.empty(), ());
m2::PointD const startPosOnFeature =
GetPointOnEdge(startEdges.front().first, 0.0 /* the start point of the feature */);
m2::PointD const finalPosOnFeature = GetPointOnEdge(finalEdges.front().first, 1.0 /* the end point of the feature */);
TestRouters(startPosOnFeature, finalPosOnFeature);
}
std::unique_ptr<routing::IRouter> RoutingTest::CreateRouter(std::string const & name)
{
std::vector<platform::LocalCountryFile> neededLocalFiles;
neededLocalFiles.reserve(m_neededMaps.size());
for (auto const & file : m_localFiles)
if (m_neededMaps.count(file.GetCountryName()) != 0)
neededLocalFiles.push_back(file);
std::unique_ptr<routing::IRouter> router =
integration::CreateVehicleRouter(m_dataSource, *m_cig, m_trafficCache, neededLocalFiles, m_type);
return router;
}
void RoutingTest::GetNearestEdges(m2::PointD const & pt,
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> & edges)
{
routing::MwmDataSource dataSource(m_dataSource, nullptr /* numMwmIDs */);
routing::FeaturesRoadGraph graph(dataSource, m_mode, CreateModelFactory());
graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(pt, routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
1 /* count */, edges);
}
void TestRouter(routing::IRouter & router, m2::PointD const & startPos, m2::PointD const & finalPos,
routing::Route & route)
{
routing::RouterDelegate delegate;
LOG(LINFO, ("Calculating routing ...", router.GetName()));
base::Timer timer;
auto const resultCode =
router.CalculateRoute(routing::Checkpoints(startPos, finalPos), m2::PointD::Zero() /* startDirection */,
false /* adjust */, delegate, route);
double const elapsedSec = timer.ElapsedSeconds();
TEST_EQUAL(routing::RouterResultCode::NoError, resultCode, ());
TEST(route.IsValid(), ());
m2::PolylineD const & poly = route.GetPoly();
TEST_GREATER(poly.GetSize(), 0, ());
TEST(AlmostEqualAbs(poly.Front(), startPos, kMwmPointAccuracy), ());
TEST(AlmostEqualAbs(poly.Back(), finalPos, kMwmPointAccuracy), ());
LOG(LINFO, ("Route polyline size:", route.GetPoly().GetSize()));
LOG(LINFO, ("Route distance, meters:", route.GetTotalDistanceMeters()));
LOG(LINFO, ("Elapsed, seconds:", elapsedSec));
}

View file

@ -0,0 +1,96 @@
#pragma once
#include "routing/road_graph.hpp"
#include "routing/route.hpp"
#include "routing/router.hpp"
#include "routing/vehicle_mask.hpp"
#include "routing_common/num_mwm_id.hpp"
#include "routing_common/vehicle_model.hpp"
#include "storage/country_info_getter.hpp"
#include "traffic/traffic_cache.hpp"
#include "indexer/data_source.hpp"
#include "geometry/point2d.hpp"
#include <memory>
#include <set>
#include <string>
#include <vector>
class RoutingTest
{
public:
RoutingTest(routing::IRoadGraph::Mode mode, routing::VehicleType type, std::set<std::string> const & neededMaps);
virtual ~RoutingTest() = default;
void TestRouters(m2::PointD const & startPos, m2::PointD const & finalPos);
void TestTwoPointsOnFeature(m2::PointD const & startPos, m2::PointD const & finalPos);
protected:
virtual std::unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() = 0;
std::unique_ptr<routing::IRouter> CreateRouter(std::string const & name);
void GetNearestEdges(m2::PointD const & pt,
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> & edges);
routing::IRoadGraph::Mode const m_mode;
routing::VehicleType m_type;
FrozenDataSource m_dataSource;
traffic::TrafficCache m_trafficCache;
std::vector<platform::LocalCountryFile> m_localFiles;
std::set<std::string> const & m_neededMaps;
std::shared_ptr<routing::NumMwmIds> m_numMwmIds;
std::unique_ptr<storage::CountryInfoGetter> m_cig;
};
template <typename Model>
class SimplifiedModelFactory : public routing::VehicleModelFactoryInterface
{
public:
// Since for test purposes we compare routes lengths to check
// algorithms consistency, we should use simplified vehicle model,
// where all available edges have max speed
class SimplifiedModel : public Model
{
public:
// VehicleModelInterface overrides:
//
// SimplifiedModel::GetSpeed() filters features and returns zero
// speed if feature is not allowed by the base model, or otherwise
// some speed depending of road type (0 <= speed <= maxSpeed). For
// tests purposes for all allowed features speed must be the same as
// max speed.
routing::SpeedKMpH GetSpeed(typename Model::FeatureTypes const & types,
routing::SpeedParams const & speedParams) const override
{
auto const speed = Model::GetSpeed(types, speedParams);
if (speed.m_weight <= 0.0)
return routing::SpeedKMpH();
// Note. Max weight speed is used for eta as well here. It's ok for test purposes.
return routing::SpeedKMpH(Model::GetMaxWeightSpeed());
}
};
SimplifiedModelFactory() : m_model(std::make_shared<SimplifiedModel>()) {}
// VehicleModelFactoryInterface overrides:
std::shared_ptr<routing::VehicleModelInterface> GetVehicleModel() const override { return m_model; }
std::shared_ptr<routing::VehicleModelInterface> GetVehicleModelForCountry(
std::string const & /* country */) const override
{
return m_model;
}
private:
std::shared_ptr<SimplifiedModel> const m_model;
};
void TestRouter(routing::IRouter & router, m2::PointD const & startPos, m2::PointD const & finalPos,
routing::Route & route);

View file

@ -0,0 +1,279 @@
#include "testing/testing.hpp"
#include "routing/routing_benchmarks/helpers.hpp"
#include "routing/pedestrian_directions.hpp"
#include "routing/road_graph.hpp"
#include "routing_common/pedestrian_model.hpp"
#include <memory>
#include <set>
#include <string>
#include <utility>
namespace pedestrian_routing_tests
{
using namespace std;
// Test preconditions: files from the kPedestrianMapFiles set with '.mwm'
// extension must be placed in omim/data folder.
set<string> const kPedestrianMapFiles = {"UK_England_East Midlands",
"UK_England_East of England_Essex",
"UK_England_East of England_Norfolk",
"UK_England_Greater London",
"UK_England_North East England",
"UK_England_North West England_Lancaster",
"UK_England_North West England_Manchester",
"UK_England_South East_Brighton",
"UK_England_South East_Oxford",
"UK_England_South West England_Bristol",
"UK_England_South West England_Cornwall",
"UK_England_West Midlands",
"UK_England_Yorkshire and the Humber"};
class PedestrianTest : public RoutingTest
{
public:
PedestrianTest()
: RoutingTest(routing::IRoadGraph::Mode::IgnoreOnewayTag, routing::VehicleType::Pedestrian, kPedestrianMapFiles)
{}
protected:
unique_ptr<routing::VehicleModelFactoryInterface> CreateModelFactory() override
{
unique_ptr<routing::VehicleModelFactoryInterface> factory(new SimplifiedModelFactory<routing::PedestrianModel>());
return factory;
}
};
// Tests on features -------------------------------------------------------------------------------
UNIT_CLASS_TEST(PedestrianTest, UK_Long1)
{
TestTwoPointsOnFeature(m2::PointD(-1.88798, 61.90292), m2::PointD(-2.06025, 61.82824));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Long2)
{
TestTwoPointsOnFeature(m2::PointD(-0.20434, 60.27445), m2::PointD(0.06962, 60.33909));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Long3)
{
TestTwoPointsOnFeature(m2::PointD(-0.07706, 60.42876), m2::PointD(-0.11058, 60.20991));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Long4)
{
TestTwoPointsOnFeature(m2::PointD(-0.48574, 60.05082), m2::PointD(-0.45973, 60.56715));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Long5)
{
TestTwoPointsOnFeature(m2::PointD(0.11646, 60.57330), m2::PointD(0.05767, 59.93019));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Long6)
{
TestTwoPointsOnFeature(m2::PointD(0.02771, 60.49348), m2::PointD(0.06533, 59.93155));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Medium1)
{
TestTwoPointsOnFeature(m2::PointD(-0.10461, 60.29721), m2::PointD(-0.07532, 60.35180));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Medium2)
{
TestTwoPointsOnFeature(m2::PointD(-0.17925, 60.06331), m2::PointD(-0.09959, 60.06880));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Medium3)
{
TestTwoPointsOnFeature(m2::PointD(-0.26440, 60.16831), m2::PointD(-0.20113, 60.20884));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Medium4)
{
TestTwoPointsOnFeature(m2::PointD(-0.25296, 60.46539), m2::PointD(-0.10975, 60.43955));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Medium5)
{
TestTwoPointsOnFeature(m2::PointD(-0.03115, 60.31819), m2::PointD(0.07400, 60.33662));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Short1)
{
TestTwoPointsOnFeature(m2::PointD(-0.10461, 60.29721), m2::PointD(-0.11905, 60.29747));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Short2)
{
TestTwoPointsOnFeature(m2::PointD(-0.11092, 60.27172), m2::PointD(-0.08159, 60.27623));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Short3)
{
TestTwoPointsOnFeature(m2::PointD(-0.09449, 60.25051), m2::PointD(-0.06520, 60.26647));
}
// Tests on points ---------------------------------------------------------------------------------
UNIT_CLASS_TEST(PedestrianTest, UK_Test1)
{
TestRouters(m2::PointD(-0.23371, 60.18821), m2::PointD(-0.27958, 60.25155));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test2)
{
TestRouters(m2::PointD(-0.23204, 60.22073), m2::PointD(-0.25325, 60.34312));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test3)
{
TestRouters(m2::PointD(-0.13493, 60.21329), m2::PointD(-0.07502, 60.38699));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test4)
{
TestRouters(m2::PointD(0.07362, 60.24965), m2::PointD(0.06262, 60.30536));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test6)
{
TestRouters(m2::PointD(0.12973, 60.28698), m2::PointD(0.16166, 60.32989));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test7)
{
TestRouters(m2::PointD(0.24339, 60.22193), m2::PointD(0.30297, 60.47235));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test9)
{
TestRouters(m2::PointD(0.01390, 60.24852), m2::PointD(-0.01102, 60.29319));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test10)
{
TestRouters(m2::PointD(-1.26084, 60.68840), m2::PointD(-1.34027, 60.37865));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test11)
{
TestRouters(m2::PointD(-1.26084, 60.68840), m2::PointD(-1.34027, 60.37865));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test14)
{
TestRouters(m2::PointD(-0.49921, 60.50093), m2::PointD(-0.42539, 60.46021));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test15)
{
TestRouters(m2::PointD(-0.35293, 60.38324), m2::PointD(-0.27232, 60.48594));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test16)
{
TestRouters(m2::PointD(-0.24521, 60.41771), m2::PointD(0.052673, 60.48102));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test17)
{
TestRouters(m2::PointD(0.60492, 60.36565), m2::PointD(0.59411, 60.31529));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test19)
{
TestRouters(m2::PointD(-0.42411, 60.22511), m2::PointD(-0.44178, 60.37796));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test20)
{
TestRouters(m2::PointD(0.08776, 60.05433), m2::PointD(0.19336, 60.38398));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test21)
{
TestRouters(m2::PointD(0.23038, 60.43846), m2::PointD(0.18335, 60.46692));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test22)
{
TestRouters(m2::PointD(-0.33907, 60.691735), m2::PointD(-0.17824, 60.478512));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test23)
{
TestRouters(m2::PointD(-0.02557, 60.41371), m2::PointD(0.05972, 60.31413));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test24)
{
TestRouters(m2::PointD(-0.12511, 60.23813), m2::PointD(-0.27656, 60.05896));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test25)
{
TestRouters(m2::PointD(-0.12511, 60.23813), m2::PointD(-0.27656, 60.05896));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test26)
{
TestRouters(m2::PointD(-3.04538, 63.44428), m2::PointD(-2.98887, 63.47582));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test27)
{
TestRouters(m2::PointD(-2.94653, 63.61187), m2::PointD(-2.83215, 63.51525));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test28)
{
TestRouters(m2::PointD(-2.85275, 63.42478), m2::PointD(-2.88245, 63.38932));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test29)
{
TestRouters(m2::PointD(-2.35266, 63.59979), m2::PointD(-2.29857, 63.54677));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test30)
{
TestRouters(m2::PointD(-2.22043, 63.41066), m2::PointD(-2.29619, 63.65305));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test31)
{
TestRouters(m2::PointD(-2.28078, 63.66735), m2::PointD(-2.25378, 63.62744));
}
// This is very slow pedestrian tests (more than 20 minutes).
#if defined(SLOW_TESTS)
UNIT_CLASS_TEST(PedestrianTest, UK_Test5)
{
TestRouters(m2::PointD(0.07362, 60.24965), m2::PointD(0.06262, 60.30536));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test8)
{
TestRouters(m2::PointD(-0.09007, 59.93887), m2::PointD(-0.36591, 60.38306));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test12)
{
TestRouters(m2::PointD(-0.41581, 60.05507), m2::PointD(-0.00499, 60.55921));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test13)
{
TestRouters(m2::PointD(-0.00847, 60.17501), m2::PointD(-0.38291, 60.48435));
}
UNIT_CLASS_TEST(PedestrianTest, UK_Test18)
{
TestTwoPoints(m2::PointD(0.57712, 60.31156), m2::PointD(-1.09911, 59.24341));
}
#endif
} // namespace pedestrian_routing_tests