[routing] Add VehicleModel.

This commit is contained in:
Denis Koronchik 2014-07-13 23:42:06 +02:00 committed by Alex Zolotarev
parent 3e6faf028f
commit d0ee5cb235
5 changed files with 274 additions and 0 deletions

View file

@ -18,6 +18,7 @@ SOURCES += \
road_graph_router.cpp \
dijkstra_router.cpp \
features_road_graph.cpp \
vehicle_model.cpp \
HEADERS += \
route.hpp \
@ -29,3 +30,4 @@ HEADERS += \
road_graph_router.hpp \
dijkstra_router.hpp \
features_road_graph.hpp \
vehicle_model.hpp \

View file

@ -19,6 +19,7 @@ SOURCES += \
road_graph_builder.cpp \
road_graph_builder_test.cpp \
dijkstra_router_test.cpp \
vehicle_model_test.cpp \
HEADERS += \
road_graph_builder.hpp \

View file

@ -0,0 +1,131 @@
#include "../../testing/testing.hpp"
#include "../vehicle_model.hpp"
#include "../../indexer/classificator.hpp"
#include "../../indexer/feature.hpp"
#include "../../base/macros.hpp"
namespace
{
routing::VehicleModel::SpeedForType s_testLimits[] = {
{ {"highway", "trunk"}, 150 },
{ {"highway", "primary"}, 120 },
{ {"highway", "secondary"}, 80 },
{ {"highway", "residential"}, 50 },
};
class TestVehicleModel : public routing::VehicleModel
{
public:
TestVehicleModel()
: VehicleModel(classif(), vector<VehicleModel::SpeedForType>(s_testLimits, s_testLimits + ARRAY_SIZE(s_testLimits)))
{
}
};
uint32_t GetType(char const * s0, char const * s1 = 0, char const * s2 = 0)
{
char const * const t[] = {s0, s1, s2};
size_t const size = (s0 != 0) + size_t(s1 != 0) + size_t(s2 != 0);
return classif().GetTypeByPath(vector<string>(t, t + size));
}
void CheckSpeed(vector<uint32_t> types, double expectedSpeed)
{
TestVehicleModel vehicleModel;
feature::TypesHolder h;
for (size_t i = 0; i < types.size(); ++i)
h(types[i]);
TEST_EQUAL(vehicleModel.GetSpeed(h), expectedSpeed, ());
}
void CheckOneWay(vector<uint32_t> types, bool expectedValue)
{
TestVehicleModel vehicleModel;
feature::TypesHolder h;
for (size_t i = 0; i < types.size(); ++i)
h(types[i]);
TEST_EQUAL(vehicleModel.IsOneWay(h), expectedValue, ());
}
}
UNIT_TEST(VehicleModel_MaxSpeed)
{
TestVehicleModel vehicleModel;
TEST_EQUAL(vehicleModel.GetMaxSpeed(), 150, ());
}
UNIT_TEST(VehicleModel_Speed)
{
CheckSpeed(vector<uint32_t>(1, GetType("highway", "secondary", "bridge")), 80.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway", "secondary", "tunnel")), 80.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway", "secondary")), 80.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway")), 0.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway", "trunk")), 150.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway", "primary")), 120.0);
CheckSpeed(vector<uint32_t>(1, GetType("highway", "residential")), 50.0);
}
UNIT_TEST(VehicleModel_Speed_MultiTypes)
{
uint32_t const typeTunnel = GetType("highway", "secondary", "tunnel");
uint32_t const typeSecondary = GetType("highway", "secondary");
uint32_t const typeHighway = GetType("highway");
{
uint32_t types[] = { typeTunnel, typeSecondary };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
}
{
uint32_t types[] = { typeTunnel, typeHighway };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
}
{
uint32_t types[] = { typeHighway, typeTunnel };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
}
{
uint32_t types[] = { typeHighway, typeHighway };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 0.0);
}
}
UNIT_TEST(VehicleModel_OneWay)
{
{
uint32_t types[] = { GetType("highway", "secondary", "bridge"), GetType("oneway") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
CheckOneWay(vector<uint32_t>(types, types + ARRAY_SIZE(types)), true);
}
{
uint32_t types[] = { GetType("oneway"), GetType("highway", "secondary", "bridge") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
CheckOneWay(vector<uint32_t>(types, types + ARRAY_SIZE(types)), true);
}
{
uint32_t types[] = { GetType("oneway") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 0.0);
CheckOneWay(vector<uint32_t>(types, types + ARRAY_SIZE(types)), true);
}
}
UNIT_TEST(VehicleModel_DifferentSpeeds)
{
{
uint32_t types[] = { GetType("highway", "secondary"), GetType("highway", "primary") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
}
{
uint32_t types[] = { GetType("highway", "primary"), GetType("highway", "secondary") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
}
{
uint32_t types[] = { GetType("highway", "primary"), GetType("oneway"), GetType("highway", "secondary") };
CheckSpeed(vector<uint32_t>(types, types + ARRAY_SIZE(types)), 80.0);
CheckOneWay(vector<uint32_t>(types, types + ARRAY_SIZE(types)), true);
}
}

85
routing/vehicle_model.cpp Normal file
View file

@ -0,0 +1,85 @@
#include "vehicle_model.hpp"
#include "../indexer/classificator.hpp"
#include "../indexer/feature.hpp"
#include "../indexer/ftypes_matcher.hpp"
#include "../base/macros.hpp"
#include "../std/limits.hpp"
namespace routing
{
VehicleModel::SpeedForType const s_carLimits[] = {
{ {"highway", "motorway"}, 90 },
{ {"highway", "trunk"}, 85 },
{ {"highway", "motorway_link"}, 75 },
{ {"highway", "trunk_link"}, 70 },
{ {"highway", "primary"}, 65 },
{ {"highway", "primary_link"}, 60 },
{ {"highway", "secondary"}, 55 },
{ {"highway", "secondary_link"}, 50 },
{ {"highway", "tertiary"}, 40 },
{ {"highway", "tertiary_link"}, 30 },
{ {"highway", "residential"}, 25 },
{ {"highway", "pedestrian"}, 25 },
{ {"highway", "unclassified"}, 25 },
{ {"highway", "service"}, 15 },
{ {"highway", "living_street"}, 10 },
{ {"highway", "road"}, 10 },
{ {"highway", "track"}, 5 },
/// @todo: Add to classificator
//{ {"highway", "shuttle_train"}, 10 },
//{ {"highway", "ferry"}, 5 },
//{ {"highway", "default"}, 10 },
/// @todo: check type
//{ {"highway", "construction"}, 40 },
};
CarModel::CarModel()
: VehicleModel(classif(), vector<VehicleModel::SpeedForType>(s_carLimits, s_carLimits + ARRAY_SIZE(s_carLimits)))
{
}
VehicleModel::VehicleModel(Classificator const & c, vector<SpeedForType> const & speedLimits) : m_maxSpeed(0)
{
m_onewayType = c.GetTypeByPath(vector<string>(1, "oneway"));
for (size_t i = 0; i < speedLimits.size(); ++i)
{
m_maxSpeed = max(m_maxSpeed, speedLimits[i].m_speed);
m_types[c.GetTypeByPath(vector<string>(speedLimits[i].m_types, speedLimits[i].m_types + 2))] = speedLimits[i];
}
}
double VehicleModel::GetSpeed(FeatureType const & f) const
{
return GetSpeed(feature::TypesHolder(f));
}
double VehicleModel::GetSpeed(feature::TypesHolder const & types) const
{
double speed = m_maxSpeed * 2;
for (size_t i = 0; i < types.Size(); ++i)
{
uint32_t const type = ftypes::BaseChecker::PrepareFeatureTypeToMatch(types[i]);
TypesT::const_iterator it = m_types.find(type);
if (it != m_types.end())
speed = min(speed, it->second.m_speed);
}
if (speed <= m_maxSpeed)
return speed;
return 0.0;
}
bool VehicleModel::IsOneWay(FeatureType const & f) const
{
return IsOneWay(feature::TypesHolder(f));
}
bool VehicleModel::IsOneWay(feature::TypesHolder const & types) const
{
return types.Has(m_onewayType);
}
}

55
routing/vehicle_model.hpp Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#include "../std/unordered_map.hpp"
#include "../std/utility.hpp"
#include "../std/vector.hpp"
class Classificator;
class FeatureType;
namespace feature { class TypesHolder; }
namespace routing
{
class IVehicleModel
{
public:
virtual ~IVehicleModel() {}
virtual double GetSpeed(FeatureType const & f) const = 0;
virtual double GetMaxSpeed() const = 0;
virtual bool IsOneWay(FeatureType const & f) const = 0;
};
class VehicleModel : public IVehicleModel
{
public:
struct SpeedForType
{
char const * m_types[2];
double m_speed;
};
VehicleModel(Classificator const & c, vector<SpeedForType> const & speedLimits);
virtual double GetSpeed(FeatureType const & f) const;
virtual double GetMaxSpeed() const { return m_maxSpeed; }
virtual bool IsOneWay(FeatureType const & f) const;
double GetSpeed(feature::TypesHolder const & types) const;
bool IsOneWay(feature::TypesHolder const & types) const;
private:
double m_maxSpeed;
typedef unordered_map<uint32_t, SpeedForType> TypesT;
TypesT m_types;
uint32_t m_onewayType;
};
class CarModel : public VehicleModel
{
public:
CarModel();
};
}