[routing] VehicleModel refactoring.
This commit is contained in:
parent
d02453b52f
commit
ae962fa7c4
29 changed files with 760 additions and 1511 deletions
|
@ -266,7 +266,7 @@ omim_add_test_subdirectory(generator_tests)
|
|||
omim_add_test_subdirectory(generator_integration_tests)
|
||||
|
||||
add_subdirectory(generator_tool)
|
||||
add_subdirectory(complex_generator)
|
||||
add_subdirectory(feature_segments_checker)
|
||||
#add_subdirectory(complex_generator)
|
||||
#add_subdirectory(feature_segments_checker)
|
||||
add_subdirectory(srtm_coverage_checker)
|
||||
add_subdirectory(world_roads_builder)
|
||||
|
|
|
@ -563,7 +563,7 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_Ferry)
|
|||
|
||||
uint32_t type = GetType({"route", "ferry"});
|
||||
TEST(params.IsTypeExist(type), (params));
|
||||
TEST(carModel.IsRoadType(type), ());
|
||||
TEST(carModel.HasRoadType(params.m_types), ());
|
||||
|
||||
type = GetType({"hwtag", "nocar"});
|
||||
TEST(params.IsTypeExist(type), ());
|
||||
|
@ -582,7 +582,7 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_Ferry)
|
|||
|
||||
uint32_t type = GetType({"route", "ferry"});
|
||||
TEST(params.IsTypeExist(type), (params));
|
||||
TEST(carModel.IsRoadType(type), ());
|
||||
TEST(carModel.HasRoadType(params.m_types), ());
|
||||
|
||||
type = GetType({"hwtag", "yescar"});
|
||||
TEST(params.IsTypeExist(type), ());
|
||||
|
@ -594,7 +594,8 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_Ferry)
|
|||
|
||||
UNIT_CLASS_TEST(TestWithClassificator, OsmType_YesCarNoCar)
|
||||
{
|
||||
routing::CarModel const & carModel = routing::CarModel::AllLimitsInstance();
|
||||
uint32_t const yesCar = GetType({"hwtag", "yescar"});
|
||||
uint32_t const noCar = GetType({"hwtag", "nocar"});
|
||||
|
||||
{
|
||||
Tags const tags = {
|
||||
|
@ -604,8 +605,8 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_YesCarNoCar)
|
|||
auto const params = GetFeatureBuilderParams(tags);
|
||||
|
||||
TEST_EQUAL(params.m_types.size(), 1, (params));
|
||||
TEST(!params.IsTypeExist(carModel.GetNoCarTypeForTesting()), ());
|
||||
TEST(!params.IsTypeExist(carModel.GetYesCarTypeForTesting()), ());
|
||||
TEST(!params.IsTypeExist(yesCar), ());
|
||||
TEST(!params.IsTypeExist(noCar), ());
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -617,8 +618,8 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_YesCarNoCar)
|
|||
auto const params = GetFeatureBuilderParams(tags);
|
||||
|
||||
TEST_EQUAL(params.m_types.size(), 2, (params));
|
||||
TEST(!params.IsTypeExist(carModel.GetNoCarTypeForTesting()), ());
|
||||
TEST(params.IsTypeExist(carModel.GetYesCarTypeForTesting()), ());
|
||||
TEST(params.IsTypeExist(yesCar), ());
|
||||
TEST(!params.IsTypeExist(noCar), ());
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -630,8 +631,20 @@ UNIT_CLASS_TEST(TestWithClassificator, OsmType_YesCarNoCar)
|
|||
auto const params = GetFeatureBuilderParams(tags);
|
||||
|
||||
TEST_EQUAL(params.m_types.size(), 2, (params));
|
||||
TEST(params.IsTypeExist(carModel.GetNoCarTypeForTesting()), ());
|
||||
TEST(!params.IsTypeExist(carModel.GetYesCarTypeForTesting()), ());
|
||||
TEST(!params.IsTypeExist(yesCar), ());
|
||||
TEST(params.IsTypeExist(noCar), ());
|
||||
}
|
||||
|
||||
{
|
||||
Tags const tags = {
|
||||
{"railway", "rail"},
|
||||
{"motor_vehicle", "yes"},
|
||||
};
|
||||
|
||||
auto const params = GetFeatureBuilderParams(tags);
|
||||
|
||||
TEST_EQUAL(params.m_types.size(), 1, (params));
|
||||
TEST(params.IsTypeExist(GetType({"railway", "rail", "motor_vehicle"})), ());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,14 +61,10 @@ namespace
|
|||
class VehicleMaskBuilder final
|
||||
{
|
||||
public:
|
||||
VehicleMaskBuilder(string const & country,
|
||||
routing::CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
: m_pedestrianModel(routing::PedestrianModelFactory(countryParentNameGetterFn)
|
||||
.GetVehicleModelForCountry(country))
|
||||
, m_bicycleModel(routing::BicycleModelFactory(countryParentNameGetterFn)
|
||||
.GetVehicleModelForCountry(country))
|
||||
, m_carModel(
|
||||
routing::CarModelFactory(countryParentNameGetterFn).GetVehicleModelForCountry(country))
|
||||
VehicleMaskBuilder(string const & country, routing::CountryParentNameGetterFn const & parentGetter)
|
||||
: m_pedestrianModel(routing::PedestrianModelFactory(parentGetter).GetVehicleModelForCountry(country))
|
||||
, m_bicycleModel(routing::BicycleModelFactory(parentGetter).GetVehicleModelForCountry(country))
|
||||
, m_carModel(routing::CarModelFactory(parentGetter).GetVehicleModelForCountry(country))
|
||||
{
|
||||
CHECK(m_pedestrianModel, ());
|
||||
CHECK(m_bicycleModel, ());
|
||||
|
@ -78,7 +74,7 @@ public:
|
|||
routing::VehicleMask CalcRoadMask(FeatureType & f) const
|
||||
{
|
||||
return CalcMask(f, [&](routing::VehicleModelInterface const & model, FeatureType & f) {
|
||||
return model.IsRoad(f);
|
||||
return model.HasRoadType(f);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -194,7 +194,7 @@ if (PLATFORM_DESKTOP)
|
|||
add_subdirectory(routes_builder)
|
||||
endif()
|
||||
|
||||
omim_add_test_subdirectory(routing_benchmarks)
|
||||
omim_add_test_subdirectory(routing_consistency_tests)
|
||||
#omim_add_test_subdirectory(routing_benchmarks)
|
||||
#omim_add_test_subdirectory(routing_consistency_tests)
|
||||
omim_add_test_subdirectory(routing_integration_tests)
|
||||
omim_add_test_subdirectory(routing_tests)
|
||||
|
|
|
@ -52,35 +52,20 @@ FeaturesRoadGraph::CrossCountryVehicleModel::CrossCountryVehicleModel(
|
|||
{
|
||||
}
|
||||
|
||||
SpeedKMpH FeaturesRoadGraph::CrossCountryVehicleModel::GetSpeed(
|
||||
FeatureType & f, SpeedParams const & speedParams) const
|
||||
VehicleModel::Response FeaturesRoadGraph::CrossCountryVehicleModel::GetFeatureInfo(
|
||||
FeatureType & ft, Request const & request) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->GetSpeed(f, speedParams);
|
||||
return GetVehicleModel(ft.GetID())->GetFeatureInfo(ft, request);
|
||||
}
|
||||
|
||||
HighwayType FeaturesRoadGraph::CrossCountryVehicleModel::GetHighwayType(FeatureType & f) const
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::HasRoadType(FeatureType & ft) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->GetHighwayType(f);
|
||||
return GetVehicleModel(ft.GetID())->HasRoadType(ft);
|
||||
}
|
||||
|
||||
SpeedKMpH const & FeaturesRoadGraph::CrossCountryVehicleModel::GetOffroadSpeed() const
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsOneWay(FeatureType & ft) const
|
||||
{
|
||||
return m_offroadSpeedKMpH;
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsOneWay(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsOneWay(f);
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsRoad(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsRoad(f);
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::CrossCountryVehicleModel::IsPassThroughAllowed(FeatureType & f) const
|
||||
{
|
||||
return GetVehicleModel(f.GetID())->IsPassThroughAllowed(f);
|
||||
return GetVehicleModel(ft.GetID())->IsOneWay(ft);
|
||||
}
|
||||
|
||||
VehicleModelInterface * FeaturesRoadGraph::CrossCountryVehicleModel::GetVehicleModel(
|
||||
|
@ -142,9 +127,7 @@ public:
|
|||
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
|
||||
IRoadGraph::RoadInfo const & roadInfo =
|
||||
m_graph.GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
CHECK_EQUAL(roadInfo.m_speedKMPH, kInvalidSpeedKMPH, ());
|
||||
IRoadGraph::RoadInfo const & roadInfo = m_graph.GetCachedRoadInfo(featureId, ft);
|
||||
|
||||
m_edgesLoader(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional);
|
||||
}
|
||||
|
@ -154,17 +137,16 @@ private:
|
|||
IRoadGraph::ICrossEdgesLoader & m_edgesLoader;
|
||||
};
|
||||
|
||||
IRoadGraph::RoadInfo FeaturesRoadGraph::GetRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
IRoadGraph::RoadInfo FeaturesRoadGraph::GetRoadInfo(FeatureID const & featureId) const
|
||||
{
|
||||
RoadInfo const & ri = GetCachedRoadInfo(featureId, speedParams);
|
||||
RoadInfo const & ri = GetCachedRoadInfo(featureId);
|
||||
ASSERT_GREATER(ri.m_speedKMPH, 0.0, ());
|
||||
return ri;
|
||||
}
|
||||
|
||||
double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const
|
||||
double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId) const
|
||||
{
|
||||
double const speedKMPH = GetCachedRoadInfo(featureId, speedParams).m_speedKMPH;
|
||||
double const speedKMPH = GetCachedRoadInfo(featureId).m_speedKMPH;
|
||||
ASSERT_GREATER(speedKMPH, 0.0, ());
|
||||
return speedKMPH;
|
||||
}
|
||||
|
@ -188,12 +170,12 @@ void FeaturesRoadGraph::FindClosestEdges(
|
|||
|
||||
auto const f = [&finder, this](FeatureType & ft)
|
||||
{
|
||||
if (!m_vehicleModel.IsRoad(ft))
|
||||
if (!IsRoad(ft))
|
||||
return;
|
||||
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
|
||||
IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft);
|
||||
finder.AddInformationSource(IRoadGraph::FullRoadInfo(featureId, roadInfo));
|
||||
};
|
||||
|
||||
|
@ -207,7 +189,7 @@ FeaturesRoadGraph::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isG
|
|||
{
|
||||
vector<IRoadGraph::FullRoadInfo> roads;
|
||||
auto const f = [&roads, &isGoodFeature, &rect, this](FeatureType & ft) {
|
||||
if (!m_vehicleModel.IsRoad(ft))
|
||||
if (!IsRoad(ft))
|
||||
return;
|
||||
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
|
@ -216,7 +198,7 @@ FeaturesRoadGraph::FindRoads(m2::RectD const & rect, IsGoodFeatureFn const & isG
|
|||
|
||||
// DataSource::ForEachInRect() gives not only features inside |rect| but some other features
|
||||
// which lie close to the rect. Removes all the features which don't cross |rect|.
|
||||
auto const & roadInfo = GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
auto const & roadInfo = GetCachedRoadInfo(featureId, ft);
|
||||
if (!RectCoversPolyline(roadInfo.m_junctions, rect))
|
||||
return;
|
||||
|
||||
|
@ -277,33 +259,22 @@ void FeaturesRoadGraph::ClearState()
|
|||
m_mwmLocks.clear();
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::IsRoad(FeatureType & ft) const { return m_vehicleModel.IsRoad(ft); }
|
||||
|
||||
IRoadGraph::PointWithAltitudeVec FeaturesRoadGraph::GetRoadGeom(FeatureType & ft) const
|
||||
bool FeaturesRoadGraph::IsRoad(FeatureType & ft) const
|
||||
{
|
||||
FeatureID const & featureId = ft.GetID();
|
||||
IRoadGraph::RoadInfo const & roadInfo = GetCachedRoadInfo(featureId, ft, kInvalidSpeedKMPH);
|
||||
CHECK_EQUAL(roadInfo.m_speedKMPH, kInvalidSpeedKMPH, ());
|
||||
return roadInfo.m_junctions;
|
||||
return m_vehicleModel.HasRoadType(ft);
|
||||
}
|
||||
|
||||
bool FeaturesRoadGraph::IsOneWay(FeatureType & ft) const { return m_vehicleModel.IsOneWay(ft); }
|
||||
|
||||
double FeaturesRoadGraph::GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams const & speedParams) const
|
||||
void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, RoadInfo & ri) const
|
||||
{
|
||||
return m_vehicleModel.GetSpeed(ft, speedParams).m_weight;
|
||||
}
|
||||
|
||||
void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMpH, RoadInfo & ri) const
|
||||
{
|
||||
ri.m_speedKMPH = speedKMpH;
|
||||
|
||||
Value const & value = LockMwm(featureId.m_mwmId);
|
||||
if (!value.IsAlive())
|
||||
return;
|
||||
|
||||
ri.m_bidirectional = !IsOneWay(ft);
|
||||
auto const response = m_vehicleModel.GetFeatureInfo(ft, {Maxspeed(), false});
|
||||
CHECK(response.m_isValid, ());
|
||||
|
||||
ri.m_speedKMPH = response.m_forwardSpeed.m_weight;
|
||||
ri.m_bidirectional = !response.m_isOneWay;
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
size_t const pointsCount = ft.GetPointsCount();
|
||||
|
@ -328,8 +299,7 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType
|
|||
ri.m_junctions[i] = geometry::PointWithAltitude(ft.GetPoint(i), altitudes[i]);
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & speedParams) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
|
@ -345,13 +315,12 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons
|
|||
|
||||
ASSERT_EQUAL(ft->GetGeomType(), feature::GeomType::Line, ());
|
||||
|
||||
ExtractRoadInfo(featureId, *ft, GetSpeedKMpHFromFt(*ft, speedParams), ri);
|
||||
ExtractRoadInfo(featureId, *ft, ri);
|
||||
return ri;
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId,
|
||||
FeatureType & ft,
|
||||
double speedKMPH) const
|
||||
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(
|
||||
FeatureID const & featureId, FeatureType & ft) const
|
||||
{
|
||||
bool found = false;
|
||||
RoadInfo & ri = m_cache.Find(featureId, found);
|
||||
|
@ -361,7 +330,7 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons
|
|||
|
||||
// ft must be set
|
||||
ASSERT_EQUAL(featureId, ft.GetID(), ());
|
||||
ExtractRoadInfo(featureId, ft, speedKMPH, ri);
|
||||
ExtractRoadInfo(featureId, ft, ri);
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,14 +33,14 @@ private:
|
|||
public:
|
||||
CrossCountryVehicleModel(std::shared_ptr<VehicleModelFactoryInterface> vehicleModelFactory);
|
||||
|
||||
// VehicleModelInterface overrides:
|
||||
SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override;
|
||||
HighwayType GetHighwayType(FeatureType & f) const override;
|
||||
/// @name VehicleModelInterface overrides:
|
||||
/// @{
|
||||
Response GetFeatureInfo(FeatureType & ft, Request const & request) const override;
|
||||
bool HasRoadType(FeatureType & ft) const override;
|
||||
bool IsOneWay(FeatureType & ft) const override;
|
||||
double GetMaxWeightSpeed() const override { return m_maxSpeed; }
|
||||
SpeedKMpH const & GetOffroadSpeed() const override;
|
||||
bool IsOneWay(FeatureType & f) const override;
|
||||
bool IsRoad(FeatureType & f) const override;
|
||||
bool IsPassThroughAllowed(FeatureType & f) const override;
|
||||
SpeedKMpH GetOffroadSpeed() const override { return m_offroadSpeedKMpH; }
|
||||
/// @}
|
||||
|
||||
void Clear();
|
||||
|
||||
|
@ -77,8 +77,8 @@ public:
|
|||
static int GetStreetReadScale();
|
||||
|
||||
// IRoadGraph overrides:
|
||||
RoadInfo GetRoadInfo(FeatureID const & featureId, SpeedParams const & speedParams) const override;
|
||||
double GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const override;
|
||||
RoadInfo GetRoadInfo(FeatureID const & featureId) const override;
|
||||
double GetSpeedKMpH(FeatureID const & featureId) const override;
|
||||
double GetMaxSpeedKMpH() const override;
|
||||
void ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgesLoader) const override;
|
||||
|
@ -94,7 +94,6 @@ public:
|
|||
void ClearState() override;
|
||||
|
||||
bool IsRoad(FeatureType & ft) const;
|
||||
IRoadGraph::PointWithAltitudeVec GetRoadGeom(FeatureType & ft) const;
|
||||
|
||||
private:
|
||||
friend class CrossFeaturesLoader;
|
||||
|
@ -110,18 +109,13 @@ private:
|
|||
std::unique_ptr<feature::AltitudeLoader> m_altitudeLoader;
|
||||
};
|
||||
|
||||
bool IsOneWay(FeatureType & ft) const;
|
||||
double GetSpeedKMpHFromFt(FeatureType & ft, SpeedParams const & speedParams) const;
|
||||
|
||||
// Searches a feature RoadInfo in the cache, and if does not find then
|
||||
// loads feature from the index and takes speed for the feature from the vehicle model.
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, SpeedParams const & speedParams) const;
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId) const;
|
||||
// Searches a feature RoadInfo in the cache, and if does not find then takes passed feature and speed.
|
||||
// This version is used to prevent redundant feature loading when feature speed is known.
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft,
|
||||
double speedKMPH) const;
|
||||
void ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, double speedKMpH,
|
||||
RoadInfo & ri) const;
|
||||
RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft) const;
|
||||
void ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, RoadInfo & ri) const;
|
||||
|
||||
Value const & LockMwm(MwmSet::MwmId const & mwmId) const;
|
||||
|
||||
|
|
|
@ -185,16 +185,15 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType
|
|||
{
|
||||
CHECK(altitudes == nullptr || altitudes->size() == feature.GetPointsCount(), ());
|
||||
|
||||
m_valid = vehicleModel.IsRoad(feature);
|
||||
m_isOneWay = vehicleModel.IsOneWay(feature);
|
||||
m_highwayType = vehicleModel.GetHighwayType(feature);
|
||||
m_isPassThroughAllowed = vehicleModel.IsPassThroughAllowed(feature);
|
||||
|
||||
uint32_t const fID = feature.GetID().m_index;
|
||||
bool const inCity = attrs.m_cityRoads.IsCityRoad(fID);
|
||||
Maxspeed const maxSpeed = attrs.m_maxSpeeds.GetMaxspeed(fID);
|
||||
m_forwardSpeed = vehicleModel.GetSpeed(feature, {true /* forward */, inCity, maxSpeed});
|
||||
m_backwardSpeed = vehicleModel.GetSpeed(feature, {false /* forward */, inCity, maxSpeed});
|
||||
auto const response = vehicleModel.GetFeatureInfo(
|
||||
feature, {attrs.m_maxSpeeds.GetMaxspeed(fID), attrs.m_cityRoads.IsCityRoad(fID)});
|
||||
m_forwardSpeed = response.m_forwardSpeed;
|
||||
m_backwardSpeed = response.m_backwardSpeed;
|
||||
m_highwayType = response.m_highwayType;
|
||||
m_valid = response.m_isValid;
|
||||
m_isOneWay = response.m_isOneWay;
|
||||
m_isPassThroughAllowed = response.m_isPassThroughAllowed;
|
||||
|
||||
feature::TypesHolder types(feature);
|
||||
auto const & optionsClassfier = RoutingOptionsClassifier::Instance();
|
||||
|
|
|
@ -92,7 +92,7 @@ double CalcMaxSpeed(NumMwmIds const & numMwmIds,
|
|||
return maxSpeed;
|
||||
}
|
||||
|
||||
SpeedKMpH const & CalcOffroadSpeed(VehicleModelFactoryInterface const & vehicleModelFactory)
|
||||
SpeedKMpH CalcOffroadSpeed(VehicleModelFactoryInterface const & vehicleModelFactory)
|
||||
{
|
||||
return vehicleModelFactory.GetVehicleModel()->GetOffroadSpeed();
|
||||
}
|
||||
|
|
|
@ -292,11 +292,9 @@ void IRoadGraph::AddIngoingFakeEdge(Edge const & e)
|
|||
AddEdge(e.GetEndJunction(), e, m_fakeIngoingEdges);
|
||||
}
|
||||
|
||||
double IRoadGraph::GetSpeedKMpH(Edge const & edge, SpeedParams const & speedParams) const
|
||||
double IRoadGraph::GetSpeedKMpH(Edge const & edge) const
|
||||
{
|
||||
double const speedKMpH =
|
||||
(edge.IsFake() ? GetMaxSpeedKMpH()
|
||||
: GetSpeedKMpH(edge.GetFeatureId(), speedParams));
|
||||
double const speedKMpH = (edge.IsFake() ? GetMaxSpeedKMpH() : GetSpeedKMpH(edge.GetFeatureId()));
|
||||
ASSERT_LESS_OR_EQUAL(speedKMpH, GetMaxSpeedKMpH(), ());
|
||||
return speedKMpH;
|
||||
}
|
||||
|
|
|
@ -287,13 +287,13 @@ public:
|
|||
void AddIngoingFakeEdge(Edge const & e);
|
||||
|
||||
/// Returns RoadInfo for a road corresponding to featureId.
|
||||
virtual RoadInfo GetRoadInfo(FeatureID const & featureId, SpeedParams const & speedParams) const = 0;
|
||||
virtual RoadInfo GetRoadInfo(FeatureID const & featureId) const = 0;
|
||||
|
||||
/// Returns speed in KM/H for a road corresponding to featureId.
|
||||
virtual double GetSpeedKMpH(FeatureID const & featureId, SpeedParams const & speedParams) const = 0;
|
||||
virtual double GetSpeedKMpH(FeatureID const & featureId) const = 0;
|
||||
|
||||
/// Returns speed in KM/H for a road corresponding to edge.
|
||||
double GetSpeedKMpH(Edge const & edge, SpeedParams const & speedParams) const;
|
||||
double GetSpeedKMpH(Edge const & edge) const;
|
||||
|
||||
/// Calls edgesLoader on each feature which is close to cross.
|
||||
virtual void ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
|
|
|
@ -45,8 +45,7 @@ bool IsBicycleRoad(Types const & types)
|
|||
template <typename Types>
|
||||
bool IsRoad(Types const & types)
|
||||
{
|
||||
return IsCarRoad(types) || PedestrianModel::AllLimitsInstance().HasRoadType(types) ||
|
||||
IsBicycleRoad(types);
|
||||
return (IsCarRoad(types) || IsBicycleRoad(types) || PedestrianModel::AllLimitsInstance().HasRoadType(types));
|
||||
}
|
||||
|
||||
void FillSegmentInfo(std::vector<Segment> const & segments,
|
||||
|
|
|
@ -25,8 +25,7 @@ void TestNearestOnMock1(m2::PointD const & point, size_t const candidatesCount,
|
|||
for (size_t i = 0; i < graph->GetRoadCount(); ++i)
|
||||
{
|
||||
FeatureID const featureId = MakeTestFeatureID(base::checked_cast<uint32_t>(i));
|
||||
auto const & roadInfo =
|
||||
graph->GetRoadInfo(featureId, {true /* forward */, false /* in city */, Maxspeed()});
|
||||
auto const & roadInfo = graph->GetRoadInfo(featureId);
|
||||
finder.AddInformationSource(IRoadGraph::FullRoadInfo(featureId, roadInfo));
|
||||
}
|
||||
|
||||
|
|
|
@ -71,15 +71,13 @@ void RoadGraphMockSource::AddRoad(RoadInfo && ri)
|
|||
m_roads.push_back(move(ri));
|
||||
}
|
||||
|
||||
IRoadGraph::RoadInfo RoadGraphMockSource::GetRoadInfo(FeatureID const & featureId,
|
||||
SpeedParams const & /* speedParams */) const
|
||||
IRoadGraph::RoadInfo RoadGraphMockSource::GetRoadInfo(FeatureID const & featureId) const
|
||||
{
|
||||
CHECK_LESS(featureId.m_index, m_roads.size(), ("Invalid feature id."));
|
||||
return m_roads[featureId.m_index];
|
||||
}
|
||||
|
||||
double RoadGraphMockSource::GetSpeedKMpH(FeatureID const & featureId,
|
||||
SpeedParams const & /* speedParams */) const
|
||||
double RoadGraphMockSource::GetSpeedKMpH(FeatureID const & featureId) const
|
||||
{
|
||||
CHECK_LESS(featureId.m_index, m_roads.size(), ("Invalid feature id."));
|
||||
return m_roads[featureId.m_index].m_speedKMPH;
|
||||
|
|
|
@ -19,9 +19,8 @@ public:
|
|||
inline size_t GetRoadCount() const { return m_roads.size(); }
|
||||
|
||||
// routing::IRoadGraph overrides:
|
||||
RoadInfo GetRoadInfo(FeatureID const & f, routing::SpeedParams const & speedParams) const override;
|
||||
double GetSpeedKMpH(FeatureID const & featureId,
|
||||
routing::SpeedParams const & speedParams) const override;
|
||||
RoadInfo GetRoadInfo(FeatureID const & f) const override;
|
||||
double GetSpeedKMpH(FeatureID const & featureId) const override;
|
||||
double GetMaxSpeedKMpH() const override;
|
||||
void ForEachFeatureClosestToCross(m2::PointD const & cross,
|
||||
ICrossEdgesLoader & edgeLoader) const override;
|
||||
|
|
|
@ -132,8 +132,7 @@ public:
|
|||
{
|
||||
ASSERT_EQUAL(v, e.GetStartJunction(), ());
|
||||
|
||||
double const speedMPS = KMPH2MPS(
|
||||
m_roadGraph.GetSpeedKMpH(e, {true /* forward */, false /* in city */, Maxspeed()}));
|
||||
double const speedMPS = KMPH2MPS(m_roadGraph.GetSpeedKMpH(e));
|
||||
adj.emplace_back(e.GetEndJunction(), TimeBetweenSec(e.GetStartJunction(), e.GetEndJunction(), speedMPS));
|
||||
}
|
||||
}
|
||||
|
@ -152,8 +151,7 @@ public:
|
|||
{
|
||||
ASSERT_EQUAL(v, e.GetEndJunction(), ());
|
||||
|
||||
double const speedMPS = KMPH2MPS(
|
||||
m_roadGraph.GetSpeedKMpH(e, {true /* forward */, false /* in city */, Maxspeed()}));
|
||||
double const speedMPS = KMPH2MPS(m_roadGraph.GetSpeedKMpH(e));
|
||||
adj.emplace_back(e.GetStartJunction(), TimeBetweenSec(e.GetStartJunction(), e.GetEndJunction(), speedMPS));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
#include "routing_common/bicycle_model.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/macros.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
|
||||
namespace bicycle_model
|
||||
{
|
||||
using namespace routing;
|
||||
|
||||
// See model specifics in different countries here:
|
||||
// https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions
|
||||
// Document contains proposals for some countries, but we assume that some kinds of roads are ready for bicycle routing,
|
||||
|
@ -28,10 +22,10 @@ namespace bicycle_model
|
|||
// As result of such heuristic road is not totally the shortest, but it avoids non bicycle roads, which were
|
||||
// not marked as "hwtag=nobicycle" in OSM.
|
||||
|
||||
HighwayBasedFactors const kDefaultFactors = GetOneFactorsForBicycleAndPedestrianModel();
|
||||
HighwayFactors const kDefaultFactors = GetOneFactorsForBicycleAndPedestrianModel();
|
||||
|
||||
HighwayBasedSpeeds const kDefaultSpeeds = {
|
||||
// {highway class : InOutCitySpeedKMpH(in city(weight, eta), out city(weight eta))}
|
||||
HighwaySpeeds const kDefaultSpeeds = {
|
||||
// {highway class, InOutCitySpeedKMpH(in city(weight, eta), out city(weight eta))}
|
||||
{HighwayType::HighwayTrunk, InOutCitySpeedKMpH(SpeedKMpH(3.0, 18.0))},
|
||||
{HighwayType::HighwayTrunkLink, InOutCitySpeedKMpH(SpeedKMpH(3.0, 18.0))},
|
||||
{HighwayType::HighwayPrimary, InOutCitySpeedKMpH(SpeedKMpH(10.0, 18.0), SpeedKMpH(14.0, 18.0))},
|
||||
|
@ -45,465 +39,219 @@ HighwayBasedSpeeds const kDefaultSpeeds = {
|
|||
{HighwayType::HighwayRoad, InOutCitySpeedKMpH(SpeedKMpH(10.0, 12.0))},
|
||||
{HighwayType::HighwayTrack, InOutCitySpeedKMpH(SpeedKMpH(8.0, 12.0))},
|
||||
{HighwayType::HighwayPath, InOutCitySpeedKMpH(SpeedKMpH(6.0, 12.0))},
|
||||
{HighwayType::HighwayBridleway, InOutCitySpeedKMpH(SpeedKMpH(4.0, 12.0))},
|
||||
{HighwayType::HighwayCycleway, InOutCitySpeedKMpH(SpeedKMpH(30.0, 20.0))},
|
||||
{HighwayType::HighwayResidential, InOutCitySpeedKMpH(SpeedKMpH(8.0, 10.0))},
|
||||
{HighwayType::HighwayLivingStreet, InOutCitySpeedKMpH(SpeedKMpH(7.0, 8.0))},
|
||||
|
||||
{HighwayType::RouteFerry, InOutCitySpeedKMpH(SpeedKMpH(3.0, 20.0))},
|
||||
|
||||
// Steps have obvious inconvenience of a bike in hands.
|
||||
{HighwayType::HighwaySteps, InOutCitySpeedKMpH(SpeedKMpH(1.0, 1.0))},
|
||||
|
||||
// Set minimun default bicycle speeds for the next disputable roads.
|
||||
{HighwayType::HighwayPedestrian, InOutCitySpeedKMpH(SpeedKMpH(2.0))},
|
||||
{HighwayType::HighwayFootway, InOutCitySpeedKMpH(SpeedKMpH(2.0))},
|
||||
{HighwayType::ManMadePier, InOutCitySpeedKMpH(SpeedKMpH(2.0))},
|
||||
{HighwayType::HighwayBridleway, InOutCitySpeedKMpH(SpeedKMpH(2.0))},
|
||||
};
|
||||
|
||||
// Normal bicycle speeds for disputable roads.
|
||||
HighwaySpeeds const kAdditionalSpeeds = {
|
||||
{HighwayType::HighwayPedestrian, InOutCitySpeedKMpH(SpeedKMpH(5.0))},
|
||||
{HighwayType::HighwayFootway, InOutCitySpeedKMpH(SpeedKMpH(7.0, 5.0))},
|
||||
{HighwayType::ManMadePier, InOutCitySpeedKMpH(SpeedKMpH(7.0))},
|
||||
{HighwayType::RouteFerry, InOutCitySpeedKMpH(SpeedKMpH(3.0, 20.0))},
|
||||
{HighwayType::HighwayBridleway, InOutCitySpeedKMpH(SpeedKMpH(4.0, 12.0))},
|
||||
};
|
||||
|
||||
SpeedKMpH constexpr kSpeedOffroadKMpH = {3.0 /* weight */, 3.0 /* eta */};
|
||||
|
||||
// Default
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsDefault = {
|
||||
// {{roadType, roadType} passThroughAllowed}
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true}};
|
||||
|
||||
// All options available.
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsAll = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
SpeedKMpH constexpr kOffroadSpeed = {3.0 /* weight */, 3.0 /* eta */};
|
||||
|
||||
// Same as defaults except trunk and trunk_link are not allowed
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsNoTrunk = {
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true}};
|
||||
HighwaySpeeds NoTrunk()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res.erase(HighwayType::HighwayTrunk);
|
||||
res.erase(HighwayType::HighwayTrunkLink);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except pedestrian is allowed
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsPedestrianAllowed = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true}};
|
||||
HighwaySpeeds PedestrianAllowed()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res[HighwayType::HighwayPedestrian] = kAdditionalSpeeds.at(HighwayType::HighwayPedestrian);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except bridleway is allowed
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsBridlewayAllowed = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true}};
|
||||
HighwaySpeeds BridlewayAllowed()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res[HighwayType::HighwayBridleway] = kAdditionalSpeeds.at(HighwayType::HighwayBridleway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except pedestrian and footway are allowed
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsPedestrianFootwayAllowed = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
HighwaySpeeds PedestrianFootwayAllowed()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res[HighwayType::HighwayPedestrian] = kAdditionalSpeeds.at(HighwayType::HighwayPedestrian);
|
||||
res[HighwayType::HighwayFootway] = kAdditionalSpeeds.at(HighwayType::HighwayFootway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Australia
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsAustralia = kBicycleOptionsAll;
|
||||
HighwaySpeeds AllAllowed()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
for (auto const & e : kAdditionalSpeeds)
|
||||
res[e.first] = e.second;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Austria
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsAustria = {
|
||||
// No trunk, trunk_link, path
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true}};
|
||||
// Austria (No trunk, no path)
|
||||
HighwaySpeeds AustriaSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = NoTrunk();
|
||||
res.erase(HighwayType::HighwayPath);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Belarus
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsBelarus = kBicycleOptionsPedestrianFootwayAllowed;
|
||||
// Belgium (No trunk, pedestrian is allowed).
|
||||
HighwaySpeeds BelgiumSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = NoTrunk();
|
||||
res[HighwayType::HighwayPedestrian] = kAdditionalSpeeds.at(HighwayType::HighwayPedestrian);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Belgium
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsBelgium = {
|
||||
// No trunk, trunk_link
|
||||
// Pedestrian is allowed
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true}};
|
||||
// Brazil (Bridleway and footway are allowed)
|
||||
HighwaySpeeds BrazilSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res[HighwayType::HighwayBridleway] = kAdditionalSpeeds.at(HighwayType::HighwayBridleway);
|
||||
res[HighwayType::HighwayFootway] = kAdditionalSpeeds.at(HighwayType::HighwayFootway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Brazil
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsBrazil = {
|
||||
// Bridleway and fotway are allowed
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
// France, same as Belgium (No trunk, pedestrian is allowed);
|
||||
HighwaySpeeds FranceSpeeds() { return BelgiumSpeeds(); }
|
||||
|
||||
// Denmark
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsDenmark = kBicycleOptionsNoTrunk;
|
||||
// Ukraine (No trunk, footway and pedestrian are allowed).
|
||||
HighwaySpeeds UkraineSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = NoTrunk();
|
||||
res[HighwayType::HighwayPedestrian] = kAdditionalSpeeds.at(HighwayType::HighwayPedestrian);
|
||||
res[HighwayType::HighwayFootway] = kAdditionalSpeeds.at(HighwayType::HighwayFootway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// France
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsFrance = {
|
||||
// No trunk, trunk_link
|
||||
// Pedestrian is allowed
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true}};
|
||||
// United States of America (Bridleway and pedestrian are allowed)
|
||||
HighwaySpeeds USASpeeds()
|
||||
{
|
||||
HighwaySpeeds res = kDefaultSpeeds;
|
||||
res[HighwayType::HighwayBridleway] = kAdditionalSpeeds.at(HighwayType::HighwayBridleway);
|
||||
res[HighwayType::HighwayPedestrian] = kAdditionalSpeeds.at(HighwayType::HighwayPedestrian);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Finland
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsFinland = kBicycleOptionsPedestrianAllowed;
|
||||
|
||||
// Germany
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsGermany = kBicycleOptionsDefault;
|
||||
|
||||
// Hungary
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsHungary = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Iceland
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsIceland = kBicycleOptionsAll;
|
||||
|
||||
// Netherlands
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsNetherlands = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Norway
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsNorway = kBicycleOptionsAll;
|
||||
|
||||
// Oman
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsOman = kBicycleOptionsBridlewayAllowed;
|
||||
|
||||
// Poland
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsPoland = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Romania
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsRomania = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Russian Federation
|
||||
// Footway and pedestrian are allowed
|
||||
// Note. Despite the fact that according to
|
||||
// https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions
|
||||
// passing through service and living_street with a bicycle is prohibited
|
||||
// it's allowed according to Russian traffic rules.
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsRussia = kBicycleOptionsPedestrianFootwayAllowed;
|
||||
|
||||
// Slovakia
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsSlovakia = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Spain
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsSpain = kBicycleOptionsPedestrianAllowed;
|
||||
|
||||
// Switzerland
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsSwitzerland = kBicycleOptionsNoTrunk;
|
||||
|
||||
// Turkey
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsTurkey = kBicycleOptionsDefault;
|
||||
|
||||
// Ukraine
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsUkraine = {
|
||||
// No trunk
|
||||
// Footway and pedestrian are allowed
|
||||
// No pass through living_street and service
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, false},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, false},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
|
||||
// United Kingdom
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsUK = kBicycleOptionsBridlewayAllowed;
|
||||
|
||||
// United States of America
|
||||
VehicleModel::LimitsInitList const kBicycleOptionsUS = {
|
||||
// Bridleway and pedesprian are allowed
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true}};
|
||||
|
||||
VehicleModel::SurfaceInitList const kBicycleSurface = {
|
||||
// {{surfaceType, surfaceType}, {weightFactor, etaFactor}}
|
||||
{{"psurface", "paved_good"}, {1.0, 1.0}},
|
||||
{{"psurface", "paved_bad"}, {0.8, 0.8}},
|
||||
{{"psurface", "unpaved_good"}, {1.0, 1.0}},
|
||||
{{"psurface", "unpaved_bad"}, {0.3, 0.3}}
|
||||
SurfaceFactors const kBicycleSurface = {
|
||||
// {SurfaceType, {weightFactor, etaFactor}}
|
||||
{SurfaceType::PavedGood, {1.0, 1.0}},
|
||||
{SurfaceType::PavedBad, {0.8, 0.8}},
|
||||
{SurfaceType::UnpavedGood, {1.0, 1.0}},
|
||||
{SurfaceType::UnpavedBad, {0.3, 0.3}}
|
||||
};
|
||||
|
||||
} // namespace bicycle_model
|
||||
|
||||
namespace routing
|
||||
{
|
||||
BicycleModel::BicycleModel()
|
||||
: VehicleModel(classif(), bicycle_model::kBicycleOptionsDefault, bicycle_model::kBicycleSurface,
|
||||
{bicycle_model::kDefaultSpeeds, bicycle_model::kDefaultFactors})
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
BicycleModel::BicycleModel(VehicleModel::LimitsInitList const & speedLimits)
|
||||
: VehicleModel(classif(), speedLimits, bicycle_model::kBicycleSurface, {bicycle_model::kDefaultSpeeds, bicycle_model::kDefaultFactors})
|
||||
BicycleModel::BicycleModel(HighwaySpeeds const & speeds)
|
||||
: VehicleModel(speeds, bicycle_model::kDefaultFactors, bicycle_model::kBicycleSurface)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
void BicycleModel::Init()
|
||||
{
|
||||
std::vector<std::string> hwtagYesBicycle = {"hwtag", "yesbicycle"};
|
||||
|
||||
auto const & cl = classif();
|
||||
m_yesBicycleType = cl.GetTypeByPath({"hwtag", "yesbicycle"});
|
||||
m_noBicycleType = cl.GetTypeByPath({"hwtag", "nobicycle"});
|
||||
m_yesBicycleType = cl.GetTypeByPath(hwtagYesBicycle);
|
||||
m_bidirBicycleType = cl.GetTypeByPath({"hwtag", "bidir_bicycle"});
|
||||
m_onedirBicycleType = cl.GetTypeByPath({"hwtag", "onedir_bicycle"});
|
||||
|
||||
AddAdditionalRoadTypes(cl, {
|
||||
{std::move(hwtagYesBicycle), m_maxModelSpeed},
|
||||
{{"route", "ferry"}, bicycle_model::kDefaultSpeeds.Get(HighwayType::RouteFerry)},
|
||||
{{"man_made", "pier"}, bicycle_model::kDefaultSpeeds.Get(HighwayType::ManMadePier)}
|
||||
});
|
||||
|
||||
// Small dismount speed with obvious inconvenience of a bike in hands.
|
||||
InOutCitySpeedKMpH const dismountSpeed(SpeedKMpH(2.0, 2.0));
|
||||
|
||||
/// @todo I suspect that 'highway-footway-bridge/tunnel' will not be processed properly ...
|
||||
AddAdditionalRoadTypes(cl, {
|
||||
{{"highway", "footway"}, dismountSpeed},
|
||||
{{"highway", "pedestrian"}, dismountSpeed},
|
||||
{{"highway", "steps"}, dismountSpeed}
|
||||
});
|
||||
}
|
||||
|
||||
VehicleModelInterface::RoadAvailability BicycleModel::GetRoadAvailability(feature::TypesHolder const & types) const
|
||||
VehicleModel::ResultT BicycleModel::IsOneWay(uint32_t type) const
|
||||
{
|
||||
if (types.Has(m_yesBicycleType))
|
||||
return RoadAvailability::Available;
|
||||
|
||||
if (types.Has(m_noBicycleType))
|
||||
return RoadAvailability::NotAvailable;
|
||||
|
||||
return RoadAvailability::Unknown;
|
||||
if (type == m_onedirBicycleType)
|
||||
return ResultT::Yes;
|
||||
else if (type == m_bidirBicycleType)
|
||||
return ResultT::No;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
bool BicycleModel::IsBicycleBidir(feature::TypesHolder const & types) const
|
||||
VehicleModel::ResultT BicycleModel::GetRoadAvailability(uint32_t type) const
|
||||
{
|
||||
return types.Has(m_bidirBicycleType);
|
||||
if (type == m_yesBicycleType)
|
||||
return ResultT::Yes;
|
||||
else if (type == m_noBicycleType)
|
||||
return ResultT::No;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
bool BicycleModel::IsBicycleOnedir(feature::TypesHolder const & types) const
|
||||
SpeedKMpH BicycleModel::GetSpeedForAvailable() const
|
||||
{
|
||||
return types.Has(m_onedirBicycleType);
|
||||
return m_maxModelSpeed.m_inCity;
|
||||
}
|
||||
|
||||
SpeedKMpH BicycleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const
|
||||
SpeedKMpH BicycleModel::GetOffroadSpeed() const
|
||||
{
|
||||
return VehicleModel::GetSpeedWihtoutMaxspeed(f, speedParams);
|
||||
return bicycle_model::kOffroadSpeed;
|
||||
}
|
||||
|
||||
bool BicycleModel::IsOneWay(FeatureType & f) const
|
||||
{
|
||||
feature::TypesHolder const types(f);
|
||||
|
||||
if (IsBicycleOnedir(types))
|
||||
return true;
|
||||
|
||||
if (IsBicycleBidir(types))
|
||||
return false;
|
||||
|
||||
return VehicleModel::IsOneWay(f);
|
||||
}
|
||||
|
||||
SpeedKMpH const & BicycleModel::GetOffroadSpeed() const { return bicycle_model::kSpeedOffroadKMpH; }
|
||||
|
||||
// If one of feature types will be disabled for bicycles, features of this type will be simplified
|
||||
// in generator. Look FeatureBuilder1::IsRoad() for more details.
|
||||
// static
|
||||
BicycleModel const & BicycleModel::AllLimitsInstance()
|
||||
{
|
||||
static BicycleModel const instance(bicycle_model::kBicycleOptionsAll);
|
||||
static BicycleModel const instance(bicycle_model::AllAllowed());
|
||||
return instance;
|
||||
}
|
||||
|
||||
BicycleModelFactory::BicycleModelFactory(
|
||||
CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
: VehicleModelFactory(countryParentNameGetterFn)
|
||||
BicycleModelFactory::BicycleModelFactory(CountryParentNameGetterFn const & parentGetter)
|
||||
: VehicleModelFactory(parentGetter)
|
||||
{
|
||||
using namespace bicycle_model;
|
||||
// Names must be the same with country names from countries.txt
|
||||
m_models[""] = make_shared<BicycleModel>(kBicycleOptionsDefault);
|
||||
m_models["Australia"] = make_shared<BicycleModel>(kBicycleOptionsAustralia);
|
||||
m_models["Austria"] = make_shared<BicycleModel>(kBicycleOptionsAustria);
|
||||
m_models["Belarus"] = make_shared<BicycleModel>(kBicycleOptionsBelarus);
|
||||
m_models["Belgium"] = make_shared<BicycleModel>(kBicycleOptionsBelgium);
|
||||
m_models["Brazil"] = make_shared<BicycleModel>(kBicycleOptionsBrazil);
|
||||
m_models["Denmark"] = make_shared<BicycleModel>(kBicycleOptionsDenmark);
|
||||
m_models["France"] = make_shared<BicycleModel>(kBicycleOptionsFrance);
|
||||
m_models["Finland"] = make_shared<BicycleModel>(kBicycleOptionsFinland);
|
||||
m_models["Germany"] = make_shared<BicycleModel>(kBicycleOptionsGermany);
|
||||
m_models["Hungary"] = make_shared<BicycleModel>(kBicycleOptionsHungary);
|
||||
m_models["Iceland"] = make_shared<BicycleModel>(kBicycleOptionsIceland);
|
||||
m_models["Netherlands"] = make_shared<BicycleModel>(kBicycleOptionsNetherlands);
|
||||
m_models["Norway"] = make_shared<BicycleModel>(kBicycleOptionsNorway);
|
||||
m_models["Oman"] = make_shared<BicycleModel>(kBicycleOptionsOman);
|
||||
m_models["Poland"] = make_shared<BicycleModel>(kBicycleOptionsPoland);
|
||||
m_models["Romania"] = make_shared<BicycleModel>(kBicycleOptionsRomania);
|
||||
m_models["Russian Federation"] = make_shared<BicycleModel>(kBicycleOptionsRussia);
|
||||
m_models["Slovakia"] = make_shared<BicycleModel>(kBicycleOptionsSlovakia);
|
||||
m_models["Spain"] = make_shared<BicycleModel>(kBicycleOptionsSpain);
|
||||
m_models["Switzerland"] = make_shared<BicycleModel>(kBicycleOptionsSwitzerland);
|
||||
m_models["Turkey"] = make_shared<BicycleModel>(kBicycleOptionsTurkey);
|
||||
m_models["Ukraine"] = make_shared<BicycleModel>(kBicycleOptionsUkraine);
|
||||
m_models["United Kingdom"] = make_shared<BicycleModel>(kBicycleOptionsUK);
|
||||
m_models["United States of America"] = make_shared<BicycleModel>(kBicycleOptionsUS);
|
||||
|
||||
m_models[""].reset(new BicycleModel(kDefaultSpeeds));
|
||||
m_models["Australia"].reset(new BicycleModel(AllAllowed()));
|
||||
m_models["Austria"].reset(new BicycleModel(AustriaSpeeds()));
|
||||
m_models["Belarus"].reset(new BicycleModel(PedestrianFootwayAllowed()));
|
||||
m_models["Belgium"].reset(new BicycleModel(BelgiumSpeeds()));
|
||||
m_models["Brazil"].reset(new BicycleModel(BrazilSpeeds()));
|
||||
m_models["Denmark"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["France"].reset(new BicycleModel(FranceSpeeds()));
|
||||
m_models["Finland"].reset(new BicycleModel(PedestrianAllowed()));
|
||||
m_models["Germany"].reset(new BicycleModel(kDefaultSpeeds));
|
||||
m_models["Hungary"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["Iceland"].reset(new BicycleModel(AllAllowed()));
|
||||
m_models["Netherlands"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["Norway"].reset(new BicycleModel(AllAllowed()));
|
||||
m_models["Oman"].reset(new BicycleModel(BridlewayAllowed()));
|
||||
m_models["Poland"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["Romania"].reset(new BicycleModel(NoTrunk()));
|
||||
|
||||
// Russian Federation
|
||||
// Footway and pedestrian are allowed
|
||||
// Note. Despite the fact that according to
|
||||
// https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions
|
||||
// passing through service and living_street with a bicycle is prohibited
|
||||
// it's allowed according to Russian traffic rules.
|
||||
m_models["Russian Federation"].reset(new BicycleModel(PedestrianFootwayAllowed()));
|
||||
|
||||
m_models["Slovakia"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["Spain"].reset(new BicycleModel(PedestrianAllowed()));
|
||||
m_models["Switzerland"].reset(new BicycleModel(NoTrunk()));
|
||||
m_models["Turkey"].reset(new BicycleModel(kDefaultSpeeds));
|
||||
m_models["Ukraine"].reset(new BicycleModel(UkraineSpeeds()));
|
||||
m_models["United Kingdom"].reset(new BicycleModel(BridlewayAllowed()));
|
||||
m_models["United States of America"].reset(new BicycleModel(USASpeeds()));
|
||||
}
|
||||
|
||||
} // routing
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing_common/vehicle_model.hpp"
|
||||
|
||||
namespace routing
|
||||
|
@ -7,39 +6,33 @@ namespace routing
|
|||
|
||||
class BicycleModel : public VehicleModel
|
||||
{
|
||||
explicit BicycleModel(HighwaySpeeds const & speeds);
|
||||
friend class BicycleModelFactory;
|
||||
|
||||
public:
|
||||
BicycleModel();
|
||||
BicycleModel(VehicleModel::LimitsInitList const & speedLimits);
|
||||
|
||||
/// VehicleModelInterface overrides:
|
||||
SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override;
|
||||
bool IsOneWay(FeatureType & f) const override;
|
||||
SpeedKMpH const & GetOffroadSpeed() const override;
|
||||
|
||||
static BicycleModel const & AllLimitsInstance();
|
||||
|
||||
/// @name VehicleModel overrides
|
||||
/// @{
|
||||
SpeedKMpH GetOffroadSpeed() const override;
|
||||
|
||||
protected:
|
||||
RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const override;
|
||||
ResultT IsOneWay(uint32_t type) const override;
|
||||
ResultT GetRoadAvailability(uint32_t type) const override;
|
||||
SpeedKMpH GetSpeedForAvailable() const override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
/// @return true if it is allowed to ride a bicycle in both directions.
|
||||
bool IsBicycleBidir(feature::TypesHolder const & types) const;
|
||||
// Returns true if the road is explicitly set oneway for bicycles.
|
||||
bool IsBicycleOnedir(feature::TypesHolder const & types) const;
|
||||
|
||||
uint32_t m_noBicycleType = 0;
|
||||
uint32_t m_yesBicycleType = 0;
|
||||
uint32_t m_bidirBicycleType = 0;
|
||||
uint32_t m_onedirBicycleType = 0;
|
||||
uint32_t m_noBicycleType;
|
||||
uint32_t m_yesBicycleType;
|
||||
uint32_t m_bidirBicycleType;
|
||||
uint32_t m_onedirBicycleType;
|
||||
};
|
||||
|
||||
class BicycleModelFactory : public VehicleModelFactory
|
||||
{
|
||||
public:
|
||||
// TODO: remove countryParentNameGetterFn default value after removing unused bicycle routing
|
||||
// from road_graph_router
|
||||
BicycleModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn = {});
|
||||
explicit BicycleModelFactory(CountryParentNameGetterFn const & parentGetter);
|
||||
};
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
#include "routing_common/car_model.hpp"
|
||||
#include "routing_common/car_model_coefs.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace car_model
|
||||
{
|
||||
using namespace std;
|
||||
|
@ -26,204 +18,94 @@ using namespace routing;
|
|||
// a start or finish. On the other hand, while route calculation the fake edges are considered
|
||||
// as quite heavy. The idea behind that is to use the closest edge for the start and the finish
|
||||
// of the route except for some edge cases.
|
||||
SpeedKMpH constexpr kSpeedOffroadKMpH = {0.01 /* weight */, kNotUsed /* eta */};
|
||||
SpeedKMpH constexpr kOffroadSpeed = {0.01 /* weight */, kNotUsed /* eta */};
|
||||
|
||||
VehicleModel::LimitsInitList const kCarOptionsDefault = {
|
||||
// {{roadType, roadType} passThroughAllowed}
|
||||
{{"highway", "motorway"}, true},
|
||||
{{"highway", "motorway_link"}, true},
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true}
|
||||
/// @todo: Add to classificator
|
||||
//{ {"highway", "shuttle_train"}, 10 },
|
||||
//{ {"highway", "ferry"}, 5 },
|
||||
//{ {"highway", "default"}, 10 },
|
||||
/// @todo: Check type
|
||||
//{ {"highway", "construction"}, 40 },
|
||||
};
|
||||
NoPassThroughHighways NoPassThroughLivingStreet()
|
||||
{
|
||||
return {HighwayType::HighwayLivingStreet};
|
||||
}
|
||||
|
||||
VehicleModel::LimitsInitList const kCarOptionsNoPassThroughLivingStreet = {
|
||||
{{"highway", "motorway"}, true},
|
||||
{{"highway", "motorway_link"}, true},
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "living_street"}, false},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true}};
|
||||
NoPassThroughHighways NoPassThroughLivingStreetAndService()
|
||||
{
|
||||
return {HighwayType::HighwayLivingStreet, HighwayType::HighwayService};
|
||||
}
|
||||
|
||||
VehicleModel::LimitsInitList const kCarOptionsNoPassThroughLivingStreetAndService = {
|
||||
{{"highway", "motorway"}, true},
|
||||
{{"highway", "motorway_link"}, true},
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "service"}, false},
|
||||
{{"highway", "living_street"}, false},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true}};
|
||||
HighwaySpeeds NoTrack()
|
||||
{
|
||||
HighwaySpeeds res = kHighwayBasedSpeeds;
|
||||
res.erase(HighwayType::HighwayTrack);
|
||||
return res;
|
||||
}
|
||||
|
||||
VehicleModel::LimitsInitList const kCarOptionsDenmark = {
|
||||
// No track
|
||||
{{"highway", "motorway"}, true},
|
||||
{{"highway", "motorway_link"}, true},
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "road"}, true}};
|
||||
NoPassThroughHighways NoPassThroughTrack()
|
||||
{
|
||||
return {HighwayType::HighwayTrack};
|
||||
}
|
||||
|
||||
VehicleModel::LimitsInitList const kCarOptionsGermany = {
|
||||
// No pass through track
|
||||
{{"highway", "motorway"}, true},
|
||||
{{"highway", "motorway_link"}, true},
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, false}};
|
||||
|
||||
VehicleModel::AdditionalRoadsList const kAdditionalRoads = {
|
||||
// {{highway tags}, {weightSpeed, etaSpeed}}
|
||||
{{"railway", "rail", "motor_vehicle"}, kHighwayBasedSpeeds.Get(HighwayType::RailwayRailMotorVehicle)},
|
||||
{{"route", "shuttle_train"}, kHighwayBasedSpeeds.Get(HighwayType::RouteShuttleTrain)},
|
||||
{{"route", "ferry"}, kHighwayBasedSpeeds.Get(HighwayType::RouteFerry)},
|
||||
{{"man_made", "pier"}, kHighwayBasedSpeeds.Get(HighwayType::ManMadePier)}};
|
||||
|
||||
VehicleModel::SurfaceInitList const kCarSurface = {
|
||||
// {{surfaceType, surfaceType}, {weightFactor, etaFactor}}
|
||||
{{"psurface", "paved_good"}, {1.0, 1.0}},
|
||||
{{"psurface", "paved_bad"}, {0.5, 0.5}},
|
||||
{{"psurface", "unpaved_good"}, {0.4, 0.8}},
|
||||
{{"psurface", "unpaved_bad"}, {0.1, 0.3}}
|
||||
};
|
||||
|
||||
// Names must be the same with country names from countries.txt
|
||||
std::unordered_map<char const *, VehicleModel::LimitsInitList> const kCarOptionsByCountries = {
|
||||
{"Austria", kCarOptionsNoPassThroughLivingStreet},
|
||||
{"Belarus", kCarOptionsNoPassThroughLivingStreet},
|
||||
{"Denmark", kCarOptionsDenmark},
|
||||
{"Germany", kCarOptionsGermany},
|
||||
{"Hungary", kCarOptionsNoPassThroughLivingStreet},
|
||||
{"Romania", kCarOptionsNoPassThroughLivingStreet},
|
||||
{"Russian Federation", kCarOptionsNoPassThroughLivingStreetAndService},
|
||||
{"Slovakia", kCarOptionsNoPassThroughLivingStreet},
|
||||
{"Ukraine", kCarOptionsNoPassThroughLivingStreetAndService}
|
||||
};
|
||||
} // namespace car_model
|
||||
|
||||
namespace routing
|
||||
{
|
||||
CarModel::CarModel()
|
||||
: VehicleModel(classif(), car_model::kCarOptionsDefault, car_model::kCarSurface,
|
||||
{kHighwayBasedSpeeds, kHighwayBasedFactors})
|
||||
|
||||
CarModel::CarModel(HighwaySpeeds const & speeds, NoPassThroughHighways const & noPassThrough)
|
||||
: VehicleModel(speeds, kHighwayBasedFactors, kHighwayBasedSurface, noPassThrough)
|
||||
{
|
||||
Init();
|
||||
auto const & cl = classif();
|
||||
m_noCarType = cl.GetTypeByPath({"hwtag", "nocar"});
|
||||
m_yesCarType = cl.GetTypeByPath({"hwtag", "yescar"});
|
||||
m_onewayType = cl.GetTypeByPath({"hwtag", "oneway"});
|
||||
}
|
||||
|
||||
CarModel::CarModel(VehicleModel::LimitsInitList const & roadLimits, HighwayBasedInfo const & info)
|
||||
: VehicleModel(classif(), roadLimits, car_model::kCarSurface, info)
|
||||
SpeedKMpH CarModel::GetOffroadSpeed() const
|
||||
{
|
||||
Init();
|
||||
return car_model::kOffroadSpeed;
|
||||
}
|
||||
|
||||
SpeedKMpH const & CarModel::GetOffroadSpeed() const { return car_model::kSpeedOffroadKMpH; }
|
||||
|
||||
void CarModel::Init()
|
||||
VehicleModel::ResultT CarModel::IsOneWay(uint32_t type) const
|
||||
{
|
||||
m_noCarType = classif().GetTypeByPath({"hwtag", "nocar"});
|
||||
m_yesCarType = classif().GetTypeByPath({"hwtag", "yescar"});
|
||||
|
||||
AddAdditionalRoadTypes(classif(), car_model::kAdditionalRoads);
|
||||
if (type == m_onewayType)
|
||||
return ResultT::Yes;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
VehicleModelInterface::RoadAvailability CarModel::GetRoadAvailability(feature::TypesHolder const & types) const
|
||||
VehicleModel::ResultT CarModel::GetRoadAvailability(uint32_t type) const
|
||||
{
|
||||
if (types.Has(m_yesCarType))
|
||||
return RoadAvailability::Available;
|
||||
if (type == m_yesCarType)
|
||||
return ResultT::Yes;
|
||||
else if (type == m_noCarType)
|
||||
return ResultT::No;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
if (types.Has(m_noCarType))
|
||||
return RoadAvailability::NotAvailable;
|
||||
|
||||
return RoadAvailability::Unknown;
|
||||
SpeedKMpH CarModel::GetSpeedForAvailable() const
|
||||
{
|
||||
/// @todo Return 20% from maximun model speed.
|
||||
return m_maxModelSpeed.m_inCity * 0.2;
|
||||
}
|
||||
|
||||
// static
|
||||
CarModel const & CarModel::AllLimitsInstance()
|
||||
{
|
||||
static CarModel const instance;
|
||||
static CarModel const instance(kHighwayBasedSpeeds);
|
||||
return instance;
|
||||
}
|
||||
|
||||
// static
|
||||
VehicleModel::LimitsInitList const & CarModel::GetOptions() { return car_model::kCarOptionsDefault; }
|
||||
|
||||
// static
|
||||
VehicleModel::AdditionalRoadsList const & CarModel::GetAdditionalRoads()
|
||||
{
|
||||
return car_model::kAdditionalRoads;
|
||||
}
|
||||
|
||||
// static
|
||||
VehicleModel::SurfaceInitList const & CarModel::GetSurfaces() { return car_model::kCarSurface; }
|
||||
|
||||
CarModelFactory::CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
: VehicleModelFactory(countryParentNameGetterFn)
|
||||
{
|
||||
m_models[""] = std::make_shared<CarModel>(
|
||||
car_model::kCarOptionsDefault,
|
||||
HighwayBasedInfo(kHighwayBasedSpeeds, kHighwayBasedFactors));
|
||||
using namespace car_model;
|
||||
// Names must be the same with country names from countries.txt
|
||||
|
||||
for (auto const & kv : car_model::kCarOptionsByCountries)
|
||||
{
|
||||
auto const * country = kv.first;
|
||||
auto const & limit = kv.second;
|
||||
m_models[country] =
|
||||
std::make_shared<CarModel>(limit, HighwayBasedInfo(kHighwayBasedSpeeds, kHighwayBasedFactors));
|
||||
}
|
||||
m_models[""].reset(new CarModel(kHighwayBasedSpeeds));
|
||||
m_models["Austria"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreet()));
|
||||
m_models["Belarus"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreet()));
|
||||
m_models["Denmark"].reset(new CarModel(NoTrack()));
|
||||
m_models["Germany"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughTrack()));
|
||||
m_models["Hungary"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreet()));
|
||||
m_models["Romania"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreet()));
|
||||
m_models["Russian Federation"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreetAndService()));
|
||||
m_models["Slovakia"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreet()));
|
||||
m_models["Ukraine"].reset(new CarModel(kHighwayBasedSpeeds, NoPassThroughLivingStreetAndService()));
|
||||
}
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -9,34 +9,31 @@ namespace routing
|
|||
|
||||
class CarModel : public VehicleModel
|
||||
{
|
||||
explicit CarModel(HighwaySpeeds const & speeds, NoPassThroughHighways const & noPassThrough = {});
|
||||
friend class CarModelFactory;
|
||||
|
||||
public:
|
||||
CarModel();
|
||||
CarModel(LimitsInitList const & roadLimits, HighwayBasedInfo const & info);
|
||||
|
||||
// VehicleModelInterface overrides:
|
||||
SpeedKMpH const & GetOffroadSpeed() const override;
|
||||
|
||||
static CarModel const & AllLimitsInstance();
|
||||
static LimitsInitList const & GetOptions();
|
||||
static AdditionalRoadsList const & GetAdditionalRoads();
|
||||
static SurfaceInitList const & GetSurfaces();
|
||||
|
||||
uint32_t GetNoCarTypeForTesting() const { return m_noCarType; }
|
||||
uint32_t GetYesCarTypeForTesting() const { return m_yesCarType; }
|
||||
/// @name VehicleModelInterface overrides
|
||||
/// @{
|
||||
SpeedKMpH GetOffroadSpeed() const override;
|
||||
|
||||
protected:
|
||||
RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const override;
|
||||
ResultT IsOneWay(uint32_t type) const override;
|
||||
ResultT GetRoadAvailability(uint32_t type) const override;
|
||||
SpeedKMpH GetSpeedForAvailable() const override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
uint32_t m_noCarType = 0;
|
||||
uint32_t m_yesCarType = 0;
|
||||
uint32_t m_onewayType = 0;
|
||||
};
|
||||
|
||||
class CarModelFactory : public VehicleModelFactory
|
||||
{
|
||||
public:
|
||||
CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterF);
|
||||
explicit CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterF);
|
||||
};
|
||||
} // namespace routing
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace routing
|
|||
* There are no (99%) traffic lights or pedestrian crossings on this kind of roads.
|
||||
*/
|
||||
|
||||
HighwayBasedFactors const kHighwayBasedFactors = {
|
||||
HighwayFactors const kHighwayBasedFactors = {
|
||||
// {highway class : InOutCityFactor(in city, out city)}
|
||||
{HighwayType::HighwayLivingStreet, InOutCityFactor(0.75)},
|
||||
{HighwayType::HighwayMotorway, InOutCityFactor(0.90, 0.94)},
|
||||
|
@ -36,7 +36,7 @@ HighwayBasedFactors const kHighwayBasedFactors = {
|
|||
{HighwayType::RouteShuttleTrain, InOutCityFactor(0.90)},
|
||||
};
|
||||
|
||||
HighwayBasedSpeeds const kHighwayBasedSpeeds = {
|
||||
HighwaySpeeds const kHighwayBasedSpeeds = {
|
||||
// {highway class : InOutCitySpeedKMpH(in city, out city)}
|
||||
{HighwayType::HighwayLivingStreet, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)},
|
||||
{HighwayType::HighwayMotorway, InOutCitySpeedKMpH(118.0 /* in city */, 124.0 /* out city */)},
|
||||
|
@ -59,4 +59,13 @@ HighwayBasedSpeeds const kHighwayBasedSpeeds = {
|
|||
{HighwayType::RouteFerry, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)},
|
||||
{HighwayType::RouteShuttleTrain, InOutCitySpeedKMpH({25.00, 25.00} /* in city */, {25.00, 25.00} /* out city */)},
|
||||
};
|
||||
|
||||
SurfaceFactors const kHighwayBasedSurface = {
|
||||
// {surfaceType, {weightFactor, etaFactor}}
|
||||
{SurfaceType::PavedGood, {1.0, 1.0}},
|
||||
{SurfaceType::PavedBad, {0.5, 0.5}},
|
||||
{SurfaceType::UnpavedGood, {0.4, 0.8}},
|
||||
{SurfaceType::UnpavedBad, {0.1, 0.3}}
|
||||
};
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -1,17 +1,11 @@
|
|||
#include "routing_common/pedestrian_model.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/macros.hpp"
|
||||
#include "base/logging.hpp"
|
||||
|
||||
using namespace routing;
|
||||
using namespace std;
|
||||
|
||||
namespace pedestrian_model
|
||||
{
|
||||
using namespace routing;
|
||||
|
||||
// See model specifics in different countries here:
|
||||
// https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions
|
||||
// Document contains proposals for some countries, but we assume that some kinds of roads are ready for pedestrian routing,
|
||||
|
@ -28,9 +22,9 @@ namespace pedestrian_model
|
|||
// As result of such heuristic road is not totally the shortest, but it avoids non pedestrian roads, which were
|
||||
// not marked as "foot=no" in OSM.
|
||||
|
||||
HighwayBasedFactors const kDefaultFactors = GetOneFactorsForBicycleAndPedestrianModel();
|
||||
HighwayFactors const kDefaultFactors = GetOneFactorsForBicycleAndPedestrianModel();
|
||||
|
||||
HighwayBasedSpeeds const kDefaultSpeeds = {
|
||||
HighwaySpeeds const kAllSpeeds = {
|
||||
// {highway class : InOutCitySpeedKMpH(in city(weight, eta), out city(weight eta))}
|
||||
{HighwayType::HighwayTrunk, InOutCitySpeedKMpH(SpeedKMpH(1.0, 5.0))},
|
||||
{HighwayType::HighwayTrunkLink, InOutCitySpeedKMpH(SpeedKMpH(1.0, 5.0))},
|
||||
|
@ -57,262 +51,93 @@ HighwayBasedSpeeds const kDefaultSpeeds = {
|
|||
{HighwayType::RouteFerry, InOutCitySpeedKMpH(SpeedKMpH(3.0, 20.0))},
|
||||
};
|
||||
|
||||
SpeedKMpH constexpr kSpeedOffroadKMpH = {3.0 /* weight */, 3.0 /* eta */};
|
||||
SpeedKMpH constexpr kOffroadSpeed = {3.0 /* weight */, 3.0 /* eta */};
|
||||
|
||||
// Default
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsDefault = {
|
||||
// {{roadType, roadType} passThroughAllowed}
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
|
||||
// All options available.
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsAll = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
// Default (No bridleway, no cycleway).
|
||||
HighwaySpeeds DefaultSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = kAllSpeeds;
|
||||
res.erase(HighwayType::HighwayBridleway);
|
||||
res.erase(HighwayType::HighwayCycleway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except trunk and trunk link are not allowed.
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsNoTrunk = {
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
HighwaySpeeds NoTrunk()
|
||||
{
|
||||
HighwaySpeeds res = DefaultSpeeds();
|
||||
res.erase(HighwayType::HighwayTrunk);
|
||||
res.erase(HighwayType::HighwayTrunkLink);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except cycleway is allowed.
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsCyclewayAllowed = {
|
||||
{{"highway", "trunk"}, true},
|
||||
{{"highway", "trunk_link"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
HighwaySpeeds AllowCycleway()
|
||||
{
|
||||
HighwaySpeeds res = DefaultSpeeds();
|
||||
res[HighwayType::HighwayCycleway] = kAllSpeeds.at(HighwayType::HighwayCycleway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Same as defaults except cycleway is allowed and trunk and trunk_link are not allowed.
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsCyclewayAllowedNoTrunk = {
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
|
||||
// Australia
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsAustralia = kPedestrianOptionsAll;
|
||||
|
||||
// Austria
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsAustria = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Belarus
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsBelarus = kPedestrianOptionsCyclewayAllowed;
|
||||
HighwaySpeeds AllowCyclewayNoTrunk()
|
||||
{
|
||||
HighwaySpeeds res = NoTrunk();
|
||||
res[HighwayType::HighwayCycleway] = kAllSpeeds.at(HighwayType::HighwayCycleway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Belgium
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsBelgium = {
|
||||
// Trunk and trunk_link are not allowed
|
||||
// Bridleway and cycleway are allowed
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "primary_link"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "secondary_link"}, true},
|
||||
{{"highway", "tertiary"}, true},
|
||||
{{"highway", "tertiary_link"}, true},
|
||||
{{"highway", "service"}, true},
|
||||
{{"highway", "unclassified"}, true},
|
||||
{{"highway", "road"}, true},
|
||||
{{"highway", "track"}, true},
|
||||
{{"highway", "path"}, true},
|
||||
{{"highway", "bridleway"}, true},
|
||||
{{"highway", "cycleway"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "living_street"}, true},
|
||||
{{"highway", "steps"}, true},
|
||||
{{"highway", "pedestrian"}, true},
|
||||
{{"highway", "footway"}, true}};
|
||||
// Trunk and trunk_link are not allowed
|
||||
// Bridleway and cycleway are allowed
|
||||
HighwaySpeeds BelgiumSpeeds()
|
||||
{
|
||||
HighwaySpeeds res = AllowCyclewayNoTrunk();
|
||||
res[HighwayType::HighwayBridleway] = kAllSpeeds.at(HighwayType::HighwayBridleway);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Brazil
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsBrazil = kPedestrianOptionsAll;
|
||||
|
||||
// Denmark
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsDenmark = kPedestrianOptionsCyclewayAllowedNoTrunk;
|
||||
|
||||
// France
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsFrance = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Finland
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsFinland = kPedestrianOptionsCyclewayAllowed;
|
||||
|
||||
// Germany
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsGermany = kPedestrianOptionsDefault;
|
||||
|
||||
// Hungary
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsHungary = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Iceland
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsIceland = kPedestrianOptionsAll;
|
||||
|
||||
// Netherlands
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsNetherlands = kPedestrianOptionsCyclewayAllowedNoTrunk;
|
||||
|
||||
// Norway
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsNorway = kPedestrianOptionsAll;
|
||||
|
||||
// Oman
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsOman = kPedestrianOptionsAll;
|
||||
|
||||
// Poland
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsPoland = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Romania
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsRomania = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Russian Federation
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsRussia = kPedestrianOptionsCyclewayAllowed;
|
||||
|
||||
// Slovakia
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsSlovakia = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Spain
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsSpain = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Switzerland
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsSwitzerland = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// Turkey
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsTurkey = kPedestrianOptionsAll;
|
||||
|
||||
// Ukraine
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsUkraine = kPedestrianOptionsNoTrunk;
|
||||
|
||||
// United Kingdom
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsUK = kPedestrianOptionsAll;
|
||||
|
||||
// United States of America
|
||||
VehicleModel::LimitsInitList const kPedestrianOptionsUS = kPedestrianOptionsAll;
|
||||
|
||||
VehicleModel::SurfaceInitList const kPedestrianSurface = {
|
||||
// {{surfaceType, surfaceType}, {weightFactor, etaFactor}}
|
||||
{{"psurface", "paved_good"}, {1.0, 1.0}},
|
||||
{{"psurface", "paved_bad"}, {1.0, 1.0}},
|
||||
{{"psurface", "unpaved_good"}, {1.0, 1.0}},
|
||||
{{"psurface", "unpaved_bad"}, {0.8, 0.8}}
|
||||
SurfaceFactors const kPedestrianSurface = {
|
||||
// {SurfaceType, {weightFactor, etaFactor}}
|
||||
{SurfaceType::PavedGood, {1.0, 1.0}},
|
||||
{SurfaceType::PavedBad, {1.0, 1.0}},
|
||||
{SurfaceType::UnpavedGood, {1.0, 1.0}},
|
||||
{SurfaceType::UnpavedBad, {0.8, 0.8}}
|
||||
};
|
||||
|
||||
} // namespace pedestrian_model
|
||||
|
||||
namespace routing
|
||||
{
|
||||
PedestrianModel::PedestrianModel()
|
||||
: VehicleModel(classif(), pedestrian_model::kPedestrianOptionsDefault, pedestrian_model::kPedestrianSurface,
|
||||
{pedestrian_model::kDefaultSpeeds, pedestrian_model::kDefaultFactors})
|
||||
PedestrianModel::PedestrianModel(HighwaySpeeds const & speeds)
|
||||
: VehicleModel(speeds, pedestrian_model::kDefaultFactors, pedestrian_model::kPedestrianSurface)
|
||||
{
|
||||
Init();
|
||||
m_noFootType = classif().GetTypeByPath({"hwtag", "nofoot"});
|
||||
m_yesFootType = classif().GetTypeByPath({"hwtag", "yesfoot"});
|
||||
}
|
||||
|
||||
PedestrianModel::PedestrianModel(VehicleModel::LimitsInitList const & speedLimits)
|
||||
: VehicleModel(classif(), speedLimits, pedestrian_model::kPedestrianSurface,
|
||||
{pedestrian_model::kDefaultSpeeds, pedestrian_model::kDefaultFactors})
|
||||
SpeedKMpH PedestrianModel::GetOffroadSpeed() const
|
||||
{
|
||||
Init();
|
||||
return pedestrian_model::kOffroadSpeed;
|
||||
}
|
||||
|
||||
SpeedKMpH PedestrianModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const
|
||||
VehicleModel::ResultT PedestrianModel::IsOneWay(uint32_t) const
|
||||
{
|
||||
return VehicleModel::GetSpeedWihtoutMaxspeed(f, speedParams);
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
SpeedKMpH const & PedestrianModel::GetOffroadSpeed() const { return pedestrian_model::kSpeedOffroadKMpH; }
|
||||
|
||||
void PedestrianModel::Init()
|
||||
VehicleModel::ResultT PedestrianModel::GetRoadAvailability(uint32_t type) const
|
||||
{
|
||||
std::vector<std::string> hwtagYesFoot = {"hwtag", "yesfoot"};
|
||||
|
||||
m_noFootType = classif().GetTypeByPath({ "hwtag", "nofoot" });
|
||||
m_yesFootType = classif().GetTypeByPath(hwtagYesFoot);
|
||||
|
||||
AddAdditionalRoadTypes(classif(), {
|
||||
{std::move(hwtagYesFoot), m_maxModelSpeed},
|
||||
{{"route", "ferry"}, pedestrian_model::kDefaultSpeeds.Get(HighwayType::RouteFerry)},
|
||||
{{"man_made", "pier"}, pedestrian_model::kDefaultSpeeds.Get(HighwayType::ManMadePier)}
|
||||
});
|
||||
if (type == m_yesFootType)
|
||||
return ResultT::Yes;
|
||||
else if (type == m_noFootType)
|
||||
return ResultT::No;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
VehicleModelInterface::RoadAvailability PedestrianModel::GetRoadAvailability(feature::TypesHolder const & types) const
|
||||
SpeedKMpH PedestrianModel::GetSpeedForAvailable() const
|
||||
{
|
||||
if (types.Has(m_yesFootType))
|
||||
return RoadAvailability::Available;
|
||||
|
||||
if (types.Has(m_noFootType))
|
||||
return RoadAvailability::NotAvailable;
|
||||
|
||||
return RoadAvailability::Unknown;
|
||||
return m_maxModelSpeed.m_inCity;
|
||||
}
|
||||
|
||||
// If one of feature types will be disabled for pedestrian, features of this type will be simplyfied
|
||||
|
@ -320,40 +145,41 @@ VehicleModelInterface::RoadAvailability PedestrianModel::GetRoadAvailability(fea
|
|||
// static
|
||||
PedestrianModel const & PedestrianModel::AllLimitsInstance()
|
||||
{
|
||||
static PedestrianModel const instance(pedestrian_model::kPedestrianOptionsAll);
|
||||
static PedestrianModel const instance(pedestrian_model::kAllSpeeds);
|
||||
return instance;
|
||||
}
|
||||
|
||||
PedestrianModelFactory::PedestrianModelFactory(
|
||||
CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
: VehicleModelFactory(countryParentNameGetterFn)
|
||||
PedestrianModelFactory::PedestrianModelFactory(CountryParentNameGetterFn const & parentGetter)
|
||||
: VehicleModelFactory(parentGetter)
|
||||
{
|
||||
using namespace pedestrian_model;
|
||||
// Names must be the same with country names from countries.txt
|
||||
m_models[""] = make_shared<PedestrianModel>(kPedestrianOptionsDefault);
|
||||
m_models["Australia"] = make_shared<PedestrianModel>(kPedestrianOptionsAustralia);
|
||||
m_models["Austria"] = make_shared<PedestrianModel>(kPedestrianOptionsAustria);
|
||||
m_models["Belarus"] = make_shared<PedestrianModel>(kPedestrianOptionsBelarus);
|
||||
m_models["Belgium"] = make_shared<PedestrianModel>(kPedestrianOptionsBelgium);
|
||||
m_models["Brazil"] = make_shared<PedestrianModel>(kPedestrianOptionsBrazil);
|
||||
m_models["Denmark"] = make_shared<PedestrianModel>(kPedestrianOptionsDenmark);
|
||||
m_models["France"] = make_shared<PedestrianModel>(kPedestrianOptionsFrance);
|
||||
m_models["Finland"] = make_shared<PedestrianModel>(kPedestrianOptionsFinland);
|
||||
m_models["Germany"] = make_shared<PedestrianModel>(kPedestrianOptionsGermany);
|
||||
m_models["Hungary"] = make_shared<PedestrianModel>(kPedestrianOptionsHungary);
|
||||
m_models["Iceland"] = make_shared<PedestrianModel>(kPedestrianOptionsIceland);
|
||||
m_models["Netherlands"] = make_shared<PedestrianModel>(kPedestrianOptionsNetherlands);
|
||||
m_models["Norway"] = make_shared<PedestrianModel>(kPedestrianOptionsNorway);
|
||||
m_models["Oman"] = make_shared<PedestrianModel>(kPedestrianOptionsOman);
|
||||
m_models["Poland"] = make_shared<PedestrianModel>(kPedestrianOptionsPoland);
|
||||
m_models["Romania"] = make_shared<PedestrianModel>(kPedestrianOptionsRomania);
|
||||
m_models["Russian Federation"] = make_shared<PedestrianModel>(kPedestrianOptionsRussia);
|
||||
m_models["Slovakia"] = make_shared<PedestrianModel>(kPedestrianOptionsSlovakia);
|
||||
m_models["Spain"] = make_shared<PedestrianModel>(kPedestrianOptionsSpain);
|
||||
m_models["Switzerland"] = make_shared<PedestrianModel>(kPedestrianOptionsSwitzerland);
|
||||
m_models["Turkey"] = make_shared<PedestrianModel>(kPedestrianOptionsTurkey);
|
||||
m_models["Ukraine"] = make_shared<PedestrianModel>(kPedestrianOptionsUkraine);
|
||||
m_models["United Kingdom"] = make_shared<PedestrianModel>(kPedestrianOptionsUK);
|
||||
m_models["United States of America"] = make_shared<PedestrianModel>(kPedestrianOptionsUS);
|
||||
|
||||
m_models[""].reset(new PedestrianModel(DefaultSpeeds()));
|
||||
m_models["Australia"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Austria"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Belarus"].reset(new PedestrianModel(AllowCycleway()));
|
||||
m_models["Belgium"].reset(new PedestrianModel(BelgiumSpeeds()));
|
||||
m_models["Brazil"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Denmark"].reset(new PedestrianModel(AllowCyclewayNoTrunk()));
|
||||
m_models["France"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Finland"].reset(new PedestrianModel(AllowCycleway()));
|
||||
m_models["Germany"].reset(new PedestrianModel(DefaultSpeeds()));
|
||||
m_models["Hungary"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Iceland"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Netherlands"].reset(new PedestrianModel(AllowCyclewayNoTrunk()));
|
||||
m_models["Norway"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Oman"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Poland"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Romania"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Russian Federation"].reset(new PedestrianModel(AllowCycleway()));
|
||||
m_models["Slovakia"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Spain"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Switzerland"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["Turkey"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["Ukraine"].reset(new PedestrianModel(NoTrunk()));
|
||||
m_models["United Kingdom"].reset(new PedestrianModel(kAllSpeeds));
|
||||
m_models["United States of America"].reset(new PedestrianModel(kAllSpeeds));
|
||||
}
|
||||
|
||||
} // routing
|
||||
|
|
|
@ -7,23 +7,23 @@ namespace routing
|
|||
|
||||
class PedestrianModel : public VehicleModel
|
||||
{
|
||||
explicit PedestrianModel(HighwaySpeeds const & speeds);
|
||||
friend class PedestrianModelFactory;
|
||||
|
||||
public:
|
||||
PedestrianModel();
|
||||
PedestrianModel(VehicleModel::LimitsInitList const & speedLimits);
|
||||
|
||||
/// VehicleModelInterface overrides:
|
||||
SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override;
|
||||
bool IsOneWay(FeatureType &) const override { return false; }
|
||||
SpeedKMpH const & GetOffroadSpeed() const override;
|
||||
|
||||
static PedestrianModel const & AllLimitsInstance();
|
||||
|
||||
/// @name VehicleModelInterface overrides
|
||||
/// @{
|
||||
SpeedKMpH GetOffroadSpeed() const override;
|
||||
|
||||
protected:
|
||||
RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const override;
|
||||
ResultT IsOneWay(uint32_t type) const override;
|
||||
ResultT GetRoadAvailability(uint32_t type) const override;
|
||||
SpeedKMpH GetSpeedForAvailable() const override;
|
||||
/// @}
|
||||
|
||||
private:
|
||||
void Init();
|
||||
|
||||
uint32_t m_noFootType = 0;
|
||||
uint32_t m_yesFootType = 0;
|
||||
};
|
||||
|
@ -31,8 +31,7 @@ private:
|
|||
class PedestrianModelFactory : public VehicleModelFactory
|
||||
{
|
||||
public:
|
||||
// TODO: remove countryParentNameGetterFn default value after removing unused pedestrian routing
|
||||
// from road_graph_router
|
||||
PedestrianModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn = {});
|
||||
explicit PedestrianModelFactory(CountryParentNameGetterFn const & parentGetter);
|
||||
};
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -39,15 +39,12 @@ string GetRegionParent(string const & id)
|
|||
template <typename VehicleModelType, typename VehicleModelFactoryType>
|
||||
void TestVehicleModelDefault()
|
||||
{
|
||||
auto defaultVehicleModel = make_shared<VehicleModelType>();
|
||||
|
||||
VehicleModelFactoryType vehicleModelFactory = VehicleModelFactoryType(GetRegionParent);
|
||||
|
||||
// Use static_pointer_cast here because VehicleModelInterface do not have EqualsForTests method
|
||||
shared_ptr<VehicleModelType> defaultVehicleModelForCountry = static_pointer_cast<VehicleModelType>(
|
||||
vehicleModelFactory.GetVehicleModelForCountry("Nonexistent Country Name"));
|
||||
TEST(defaultVehicleModel->EqualsForTests(*defaultVehicleModelForCountry),
|
||||
("Vehicle model for nonexistent counry is not equal to default."));
|
||||
VehicleModelFactoryType(GetRegionParent).GetVehicleModelForCountry("Nonexistent Country Name"));
|
||||
|
||||
TEST(VehicleModelType::AllLimitsInstance().EqualsForTests(*defaultVehicleModelForCountry),
|
||||
("Vehicle model for nonexistent country is not equal to default."));
|
||||
}
|
||||
|
||||
// DirectParent and IndirectParent tests require tested countries to have nondefault restriction
|
||||
|
@ -55,17 +52,14 @@ void TestVehicleModelDefault()
|
|||
template <typename VehicleModelType, typename VehicleModelFactoryType>
|
||||
void TestHaveNondefaultRestrictionForSelectedCountry(string country)
|
||||
{
|
||||
auto defaultVehicleModel = make_shared<VehicleModelType>();
|
||||
auto const & defaultVehicleModel = VehicleModelType::AllLimitsInstance();
|
||||
|
||||
VehicleModelFactoryType vehicleModelFactory = VehicleModelFactoryType(GetRegionParent);
|
||||
|
||||
shared_ptr<VehicleModelType> vehicleModelCountry =
|
||||
static_pointer_cast<VehicleModelType>(vehicleModelFactory.GetVehicleModelForCountry(country));
|
||||
|
||||
TEST(!(vehicleModelCountry->EqualsForTests(*defaultVehicleModel)),
|
||||
(country,
|
||||
"has default model. It may be ok if traffic restrictions was changed. "
|
||||
"If so, select other country for this and next test."));
|
||||
TEST(!defaultVehicleModel.EqualsForTests(*vehicleModelCountry), (country));
|
||||
}
|
||||
|
||||
template <typename VehicleModelType, typename VehicleModelFactoryType>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace vehicle_model_test
|
|||
using namespace routing;
|
||||
using namespace std;
|
||||
|
||||
HighwayBasedSpeeds const kDefaultSpeeds = {
|
||||
HighwaySpeeds const kDefaultSpeeds = {
|
||||
{HighwayType::HighwayTrunk, InOutCitySpeedKMpH(100.0 /* in city */, 150.0 /* out city */)},
|
||||
{HighwayType::HighwayPrimary, InOutCitySpeedKMpH(90.0 /* in city */, 120.0 /* out city */)},
|
||||
{HighwayType::HighwaySecondary,
|
||||
|
@ -31,25 +31,24 @@ HighwayBasedSpeeds const kDefaultSpeeds = {
|
|||
SpeedKMpH(50.0 /* weight */, 60.0 /* eta */) /* out city */)},
|
||||
{HighwayType::HighwayService,
|
||||
InOutCitySpeedKMpH(SpeedKMpH(47.0 /* weight */, 36.0 /* eta */) /* in city */,
|
||||
SpeedKMpH(50.0 /* weight */, 40.0 /* eta */) /* out city */)}};
|
||||
SpeedKMpH(50.0 /* weight */, 40.0 /* eta */) /* out city */)}
|
||||
};
|
||||
|
||||
HighwayBasedFactors const kDefaultFactors = {
|
||||
HighwayFactors const kDefaultFactors = {
|
||||
{HighwayType::HighwayTrunk, InOutCityFactor(1.0)},
|
||||
{HighwayType::HighwayPrimary, InOutCityFactor(1.0)},
|
||||
{HighwayType::HighwaySecondary, InOutCityFactor(1.0)},
|
||||
{HighwayType::HighwayResidential, InOutCityFactor(0.5)}};
|
||||
{HighwayType::HighwayResidential, InOutCityFactor(0.5)}
|
||||
};
|
||||
|
||||
VehicleModel::LimitsInitList const kTestLimits = {{{"highway", "trunk"}, true},
|
||||
{{"highway", "primary"}, true},
|
||||
{{"highway", "secondary"}, true},
|
||||
{{"highway", "residential"}, true},
|
||||
{{"highway", "service"}, false}};
|
||||
NoPassThroughHighways const kTestLimits = {HighwayType::HighwayService};
|
||||
|
||||
VehicleModel::SurfaceInitList const kCarSurface = {
|
||||
{{"psurface", "paved_good"}, {0.8 /* weightFactor */, 0.9 /* etaFactor */}},
|
||||
{{"psurface", "paved_bad"}, {0.4, 0.5}},
|
||||
{{"psurface", "unpaved_good"}, {0.6, 0.8}},
|
||||
{{"psurface", "unpaved_bad"}, {0.2, 0.2}}};
|
||||
SurfaceFactors const kCarSurface = {
|
||||
{SurfaceType::PavedGood, {0.8 /* weightFactor */, 0.9 /* etaFactor */}},
|
||||
{SurfaceType::PavedBad, {0.4, 0.5}},
|
||||
{SurfaceType::UnpavedGood, {0.6, 0.8}},
|
||||
{SurfaceType::UnpavedBad, {0.2, 0.2}}
|
||||
};
|
||||
|
||||
class VehicleModelTest
|
||||
{
|
||||
|
@ -62,23 +61,42 @@ class TestVehicleModel : public VehicleModel
|
|||
friend void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue);
|
||||
friend void CheckPassThroughAllowed(initializer_list<uint32_t> const & types, bool expectedValue);
|
||||
friend void CheckSpeedWithParams(initializer_list<uint32_t> const & types,
|
||||
SpeedParams const & params, SpeedKMpH const & expectedSpeed);
|
||||
Request const & request, SpeedKMpH const & expectedSpeed);
|
||||
|
||||
public:
|
||||
TestVehicleModel()
|
||||
: VehicleModel(classif(), kTestLimits, kCarSurface, {kDefaultSpeeds, kDefaultFactors})
|
||||
: VehicleModel(kDefaultSpeeds, kDefaultFactors, kCarSurface, kTestLimits)
|
||||
{
|
||||
m_oneway = classif().GetTypeByPath({"hwtag", "oneway"});
|
||||
}
|
||||
|
||||
// We are not going to use offroad routing in these tests.
|
||||
SpeedKMpH const & GetOffroadSpeed() const override { return kDummy; }
|
||||
SpeedKMpH GetOffroadSpeed() const override { return kDummy; }
|
||||
|
||||
protected:
|
||||
ResultT IsOneWay(uint32_t type) const override
|
||||
{
|
||||
if (type == m_oneway)
|
||||
return ResultT::Yes;
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
ResultT GetRoadAvailability(uint32_t type) const override
|
||||
{
|
||||
return ResultT::Unknown;
|
||||
}
|
||||
|
||||
SpeedKMpH GetSpeedForAvailable() const override
|
||||
{
|
||||
TEST(false, ());
|
||||
return kDummy;
|
||||
}
|
||||
|
||||
private:
|
||||
static SpeedKMpH const kDummy;
|
||||
uint32_t m_oneway;
|
||||
SpeedKMpH const kDummy = {0.0 /* weight */, 0.0 /* eta */};
|
||||
};
|
||||
|
||||
SpeedKMpH const TestVehicleModel::kDummy = {0.0 /* weight */, 0.0 /* eta */};
|
||||
|
||||
uint32_t GetType(char const * s0, char const * s1 = 0, char const * s2 = 0)
|
||||
{
|
||||
char const * const t[] = {s0, s1, s2};
|
||||
|
@ -91,23 +109,24 @@ uint32_t GetOnewayType()
|
|||
return GetType("hwtag", "oneway");
|
||||
}
|
||||
|
||||
void CheckSpeedWithParams(initializer_list<uint32_t> const & types, SpeedParams const & params,
|
||||
SpeedKMpH const & expectedSpeed)
|
||||
void CheckSpeedWithParams(initializer_list<uint32_t> const & types, VehicleModel::Request const & request,
|
||||
SpeedKMpH const & expectedForward, SpeedKMpH const & expectedBackward = {})
|
||||
{
|
||||
TestVehicleModel vehicleModel;
|
||||
feature::TypesHolder h;
|
||||
for (uint32_t t : types)
|
||||
h.Add(t);
|
||||
|
||||
TEST_EQUAL(vehicleModel.GetTypeSpeed(h, params), expectedSpeed, ());
|
||||
auto const response = vehicleModel.GetFeatureInfo(h, request);
|
||||
TEST_EQUAL(response.m_forwardSpeed, expectedForward, ());
|
||||
if (expectedBackward.IsValid())
|
||||
TEST_EQUAL(response.m_backwardSpeed, expectedBackward, ());
|
||||
}
|
||||
|
||||
void CheckSpeed(initializer_list<uint32_t> const & types, InOutCitySpeedKMpH const & expectedSpeed)
|
||||
{
|
||||
SpeedParams const inCity(true /* forward */, true /* in city */, Maxspeed());
|
||||
CheckSpeedWithParams(types, inCity, expectedSpeed.m_inCity);
|
||||
SpeedParams const outCity(true /* forward */, false /* in city */, Maxspeed());
|
||||
CheckSpeedWithParams(types, outCity, expectedSpeed.m_outCity);
|
||||
CheckSpeedWithParams(types, {Maxspeed(), true /* in city */}, expectedSpeed.m_inCity);
|
||||
CheckSpeedWithParams(types, {Maxspeed(), false /* in city */}, expectedSpeed.m_outCity);
|
||||
}
|
||||
|
||||
void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue)
|
||||
|
@ -117,7 +136,8 @@ void CheckOneWay(initializer_list<uint32_t> const & types, bool expectedValue)
|
|||
for (uint32_t t : types)
|
||||
h.Add(t);
|
||||
|
||||
TEST_EQUAL(vehicleModel.HasOneWayType(h), expectedValue, ());
|
||||
auto const response = vehicleModel.GetFeatureInfo(h, {});
|
||||
TEST_EQUAL(response.m_isOneWay, expectedValue, ());
|
||||
}
|
||||
|
||||
void CheckPassThroughAllowed(initializer_list<uint32_t> const & types, bool expectedValue)
|
||||
|
@ -127,7 +147,8 @@ void CheckPassThroughAllowed(initializer_list<uint32_t> const & types, bool expe
|
|||
for (uint32_t t : types)
|
||||
h.Add(t);
|
||||
|
||||
TEST_EQUAL(vehicleModel.HasPassThroughType(h), expectedValue, ());
|
||||
auto const response = vehicleModel.GetFeatureInfo(h, {});
|
||||
TEST_EQUAL(response.m_isPassThroughAllowed, expectedValue, ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,9 +161,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed)
|
|||
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed)
|
||||
{
|
||||
{
|
||||
CheckSpeed({GetType("highway", "secondary", "bridge")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({GetType("highway", "secondary", "tunnel")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({GetType("highway", "secondary")}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({GetType("highway", "secondary", "bridge")}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({GetType("highway", "secondary", "tunnel")}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({GetType("highway", "secondary")}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
}
|
||||
|
||||
CheckSpeed({GetType("highway", "trunk")},
|
||||
|
@ -158,9 +179,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes)
|
|||
uint32_t const typeSecondary = GetType("highway", "secondary");
|
||||
uint32_t const typeHighway = GetType("highway");
|
||||
|
||||
CheckSpeed({typeTunnel, typeSecondary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeTunnel, typeHighway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeHighway, typeTunnel}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeTunnel, typeSecondary}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeTunnel, typeHighway}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeHighway, typeTunnel}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
}
|
||||
|
||||
UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay)
|
||||
|
@ -168,9 +189,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay)
|
|||
uint32_t const typeBridge = GetType("highway", "secondary", "bridge");
|
||||
uint32_t const typeOneway = GetOnewayType();
|
||||
|
||||
CheckSpeed({typeBridge, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeBridge, typeOneway}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckOneWay({typeBridge, typeOneway}, true);
|
||||
CheckSpeed({typeOneway, typeBridge}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeOneway, typeBridge}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckOneWay({typeOneway, typeBridge}, true);
|
||||
|
||||
CheckOneWay({typeOneway}, true);
|
||||
|
@ -182,9 +203,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_DifferentSpeeds)
|
|||
uint32_t const typePrimary = GetType("highway", "primary");
|
||||
uint32_t const typeOneway = GetOnewayType();
|
||||
|
||||
CheckSpeed({typeSecondary, typePrimary}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeSecondary, typePrimary}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
|
||||
CheckSpeed({typeSecondary, typePrimary, typeOneway}, kDefaultSpeeds.Get(HighwayType::HighwaySecondary));
|
||||
CheckSpeed({typeSecondary, typePrimary, typeOneway}, kDefaultSpeeds.at(HighwayType::HighwaySecondary));
|
||||
CheckOneWay({typePrimary, typeOneway, typeSecondary}, true);
|
||||
}
|
||||
|
||||
|
@ -228,26 +249,23 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor)
|
|||
Maxspeed const maxspeed90 =
|
||||
Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, kInvalidSpeed);
|
||||
CheckSpeedWithParams({secondary, unpavedBad},
|
||||
SpeedParams(true /* forward */, false /* in city */, maxspeed90),
|
||||
{maxspeed90, false /* in city */},
|
||||
SpeedKMpH(18.0));
|
||||
|
||||
CheckSpeedWithParams({primary, pavedGood},
|
||||
SpeedParams(true /* forward */, false /* in city */, maxspeed90),
|
||||
{maxspeed90, false /* in city */},
|
||||
SpeedKMpH(72.0, 81.0));
|
||||
|
||||
Maxspeed const maxspeed9070 =
|
||||
Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, 70);
|
||||
Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, 70 /* backward speed */);
|
||||
CheckSpeedWithParams({primary, pavedGood},
|
||||
SpeedParams(true /* forward */, false /* in city */, maxspeed9070),
|
||||
SpeedKMpH(72.0, 81.0));
|
||||
CheckSpeedWithParams({primary, pavedGood},
|
||||
SpeedParams(false /* forward */, false /* in city */, maxspeed9070),
|
||||
SpeedKMpH(56.0, 63.0));
|
||||
{maxspeed9070, false},
|
||||
SpeedKMpH(72.0, 81.0), SpeedKMpH(56.0, 63.0));
|
||||
|
||||
Maxspeed const maxspeed60 =
|
||||
Maxspeed(measurement_utils::Units::Metric, 60 /* forward speed */, kInvalidSpeed);
|
||||
Maxspeed(measurement_utils::Units::Metric, 60 /* forward speed */, kInvalidSpeed /* backward speed */);
|
||||
CheckSpeedWithParams({residential, pavedGood},
|
||||
SpeedParams(true /* forward */, false /* in city */, maxspeed60),
|
||||
{maxspeed60, false /* in city */},
|
||||
SpeedKMpH(24.0, 27.0));
|
||||
}
|
||||
|
||||
|
@ -279,13 +297,11 @@ UNIT_TEST(VehicleModel_CarModelValidation)
|
|||
|
||||
for (auto const hwType : carRoadTypes)
|
||||
{
|
||||
auto const * factor = kHighwayBasedFactors.Find(hwType);
|
||||
TEST(factor, (hwType));
|
||||
TEST(factor->IsValid(), (hwType, *factor));
|
||||
auto const factor = kHighwayBasedFactors.at(hwType);
|
||||
TEST(factor.IsValid(), ());
|
||||
|
||||
auto const * speed = kHighwayBasedSpeeds.Find(hwType);
|
||||
TEST(speed, (hwType));
|
||||
TEST(speed->IsValid(), (hwType, *speed));
|
||||
auto const speed = kHighwayBasedSpeeds.at(hwType);
|
||||
TEST(speed.IsValid(), ());
|
||||
}
|
||||
}
|
||||
} // namespace vehicle_model_test
|
||||
|
|
|
@ -12,115 +12,140 @@
|
|||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
using namespace routing;
|
||||
namespace routing
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
template <double const & (*F)(double const &, double const &), typename WeightAndETA>
|
||||
WeightAndETA Pick(WeightAndETA const & lhs, WeightAndETA const & rhs)
|
||||
{
|
||||
return {F(lhs.m_weight, rhs.m_weight), F(lhs.m_eta, rhs.m_eta)};
|
||||
};
|
||||
}
|
||||
|
||||
InOutCitySpeedKMpH Max(InOutCitySpeedKMpH const & lhs, InOutCitySpeedKMpH const & rhs)
|
||||
{
|
||||
return {Pick<max>(lhs.m_inCity, rhs.m_inCity), Pick<max>(lhs.m_outCity, rhs.m_outCity)};
|
||||
}
|
||||
|
||||
/// @todo This function is used to to get key to fetch speed factor from model,
|
||||
/// but we assign factors for links too. @see kHighwayBasedFactors.
|
||||
HighwayType GetHighwayTypeKey(HighwayType type)
|
||||
|
||||
VehicleModel::VehicleModel(HighwaySpeeds const & speeds, HighwayFactors const & factors,
|
||||
SurfaceFactors const & surfaces, NoPassThroughHighways const & noPassThrough)
|
||||
{
|
||||
switch (type)
|
||||
m_surfaceFactors.Reserve(surfaces.size());
|
||||
for (auto const & e : surfaces)
|
||||
{
|
||||
case HighwayType::HighwayMotorwayLink: return HighwayType::HighwayMotorway;
|
||||
case HighwayType::HighwayTrunkLink: return HighwayType::HighwayTrunk;
|
||||
case HighwayType::HighwayPrimaryLink: return HighwayType::HighwayPrimary;
|
||||
case HighwayType::HighwaySecondaryLink: return HighwayType::HighwaySecondary;
|
||||
case HighwayType::HighwayTertiaryLink: return HighwayType::HighwayTertiary;
|
||||
default: return type;
|
||||
ASSERT(e.second.IsValid(), ());
|
||||
m_surfaceFactors.Insert(static_cast<uint32_t>(e.first), e.second);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace routing
|
||||
{
|
||||
|
||||
VehicleModel::VehicleModel(Classificator const & classif, LimitsInitList const & featureTypeLimits,
|
||||
SurfaceInitList const & featureTypeSurface, HighwayBasedInfo const & info)
|
||||
: m_highwayBasedInfo(info), m_onewayType(classif.GetTypeByPath({"hwtag", "oneway"}))
|
||||
{
|
||||
m_roadTypes.Reserve(featureTypeLimits.size());
|
||||
for (auto const & v : featureTypeLimits)
|
||||
m_highwayInfo.Reserve(speeds.size());
|
||||
for (auto const & e : speeds)
|
||||
{
|
||||
auto const clType = classif.GetTypeByPath(v.m_type);
|
||||
auto const hwType = static_cast<HighwayType>(classif.GetIndexForType(clType));
|
||||
auto const * speed = info.m_speeds.Find(hwType);
|
||||
ASSERT(speed, ("Can't found speed for", hwType));
|
||||
ASSERT(e.second.IsValid(), ());
|
||||
|
||||
/// @todo Consider using not only highway class speed but max_speed * max_speed_factor.
|
||||
m_maxModelSpeed = Max(m_maxModelSpeed, *speed);
|
||||
m_roadTypes.Insert(clType, v.m_isPassThroughAllowed);
|
||||
}
|
||||
m_roadTypes.FinishBuilding();
|
||||
Info info;
|
||||
info.m_speed = e.second;
|
||||
|
||||
m_surfaceFactors.Reserve(featureTypeSurface.size());
|
||||
for (auto const & v : featureTypeSurface)
|
||||
{
|
||||
auto const & speedFactor = v.m_factor;
|
||||
ASSERT_LESS_OR_EQUAL(speedFactor.m_weight, 1.0, ());
|
||||
ASSERT_LESS_OR_EQUAL(speedFactor.m_eta, 1.0, ());
|
||||
ASSERT_GREATER(speedFactor.m_weight, 0.0, ());
|
||||
ASSERT_GREATER(speedFactor.m_eta, 0.0, ());
|
||||
m_surfaceFactors.Insert(classif.GetTypeByPath(v.m_type), v.m_factor);
|
||||
auto const itFactor = factors.find(e.first);
|
||||
if (itFactor != factors.end())
|
||||
info.m_factor = itFactor->second;
|
||||
|
||||
if (noPassThrough.count(e.first) > 0)
|
||||
info.m_isPassThroughAllowed = false;
|
||||
|
||||
m_highwayInfo.Insert(static_cast<uint32_t>(e.first), info);
|
||||
|
||||
m_maxModelSpeed = Max(m_maxModelSpeed, info.m_speed);
|
||||
}
|
||||
m_highwayInfo.FinishBuilding();
|
||||
}
|
||||
|
||||
void VehicleModel::AddAdditionalRoadTypes(Classificator const & classif, AdditionalRoadsList const & roads)
|
||||
VehicleModel::Response VehicleModel::GetFeatureInfo(FeatureType & ft, Request const & request) const
|
||||
{
|
||||
for (auto const & r : roads)
|
||||
return GetFeatureInfo(feature::TypesHolder(ft), request);
|
||||
}
|
||||
|
||||
bool VehicleModel::HasRoadType(FeatureType & ft) const
|
||||
{
|
||||
return HasRoadType(feature::TypesHolder(ft));
|
||||
}
|
||||
|
||||
bool VehicleModel::IsOneWay(FeatureType & ft) const
|
||||
{
|
||||
for (uint32_t type : feature::TypesHolder(ft))
|
||||
{
|
||||
uint32_t const type = classif.GetTypeByPath(r.m_type);
|
||||
if (m_roadTypes.Find(type) == nullptr)
|
||||
NormalizeType(type);
|
||||
if (IsOneWay(type) == ResultT::Yes)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VehicleModel::Response VehicleModel::GetFeatureInfo(feature::TypesHolder const & types,
|
||||
Request const & request) const
|
||||
{
|
||||
Response response;
|
||||
|
||||
SpeedFactor surface;
|
||||
Info const * info = nullptr;
|
||||
|
||||
for (uint32_t type : types)
|
||||
{
|
||||
switch (GetRoadAvailability(type))
|
||||
{
|
||||
m_addRoadTypes.Insert(type, r.m_speed);
|
||||
m_maxModelSpeed = Max(m_maxModelSpeed, r.m_speed);
|
||||
case ResultT::Yes:
|
||||
response.m_isValid = true;
|
||||
continue;
|
||||
case ResultT::No:
|
||||
response.m_isValid = false;
|
||||
return response;
|
||||
}
|
||||
|
||||
switch (IsOneWay(type))
|
||||
{
|
||||
case ResultT::Yes:
|
||||
response.m_isOneWay = true;
|
||||
continue;
|
||||
case ResultT::No:
|
||||
response.m_isOneWay = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto const * sf = m_surfaceFactors.Find(type);
|
||||
if (sf)
|
||||
{
|
||||
surface = Pick<min>(*sf, surface);
|
||||
continue;
|
||||
}
|
||||
|
||||
NormalizeType(type);
|
||||
|
||||
if (info == nullptr)
|
||||
{
|
||||
info = m_highwayInfo.Find(type);
|
||||
if (info)
|
||||
{
|
||||
response.m_highwayType = static_cast<HighwayType>(type);
|
||||
response.m_isValid = true;
|
||||
response.m_isPassThroughAllowed = info->m_isPassThroughAllowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t VehicleModel::PrepareToMatchType(uint32_t type)
|
||||
{
|
||||
return ftypes::BaseChecker::PrepareToMatch(type, 2);
|
||||
}
|
||||
if (!response.m_isValid)
|
||||
return response;
|
||||
|
||||
SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const
|
||||
{
|
||||
feature::TypesHolder const types(f);
|
||||
|
||||
RoadAvailability const restriction = GetRoadAvailability(types);
|
||||
if (restriction == RoadAvailability::NotAvailable || !HasRoadType(types))
|
||||
return {};
|
||||
|
||||
return GetTypeSpeed(types, speedParams);
|
||||
}
|
||||
|
||||
HighwayType VehicleModel::GetHighwayType(FeatureType & f) const
|
||||
{
|
||||
feature::TypesHolder const types(f);
|
||||
for (auto const t : types)
|
||||
if (info == nullptr)
|
||||
{
|
||||
auto const ret = GetHighwayType(t);
|
||||
if (ret)
|
||||
return *ret;
|
||||
// LOG(LWARNING, ("Model doesn't have HighwayType entry, but hwtag=yes.",
|
||||
// ft.DebugString(FeatureType::BEST_GEOMETRY)));
|
||||
|
||||
if (m_addRoadTypes.Find(t))
|
||||
return static_cast<HighwayType>(classif().GetIndexForType(t));
|
||||
response.m_isPassThroughAllowed = true;
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return HighwayType::HighwayResidential;
|
||||
response.m_forwardSpeed = GetSpeed(info, request.m_speed.GetSpeedKmPH(true), request.m_inCity) * surface;
|
||||
response.m_backwardSpeed = GetSpeed(info, request.m_speed.GetSpeedKmPH(false), request.m_inCity) * surface;
|
||||
return response;
|
||||
}
|
||||
|
||||
double VehicleModel::GetMaxWeightSpeed() const
|
||||
|
@ -128,186 +153,53 @@ double VehicleModel::GetMaxWeightSpeed() const
|
|||
return max(m_maxModelSpeed.m_inCity.m_weight, m_maxModelSpeed.m_outCity.m_weight);
|
||||
}
|
||||
|
||||
optional<HighwayType> VehicleModel::GetHighwayType(uint32_t type) const
|
||||
void VehicleModel::NormalizeType(uint32_t type) const
|
||||
{
|
||||
type = PrepareToMatchType(type);
|
||||
auto const * value = m_roadTypes.Find(type);
|
||||
if (value)
|
||||
return static_cast<HighwayType>(classif().GetIndexForType(type));
|
||||
return {};
|
||||
// The only exception that has 3-arity type.
|
||||
if (type != static_cast<uint32_t>(HighwayType::RailwayRailMotorVehicle))
|
||||
ftype::TruncValue(type, 2);
|
||||
}
|
||||
|
||||
void VehicleModel::GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const
|
||||
SpeedKMpH VehicleModel::GetSpeed(Info const * info, MaxspeedType ftMaxSpeed, bool inCity) const
|
||||
{
|
||||
auto const * surface = m_surfaceFactors.Find(type);
|
||||
if (surface)
|
||||
factor = Pick<min>(factor, *surface);
|
||||
auto const maxModelSpeed = m_maxModelSpeed.GetSpeed(inCity);
|
||||
auto const factor = info ? info->m_factor.GetFactor(inCity) : 1.0;
|
||||
|
||||
ASSERT_LESS_OR_EQUAL(factor.m_weight, 1.0, ());
|
||||
ASSERT_LESS_OR_EQUAL(factor.m_eta, 1.0, ());
|
||||
ASSERT_GREATER(factor.m_weight, 0.0, ());
|
||||
ASSERT_GREATER(factor.m_eta, 0.0, ());
|
||||
}
|
||||
|
||||
void VehicleModel::GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad,
|
||||
optional<SpeedKMpH> & speed) const
|
||||
{
|
||||
auto const * s = m_addRoadTypes.Find(type);
|
||||
if (s)
|
||||
if (ftMaxSpeed != kInvalidSpeed)
|
||||
{
|
||||
auto const & res = isCityRoad ? s->m_inCity : s->m_outCity;
|
||||
speed = speed ? Pick<min>(*speed, res) : res;
|
||||
return Pick<min>(SpeedKMpH(static_cast<double>(ftMaxSpeed)) * factor, maxModelSpeed);
|
||||
}
|
||||
else if (info)
|
||||
{
|
||||
SpeedKMpH const speed = info->m_speed.GetSpeed(inCity);
|
||||
|
||||
/// @todo Hm, well this is not obvious for me and should be revised.
|
||||
// Predefined model speeds are taken from the former code and should not be multiplied with the factor.
|
||||
// On the contrary, ETA speed should be multiplied.
|
||||
return SpeedKMpH(min(speed.m_weight, maxModelSpeed.m_weight),
|
||||
min(factor.m_eta * speed.m_eta, maxModelSpeed.m_eta));
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetSpeedForAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
SpeedKMpH VehicleModel::GetSpeedOnFeatureWithMaxspeed(HighwayType const & type,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
ASSERT(speedParams.m_maxspeed.IsValid(), ());
|
||||
|
||||
auto const featureMaxSpeedKmPH = speedParams.m_maxspeed.GetSpeedKmPH(speedParams.m_forward);
|
||||
ASSERT(featureMaxSpeedKmPH != kInvalidSpeed, (type, speedParams.m_forward, speedParams.m_maxspeed));
|
||||
|
||||
auto const typeKey = GetHighwayTypeKey(type);
|
||||
auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey);
|
||||
ASSERT(factor, ("Key:", typeKey, "is not found."));
|
||||
|
||||
bool const isCityRoad = speedParams.m_inCity;
|
||||
return Pick<min>(SpeedKMpH(static_cast<double>(featureMaxSpeedKmPH)) * factor->GetFactor(isCityRoad),
|
||||
m_maxModelSpeed.GetSpeed(isCityRoad));
|
||||
}
|
||||
|
||||
SpeedKMpH VehicleModel::GetSpeedOnFeatureWithoutMaxspeed(HighwayType const & type,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
ASSERT(!speedParams.m_maxspeed.IsValid(), ());
|
||||
|
||||
auto const * s = m_highwayBasedInfo.m_speeds.Find(type);
|
||||
ASSERT(s, ("Key:", type, "is not found."));
|
||||
|
||||
auto const typeKey = GetHighwayTypeKey(type);
|
||||
auto const * factor = m_highwayBasedInfo.m_factors.Find(typeKey);
|
||||
ASSERT(factor, ("Key:", typeKey, "is not found."));
|
||||
|
||||
auto const isCityRoad = speedParams.m_inCity;
|
||||
SpeedKMpH const speed = s->GetSpeed(isCityRoad);
|
||||
ASSERT(speed.IsValid(), (speed));
|
||||
|
||||
SpeedKMpH const & maxModelSpeed = m_maxModelSpeed.GetSpeed(isCityRoad);
|
||||
|
||||
/// @todo Hm, well this is not obvious for me and should be revised.
|
||||
// Speeds from the m_highwayBasedInfo are taken from the former code and should not
|
||||
// be multiplied to the factor. On the contrary, ETA speed should be multiplied.
|
||||
return SpeedKMpH(
|
||||
min(speed.m_weight, maxModelSpeed.m_weight),
|
||||
min(factor->GetFactor(isCityRoad).m_eta * speed.m_eta, maxModelSpeed.m_eta));
|
||||
}
|
||||
|
||||
SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
bool const isCityRoad = speedParams.m_inCity;
|
||||
optional<HighwayType> hwType;
|
||||
SpeedFactor surfaceFactor;
|
||||
optional<SpeedKMpH> additionalRoadSpeed;
|
||||
for (uint32_t t : types)
|
||||
{
|
||||
if (!hwType)
|
||||
hwType = GetHighwayType(t);
|
||||
|
||||
GetSurfaceFactor(t, surfaceFactor);
|
||||
GetAdditionalRoadSpeed(t, isCityRoad, additionalRoadSpeed);
|
||||
}
|
||||
|
||||
if (additionalRoadSpeed)
|
||||
return *additionalRoadSpeed * surfaceFactor;
|
||||
|
||||
ASSERT(hwType, ());
|
||||
auto const resultHwType = *hwType;
|
||||
if (speedParams.m_maxspeed.IsValid())
|
||||
return GetSpeedOnFeatureWithMaxspeed(resultHwType, speedParams) * surfaceFactor;
|
||||
|
||||
return GetSpeedOnFeatureWithoutMaxspeed(resultHwType, speedParams) * surfaceFactor;
|
||||
}
|
||||
|
||||
SpeedKMpH VehicleModel::GetSpeedWihtoutMaxspeed(FeatureType & f,
|
||||
SpeedParams const & speedParams) const
|
||||
{
|
||||
return VehicleModel::GetSpeed(f, {speedParams.m_forward, speedParams.m_inCity, Maxspeed()});
|
||||
}
|
||||
|
||||
bool VehicleModel::IsOneWay(FeatureType & f) const
|
||||
{
|
||||
return HasOneWayType(feature::TypesHolder(f));
|
||||
}
|
||||
|
||||
bool VehicleModel::HasOneWayType(feature::TypesHolder const & types) const
|
||||
{
|
||||
return types.Has(m_onewayType);
|
||||
}
|
||||
|
||||
bool VehicleModel::IsRoad(FeatureType & f) const
|
||||
{
|
||||
if (f.GetGeomType() != feature::GeomType::Line)
|
||||
return false;
|
||||
|
||||
feature::TypesHolder const types(f);
|
||||
|
||||
if (GetRoadAvailability(types) == RoadAvailability::NotAvailable)
|
||||
return false;
|
||||
return HasRoadType(types);
|
||||
}
|
||||
|
||||
bool VehicleModel::IsPassThroughAllowed(FeatureType & f) const
|
||||
{
|
||||
feature::TypesHolder const types(f);
|
||||
// Allow pass through additional road types e.g. peer, ferry.
|
||||
for (uint32_t t : types)
|
||||
{
|
||||
if (m_addRoadTypes.Find(t))
|
||||
return true;
|
||||
}
|
||||
return HasPassThroughType(types);
|
||||
}
|
||||
|
||||
bool VehicleModel::HasPassThroughType(feature::TypesHolder const & types) const
|
||||
{
|
||||
for (uint32_t const t : types)
|
||||
{
|
||||
bool const * allow = m_roadTypes.Find(PrepareToMatchType(t));
|
||||
if (allow && *allow)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VehicleModel::IsRoadType(uint32_t type) const
|
||||
{
|
||||
return m_addRoadTypes.Find(type) || m_roadTypes.Find(PrepareToMatchType(type));
|
||||
}
|
||||
|
||||
VehicleModelInterface::RoadAvailability VehicleModel::GetRoadAvailability(feature::TypesHolder const &) const
|
||||
{
|
||||
return RoadAvailability::Unknown;
|
||||
}
|
||||
|
||||
VehicleModelFactory::VehicleModelFactory(
|
||||
CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
VehicleModelFactory::VehicleModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn)
|
||||
: m_countryParentNameGetterFn(countryParentNameGetterFn)
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<VehicleModelInterface> VehicleModelFactory::GetVehicleModel() const
|
||||
{
|
||||
auto const itr = m_models.find("");
|
||||
ASSERT(itr != m_models.end(), ("No default vehicle model. VehicleModelFactory was not "
|
||||
"properly constructed"));
|
||||
return itr->second;
|
||||
auto const it = m_models.find("");
|
||||
CHECK(it != m_models.end(), ());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
shared_ptr<VehicleModelInterface> VehicleModelFactory::GetVehicleModelForCountry(
|
||||
string const & country) const
|
||||
shared_ptr<VehicleModelInterface>
|
||||
VehicleModelFactory::GetVehicleModelForCountry(string const & country) const
|
||||
{
|
||||
string parent = country;
|
||||
while (!parent.empty())
|
||||
|
@ -329,9 +221,9 @@ string VehicleModelFactory::GetParent(string const & country) const
|
|||
return m_countryParentNameGetterFn(country);
|
||||
}
|
||||
|
||||
HighwayBasedFactors GetOneFactorsForBicycleAndPedestrianModel()
|
||||
HighwayFactors GetOneFactorsForBicycleAndPedestrianModel()
|
||||
{
|
||||
return HighwayBasedFactors{
|
||||
return {
|
||||
{HighwayType::HighwayTrunk, InOutCityFactor(1.0)},
|
||||
{HighwayType::HighwayTrunkLink, InOutCityFactor(1.0)},
|
||||
{HighwayType::HighwayPrimary, InOutCityFactor(1.0)},
|
||||
|
@ -357,18 +249,6 @@ HighwayBasedFactors GetOneFactorsForBicycleAndPedestrianModel()
|
|||
};
|
||||
}
|
||||
|
||||
string DebugPrint(VehicleModelInterface::RoadAvailability const l)
|
||||
{
|
||||
switch (l)
|
||||
{
|
||||
case VehicleModelInterface::RoadAvailability::Available: return "Available";
|
||||
case VehicleModelInterface::RoadAvailability::NotAvailable: return "NotAvailable";
|
||||
case VehicleModelInterface::RoadAvailability::Unknown: return "Unknown";
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
string DebugPrint(SpeedKMpH const & speed)
|
||||
{
|
||||
ostringstream oss;
|
||||
|
|
|
@ -5,34 +5,26 @@
|
|||
#include "base/small_map.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class Classificator;
|
||||
class FeatureType;
|
||||
|
||||
namespace feature { class TypesHolder; }
|
||||
class FeatureType;
|
||||
|
||||
namespace routing
|
||||
{
|
||||
double constexpr kNotUsed = std::numeric_limits<double>::max();
|
||||
|
||||
struct InOutCityFactor;
|
||||
struct InOutCitySpeedKMpH;
|
||||
|
||||
// Each value is equal to the corresponding type index from types.txt.
|
||||
// The ascending order is strict. Check for static_cast<HighwayType> in vehicle_model.cpp
|
||||
enum class HighwayType : uint32_t
|
||||
// Check for static_cast<HighwayType> in vehicle_model.cpp
|
||||
enum class HighwayType : uint16_t
|
||||
{
|
||||
HighwayResidential = 1,
|
||||
HighwayService = 2,
|
||||
|
@ -62,22 +54,14 @@ enum class HighwayType : uint32_t
|
|||
RouteShuttleTrain = 1054,
|
||||
};
|
||||
|
||||
using HighwayBasedFactors = base::SmallMap<HighwayType, InOutCityFactor>;
|
||||
using HighwayBasedSpeeds = base::SmallMap<HighwayType, InOutCitySpeedKMpH>;
|
||||
|
||||
/// \brief Params for calculation of an approximate speed on a feature.
|
||||
struct SpeedParams
|
||||
// Each value is equal to the corresponding type index from types.txt.
|
||||
// Check for static_cast<SurfaceType> in vehicle_model.cpp
|
||||
enum class SurfaceType : uint16_t
|
||||
{
|
||||
SpeedParams(bool forward, bool inCity, Maxspeed const & maxspeed)
|
||||
: m_maxspeed(maxspeed), m_forward(forward), m_inCity(inCity)
|
||||
{
|
||||
}
|
||||
|
||||
Maxspeed m_maxspeed;
|
||||
// Retrieve forward (true) or backward (false) speed.
|
||||
bool m_forward;
|
||||
// If a corresponding feature lies inside a city of a town.
|
||||
bool m_inCity;
|
||||
PavedGood = 1116,
|
||||
PavedBad = 1117,
|
||||
UnpavedGood = 1118,
|
||||
UnpavedBad = 1119,
|
||||
};
|
||||
|
||||
/// \brief Speeds which are used for edge weight and ETA estimations.
|
||||
|
@ -99,8 +83,8 @@ struct SpeedKMpH
|
|||
double m_eta = 0.0; // KMpH
|
||||
};
|
||||
|
||||
/// \brief Factors which modify weight and ETA speed on feature in case of bad pavement (reduce)
|
||||
/// or good highway class (increase).
|
||||
/// \brief Factors which modify weight and ETA speed on feature in case of
|
||||
/// bad pavement (reduce) or good highway class (increase).
|
||||
/// Both should be greater then 0.
|
||||
struct SpeedFactor
|
||||
{
|
||||
|
@ -156,6 +140,7 @@ struct InOutCitySpeedKMpH
|
|||
|
||||
struct InOutCityFactor
|
||||
{
|
||||
constexpr InOutCityFactor() = default;
|
||||
constexpr explicit InOutCityFactor(SpeedFactor const & factor) noexcept
|
||||
: m_inCity(factor), m_outCity(factor)
|
||||
{
|
||||
|
@ -177,37 +162,39 @@ struct InOutCityFactor
|
|||
SpeedFactor m_outCity;
|
||||
};
|
||||
|
||||
struct HighwayBasedInfo
|
||||
{
|
||||
HighwayBasedInfo(HighwayBasedSpeeds const & speeds, HighwayBasedFactors const & factors)
|
||||
: m_speeds(speeds)
|
||||
, m_factors(factors)
|
||||
{
|
||||
}
|
||||
using HighwaySpeeds = std::unordered_map<HighwayType, InOutCitySpeedKMpH>;
|
||||
using HighwayFactors = std::unordered_map<HighwayType, InOutCityFactor>;
|
||||
using SurfaceFactors = std::unordered_map<SurfaceType, SpeedFactor>;
|
||||
using NoPassThroughHighways = std::unordered_set<HighwayType>;
|
||||
|
||||
HighwayBasedSpeeds const & m_speeds;
|
||||
HighwayBasedFactors const & m_factors;
|
||||
};
|
||||
|
||||
class VehicleModelInterface
|
||||
{
|
||||
public:
|
||||
enum class RoadAvailability
|
||||
{
|
||||
NotAvailable,
|
||||
Available,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
virtual ~VehicleModelInterface() = default;
|
||||
|
||||
/// @return Allowed weight and ETA speed in KMpH.
|
||||
/// 0 means that it's forbidden to move on this feature or it's not a road at all.
|
||||
/// Weight and ETA should be less than max model speed's values respectively.
|
||||
/// @param inCity is true if |f| lies in a city of town.
|
||||
virtual SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const = 0;
|
||||
struct Request
|
||||
{
|
||||
Maxspeed m_speed;
|
||||
bool m_inCity;
|
||||
};
|
||||
struct Response
|
||||
{
|
||||
SpeedKMpH m_forwardSpeed, m_backwardSpeed;
|
||||
|
||||
virtual HighwayType GetHighwayType(FeatureType & f) const = 0;
|
||||
// Highway type can be null, but m_isValid == true if Feature has hwtype=yes*
|
||||
// without any recognizable highway classifier type in it.
|
||||
std::optional<HighwayType> m_highwayType;
|
||||
bool m_isValid = false;
|
||||
|
||||
bool m_isOneWay;
|
||||
bool m_isPassThroughAllowed;
|
||||
};
|
||||
virtual Response GetFeatureInfo(FeatureType & ft, Request const & request) const = 0;
|
||||
|
||||
/// @todo Remove after proper FeaturesRoadGraph refactoring.
|
||||
virtual bool HasRoadType(FeatureType & ft) const = 0;
|
||||
virtual bool IsOneWay(FeatureType & ft) const = 0;
|
||||
|
||||
/// @return Maximum model weight speed.
|
||||
/// All speeds which the model returns must be less than or equal to this speed.
|
||||
|
@ -215,20 +202,7 @@ public:
|
|||
|
||||
/// @return Offroad speed in KMpH for vehicle. This speed should be used for non-feature routing
|
||||
/// e.g. to connect start point to nearest feature.
|
||||
virtual SpeedKMpH const & GetOffroadSpeed() const = 0;
|
||||
|
||||
virtual bool IsOneWay(FeatureType & f) const = 0;
|
||||
|
||||
/// @returns true iff feature |f| can be used for routing with corresponding vehicle model.
|
||||
virtual bool IsRoad(FeatureType & f) const = 0;
|
||||
|
||||
/// @returns true iff feature |f| can be used for through passage with corresponding vehicle model.
|
||||
/// e.g. in Russia roads tagged "highway = service" are not allowed for through passage;
|
||||
/// however, road with this tag can be be used if it is close enough to the start or destination
|
||||
/// point of the route.
|
||||
/// Roads with additional types e.g. "path = ferry", "vehicle_type = yes" considered as allowed
|
||||
/// to pass through.
|
||||
virtual bool IsPassThroughAllowed(FeatureType & f) const = 0;
|
||||
virtual SpeedKMpH GetOffroadSpeed() const = 0;
|
||||
};
|
||||
|
||||
class VehicleModelFactoryInterface
|
||||
|
@ -239,7 +213,7 @@ public:
|
|||
/// but it may be non optimal for some countries
|
||||
virtual std::shared_ptr<VehicleModelInterface> GetVehicleModel() const = 0;
|
||||
|
||||
/// @return The most optimal vehicle model for specified country
|
||||
/// @return The most optimal vehicle model for specified \a country
|
||||
virtual std::shared_ptr<VehicleModelInterface> GetVehicleModelForCountry(
|
||||
std::string const & country) const = 0;
|
||||
};
|
||||
|
@ -247,51 +221,27 @@ public:
|
|||
class VehicleModel : public VehicleModelInterface
|
||||
{
|
||||
public:
|
||||
struct FeatureTypeLimits
|
||||
{
|
||||
std::vector<std::string> m_type;
|
||||
bool m_isPassThroughAllowed; // pass through this road type is allowed
|
||||
};
|
||||
|
||||
struct FeatureTypeSurface
|
||||
{
|
||||
std::vector<std::string> m_type; // road surface type 'psurface=*'
|
||||
SpeedFactor m_factor;
|
||||
};
|
||||
|
||||
struct AdditionalRoad
|
||||
{
|
||||
std::vector<std::string> m_type;
|
||||
InOutCitySpeedKMpH m_speed;
|
||||
};
|
||||
|
||||
using AdditionalRoadsList = std::initializer_list<AdditionalRoad>;
|
||||
using LimitsInitList = std::initializer_list<FeatureTypeLimits>;
|
||||
using SurfaceInitList = std::initializer_list<FeatureTypeSurface>;
|
||||
|
||||
VehicleModel(Classificator const & classif, LimitsInitList const & featureTypeLimits,
|
||||
SurfaceInitList const & featureTypeSurface, HighwayBasedInfo const & info);
|
||||
VehicleModel(HighwaySpeeds const & speeds, HighwayFactors const & factors,
|
||||
SurfaceFactors const & surfaces, NoPassThroughHighways const & noPassThrough = {});
|
||||
|
||||
/// @name VehicleModelInterface overrides.
|
||||
/// @{
|
||||
SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override;
|
||||
HighwayType GetHighwayType(FeatureType & f) const override;
|
||||
Response GetFeatureInfo(FeatureType & ft, Request const & request) const override;
|
||||
|
||||
bool HasRoadType(FeatureType & ft) const override;
|
||||
bool IsOneWay(FeatureType & ft) const override;
|
||||
|
||||
double GetMaxWeightSpeed() const override;
|
||||
bool IsOneWay(FeatureType & f) const override;
|
||||
bool IsRoad(FeatureType & f) const override;
|
||||
bool IsPassThroughAllowed(FeatureType & f) const override;
|
||||
/// @}
|
||||
|
||||
public:
|
||||
/// @returns true if |m_highwayTypes| or |m_addRoadTypes| contains |type| and false otherwise.
|
||||
bool IsRoadType(uint32_t type) const;
|
||||
Response GetFeatureInfo(feature::TypesHolder const & types, Request const & request) const;
|
||||
|
||||
template <class TList>
|
||||
bool HasRoadType(TList const & types) const
|
||||
template <class ContT> bool HasRoadType(ContT const & types) const
|
||||
{
|
||||
for (uint32_t t : types)
|
||||
for (uint32_t type : types)
|
||||
{
|
||||
if (IsRoadType(t))
|
||||
NormalizeType(type);
|
||||
if (m_highwayInfo.Find(type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -299,57 +249,50 @@ public:
|
|||
|
||||
bool EqualsForTests(VehicleModel const & rhs) const
|
||||
{
|
||||
return (m_roadTypes == rhs.m_roadTypes) && (m_addRoadTypes == rhs.m_addRoadTypes) &&
|
||||
(m_onewayType == rhs.m_onewayType);
|
||||
return (m_highwayInfo == rhs.m_highwayInfo && m_highwayInfo == rhs.m_highwayInfo &&
|
||||
m_maxModelSpeed == rhs.m_maxModelSpeed);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// @returns a special restriction which is set to the feature.
|
||||
virtual RoadAvailability GetRoadAvailability(feature::TypesHolder const & types) const;
|
||||
enum class ResultT
|
||||
{
|
||||
Yes, No, Unknown
|
||||
};
|
||||
|
||||
void AddAdditionalRoadTypes(Classificator const & classif, AdditionalRoadsList const & roads);
|
||||
/// @returns If oneway road.
|
||||
virtual ResultT IsOneWay(uint32_t type) const = 0;
|
||||
|
||||
static uint32_t PrepareToMatchType(uint32_t type);
|
||||
/// @returns Availability according to a special restriction: hwtag={yes,no}{car,bicycle,foot}.
|
||||
virtual ResultT GetRoadAvailability(uint32_t type) const = 0;
|
||||
|
||||
/// \returns true if |types| is a oneway feature.
|
||||
/// \note According to OSM, tag "oneway" could have value "-1". That means it's a oneway feature
|
||||
/// with reversed geometry. In that case at map generation the geometry of such features
|
||||
/// is reversed (the order of points is changed) so in vehicle model all oneway feature
|
||||
/// may be considered as features with forward geometry.
|
||||
bool HasOneWayType(feature::TypesHolder const & types) const;
|
||||
|
||||
bool HasPassThroughType(feature::TypesHolder const & types) const;
|
||||
|
||||
SpeedKMpH GetTypeSpeed(feature::TypesHolder const & types, SpeedParams const & speedParams) const;
|
||||
|
||||
SpeedKMpH GetSpeedWihtoutMaxspeed(FeatureType & f, SpeedParams const & speedParams) const;
|
||||
/// @returns Default speed for available road, but not in the current HighwayType model.
|
||||
virtual SpeedKMpH GetSpeedForAvailable() const = 0;
|
||||
|
||||
/// \brief Maximum within all the speed limits set in a model (car model, bicycle model and so on).
|
||||
/// Do not mix with maxspeed value tag, which defines maximum legal speed on a feature.
|
||||
InOutCitySpeedKMpH m_maxModelSpeed;
|
||||
|
||||
private:
|
||||
std::optional<HighwayType> GetHighwayType(uint32_t type) const;
|
||||
void GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const;
|
||||
void GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad,
|
||||
std::optional<SpeedKMpH> & speed) const;
|
||||
void NormalizeType(uint32_t type) const;
|
||||
|
||||
SpeedKMpH GetSpeedOnFeatureWithoutMaxspeed(HighwayType const & type,
|
||||
SpeedParams const & speedParams) const;
|
||||
SpeedKMpH GetSpeedOnFeatureWithMaxspeed(HighwayType const & type,
|
||||
SpeedParams const & speedParams) const;
|
||||
struct Info
|
||||
{
|
||||
InOutCitySpeedKMpH m_speed;
|
||||
InOutCityFactor m_factor;
|
||||
bool m_isPassThroughAllowed = true;
|
||||
|
||||
// HW type -> speed and factor.
|
||||
HighwayBasedInfo m_highwayBasedInfo;
|
||||
uint32_t m_onewayType;
|
||||
bool operator==(Info const & rhs) const
|
||||
{
|
||||
return (m_speed == rhs.m_speed && m_factor == rhs.m_factor &&
|
||||
m_isPassThroughAllowed == rhs.m_isPassThroughAllowed);
|
||||
}
|
||||
};
|
||||
|
||||
SpeedKMpH GetSpeed(Info const * info, MaxspeedType ftMaxSpeed, bool inCity) const;
|
||||
|
||||
base::SmallMap<uint32_t, Info> m_highwayInfo;
|
||||
|
||||
// HW type -> allow pass through.
|
||||
base::SmallMap<uint32_t, bool> m_roadTypes;
|
||||
// Mapping surface types psurface={paved_good/paved_bad/unpaved_good/unpaved_bad} to surface speed factors.
|
||||
base::SmallMapBase<uint32_t, SpeedFactor> m_surfaceFactors;
|
||||
|
||||
/// @todo Do we really need a separate map here or can merge with the m_roadTypes map?
|
||||
base::SmallMapBase<uint32_t, InOutCitySpeedKMpH> m_addRoadTypes;
|
||||
};
|
||||
|
||||
class VehicleModelFactory : public VehicleModelFactoryInterface
|
||||
|
@ -375,12 +318,12 @@ protected:
|
|||
CountryParentNameGetterFn m_countryParentNameGetterFn;
|
||||
};
|
||||
|
||||
HighwayBasedFactors GetOneFactorsForBicycleAndPedestrianModel();
|
||||
HighwayFactors GetOneFactorsForBicycleAndPedestrianModel();
|
||||
|
||||
std::string DebugPrint(VehicleModelInterface::RoadAvailability const l);
|
||||
std::string DebugPrint(SpeedKMpH const & speed);
|
||||
std::string DebugPrint(SpeedFactor const & speedFactor);
|
||||
std::string DebugPrint(InOutCitySpeedKMpH const & speed);
|
||||
std::string DebugPrint(InOutCityFactor const & speedFactor);
|
||||
std::string DebugPrint(HighwayType type);
|
||||
|
||||
} // namespace routing
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "routing/index_graph_loader.hpp"
|
||||
#include "routing/maxspeeds.hpp"
|
||||
|
||||
#include "routing_common/car_model_coefs.hpp"
|
||||
#include "routing_common/car_model.hpp"
|
||||
#include "routing_common/maxspeed_conversion.hpp"
|
||||
#include "routing_common/vehicle_model.hpp"
|
||||
|
@ -90,16 +91,11 @@ class CarModelTypes final
|
|||
public:
|
||||
CarModelTypes()
|
||||
{
|
||||
auto const & cl = classif();
|
||||
for (auto const & e : routing::kHighwayBasedSpeeds)
|
||||
m_hwtags.push_back(static_cast<uint32_t>(e.first));
|
||||
|
||||
for (auto const & road : CarModel::GetAdditionalRoads())
|
||||
m_hwtags.push_back(cl.GetTypeByPath(road.m_type));
|
||||
|
||||
for (auto const & speed : CarModel::GetOptions())
|
||||
m_hwtags.push_back(cl.GetTypeByPath(speed.m_type));
|
||||
|
||||
for (auto const & surface : CarModel::GetSurfaces())
|
||||
m_surfaceTags.push_back(cl.GetTypeByPath(surface.m_type));
|
||||
for (auto const & e : routing::kHighwayBasedSurface)
|
||||
m_surfaceTags.push_back(static_cast<uint32_t>(e.first));
|
||||
}
|
||||
|
||||
struct Type
|
||||
|
@ -402,8 +398,8 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
|
|||
|
||||
auto const countryName = storage.GetTopmostParentFor(mwmName);
|
||||
auto const carModelFactory = make_shared<CarModelFactory>(VehicleModelFactory::CountryParentNameGetterFn{});
|
||||
shared_ptr<VehicleModelInterface> vehicleModel =
|
||||
carModelFactory->GetVehicleModelForCountry(mwmName);
|
||||
shared_ptr<VehicleModelInterface> vehicleModel = carModelFactory->GetVehicleModelForCountry(mwmName);
|
||||
|
||||
string const mwmFile = GetCurrentVersionMwmFile(storage, mwmName);
|
||||
MatchedTrackPointToMoveType pointToMoveType(FilesContainerR(make_unique<FileReader>(mwmFile)), *vehicleModel);
|
||||
Geometry geometry(GeometryLoader::CreateFromFile(mwmFile, vehicleModel));
|
||||
|
|
|
@ -147,7 +147,7 @@ void TrackMatcher::Step::FillCandidatesWithNearbySegments(
|
|||
if (ft.GetID().m_mwmId.GetInfo()->GetType() != MwmInfo::COUNTRY)
|
||||
return;
|
||||
|
||||
if (!vehicleModel.IsRoad(ft))
|
||||
if (!vehicleModel.HasRoadType(ft))
|
||||
return;
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
|
|
|
@ -177,13 +177,17 @@ SpeedGroup TrafficInfo::GetSpeedGroup(RoadSegmentId const & id) const
|
|||
void TrafficInfo::ExtractTrafficKeys(string const & mwmPath, vector<RoadSegmentId> & result)
|
||||
{
|
||||
result.clear();
|
||||
feature::ForEachFeature(mwmPath, [&](FeatureType & ft, uint32_t const fid) {
|
||||
if (!routing::CarModel::AllLimitsInstance().IsRoad(ft))
|
||||
|
||||
auto const & carModel = routing::CarModel::AllLimitsInstance();
|
||||
feature::ForEachFeature(mwmPath, [&](FeatureType & ft, uint32_t const fid)
|
||||
{
|
||||
auto const response = carModel.GetFeatureInfo(ft, {});
|
||||
if (!response.m_isValid)
|
||||
return;
|
||||
|
||||
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
|
||||
auto const numPoints = static_cast<uint16_t>(ft.GetPointsCount());
|
||||
uint8_t const numDirs = routing::CarModel::AllLimitsInstance().IsOneWay(ft) ? 1 : 2;
|
||||
uint8_t const numDirs = response.m_isOneWay ? 1 : 2;
|
||||
for (uint16_t i = 0; i + 1 < numPoints; ++i)
|
||||
{
|
||||
for (uint8_t dir = 0; dir < numDirs; ++dir)
|
||||
|
|
Reference in a new issue