diff options
author | VladiMihaylenko <vxmihaylenko@gmail.com> | 2019-03-05 12:21:58 +0300 |
---|---|---|
committer | VladiMihaylenko <vxmihaylenko@gmail.com> | 2019-03-25 17:48:15 +0300 |
commit | 0b3678e958fa2ba12d9cae400c92e98bb1a70b10 (patch) | |
tree | fad7732d51a604d3d01292abcb3493aecbfcba13 /routing_common | |
parent | 4ee5c709ad929c44ae235680c950731abf5865e5 (diff) |
[routing] Refactored vehicle models and fixed tests.
Diffstat (limited to 'routing_common')
-rw-r--r-- | routing_common/bicycle_model.cpp | 727 | ||||
-rw-r--r-- | routing_common/car_model.cpp | 407 | ||||
-rw-r--r-- | routing_common/car_model.hpp | 6 | ||||
-rw-r--r-- | routing_common/car_model_coefs_default.hpp | 76 | ||||
-rw-r--r-- | routing_common/pedestrian_model.cpp | 438 | ||||
-rw-r--r-- | routing_common/routing_common_tests/vehicle_model_test.cpp | 131 | ||||
-rw-r--r-- | routing_common/vehicle_model.cpp | 317 | ||||
-rw-r--r-- | routing_common/vehicle_model.hpp | 273 |
8 files changed, 1291 insertions, 1084 deletions
diff --git a/routing_common/bicycle_model.cpp b/routing_common/bicycle_model.cpp index df7a0ef66a..b65a0533db 100644 --- a/routing_common/bicycle_model.cpp +++ b/routing_common/bicycle_model.cpp @@ -12,10 +12,6 @@ using namespace std; namespace { -using InOutCitySpeedKMpH = VehicleModel::InOutCitySpeedKMpH; -using SpeedKMpH = VehicleModel::SpeedKMpH; -using MaxspeedFactor = VehicleModel::MaxspeedFactor; - // 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, @@ -26,407 +22,385 @@ using MaxspeedFactor = VehicleModel::MaxspeedFactor; // https://wiki.openstreetmap.org/wiki/Key:highway // Heuristics: -// For less bicycle roads we add fine by setting smaller value of speed, and for more bicycle roads we -// set greater values of speed. Algorithm picks roads with greater speed first, preferencing a more bicycle roads over -// less bicycle. As result of such heuristic road is not totally the shortest, but it avoids non bicycle roads, which were +// For less bicycle roads we add fine by setting smaller value of weight speed, and for more bicycle roads we +// set greater values of weight speed. Algorithm picks roads with greater weight speed first, +// preferencing a more bicycle roads over less bicycle. +// 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. -// Speed of road features located inside and outside cities and towns polygons in km per hour. -// in city out city maxspeed factor is not used -InOutCitySpeedKMpH constexpr kSpeedTrunkKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTrunkLinkKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryKMpH(SpeedKMpH(10.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryLinkKMpH(SpeedKMpH(10.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryKMpH(SpeedKMpH(15.0), SpeedKMpH(20.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryLinkKMpH(SpeedKMpH(15.0), SpeedKMpH(20.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryKMpH(SpeedKMpH(15.0), SpeedKMpH(20.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryLinkKMpH(SpeedKMpH(15.0), SpeedKMpH(20.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedServiceKMpH(SpeedKMpH(12.0), SpeedKMpH(12.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedUnclassifiedKMpH(SpeedKMpH(12.0), SpeedKMpH(12.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedRoadKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTrackKMpH(SpeedKMpH(8.0), SpeedKMpH(8.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPathKMpH(SpeedKMpH(6.0), SpeedKMpH(6.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedBridlewayKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedCyclewayKMpH(SpeedKMpH(20.0), SpeedKMpH(20.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedResidentialKMpH(SpeedKMpH(8.0), SpeedKMpH(8.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedLivingStreetKMpH(SpeedKMpH(7.0), SpeedKMpH(7.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedStepsKMpH(SpeedKMpH(1.0), SpeedKMpH(1.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPedestrianKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedFootwayKMpH(SpeedKMpH(7.0), SpeedKMpH(7.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPlatformKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPierKMpH(SpeedKMpH(7.0), SpeedKMpH(7.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedFerryKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); +HighwayBasedFactors const kDefaultFactors{}; + +HighwayBasedMeanSpeeds 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))}, + {HighwayType::HighwayPrimaryLink, InOutCitySpeedKMpH(SpeedKMpH(10.0, 18.0), SpeedKMpH(14.0, 18.0))}, + {HighwayType::HighwaySecondary, InOutCitySpeedKMpH(SpeedKMpH(15.0, 18.0), SpeedKMpH(20.0, 18.0))}, + {HighwayType::HighwaySecondaryLink, InOutCitySpeedKMpH(SpeedKMpH(15.0, 18.0), SpeedKMpH(20.0, 18.0))}, + {HighwayType::HighwayTertiary, InOutCitySpeedKMpH(SpeedKMpH(15.0, 18.0), SpeedKMpH(20.0, 18.0))}, + {HighwayType::HighwayTertiaryLink, InOutCitySpeedKMpH(SpeedKMpH(15.0, 18.0), SpeedKMpH(20.0, 18.0))}, + {HighwayType::HighwayService, InOutCitySpeedKMpH(SpeedKMpH(12.0, 18.0))}, + {HighwayType::HighwayUnclassified, InOutCitySpeedKMpH(SpeedKMpH(12.0, 18.0))}, + {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::HighwaySteps, InOutCitySpeedKMpH(SpeedKMpH(1.0, 5.0))}, + {HighwayType::HighwayPedestrian, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayFootway, InOutCitySpeedKMpH(SpeedKMpH(7.0, 5.0))}, + {HighwayType::HighwayPlatform, InOutCitySpeedKMpH(SpeedKMpH(3.0))}, + {HighwayType::ManMadePier, InOutCitySpeedKMpH(SpeedKMpH(7.0))}, + {HighwayType::RouteFerry, InOutCitySpeedKMpH(SpeedKMpH(3.0, 20.0))}, +}; double constexpr kSpeedOffroadKMpH = 3.0; // Default -VehicleModel::LimitsInitList const g_bicycleLimitsDefault = -{ -// {{roadType, roadType} Speed km per hour passThroughAllowed} - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // All options available. -VehicleModel::LimitsInitList const g_bicycleLimitsAll = -{ - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except trunk and trunk_link are not allowed -VehicleModel::LimitsInitList const g_bicycleLimitsNoTrunk = -{ - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except pedestrian is allowed -VehicleModel::LimitsInitList const g_bicycleLimitsPedestrianAllowed = -{ - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except bridleway is allowed -VehicleModel::LimitsInitList const g_bicycleLimitsBridlewayAllowed = -{ - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Australia -VehicleModel::LimitsInitList const g_bicycleLimitsAustralia = g_bicycleLimitsAll; +VehicleModel::LimitsInitList const kBicycleOptionsAustralia = kBicycleOptionsAll; // Austria -VehicleModel::LimitsInitList const g_bicycleLimitsAustria = -{ - // No trunk, trunk_link, path - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Belarus -VehicleModel::LimitsInitList const g_bicycleLimitsBelarus = -{ - // Footway and pedestrian are allowed - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +VehicleModel::LimitsInitList const kBicycleOptionsBelarus = { + // Footway and pedestrian 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", "cycleway"}, true}, + {{"highway", "residential"}, true}, + {{"highway", "living_street"}, true}, + {{"highway", "steps"}, true}, + {{"highway", "pedestrian"}, true}, + {{"highway", "footway"}, true}, + {{"highway", "platform"}, true}}; // Belgium -VehicleModel::LimitsInitList const g_bicycleLimitsBelgium = -{ - // No trunk, trunk_link - // Pedestrian is allowed - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Brazil -VehicleModel::LimitsInitList const g_bicycleLimitsBrazil = -{ - // Bridleway and fotway are allowed - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Denmark -VehicleModel::LimitsInitList const g_bicycleLimitsDenmark = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsDenmark = kBicycleOptionsNoTrunk; // France -VehicleModel::LimitsInitList const g_bicycleLimitsFrance = -{ - // No trunk, trunk_link - // Pedestrian is allowed - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Finland -VehicleModel::LimitsInitList const g_bicycleLimitsFinland = g_bicycleLimitsPedestrianAllowed; +VehicleModel::LimitsInitList const kBicycleOptionsFinland = kBicycleOptionsPedestrianAllowed; // Germany -VehicleModel::LimitsInitList const g_bicycleLimitsGermany = g_bicycleLimitsDefault; +VehicleModel::LimitsInitList const kBicycleOptionsGermany = kBicycleOptionsDefault; // Hungary -VehicleModel::LimitsInitList const g_bicycleLimitsHungary = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsHungary = kBicycleOptionsNoTrunk; // Iceland -VehicleModel::LimitsInitList const g_bicycleLimitsIceland = g_bicycleLimitsAll; +VehicleModel::LimitsInitList const kBicycleOptionsIceland = kBicycleOptionsAll; // Netherlands -VehicleModel::LimitsInitList const g_bicycleLimitsNetherlands = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsNetherlands = kBicycleOptionsNoTrunk; // Norway -VehicleModel::LimitsInitList const g_bicycleLimitsNorway = g_bicycleLimitsAll; +VehicleModel::LimitsInitList const kBicycleOptionsNorway = kBicycleOptionsAll; // Oman -VehicleModel::LimitsInitList const g_bicycleLimitsOman = g_bicycleLimitsBridlewayAllowed; +VehicleModel::LimitsInitList const kBicycleOptionsOman = kBicycleOptionsBridlewayAllowed; // Poland -VehicleModel::LimitsInitList const g_bicycleLimitsPoland = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsPoland = kBicycleOptionsNoTrunk; // Romania -VehicleModel::LimitsInitList const g_bicycleLimitsRomania = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsRomania = kBicycleOptionsNoTrunk; // Russian Federation -VehicleModel::LimitsInitList const g_bicycleLimitsRussia = -{ - // Footway and pedestrian are allowed - // No pass through service and living_street - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, false}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, false}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedPedestrianKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +VehicleModel::LimitsInitList const kBicycleOptionsRussia = { + // Footway and pedestrian are allowed + // No pass through service and living_street + {{"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"}, 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}, + {{"highway", "platform"}, true}}; // Slovakia -VehicleModel::LimitsInitList const g_bicycleLimitsSlovakia = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsSlovakia = kBicycleOptionsNoTrunk; // Spain -VehicleModel::LimitsInitList const g_bicycleLimitsSpain = g_bicycleLimitsPedestrianAllowed; +VehicleModel::LimitsInitList const kBicycleOptionsSpain = kBicycleOptionsPedestrianAllowed; // Switzerland -VehicleModel::LimitsInitList const g_bicycleLimitsSwitzerland = g_bicycleLimitsNoTrunk; +VehicleModel::LimitsInitList const kBicycleOptionsSwitzerland = kBicycleOptionsNoTrunk; // Turkey -VehicleModel::LimitsInitList const g_bicycleLimitsTurkey = g_bicycleLimitsDefault; +VehicleModel::LimitsInitList const kBicycleOptionsTurkey = kBicycleOptionsDefault; // Ukraine -VehicleModel::LimitsInitList const g_bicycleLimitsUkraine = -{ - // No trunk - // Footway and perestrian are allowed - // No pass through living_street and service - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, false}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, false}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +VehicleModel::LimitsInitList const kBicycleOptionsUkraine = { + // No trunk + // Footway and perestrian 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}, + {{"highway", "platform"}, true}}; // United Kingdom -VehicleModel::LimitsInitList const g_bicycleLimitsUK = g_bicycleLimitsBridlewayAllowed; +VehicleModel::LimitsInitList const kBicycleOptionsUK = kBicycleOptionsBridlewayAllowed; // United States of America -VehicleModel::LimitsInitList const g_bicycleLimitsUS = -{ - // Bridleway and pedesprian are allowed - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; - -VehicleModel::SurfaceInitList const g_bicycleSurface = { +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}, + {{"highway", "platform"}, true}}; + +VehicleModel::SurfaceInitList const kBicycleSurface = { // {{surfaceType, surfaceType}, {weightFactor, etaFactor}} {{"psurface", "paved_good"}, {1.0, 1.0}}, {{"psurface", "paved_bad"}, {0.8, 0.8}}, @@ -437,13 +411,15 @@ VehicleModel::SurfaceInitList const g_bicycleSurface = { namespace routing { -BicycleModel::BicycleModel() : VehicleModel(classif(), g_bicycleLimitsDefault, g_bicycleSurface) +BicycleModel::BicycleModel() + : VehicleModel(classif(), kBicycleOptionsDefault, kBicycleSurface, + {kDefaultSpeeds, kDefaultFactors}) { Init(); } BicycleModel::BicycleModel(VehicleModel::LimitsInitList const & speedLimits) - : VehicleModel(classif(), speedLimits, g_bicycleSurface) + : VehicleModel(classif(), speedLimits, kBicycleSurface, {kDefaultSpeeds, kDefaultFactors}) { Init(); } @@ -457,10 +433,9 @@ void BicycleModel::Init() m_bidirBicycleType = classif().GetTypeByPath({"hwtag", "bidir_bicycle"}); vector<AdditionalRoadTags> const additionalTags = { - {hwtagYesBicycle, m_modelMaxSpeed}, - {{"route", "ferry"}, kSpeedFerryKMpH}, - {{"man_made", "pier"}, kSpeedPierKMpH} - }; + {hwtagYesBicycle, m_maxModelSpeed}, + {{"route", "ferry"}, kDefaultSpeeds.at(HighwayType::RouteFerry)}, + {{"man_made", "pier"}, kDefaultSpeeds.at(HighwayType::ManMadePier)}}; SetAdditionalRoadTypes(classif(), additionalTags); } @@ -469,8 +444,10 @@ VehicleModelInterface::RoadAvailability BicycleModel::GetRoadAvailability(featur { if (types.Has(m_yesBicycleType)) return RoadAvailability::Available; + if (types.Has(m_noBicycleType)) return RoadAvailability::NotAvailable; + return RoadAvailability::Unknown; } @@ -501,7 +478,7 @@ double BicycleModel::GetOffroadSpeed() const { return kSpeedOffroadKMpH; } // static BicycleModel const & BicycleModel::AllLimitsInstance() { - static BicycleModel const instance(g_bicycleLimitsAll); + static BicycleModel const instance(kBicycleOptionsAll); return instance; } @@ -510,30 +487,30 @@ BicycleModelFactory::BicycleModelFactory( : VehicleModelFactory(countryParentNameGetterFn) { // Names must be the same with country names from countries.txt - m_models[""] = make_shared<BicycleModel>(g_bicycleLimitsDefault); - m_models["Australia"] = make_shared<BicycleModel>(g_bicycleLimitsAustralia); - m_models["Austria"] = make_shared<BicycleModel>(g_bicycleLimitsAustria); - m_models["Belarus"] = make_shared<BicycleModel>(g_bicycleLimitsBelarus); - m_models["Belgium"] = make_shared<BicycleModel>(g_bicycleLimitsBelgium); - m_models["Brazil"] = make_shared<BicycleModel>(g_bicycleLimitsBrazil); - m_models["Denmark"] = make_shared<BicycleModel>(g_bicycleLimitsDenmark); - m_models["France"] = make_shared<BicycleModel>(g_bicycleLimitsFrance); - m_models["Finland"] = make_shared<BicycleModel>(g_bicycleLimitsFinland); - m_models["Germany"] = make_shared<BicycleModel>(g_bicycleLimitsGermany); - m_models["Hungary"] = make_shared<BicycleModel>(g_bicycleLimitsHungary); - m_models["Iceland"] = make_shared<BicycleModel>(g_bicycleLimitsIceland); - m_models["Netherlands"] = make_shared<BicycleModel>(g_bicycleLimitsNetherlands); - m_models["Norway"] = make_shared<BicycleModel>(g_bicycleLimitsNorway); - m_models["Oman"] = make_shared<BicycleModel>(g_bicycleLimitsOman); - m_models["Poland"] = make_shared<BicycleModel>(g_bicycleLimitsPoland); - m_models["Romania"] = make_shared<BicycleModel>(g_bicycleLimitsRomania); - m_models["Russian Federation"] = make_shared<BicycleModel>(g_bicycleLimitsRussia); - m_models["Slovakia"] = make_shared<BicycleModel>(g_bicycleLimitsSlovakia); - m_models["Spain"] = make_shared<BicycleModel>(g_bicycleLimitsSpain); - m_models["Switzerland"] = make_shared<BicycleModel>(g_bicycleLimitsSwitzerland); - m_models["Turkey"] = make_shared<BicycleModel>(g_bicycleLimitsTurkey); - m_models["Ukraine"] = make_shared<BicycleModel>(g_bicycleLimitsUkraine); - m_models["United Kingdom"] = make_shared<BicycleModel>(g_bicycleLimitsUK); - m_models["United States of America"] = make_shared<BicycleModel>(g_bicycleLimitsUS); + 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); } } // routing diff --git a/routing_common/car_model.cpp b/routing_common/car_model.cpp index 57c522fb0c..9bec801045 100644 --- a/routing_common/car_model.cpp +++ b/routing_common/car_model.cpp @@ -1,234 +1,209 @@ #include "routing_common/car_model.hpp" +#include "routing_common/car_model_coefs.hpp" #include "base/macros.hpp" #include "indexer/classificator.hpp" -#include <algorithm> -#include <vector> +#include <array> +#include <unordered_map> using namespace std; using namespace routing; namespace { -using InOutCitySpeedKMpH = VehicleModel::InOutCitySpeedKMpH; -using SpeedKMpH = VehicleModel::SpeedKMpH; -using MaxspeedFactor = VehicleModel::MaxspeedFactor; - // See model specifics in different countries here: // https://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Access-Restrictions // See road types here: // https://wiki.openstreetmap.org/wiki/Key:highway -// Speed of road features located inside and outside cities and towns polygons in km per hour. -// in city out city -InOutCitySpeedKMpH constexpr kSpeedMotorwayKMpH(SpeedKMpH(117.8), SpeedKMpH(123.4), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedMotorwayLinkKMpH(SpeedKMpH(82.0), SpeedKMpH(81.2), MaxspeedFactor(0.85)); -InOutCitySpeedKMpH constexpr kSpeedTrunkKMpH(SpeedKMpH(83.4), SpeedKMpH(100.2), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTrunkLinkKMpH(SpeedKMpH(73.0), SpeedKMpH(77.2), MaxspeedFactor(0.85)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryKMpH(SpeedKMpH(63.1), SpeedKMpH(75.2), MaxspeedFactor(0.95)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryLinkKMpH(SpeedKMpH(66.5), SpeedKMpH(64.8), MaxspeedFactor(0.8)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryKMpH(SpeedKMpH(52.8), SpeedKMpH(60.3), MaxspeedFactor(0.9)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryLinkKMpH(SpeedKMpH(50.2), SpeedKMpH(60.0), MaxspeedFactor(0.75)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryKMpH(SpeedKMpH(45.5), SpeedKMpH(50.5), MaxspeedFactor(0.85)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryLinkKMpH(SpeedKMpH(25.0), SpeedKMpH(30.0), MaxspeedFactor(0.7)); -InOutCitySpeedKMpH constexpr kSpeedResidentialKMpH(SpeedKMpH(20.0), SpeedKMpH(25.0), MaxspeedFactor(0.75)); -InOutCitySpeedKMpH constexpr kSpeedUnclassifiedKMpH(SpeedKMpH(51.3), SpeedKMpH(66.0), MaxspeedFactor(0.8)); -InOutCitySpeedKMpH constexpr kSpeedServiceKMpH(SpeedKMpH(15.0), SpeedKMpH(15.0), MaxspeedFactor(0.8)); -InOutCitySpeedKMpH constexpr kSpeedLivingStreetKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.75)); -InOutCitySpeedKMpH constexpr kSpeedRoadKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.3)); -InOutCitySpeedKMpH constexpr kSpeedTrackKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(0.3)); -InOutCitySpeedKMpH constexpr kSpeedFerryMotorcarKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.9)); -InOutCitySpeedKMpH constexpr kSpeedFerryMotorcarVehicleKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.9)); -InOutCitySpeedKMpH constexpr kSpeedRailMotorcarVehicleKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.9)); -InOutCitySpeedKMpH constexpr kSpeedShuttleTrainKMpH(SpeedKMpH(25.0), SpeedKMpH(25.0), MaxspeedFactor(0.9)); -InOutCitySpeedKMpH constexpr kSpeedPierKMpH(SpeedKMpH(10.0), SpeedKMpH(10.0), MaxspeedFactor(0.9)); - -double constexpr kSpeedOffroadKMpH = 10.0; - -VehicleModel::LimitsInitList const g_carLimitsDefault = -{ - // {{roadType, roadType} Speed km per hour passThroughAllowed} - {{"highway", "motorway"}, kSpeedMotorwayKMpH, true}, - {{"highway", "motorway_link"}, kSpeedMotorwayLinkKMpH, true}, - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true} - /// @todo: Add to classificator - //{ {"highway", "shuttle_train"}, 10 }, - //{ {"highway", "ferry"}, 5 }, - //{ {"highway", "default"}, 10 }, - /// @todo: Check type - //{ {"highway", "construction"}, 40 }, -}; -VehicleModel::LimitsInitList const g_carLimitsNoPassThroughLivingStreet = -{ - {{"highway", "motorway"}, kSpeedMotorwayKMpH, true}, - {{"highway", "motorway_link"}, kSpeedMotorwayLinkKMpH, true}, - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, false}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true} -}; - -VehicleModel::LimitsInitList const g_carLimitsNoPassThroughLivingStreetAndService = -{ - {{"highway", "motorway"}, kSpeedMotorwayKMpH, true}, - {{"highway", "motorway_link"}, kSpeedMotorwayLinkKMpH, true}, - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, false}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, false}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true} -}; +// // Names must be the same with country names from countries.txt +std::array<char const *, 41> constexpr kCountries = {"Australia", + "Austria", + "Belarus", + "Belgium", + "Brazil", + "Canada", + "Colombia", + "Czech Republic", + "Denmark", + "Ecuador", + "Finland", + "France", + "Germany", + "Hungary", + "Indonesia", + "Ireland", + "Italy", + "Kuwait", + "Luxembourg", + "Mexico", + "Netherlands", + "New Zealand", + "Norway", + "Poland", + "Portugal", + "Romania", + "Russian Federation", + "Saudi Arabia", + "Singapore", + "Slovakia", + "South Africa", + "Spain", + "Sweden", + "Switzerland", + "Thailand", + "Turkey", + "Ukraine", + "United Arab Emirates", + "United Kingdom", + "United States of America", + "Venezuela"}; -VehicleModel::LimitsInitList const g_carLimitsAustralia = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsAustria = g_carLimitsNoPassThroughLivingStreet; - -VehicleModel::LimitsInitList const g_carLimitsBelarus = g_carLimitsNoPassThroughLivingStreet; - -VehicleModel::LimitsInitList const g_carLimitsBelgium = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsBrazil = g_carLimitsDefault; +double constexpr kSpeedOffroadKMpH = 10.0; -VehicleModel::LimitsInitList const g_carLimitsDenmark = -{ - // No track - {{"highway", "motorway"}, kSpeedMotorwayKMpH, true}, - {{"highway", "motorway_link"}, kSpeedMotorwayLinkKMpH, true}, - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true} +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 }, }; -VehicleModel::LimitsInitList const g_carLimitsFrance = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsFinland = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsGermany = -{ - // No pass through track - {{"highway", "motorway"}, kSpeedMotorwayKMpH, true}, - {{"highway", "motorway_link"}, kSpeedMotorwayLinkKMpH, true}, - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, false} -}; - -VehicleModel::LimitsInitList const g_carLimitsHungary = g_carLimitsNoPassThroughLivingStreet; - -VehicleModel::LimitsInitList const g_carLimitsIceland = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsNetherlands = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsNorway = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsOman = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsPoland = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsRomania = g_carLimitsNoPassThroughLivingStreet; - -VehicleModel::LimitsInitList const g_carLimitsRussia = g_carLimitsNoPassThroughLivingStreetAndService; - -VehicleModel::LimitsInitList const g_carLimitsSlovakia = g_carLimitsNoPassThroughLivingStreet; - -VehicleModel::LimitsInitList const g_carLimitsSpain = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsSwitzerland = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsTurkey = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsUkraine = g_carLimitsNoPassThroughLivingStreetAndService; - -VehicleModel::LimitsInitList const g_carLimitsUK = g_carLimitsDefault; - -VehicleModel::LimitsInitList const g_carLimitsUS = g_carLimitsDefault; +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}}; + +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}}; + +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}}; + +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}}; vector<VehicleModel::AdditionalRoadTags> const kAdditionalTags = { - // {{highway tags}, {weightSpeed, etaSpeed}} - {{"route", "ferry", "motorcar"}, kSpeedFerryMotorcarKMpH}, - {{"route", "ferry", "motor_vehicle"}, kSpeedFerryMotorcarVehicleKMpH}, - {{"railway", "rail", "motor_vehicle"}, kSpeedRailMotorcarVehicleKMpH}, - {{"route", "shuttle_train"}, kSpeedShuttleTrainKMpH}, - {{"route", "ferry"}, kSpeedFerryMotorcarKMpH}, - {{"man_made", "pier"}, kSpeedPierKMpH} -}; - -VehicleModel::SurfaceInitList const g_carSurface = { + // {{highway tags}, {weightSpeed, etaSpeed}} + {{"route", "ferry", "motorcar"}, kGlobalHighwayBasedMeanSpeeds.at(HighwayType::RouteFerryMotorcar)}, + {{"route", "ferry", "motor_vehicle"}, kGlobalHighwayBasedMeanSpeeds.at(HighwayType::RouteFerryMotorVehicle)}, + {{"railway", "rail", "motor_vehicle"}, kGlobalHighwayBasedMeanSpeeds.at(HighwayType::RailwayRailMotorVehicle)}, + {{"route", "shuttle_train"}, kGlobalHighwayBasedMeanSpeeds.at(HighwayType::RouteShuttleTrain)}, + {{"route", "ferry"}, kGlobalHighwayBasedMeanSpeeds.at(HighwayType::RouteFerryMotorcar)}, + {{"man_made", "pier"}, kGlobalHighwayBasedMeanSpeeds.at(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.8, 0.8}}, {{"psurface", "unpaved_bad"}, {0.3, 0.3}} }; + +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 namespace routing { - CarModel::CarModel() - : VehicleModel(classif(), g_carLimitsDefault, g_carSurface) + : VehicleModel(classif(), kCarOptionsDefault, kCarSurface, + {kGlobalHighwayBasedMeanSpeeds, kGlobalHighwayBasedFactors}) { InitAdditionalRoadTypes(); } -CarModel::CarModel(VehicleModel::LimitsInitList const & roadLimits) - : VehicleModel(classif(), roadLimits, g_carSurface) +CarModel::CarModel(VehicleModel::LimitsInitList const & roadLimits, HighwayBasedInfo const & info) + : VehicleModel(classif(), roadLimits, kCarSurface, info) { InitAdditionalRoadTypes(); } @@ -248,7 +223,7 @@ CarModel const & CarModel::AllLimitsInstance() } // static -routing::VehicleModel::LimitsInitList const & CarModel::GetLimits() { return g_carLimitsDefault; } +routing::VehicleModel::LimitsInitList const & CarModel::GetOptions() { return kCarOptionsDefault; } // static vector<routing::VehicleModel::AdditionalRoadTags> const & CarModel::GetAdditionalTags() @@ -257,36 +232,28 @@ vector<routing::VehicleModel::AdditionalRoadTags> const & CarModel::GetAdditiona } // static -VehicleModel::SurfaceInitList const & CarModel::GetSurfaces() { return g_carSurface; } +VehicleModel::SurfaceInitList const & CarModel::GetSurfaces() { return kCarSurface; } CarModelFactory::CarModelFactory(CountryParentNameGetterFn const & countryParentNameGetterFn) : VehicleModelFactory(countryParentNameGetterFn) { - // Names must be the same with country names from countries.txt - m_models[""] = make_shared<CarModel>(g_carLimitsDefault); - m_models["Australia"] = make_shared<CarModel>(g_carLimitsAustralia); - m_models["Austria"] = make_shared<CarModel>(g_carLimitsAustria); - m_models["Belarus"] = make_shared<CarModel>(g_carLimitsBelarus); - m_models["Belgium"] = make_shared<CarModel>(g_carLimitsBelgium); - m_models["Brazil"] = make_shared<CarModel>(g_carLimitsBrazil); - m_models["Denmark"] = make_shared<CarModel>(g_carLimitsDenmark); - m_models["France"] = make_shared<CarModel>(g_carLimitsFrance); - m_models["Finland"] = make_shared<CarModel>(g_carLimitsFinland); - m_models["Germany"] = make_shared<CarModel>(g_carLimitsGermany); - m_models["Hungary"] = make_shared<CarModel>(g_carLimitsHungary); - m_models["Iceland"] = make_shared<CarModel>(g_carLimitsIceland); - m_models["Netherlands"] = make_shared<CarModel>(g_carLimitsNetherlands); - m_models["Norway"] = make_shared<CarModel>(g_carLimitsNorway); - m_models["Oman"] = make_shared<CarModel>(g_carLimitsOman); - m_models["Poland"] = make_shared<CarModel>(g_carLimitsPoland); - m_models["Romania"] = make_shared<CarModel>(g_carLimitsRomania); - m_models["Russian Federation"] = make_shared<CarModel>(g_carLimitsRussia); - m_models["Slovakia"] = make_shared<CarModel>(g_carLimitsSlovakia); - m_models["Spain"] = make_shared<CarModel>(g_carLimitsSpain); - m_models["Switzerland"] = make_shared<CarModel>(g_carLimitsSwitzerland); - m_models["Turkey"] = make_shared<CarModel>(g_carLimitsTurkey); - m_models["Ukraine"] = make_shared<CarModel>(g_carLimitsUkraine); - m_models["United Kingdom"] = make_shared<CarModel>(g_carLimitsUK); - m_models["United States of America"] = make_shared<CarModel>(g_carLimitsUS); + auto const & speeds = kCountryToHighwayBasedMeanSpeeds; + auto const & factors = kCountryToHighwayBasedFactors; + m_models[""] = make_shared<CarModel>( + kCarOptionsDefault, + HighwayBasedInfo(kGlobalHighwayBasedMeanSpeeds, kGlobalHighwayBasedFactors)); + for (auto const * country : kCountries) + { + auto const limitIt = kCarOptionsByCountries.find(country); + auto const & limit = limitIt == kCarOptionsByCountries.cend() ? kCarOptionsDefault : limitIt->second; + auto const speedIt = speeds.find(country); + auto const & speed = speedIt == speeds.cend() ? kGlobalHighwayBasedMeanSpeeds : speedIt->second; + auto const factorIt = factors.find(country); + auto const & factor = + factorIt == factors.cend() ? kGlobalHighwayBasedFactors : factorIt->second; + m_models[country] = make_shared<CarModel>( + limit, + HighwayBasedInfo(speed, kGlobalHighwayBasedMeanSpeeds, factor, kGlobalHighwayBasedFactors)); + } } } // namespace routing diff --git a/routing_common/car_model.hpp b/routing_common/car_model.hpp index fbbecf5c0c..d72b4410fa 100644 --- a/routing_common/car_model.hpp +++ b/routing_common/car_model.hpp @@ -2,6 +2,8 @@ #include "routing_common/vehicle_model.hpp" +#include <vector> + namespace routing { @@ -9,13 +11,13 @@ class CarModel : public VehicleModel { public: CarModel(); - CarModel(VehicleModel::LimitsInitList const & roadLimits); + CarModel(VehicleModel::LimitsInitList const & roadLimits, HighwayBasedInfo const & info); // VehicleModelInterface overrides: double GetOffroadSpeed() const override; static CarModel const & AllLimitsInstance(); - static LimitsInitList const & GetLimits(); + static LimitsInitList const & GetOptions(); static std::vector<AdditionalRoadTags> const & GetAdditionalTags(); static VehicleModel::SurfaceInitList const & GetSurfaces(); diff --git a/routing_common/car_model_coefs_default.hpp b/routing_common/car_model_coefs_default.hpp index 0f9ecff31a..d9718e8702 100644 --- a/routing_common/car_model_coefs_default.hpp +++ b/routing_common/car_model_coefs_default.hpp @@ -8,71 +8,71 @@ namespace routing { HighwayBasedFactors const kGlobalHighwayBasedFactors = { - {"highway-motorway" /* highway class */, { + {HighwayType::HighwayMotorway, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(1.0)} }}, - {"highway-trunk" /* highway class */, { + {HighwayType::HighwayTrunk, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(1.0)} }}, - {"highway-primary" /* highway class */, { + {HighwayType::HighwayPrimary /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.95)} }}, - {"highway-secondary" /* highway class */, { + {HighwayType::HighwaySecondary /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, - {"highway-tertiary" /* highway class */, { + {HighwayType::HighwayTertiary /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.85)} }}, - {"highway-residential" /* highway class */, { + {HighwayType::HighwayResidential /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.75)} }}, - {"highway-unclassified" /* highway class */, { + {HighwayType::HighwayUnclassified /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.80)} }}, - {"highway-service" /* highway class */, { + {HighwayType::HighwayService /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.80)} }}, - {"highway-living_street" /* highway class */, { + {HighwayType::HighwayLiving_street /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.75)} }}, - {"highway-road" /* highway class */, { + {HighwayType::HighwayRoad /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.30)} }}, - {"highway-track" /* highway class */, { + {HighwayType::HighwayTrack /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.30)} }}, - {"highway-track" /* highway class */, { + {HighwayType::HighwayTrack /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.30)} }}, - {"highway-ferry-motorcar" /* highway class */, { + {HighwayType::RouteFerryMotorcar /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, - {"highway-ferry-motor_vehicle" /* highway class */, { + {HighwayType::RouteFerryMotorVehicle /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, - {"highway-rail-motor_vehicle" /* highway class */, { + {HighwayType::RailwayRailMotorVehicle /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, - {"highway-shuttle_train" /* highway class */, { + {HighwayType::RouteShuttleTrain /* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, - {"man_made-pier" /* highway class */, { + {HighwayType::ManMadePier/* highway class */, { // {maxspeed : InOutCityFactor(in city, out city)} {kCommonMaxSpeedValue, InOutCityFactor(0.90)} }}, @@ -80,27 +80,27 @@ HighwayBasedFactors const kGlobalHighwayBasedFactors = { HighwayBasedMeanSpeeds const kGlobalHighwayBasedMeanSpeeds = { // {highway class : InOutCitySpeedKMpH(in city, out city)} - {"highway-motorway", InOutCitySpeedKMpH({117.80, 104.70} /* in city */, {123.40, 111.79} /* out city */)}, - {"highway-motorway_link", InOutCitySpeedKMpH({106.02, 94.23} /* in city */, {111.06, 100.61} /* out city */)}, - {"highway-trunk", InOutCitySpeedKMpH({83.40, 78.55} /* in city */, {100.20, 92.55} /* out city */)}, - {"highway-trunk_link", InOutCitySpeedKMpH({75.06, 70.69} /* in city */, {90.18, 83.30} /* out city */)}, - {"highway-primary", InOutCitySpeedKMpH({63.10, 58.81} /* in city */, {75.20, 69.60} /* out city */)}, - {"highway-primary_link", InOutCitySpeedKMpH({56.79, 52.93} /* in city */, {67.68, 62.64} /* out city */)}, - {"highway-secondary", InOutCitySpeedKMpH({52.80, 47.63} /* in city */, {60.30, 56.99} /* out city */)}, - {"highway-secondary_link", InOutCitySpeedKMpH({47.52, 42.87} /* in city */, {54.27, 51.29} /* out city */)}, - {"highway-tertiary", InOutCitySpeedKMpH({45.50, 38.86} /* in city */, {50.50, 44.14} /* out city */)}, - {"highway-tertiary_link", InOutCitySpeedKMpH({40.95, 34.97} /* in city */, {45.45, 39.73} /* out city */)}, - {"highway-residential", InOutCitySpeedKMpH({20.00, 20.00} /* in city */, {25.00, 25.00} /* out city */)}, - {"highway-unclassified", InOutCitySpeedKMpH({51.30, 51.30} /* in city */, {66.00, 66.00} /* out city */)}, - {"highway-service", InOutCitySpeedKMpH({15.00, 15.00} /* in city */, {15.00, 15.00} /* out city */)}, - {"highway-living_street", InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, - {"highway-road", InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, - {"highway-track", InOutCitySpeedKMpH({5.00, 5.00} /* in city */, {5.00, 5.00} /* out city */)}, - {"route-ferry-motorcar", InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, - {"route-ferry-motor_vehicle", InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, - {"railway-rail-motor_vehicle", InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, - {"route-shuttle_train", InOutCitySpeedKMpH({25.00, 25.00} /* in city */, {25.00, 25.00} /* out city */)}, - {"man_made-pier", InOutCitySpeedKMpH({17.00, 10.00} /* in city */, {17.00, 10.00} /* out city */)}, + {HighwayType::HighwayMotorway, InOutCitySpeedKMpH({117.80, 104.70} /* in city */, {123.40, 111.79} /* out city */)}, + {HighwayType::HighwayMotorwayLink, InOutCitySpeedKMpH({106.02, 94.23} /* in city */, {111.06, 100.61} /* out city */)}, + {HighwayType::HighwayTrunk, InOutCitySpeedKMpH({83.40, 78.55} /* in city */, {100.20, 92.55} /* out city */)}, + {HighwayType::HighwayTrunkLink, InOutCitySpeedKMpH({75.06, 70.69} /* in city */, {90.18, 83.30} /* out city */)}, + {HighwayType::HighwayPrimary, InOutCitySpeedKMpH({63.10, 58.81} /* in city */, {75.20, 69.60} /* out city */)}, + {HighwayType::HighwayPrimary_link, InOutCitySpeedKMpH({56.79, 52.93} /* in city */, {67.68, 62.64} /* out city */)}, + {HighwayType::HighwaySecondary, InOutCitySpeedKMpH({52.80, 47.63} /* in city */, {60.30, 56.99} /* out city */)}, + {HighwayType::HighwaySecondary_link, InOutCitySpeedKMpH({47.52, 42.87} /* in city */, {54.27, 51.29} /* out city */)}, + {HighwayType::HighwayTertiary, InOutCitySpeedKMpH({45.50, 38.86} /* in city */, {50.50, 44.14} /* out city */)}, + {HighwayType::HighwayTertiary_link, InOutCitySpeedKMpH({40.95, 34.97} /* in city */, {45.45, 39.73} /* out city */)}, + {HighwayType::HighwayResidential, InOutCitySpeedKMpH({20.00, 20.00} /* in city */, {25.00, 25.00} /* out city */)}, + {HighwayType::HighwayUnclassified, InOutCitySpeedKMpH({51.30, 51.30} /* in city */, {66.00, 66.00} /* out city */)}, + {HighwayType::HighwayService, InOutCitySpeedKMpH({15.00, 15.00} /* in city */, {15.00, 15.00} /* out city */)}, + {HighwayType::HighwayLiving_street, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, + {HighwayType::HighwayRoad, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, + {HighwayType::HighwayTrack, InOutCitySpeedKMpH({5.00, 5.00} /* in city */, {5.00, 5.00} /* out city */)}, + {HighwayType::RouteFerryMotorcar, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, + {HighwayType::RouteFerryMotorVehicle, InOutCitySpeedKMpH({10.00, 10.00} /* in city */, {10.00, 10.00} /* out city */)}, + {HighwayType::RailwayRailMotorVehicle, 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 */)}, + {HighwayType::ManMadePier, InOutCitySpeedKMpH({17.00, 10.00} /* in city */, {17.00, 10.00} /* out city */)}, }; CountryToHighwayBasedFactors const kCountryToHighwayBasedFactors{}; diff --git a/routing_common/pedestrian_model.cpp b/routing_common/pedestrian_model.cpp index bb34454f89..f75b502d65 100644 --- a/routing_common/pedestrian_model.cpp +++ b/routing_common/pedestrian_model.cpp @@ -12,10 +12,6 @@ using namespace std; namespace { -using InOutCitySpeedKMpH = VehicleModel::InOutCitySpeedKMpH; -using SpeedKMpH = VehicleModel::SpeedKMpH; -using MaxspeedFactor = VehicleModel::MaxspeedFactor; - // 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, @@ -26,257 +22,249 @@ using MaxspeedFactor = VehicleModel::MaxspeedFactor; // https://wiki.openstreetmap.org/wiki/Key:highway // Heuristics: -// For less pedestrian roads we add fine by setting smaller value of speed, and for more pedestrian roads we -// set greater values of speed. Algorithm picks roads with greater speed first, preferencing a more pedestrian roads over -// less pedestrian. As result of such heuristic road is not totally the shortest, but it avoids non pedestrian roads, which were +// For less pedestrian roads we add fine by setting smaller value of weight speed, and for more pedestrian roads we +// set greater values of weight speed. Algorithm picks roads with greater speed first, +// preferencing a more pedestrian roads over less pedestrian. +// 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. -// Speed of road features located inside and outside cities and towns polygons in km per hour. -// in city out city maxspeed factor is not used -InOutCitySpeedKMpH constexpr kSpeedTrunkKMpH(SpeedKMpH(1.0), SpeedKMpH(1.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTrunkLinkKMpH(SpeedKMpH(1.0), SpeedKMpH(1.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryKMpH(SpeedKMpH(2.0), SpeedKMpH(2.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPrimaryLinkKMpH(SpeedKMpH(2.0), SpeedKMpH(2.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedSecondaryLinkKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTertiaryLinkKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedServiceKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedUnclassifiedKMpH(SpeedKMpH(4.5), SpeedKMpH(4.5), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedRoadKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedTrackKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPathKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedBridlewayKMpH(SpeedKMpH(1.0), SpeedKMpH(1.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedCyclewayKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedResidentialKMpH(SpeedKMpH(4.5), SpeedKMpH(4.5), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedLivingStreetKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedStepsKMpH(SpeedKMpH(3.0), SpeedKMpH(3.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPedestrianKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedFootwayKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPlatformKMpH(SpeedKMpH(5.0), SpeedKMpH(5.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedPierKMpH(SpeedKMpH(4.0), SpeedKMpH(4.0), MaxspeedFactor(1.0)); -InOutCitySpeedKMpH constexpr kSpeedFerryKMpH(SpeedKMpH(1.0), SpeedKMpH(1.0), MaxspeedFactor(1.0)); +HighwayBasedFactors const kDefaultFactors{}; + +HighwayBasedMeanSpeeds const kDefaultSpeeds = { + // {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))}, + {HighwayType::HighwayPrimary, InOutCitySpeedKMpH(SpeedKMpH(2.0, 5.0))}, + {HighwayType::HighwayPrimaryLink, InOutCitySpeedKMpH(SpeedKMpH(2.0, 5.0))}, + {HighwayType::HighwaySecondary, InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0))}, + {HighwayType::HighwaySecondaryLink, InOutCitySpeedKMpH(SpeedKMpH(3.0, 5.0))}, + {HighwayType::HighwayTertiary, InOutCitySpeedKMpH(SpeedKMpH(4.0, 5.0))}, + {HighwayType::HighwayTertiaryLink, InOutCitySpeedKMpH(SpeedKMpH(4.0, 5.0))}, + {HighwayType::HighwayService, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayUnclassified, InOutCitySpeedKMpH(SpeedKMpH(4.5, 5.0))}, + {HighwayType::HighwayRoad, InOutCitySpeedKMpH(SpeedKMpH(4.0, 5.0))}, + {HighwayType::HighwayTrack, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayPath, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayBridleway, InOutCitySpeedKMpH(SpeedKMpH(1.0, 5.0))}, + {HighwayType::HighwayCycleway, InOutCitySpeedKMpH(SpeedKMpH(4.0, 5.0))}, + {HighwayType::HighwayResidential, InOutCitySpeedKMpH(SpeedKMpH(4.5, 5.0))}, + {HighwayType::HighwayLivingStreet, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwaySteps, InOutCitySpeedKMpH(SpeedKMpH(3.0))}, + {HighwayType::HighwayPedestrian, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayFootway, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::HighwayPlatform, InOutCitySpeedKMpH(SpeedKMpH(5.0))}, + {HighwayType::ManMadePier, InOutCitySpeedKMpH(SpeedKMpH(7.0))}, + {HighwayType::RouteFerry, InOutCitySpeedKMpH(SpeedKMpH(1.0, 20.0))}, +}; double constexpr kSpeedOffroadKMpH = 3.0; // Default -VehicleModel::LimitsInitList const g_pedestrianLimitsDefault = -{ - // {{roadType, roadType} {weightSpeedKMpH, etSpeedKMpH} passThroughAllowed} - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // All options available. -VehicleModel::LimitsInitList const g_pedestrianLimitsAll = -{ - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except trunk and trunk link are not allowed. -VehicleModel::LimitsInitList const g_pedestrianLimitsNoTrunk = -{ - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except cycleway is allowed. -VehicleModel::LimitsInitList const g_pedestrianLimitsCyclewayAllowed = -{ - {{"highway", "trunk"}, kSpeedTrunkKMpH, true}, - {{"highway", "trunk_link"}, kSpeedTrunkLinkKMpH, true}, - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Same as defaults except cycleway is allowed and trunk and trunk_link are not allowed. -VehicleModel::LimitsInitList const g_pedestrianLimitsCyclewayAllowedNoTrunk = -{ - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Australia -VehicleModel::LimitsInitList const g_pedestrianLimitsAustralia = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsAustralia = kPedestrianOptionsAll; // Austria -VehicleModel::LimitsInitList const g_pedestrianLimitsAustria = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsAustria = kPedestrianOptionsNoTrunk; // Belarus -VehicleModel::LimitsInitList const g_pedestrianLimitsBelarus = g_pedestrianLimitsCyclewayAllowed; +VehicleModel::LimitsInitList const kPedestrianOptionsBelarus = kPedestrianOptionsCyclewayAllowed; // Belgium -VehicleModel::LimitsInitList const g_pedestrianLimitsBelgium = -{ - // Trunk and trunk_link are not allowed - // Bridleway and cycleway are allowed - {{"highway", "primary"}, kSpeedPrimaryKMpH, true}, - {{"highway", "primary_link"}, kSpeedPrimaryLinkKMpH, true}, - {{"highway", "secondary"}, kSpeedSecondaryKMpH, true}, - {{"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH, true}, - {{"highway", "tertiary"}, kSpeedTertiaryKMpH, true}, - {{"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH, true}, - {{"highway", "service"}, kSpeedServiceKMpH, true}, - {{"highway", "unclassified"}, kSpeedUnclassifiedKMpH, true}, - {{"highway", "road"}, kSpeedRoadKMpH, true}, - {{"highway", "track"}, kSpeedTrackKMpH, true}, - {{"highway", "path"}, kSpeedPathKMpH, true}, - {{"highway", "bridleway"}, kSpeedBridlewayKMpH, true}, - {{"highway", "cycleway"}, kSpeedCyclewayKMpH, true}, - {{"highway", "residential"}, kSpeedResidentialKMpH, true}, - {{"highway", "living_street"}, kSpeedLivingStreetKMpH, true}, - {{"highway", "steps"}, kSpeedStepsKMpH, true}, - {{"highway", "pedestrian"}, kSpeedPedestrianKMpH, true}, - {{"highway", "footway"}, kSpeedFootwayKMpH, true}, - {{"highway", "platform"}, kSpeedPlatformKMpH, true} -}; +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}, + {{"highway", "platform"}, true}}; // Brazil -VehicleModel::LimitsInitList const g_pedestrianLimitsBrazil = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsBrazil = kPedestrianOptionsAll; // Denmark -VehicleModel::LimitsInitList const g_pedestrianLimitsDenmark = g_pedestrianLimitsCyclewayAllowedNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsDenmark = kPedestrianOptionsCyclewayAllowedNoTrunk; // France -VehicleModel::LimitsInitList const g_pedestrianLimitsFrance = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsFrance = kPedestrianOptionsNoTrunk; // Finland -VehicleModel::LimitsInitList const g_pedestrianLimitsFinland = g_pedestrianLimitsCyclewayAllowed; +VehicleModel::LimitsInitList const kPedestrianOptionsFinland = kPedestrianOptionsCyclewayAllowed; // Germany -VehicleModel::LimitsInitList const g_pedestrianLimitsGermany = g_pedestrianLimitsDefault; +VehicleModel::LimitsInitList const kPedestrianOptionsGermany = kPedestrianOptionsDefault; // Hungary -VehicleModel::LimitsInitList const g_pedestrianLimitsHungary = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsHungary = kPedestrianOptionsNoTrunk; // Iceland -VehicleModel::LimitsInitList const g_pedestrianLimitsIceland = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsIceland = kPedestrianOptionsAll; // Netherlands -VehicleModel::LimitsInitList const g_pedestrianLimitsNetherlands = g_pedestrianLimitsCyclewayAllowedNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsNetherlands = kPedestrianOptionsCyclewayAllowedNoTrunk; // Norway -VehicleModel::LimitsInitList const g_pedestrianLimitsNorway = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsNorway = kPedestrianOptionsAll; // Oman -VehicleModel::LimitsInitList const g_pedestrianLimitsOman = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsOman = kPedestrianOptionsAll; // Poland -VehicleModel::LimitsInitList const g_pedestrianLimitsPoland = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsPoland = kPedestrianOptionsNoTrunk; // Romania -VehicleModel::LimitsInitList const g_pedestrianLimitsRomania = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsRomania = kPedestrianOptionsNoTrunk; // Russian Federation -VehicleModel::LimitsInitList const g_pedestrianLimitsRussia = g_pedestrianLimitsCyclewayAllowed; +VehicleModel::LimitsInitList const kPedestrianOptionsRussia = kPedestrianOptionsCyclewayAllowed; // Slovakia -VehicleModel::LimitsInitList const g_pedestrianLimitsSlovakia = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsSlovakia = kPedestrianOptionsNoTrunk; // Spain -VehicleModel::LimitsInitList const g_pedestrianLimitsSpain = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsSpain = kPedestrianOptionsNoTrunk; // Switzerland -VehicleModel::LimitsInitList const g_pedestrianLimitsSwitzerland = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsSwitzerland = kPedestrianOptionsNoTrunk; // Turkey -VehicleModel::LimitsInitList const g_pedestrianLimitsTurkey = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsTurkey = kPedestrianOptionsAll; // Ukraine -VehicleModel::LimitsInitList const g_pedestrianLimitsUkraine = g_pedestrianLimitsNoTrunk; +VehicleModel::LimitsInitList const kPedestrianOptionsUkraine = kPedestrianOptionsNoTrunk; // United Kingdom -VehicleModel::LimitsInitList const g_pedestrianLimitsUK = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsUK = kPedestrianOptionsAll; // United States of America -VehicleModel::LimitsInitList const g_pedestrianLimitsUS = g_pedestrianLimitsAll; +VehicleModel::LimitsInitList const kPedestrianOptionsUS = kPedestrianOptionsAll; -VehicleModel::SurfaceInitList const g_pedestrianSurface = { +VehicleModel::SurfaceInitList const kPedestrianSurface = { // {{surfaceType, surfaceType}, {weightFactor, etaFactor}} {{"psurface", "paved_good"}, {1.0, 1.0}}, {{"psurface", "paved_bad"}, {1.0, 1.0}}, @@ -288,13 +276,14 @@ VehicleModel::SurfaceInitList const g_pedestrianSurface = { namespace routing { PedestrianModel::PedestrianModel() - : VehicleModel(classif(), g_pedestrianLimitsDefault, g_pedestrianSurface) + : VehicleModel(classif(), kPedestrianOptionsDefault, kPedestrianSurface, + {kDefaultSpeeds, kDefaultFactors}) { Init(); } PedestrianModel::PedestrianModel(VehicleModel::LimitsInitList const & speedLimits) - : VehicleModel(classif(), speedLimits, g_pedestrianSurface) + : VehicleModel(classif(), speedLimits, kPedestrianSurface, {kDefaultSpeeds, kDefaultFactors}) { Init(); } @@ -314,10 +303,9 @@ void PedestrianModel::Init() m_yesFootType = classif().GetTypeByPath(hwtagYesFoot); vector<AdditionalRoadTags> const additionalTags = { - {hwtagYesFoot, m_modelMaxSpeed}, - {{"route", "ferry"}, kSpeedFerryKMpH}, - {{"man_made", "pier"}, kSpeedPierKMpH} - }; + {hwtagYesFoot, m_maxModelSpeed}, + {{"route", "ferry"}, kDefaultSpeeds.at(HighwayType::RouteFerry)}, + {{"man_made", "pier"}, kDefaultSpeeds.at(HighwayType::ManMadePier)}}; SetAdditionalRoadTypes(classif(), additionalTags); } @@ -326,8 +314,10 @@ VehicleModelInterface::RoadAvailability PedestrianModel::GetRoadAvailability(fea { if (types.Has(m_yesFootType)) return RoadAvailability::Available; + if (types.Has(m_noFootType)) return RoadAvailability::NotAvailable; + return RoadAvailability::Unknown; } @@ -336,7 +326,7 @@ VehicleModelInterface::RoadAvailability PedestrianModel::GetRoadAvailability(fea // static PedestrianModel const & PedestrianModel::AllLimitsInstance() { - static PedestrianModel const instance(g_pedestrianLimitsAll); + static PedestrianModel const instance(kPedestrianOptionsAll); return instance; } @@ -345,30 +335,30 @@ PedestrianModelFactory::PedestrianModelFactory( : VehicleModelFactory(countryParentNameGetterFn) { // Names must be the same with country names from countries.txt - m_models[""] = make_shared<PedestrianModel>(g_pedestrianLimitsDefault); - m_models["Australia"] = make_shared<PedestrianModel>(g_pedestrianLimitsAustralia); - m_models["Austria"] = make_shared<PedestrianModel>(g_pedestrianLimitsAustria); - m_models["Belarus"] = make_shared<PedestrianModel>(g_pedestrianLimitsBelarus); - m_models["Belgium"] = make_shared<PedestrianModel>(g_pedestrianLimitsBelgium); - m_models["Brazil"] = make_shared<PedestrianModel>(g_pedestrianLimitsBrazil); - m_models["Denmark"] = make_shared<PedestrianModel>(g_pedestrianLimitsDenmark); - m_models["France"] = make_shared<PedestrianModel>(g_pedestrianLimitsFrance); - m_models["Finland"] = make_shared<PedestrianModel>(g_pedestrianLimitsFinland); - m_models["Germany"] = make_shared<PedestrianModel>(g_pedestrianLimitsGermany); - m_models["Hungary"] = make_shared<PedestrianModel>(g_pedestrianLimitsHungary); - m_models["Iceland"] = make_shared<PedestrianModel>(g_pedestrianLimitsIceland); - m_models["Netherlands"] = make_shared<PedestrianModel>(g_pedestrianLimitsNetherlands); - m_models["Norway"] = make_shared<PedestrianModel>(g_pedestrianLimitsNorway); - m_models["Oman"] = make_shared<PedestrianModel>(g_pedestrianLimitsOman); - m_models["Poland"] = make_shared<PedestrianModel>(g_pedestrianLimitsPoland); - m_models["Romania"] = make_shared<PedestrianModel>(g_pedestrianLimitsRomania); - m_models["Russian Federation"] = make_shared<PedestrianModel>(g_pedestrianLimitsRussia); - m_models["Slovakia"] = make_shared<PedestrianModel>(g_pedestrianLimitsSlovakia); - m_models["Spain"] = make_shared<PedestrianModel>(g_pedestrianLimitsSpain); - m_models["Switzerland"] = make_shared<PedestrianModel>(g_pedestrianLimitsSwitzerland); - m_models["Turkey"] = make_shared<PedestrianModel>(g_pedestrianLimitsTurkey); - m_models["Ukraine"] = make_shared<PedestrianModel>(g_pedestrianLimitsUkraine); - m_models["United Kingdom"] = make_shared<PedestrianModel>(g_pedestrianLimitsUK); - m_models["United States of America"] = make_shared<PedestrianModel>(g_pedestrianLimitsUS); + 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); } } // routing diff --git a/routing_common/routing_common_tests/vehicle_model_test.cpp b/routing_common/routing_common_tests/vehicle_model_test.cpp index 670c1cdd64..ec60e1caf9 100644 --- a/routing_common/routing_common_tests/vehicle_model_test.cpp +++ b/routing_common/routing_common_tests/vehicle_model_test.cpp @@ -10,38 +10,46 @@ #include "platform/measurement_utils.hpp" #include "base/macros.hpp" +#include "base/math.hpp" #include <cstdint> using namespace routing; using namespace std; -using MaxspeedFactor = VehicleModel::MaxspeedFactor; - namespace { -using SpeedKMpH = routing::VehicleModel::SpeedKMpH; -using InOutCitySpeedKMpH = routing::VehicleModel::InOutCitySpeedKMpH; - -InOutCitySpeedKMpH const speedSecondaryExpected = { - SpeedKMpH(80.0 /* weight */, 70.0 /* eta */) /* in city */, - SpeedKMpH(80.0 /* weight */, 70.0 /* eta */) /* out of city */, MaxspeedFactor(1.0)}; - -routing::VehicleModel::LimitsInitList const s_testLimits = { - {{"highway", "trunk"}, {SpeedKMpH(100.0 /* weight */, 100.0 /* eta */) /* in city */, - SpeedKMpH(150.0 /* weight */, 150.0 /* eta */) /* out of city */, - MaxspeedFactor(1.0)}, true}, - {{"highway", "primary"}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0), MaxspeedFactor(1.0)}, true}, - {{"highway", "secondary"}, speedSecondaryExpected, true}, - {{"highway", "residential"}, {SpeedKMpH(45.0, 55.0), SpeedKMpH(50.0, 60.0), MaxspeedFactor(0.5)}, true}, - {{"highway", "service"}, {SpeedKMpH(47.0, 36.0), SpeedKMpH(50.0, 40.0), MaxspeedFactor(1.0)}, false}}; - -routing::VehicleModel::SurfaceInitList const g_carSurface = { +HighwayBasedMeanSpeeds 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, + InOutCitySpeedKMpH(SpeedKMpH(80.0 /* weight */, 70.0 /* eta */) /* in and out city*/)}, + {HighwayType::HighwayResidential, + InOutCitySpeedKMpH(SpeedKMpH(45.0 /* weight */, 55.0 /* eta */) /* in city */, + 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 */)}}; + +HighwayBasedFactors const kDefaultFactors = { + {HighwayType::HighwayPrimary, + {// maxspeed : InOutCityFactor(in and out city factor value) + {70, InOutCityFactor(1.0)}, + {90, InOutCityFactor(1.0)}}}, + {HighwayType::HighwaySecondary, {{90, InOutCityFactor(1.0)}}}, + {HighwayType::HighwayResidential, {{60, InOutCityFactor(0.5)}}}}; + +VehicleModel::LimitsInitList const kTestLimits = {{{"highway", "trunk"}, true}, + {{"highway", "primary"}, true}, + {{"highway", "secondary"}, true}, + {{"highway", "residential"}, true}, + {{"highway", "service"}, false}}; + +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}} -}; + {{"psurface", "unpaved_bad"}, {0.2, 0.2}}}; class VehicleModelTest { @@ -49,15 +57,17 @@ public: VehicleModelTest() { classificator::Load(); } }; -class TestVehicleModel : public routing::VehicleModel +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); - public : TestVehicleModel() - : VehicleModel(classif(), s_testLimits, g_carSurface) +public: + TestVehicleModel() + : VehicleModel(classif(), kTestLimits, kCarSurface, + {kDefaultSpeeds, kDefaultSpeeds, kDefaultFactors, kDefaultFactors}) { } @@ -126,19 +136,16 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxSpeed) UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed) { { - CheckSpeed({GetType("highway", "secondary", "bridge")}, speedSecondaryExpected); - CheckSpeed({GetType("highway", "secondary", "tunnel")}, speedSecondaryExpected); - CheckSpeed({GetType("highway", "secondary")}, speedSecondaryExpected); + 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")}, {SpeedKMpH(100.0 /* weight */, 100.0 /* eta */) /* in city */, - SpeedKMpH(150.0 /* weight */, 150.0 /* eta */) /* out of city */, - MaxspeedFactor(1.0)}); - CheckSpeed({GetType("highway", "primary")}, - {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0), MaxspeedFactor(1.0)}); - CheckSpeed({GetType("highway", "residential")}, - {SpeedKMpH(45.0, 55.0), SpeedKMpH(50.0, 60.0), MaxspeedFactor(1.0)}); + SpeedKMpH(150.0 /* weight */, 150.0 /* eta */) /* out of city */}); + CheckSpeed({GetType("highway", "primary")}, {SpeedKMpH(90.0, 90.0), SpeedKMpH(120.0, 120.0)}); + CheckSpeed({GetType("highway", "residential")}, {SpeedKMpH(45.0, 55.0), SpeedKMpH(50.0, 60.0)}); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) @@ -147,9 +154,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_Speed_MultiTypes) uint32_t const typeSecondary = GetType("highway", "secondary"); uint32_t const typeHighway = GetType("highway"); - CheckSpeed({typeTunnel, typeSecondary}, speedSecondaryExpected); - CheckSpeed({typeTunnel, typeHighway}, speedSecondaryExpected); - CheckSpeed({typeHighway, typeTunnel}, speedSecondaryExpected); + 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) @@ -157,9 +164,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_OneWay) uint32_t const typeBridge = GetType("highway", "secondary", "bridge"); uint32_t const typeOneway = GetOnewayType(); - CheckSpeed({typeBridge, typeOneway}, speedSecondaryExpected); + CheckSpeed({typeBridge, typeOneway}, kDefaultSpeeds.at(HighwayType::HighwaySecondary)); CheckOneWay({typeBridge, typeOneway}, true); - CheckSpeed({typeOneway, typeBridge}, speedSecondaryExpected); + CheckSpeed({typeOneway, typeBridge}, kDefaultSpeeds.at(HighwayType::HighwaySecondary)); CheckOneWay({typeOneway, typeBridge}, true); CheckOneWay({typeOneway}, true); @@ -171,9 +178,9 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_DifferentSpeeds) uint32_t const typePrimary = GetType("highway", "primary"); uint32_t const typeOneway = GetOnewayType(); - CheckSpeed({typeSecondary, typePrimary}, speedSecondaryExpected); + CheckSpeed({typeSecondary, typePrimary}, kDefaultSpeeds.at(HighwayType::HighwaySecondary)); - CheckSpeed({typeSecondary, typePrimary, typeOneway}, speedSecondaryExpected); + CheckSpeed({typeSecondary, typePrimary, typeOneway}, kDefaultSpeeds.at(HighwayType::HighwaySecondary)); CheckOneWay({typePrimary, typeOneway, typeSecondary}, true); } @@ -193,17 +200,17 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_SpeedFactor) uint32_t const unpavedGood = GetType("psurface", "unpaved_good"); uint32_t const unpavedBad = GetType("psurface", "unpaved_bad"); - CheckSpeed({secondary, pavedGood}, {SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* in city */, - SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* out of city */, - MaxspeedFactor(1.0)}); - CheckSpeed({secondary, pavedBad}, {SpeedKMpH(32.0, 35.0), SpeedKMpH(32.0, 35.0), MaxspeedFactor(1.0)}); - CheckSpeed({secondary, unpavedGood}, {SpeedKMpH(48.0, 56.0), SpeedKMpH(48.0, 56.0), MaxspeedFactor(1.0)}); - CheckSpeed({secondary, unpavedBad}, {SpeedKMpH(16.0, 14.0), SpeedKMpH(16.0, 14.0), MaxspeedFactor(1.0)}); - - CheckSpeed({residential, pavedGood}, {SpeedKMpH(36.0, 49.5), SpeedKMpH(40.0, 54.0), MaxspeedFactor(1.0)}); - CheckSpeed({residential, pavedBad}, {SpeedKMpH(18.0, 27.5), SpeedKMpH(20.0, 30.0), MaxspeedFactor(1.0)}); - CheckSpeed({residential, unpavedGood}, {SpeedKMpH(27.0, 44.0), SpeedKMpH(30.0, 48.0), MaxspeedFactor(1.0)}); - CheckSpeed({residential, unpavedBad}, {SpeedKMpH(9.0, 11.0), SpeedKMpH(10.0, 12.0), MaxspeedFactor(1.0)}); + CheckSpeed({secondary, pavedGood}, + {SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* in city */, + SpeedKMpH(64.0 /* weight */, 63.0 /* eta */) /* out of city */}); + CheckSpeed({secondary, pavedBad}, {SpeedKMpH(32.0, 35.0), SpeedKMpH(32.0, 35.0)}); + CheckSpeed({secondary, unpavedGood}, {SpeedKMpH(48.0, 56.0), SpeedKMpH(48.0, 56.0)}); + CheckSpeed({secondary, unpavedBad}, {SpeedKMpH(16.0, 14.0), SpeedKMpH(16.0, 14.0)}); + + CheckSpeed({residential, pavedGood}, {SpeedKMpH(36.0, 49.5), SpeedKMpH(40.0, 54.0)}); + CheckSpeed({residential, pavedBad}, {SpeedKMpH(18.0, 27.5), SpeedKMpH(20.0, 30.0)}); + CheckSpeed({residential, unpavedGood}, {SpeedKMpH(27.0, 44.0), SpeedKMpH(30.0, 48.0)}); + CheckSpeed({residential, unpavedBad}, {SpeedKMpH(9.0, 11.0), SpeedKMpH(10.0, 12.0)}); } UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor) @@ -218,23 +225,35 @@ UNIT_CLASS_TEST(VehicleModelTest, VehicleModel_MaxspeedFactor) Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, kInvalidSpeed); CheckSpeedWithParams({secondary, unpavedBad}, SpeedParams(true /* forward */, false /* in city */, maxspeed90), - SpeedKMpH(90.0)); + SpeedKMpH(18.0)); + CheckSpeedWithParams({primary, pavedGood}, SpeedParams(true /* forward */, false /* in city */, maxspeed90), - SpeedKMpH(90.0)); + SpeedKMpH(72.0, 81.0)); Maxspeed const maxspeed9070 = Maxspeed(measurement_utils::Units::Metric, 90 /* forward speed */, 70); CheckSpeedWithParams({primary, pavedGood}, SpeedParams(true /* forward */, false /* in city */, maxspeed9070), - SpeedKMpH(90.0)); + SpeedKMpH(72.0, 81.0)); CheckSpeedWithParams({primary, pavedGood}, SpeedParams(false /* forward */, false /* in city */, maxspeed9070), - SpeedKMpH(70.0)); + SpeedKMpH(56.0, 63.0)); Maxspeed const maxspeed60 = Maxspeed(measurement_utils::Units::Metric, 60 /* forward speed */, kInvalidSpeed); CheckSpeedWithParams({residential, pavedGood}, SpeedParams(true /* forward */, false /* in city */, maxspeed60), - SpeedKMpH(30.0)); + SpeedKMpH(24.0, 27.0)); +} + +UNIT_TEST(VehicleModel_MultiplicationOperatorTest) +{ + SpeedKMpH const speed(90 /* weight */, 100 /* eta */); + SpeedFactor const factor(1.0, 1.1); + SpeedKMpH const lResult = speed * factor; + SpeedKMpH const rResult = factor * speed; + TEST_EQUAL(lResult, rResult, ()); + TEST(base::AlmostEqualAbs(lResult.m_weight, 90.0, 1e-7), ()); + TEST(base::AlmostEqualAbs(lResult.m_eta, 110.0, 1e-7), ()); } diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index 88d45fc722..27ca406711 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -4,30 +4,50 @@ #include "indexer/feature.hpp" #include "indexer/ftypes_matcher.hpp" +#include "base/assert.hpp" +#include "base/checked_cast.hpp" #include "base/macros.hpp" #include "base/math.hpp" #include <algorithm> #include <sstream> +#include <boost/optional.hpp> + using namespace routing; using namespace std; namespace { +double constexpr kInvalidModelValue = -1.0; + 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)}; }; -VehicleModel::InOutCitySpeedKMpH Max(VehicleModel::InOutCitySpeedKMpH const & lhs, - VehicleModel::InOutCitySpeedKMpH const & rhs) +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)}; +} + +MaxspeedType GetMaxspeedKey(double maxspeedValue) +{ + return base::asserted_cast<MaxspeedType>(10 * static_cast<MaxspeedType>((maxspeedValue + 5) / 10)); +} + +HighwayType GetHighwayTypeKey(HighwayType type) { - using MaxspeedFactor = VehicleModel::MaxspeedFactor; - return {Pick<max>(lhs.m_inCity, rhs.m_inCity), Pick<max>(lhs.m_outCity, rhs.m_outCity), - MaxspeedFactor(min(lhs.m_maxspeedFactor.m_weight, rhs.m_maxspeedFactor.m_weight), - min(lhs.m_maxspeedFactor.m_eta, rhs.m_maxspeedFactor.m_eta))}; + switch (type) + { + 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; + } } } // namespace @@ -40,19 +60,10 @@ VehicleModel::AdditionalRoadType::AdditionalRoadType(Classificator const & c, { } -VehicleModel::RoadLimits::RoadLimits(VehicleModel::InOutCitySpeedKMpH const & speed, - bool isPassThroughAllowed) - : m_speed(speed), m_isPassThroughAllowed(isPassThroughAllowed) -{ - CHECK_GREATER(m_speed.m_inCity.m_weight, 0.0, ()); - CHECK_GREATER(m_speed.m_inCity.m_eta, 0.0, ()); - CHECK_GREATER(m_speed.m_outCity.m_weight, 0.0, ()); - CHECK_GREATER(m_speed.m_outCity.m_eta, 0.0, ()); -} - VehicleModel::VehicleModel(Classificator const & c, LimitsInitList const & featureTypeLimits, - SurfaceInitList const & featureTypeSurface) - : m_modelMaxSpeed({}, {}, MaxspeedFactor(1.0)), m_onewayType(c.GetTypeByPath({"hwtag", "oneway"})) + SurfaceInitList const & featureTypeSurface, + HighwayBasedInfo const & info) + : m_onewayType(c.GetTypeByPath({"hwtag", "oneway"})), m_highwayBasedInfo(info) { CHECK_EQUAL(m_surfaceFactors.size(), 4, ("If you want to change the size of the container please take into account that it's " @@ -61,9 +72,13 @@ VehicleModel::VehicleModel(Classificator const & c, LimitsInitList const & featu for (auto const & v : featureTypeLimits) { - m_modelMaxSpeed = Max(m_modelMaxSpeed, v.m_speed); - m_highwayTypes.emplace(c.GetTypeByPath(v.m_types), - RoadLimits(v.m_speed, v.m_isPassThroughAllowed)); + auto const classificatorType = c.GetTypeByPath(v.m_types); + auto const highwayType = static_cast<HighwayType>(c.GetIndexForType(classificatorType)); + auto const speedIt = info.m_globalSpeeds.find(highwayType); + CHECK(speedIt != info.m_globalSpeeds.cend(), ("Can't found speed for", highwayType)); + // TODO: Consider using not only highway class speed but max sped * max speed factor. + m_maxModelSpeed = Max(m_maxModelSpeed, speedIt->second); + m_roadTypes.emplace(classificatorType, RoadType(highwayType, v.m_isPassThroughAllowed)); } size_t i = 0; @@ -72,11 +87,9 @@ VehicleModel::VehicleModel(Classificator const & c, LimitsInitList const & featu auto const & speedFactor = v.m_factor; CHECK_LESS_OR_EQUAL(speedFactor.m_weight, 1.0, ()); CHECK_LESS_OR_EQUAL(speedFactor.m_eta, 1.0, ()); - CHECK_GREATER_OR_EQUAL(speedFactor.m_weight, 0.0, ()); - CHECK_GREATER_OR_EQUAL(speedFactor.m_eta, 0.0, ()); - double const weightFactor = base::clamp(speedFactor.m_weight, 0.0, 1.0); - double const etaFactor = base::clamp(speedFactor.m_eta, 0.0, 1.0); - m_surfaceFactors[i++] = {c.GetTypeByPath(v.m_types), {weightFactor, etaFactor}}; + CHECK_GREATER(speedFactor.m_weight, 0.0, ()); + CHECK_GREATER(speedFactor.m_eta, 0.0, ()); + m_surfaceFactors[i++] = {c.GetTypeByPath(v.m_types), v.m_factor}; } } @@ -86,96 +99,178 @@ void VehicleModel::SetAdditionalRoadTypes(Classificator const & c, for (auto const & tag : additionalTags) { m_addRoadTypes.emplace_back(c, tag); - m_modelMaxSpeed = Max(m_modelMaxSpeed, tag.m_speed); + m_maxModelSpeed = Max(m_maxModelSpeed, tag.m_speed); } } -VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const +SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, SpeedParams const & speedParams) const { feature::TypesHolder const types(f); RoadAvailability const restriction = GetRoadAvailability(types); - // @TODO(bykoianko) Consider using speed on feature |f| instead of using max speed below. - if (restriction == RoadAvailability::Available) - return speedParams.m_inCity ? m_modelMaxSpeed.m_inCity : m_modelMaxSpeed.m_outCity; - if (restriction != RoadAvailability::NotAvailable && HasRoadType(types)) - return GetTypeSpeed(types, speedParams); + if (restriction == RoadAvailability::NotAvailable || !HasRoadType(types)) + return {}; - return {}; + return GetTypeSpeed(types, speedParams); } double VehicleModel::GetMaxWeightSpeed() const { - return max(m_modelMaxSpeed.m_inCity.m_weight, m_modelMaxSpeed.m_outCity.m_weight); + return max(m_maxModelSpeed.m_inCity.m_weight, m_maxModelSpeed.m_outCity.m_weight); +} + +void VehicleModel::GetHighwayType(uint32_t type, boost::optional<HighwayType> & hwType) const +{ + if (hwType) + return; + + type = ftypes::BaseChecker::PrepareToMatch(type, 2); + auto const it = m_roadTypes.find(type); + if (it != m_roadTypes.cend()) + hwType = it->second.GetHighwayType(); +} + +void VehicleModel::GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const +{ + auto const it = find_if(m_surfaceFactors.cbegin(), m_surfaceFactors.cend(), + [type](TypeFactor const & v) { return v.m_type == type; }); + + if (it != m_surfaceFactors.cend()) + factor = Pick<min>(factor, it->m_factor); + + CHECK_LESS_OR_EQUAL(factor.m_weight, 1.0, ()); + CHECK_LESS_OR_EQUAL(factor.m_eta, 1.0, ()); + CHECK_GREATER(factor.m_weight, 0.0, ()); + CHECK_GREATER(factor.m_eta, 0.0, ()); +} + +void VehicleModel::GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad, boost::optional<SpeedKMpH> & speed) const +{ + auto const it = FindAdditionalRoadType(type); + if (it == m_addRoadTypes.cend()) + return; + + auto const & res = isCityRoad ? it->m_speed.m_inCity : it->m_speed.m_outCity; + speed = speed ? Pick<min>(*speed, res) : res; } -VehicleModel::SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types, - SpeedParams const & speedParams) const +SpeedKMpH VehicleModel::GetSpeedOnFeatureWithMaxspeed(boost::optional<HighwayType> const & type, + SpeedParams const & speedParams) const { - double const maxSpeedWeight = - speedParams.m_inCity ? m_modelMaxSpeed.m_inCity.m_weight : m_modelMaxSpeed.m_outCity.m_weight; - double const maxEtaWeight = - speedParams.m_inCity ? m_modelMaxSpeed.m_inCity.m_eta : m_modelMaxSpeed.m_outCity.m_eta; + CHECK(speedParams.m_maxspeed.IsValid(), ()); + bool const isCityRoad = speedParams.m_inCity; + SpeedKMpH const & maxModelSpeed = m_maxModelSpeed.GetSpeed(isCityRoad); + auto const maxspeedKmPH = static_cast<double>(speedParams.m_maxspeed.GetSpeedKmPH(speedParams.m_forward)); + SpeedKMpH speed = Pick<min>(SpeedKMpH(maxspeedKmPH, maxspeedKmPH), maxModelSpeed); // Note. If a highway type is not found and |maxspeed| is set, |maxspeed| in kms per hour // should be returned. That means |maxspeedFactor| should be 1.0. - MaxspeedFactor maxspeedFactor(1.0); - VehicleModel::SpeedKMpH speed{maxSpeedWeight * 2.0, maxEtaWeight * 2.0}; - for (uint32_t t : types) + if (!type) + return speed; + + // We assume that all link roads are equal to its parents and drop "_link" suffix + // while searching for the particular factor. + auto const maxspeedKey = GetMaxspeedKey(maxspeedKmPH); + SpeedFactor maxspeedFactor(kInvalidModelValue, kInvalidModelValue); + auto const typeKey = GetHighwayTypeKey(*type); + auto const local = m_highwayBasedInfo.m_localFactors.find(typeKey); + if (local != m_highwayBasedInfo.m_localFactors.cend()) { - uint32_t const type = ftypes::BaseChecker::PrepareToMatch(t, 2); - auto const itHighway = m_highwayTypes.find(type); - if (itHighway != m_highwayTypes.cend()) - { - speed = itHighway->second.GetSpeed(speedParams.m_inCity); - maxspeedFactor = itHighway->second.GetMaxspeedFactor(); - break; - } + auto const & maxspeedsToFactors = local->second; + auto const it = maxspeedsToFactors.find(maxspeedKey); + if (it != maxspeedsToFactors.cend()) + maxspeedFactor = it->second.GetFactor(isCityRoad); } - if (speedParams.m_maxspeed.IsValid()) - { - double const maxspeedKmPH = - static_cast<double>(speedParams.m_maxspeed.GetSpeedKmPH(speedParams.m_forward)); - auto const weightSpeedKmPH = - min(static_cast<double>(maxspeedFactor.m_weight * maxspeedKmPH), GetMaxWeightSpeed()); - return SpeedKMpH(weightSpeedKmPH, maxspeedFactor.m_eta * maxspeedKmPH); - } + if (maxspeedFactor.m_weight != kInvalidModelValue && maxspeedFactor.m_eta != kInvalidModelValue) + return Pick<min>(speed * maxspeedFactor, maxModelSpeed); - // Decreasing speed factor based on road surface (cover). - VehicleModel::SpeedFactor factor; - for (uint32_t t : types) + auto const global = m_highwayBasedInfo.m_globalFactors.find(typeKey); + if (global != m_highwayBasedInfo.m_globalFactors.cend()) { - auto const addRoadInfoIter = FindRoadType(t); - if (addRoadInfoIter != m_addRoadTypes.cend()) + auto const & maxspeedsToFactors = global->second; + auto const it = maxspeedsToFactors.find(maxspeedKey); + if (it != maxspeedsToFactors.cend()) { - speed = Pick<min>( - speed, speedParams.m_inCity ? addRoadInfoIter->m_speed.m_inCity : addRoadInfoIter->m_speed.m_outCity); + auto const & factor = it->second.GetFactor(isCityRoad); + if (factor.m_weight != kInvalidModelValue && maxspeedFactor.m_weight == kInvalidModelValue) + maxspeedFactor.m_weight = factor.m_weight; + + if (factor.m_eta != kInvalidModelValue && maxspeedFactor.m_weight == kInvalidModelValue) + maxspeedFactor.m_eta = factor.m_eta; } - auto const itFactor = find_if(m_surfaceFactors.cbegin(), m_surfaceFactors.cend(), - [t](TypeFactor const & v) { return v.m_type == t; }); - if (itFactor != m_surfaceFactors.cend()) - factor = Pick<min>(factor, itFactor->m_factor); + auto const defaultIt = maxspeedsToFactors.find(kCommonMaxSpeedValue); + CHECK(defaultIt != maxspeedsToFactors.cend(), ()); + SpeedFactor const & defaultFactor = defaultIt->second.GetFactor(isCityRoad); + if (maxspeedFactor.m_weight == kInvalidModelValue) + maxspeedFactor.m_weight = defaultFactor.m_weight; + + if (maxspeedFactor.m_eta == kInvalidModelValue) + maxspeedFactor.m_eta = defaultFactor.m_eta; } - CHECK_LESS_OR_EQUAL(factor.m_weight, 1.0, ()); - CHECK_LESS_OR_EQUAL(factor.m_eta, 1.0, ()); - CHECK_GREATER_OR_EQUAL(factor.m_weight, 0.0, ()); - CHECK_GREATER_OR_EQUAL(factor.m_eta, 0.0, ()); + CHECK_NOT_EQUAL(maxspeedFactor.m_weight, kInvalidModelValue, ()); + CHECK_NOT_EQUAL(maxspeedFactor.m_eta, kInvalidModelValue, ()); + return Pick<min>(speed * maxspeedFactor, maxModelSpeed); +} - VehicleModel::SpeedKMpH ret; - if (speed.m_weight <= maxSpeedWeight) - ret.m_weight = speed.m_weight * factor.m_weight; +SpeedKMpH VehicleModel::GetSpeedOnFeatureWithoutMaxspeed(boost::optional<HighwayType> const & type, + SpeedParams const & speedParams) const +{ + CHECK(!speedParams.m_maxspeed.IsValid(), ()); + auto const isCityRoad = speedParams.m_inCity; + if (!type) + return m_maxModelSpeed.GetSpeed(isCityRoad); + + SpeedKMpH const & maxModelSpeed = m_maxModelSpeed.GetSpeed(isCityRoad); + SpeedKMpH speed(kInvalidModelValue, kInvalidModelValue); + auto const local = m_highwayBasedInfo.m_localSpeeds.find(*type); + if (local != m_highwayBasedInfo.m_localSpeeds.cend()) + speed = local->second.GetSpeed(isCityRoad); + + if (speed.m_weight != kInvalidModelValue && speed.m_eta != kInvalidModelValue) + return speed; + + auto const globalIt = m_highwayBasedInfo.m_globalSpeeds.find(*type); + CHECK(globalIt != m_highwayBasedInfo.m_globalSpeeds.cend(), ("Can't find type in global speeds", *type)); + SpeedKMpH const & global = globalIt->second.GetSpeed(isCityRoad); + CHECK_NOT_EQUAL(global.m_weight, kInvalidModelValue, ()); + CHECK_NOT_EQUAL(global.m_eta, kInvalidModelValue, ()); + if (speed.m_weight == kInvalidModelValue) + speed.m_weight = global.m_weight; + + if (speed.m_eta == kInvalidModelValue) + speed.m_eta = global.m_eta; + + return Pick<min>(speed, maxModelSpeed); +} + +SpeedKMpH VehicleModel::GetTypeSpeed(feature::TypesHolder const & types, + SpeedParams const & speedParams) const +{ + bool const isCityRoad = speedParams.m_inCity; + boost::optional<HighwayType> hwType; + SpeedFactor surfaceFactor; + boost::optional<SpeedKMpH> additionalRoadSpeed; + for (uint32_t t : types) + { + GetHighwayType(t, hwType); + GetSurfaceFactor(t, surfaceFactor); + GetAdditionalRoadSpeed(t, isCityRoad, additionalRoadSpeed); + } - if (speed.m_eta <= maxEtaWeight) - ret.m_eta = speed.m_eta * factor.m_eta; + if (additionalRoadSpeed) + return *additionalRoadSpeed * surfaceFactor; - return ret; + if (speedParams.m_maxspeed.IsValid()) + return GetSpeedOnFeatureWithMaxspeed(hwType, speedParams) * surfaceFactor; + + return GetSpeedOnFeatureWithoutMaxspeed(hwType, speedParams) * surfaceFactor; } -VehicleModel::SpeedKMpH VehicleModel::GetSpeedWihtoutMaxspeed(FeatureType & f, - SpeedParams const & speedParams) const +SpeedKMpH VehicleModel::GetSpeedWihtoutMaxspeed(FeatureType & f, + SpeedParams const & speedParams) const { return VehicleModel::GetSpeed(f, {speedParams.m_forward, speedParams.m_inCity, Maxspeed()}); } @@ -218,7 +313,7 @@ bool VehicleModel::IsPassThroughAllowed(FeatureType & f) const // Allow pass through additional road types e.g. peer, ferry. for (uint32_t t : types) { - auto const addRoadInfoIter = FindRoadType(t); + auto const addRoadInfoIter = FindAdditionalRoadType(t); if (addRoadInfoIter != m_addRoadTypes.cend()) return true; } @@ -230,8 +325,8 @@ bool VehicleModel::HasPassThroughType(feature::TypesHolder const & types) const for (uint32_t t : types) { uint32_t const type = ftypes::BaseChecker::PrepareToMatch(t, 2); - auto it = m_highwayTypes.find(type); - if (it != m_highwayTypes.end() && it->second.IsPassThroughAllowed()) + auto it = m_roadTypes.find(type); + if (it != m_roadTypes.end() && it->second.IsPassThroughAllowed()) return true; } @@ -240,8 +335,8 @@ bool VehicleModel::HasPassThroughType(feature::TypesHolder const & types) const bool VehicleModel::IsRoadType(uint32_t type) const { - return FindRoadType(type) != m_addRoadTypes.cend() || - m_highwayTypes.find(ftypes::BaseChecker::PrepareToMatch(type, 2)) != m_highwayTypes.end(); + return FindAdditionalRoadType(type) != m_addRoadTypes.cend() || + m_roadTypes.find(ftypes::BaseChecker::PrepareToMatch(type, 2)) != m_roadTypes.end(); } VehicleModelInterface::RoadAvailability VehicleModel::GetRoadAvailability(feature::TypesHolder const & /* types */) const @@ -249,7 +344,7 @@ VehicleModelInterface::RoadAvailability VehicleModel::GetRoadAvailability(featur return RoadAvailability::Unknown; } -vector<VehicleModel::AdditionalRoadType>::const_iterator VehicleModel::FindRoadType( +vector<VehicleModel::AdditionalRoadType>::const_iterator VehicleModel::FindAdditionalRoadType( uint32_t type) const { return find_if(m_addRoadTypes.begin(), m_addRoadTypes.cend(), @@ -305,12 +400,10 @@ string DebugPrint(VehicleModelInterface::RoadAvailability const l) case VehicleModelInterface::RoadAvailability::Unknown: return "Unknown"; } - ostringstream out; - out << "Unknown VehicleModelInterface::RoadAvailability (" << static_cast<int>(l) << ")"; - return out.str(); + UNREACHABLE(); } -std::string DebugPrint(VehicleModelInterface::SpeedKMpH const & speed) +string DebugPrint(SpeedKMpH const & speed) { ostringstream oss; oss << "SpeedKMpH [ "; @@ -319,7 +412,7 @@ std::string DebugPrint(VehicleModelInterface::SpeedKMpH const & speed) return oss.str(); } -std::string DebugPrint(VehicleModelInterface::InOutCitySpeedKMpH const & speed) +string DebugPrint(InOutCitySpeedKMpH const & speed) { ostringstream oss; oss << "InOutCitySpeedKMpH [ "; @@ -327,4 +420,40 @@ std::string DebugPrint(VehicleModelInterface::InOutCitySpeedKMpH const & speed) oss << "outCity:" << DebugPrint(speed.m_outCity) << " ]"; return oss.str(); } + +string DebugPrint(HighwayType type) +{ + switch (type) + { + case HighwayType::HighwayResidential: return "highway-residential"; + case HighwayType::HighwayService: return "highway-service"; + case HighwayType::HighwayUnclassified: return "highway-unclassified"; + case HighwayType::HighwayFootway: return "highway-footway"; + case HighwayType::HighwayTrack: return "highway-track"; + case HighwayType::HighwayTertiary: return "highway-tertiary"; + case HighwayType::HighwaySecondary: return "highway-secondary"; + case HighwayType::HighwayPath: return "highway-path"; + case HighwayType::HighwayPrimary: return "highway-primary"; + case HighwayType::HighwayRoad: return "highway-road"; + case HighwayType::HighwayCycleway: return "highway-cycleway"; + case HighwayType::HighwayMotorwayLink: return "highway-motorway_link"; + case HighwayType::HighwayLivingStreet: return "highway-living_street"; + case HighwayType::HighwayMotorway: return "highway-motorway"; + case HighwayType::HighwaySteps: return "highway-steps"; + case HighwayType::HighwayTrunk: return "highway-trunk"; + case HighwayType::HighwayPedestrian: return "highway-pedestrian"; + case HighwayType::HighwayTrunkLink: return "highway-trunk_link"; + case HighwayType::HighwayPrimaryLink: return "highway-primary_link"; + case HighwayType::ManMadePier: return "man_made-pier"; + case HighwayType::HighwayBridleway: return "highway-bridleway"; + case HighwayType::HighwaySecondaryLink: return "highway-secondary_link"; + case HighwayType::RouteFerry: return "route-ferry"; + case HighwayType::HighwayTertiaryLink: return "highway-tertiary_link"; + case HighwayType::RouteFerryMotorcar: return "route-ferry-motorcar"; + case HighwayType::RouteFerryMotorVehicle: return "route-ferry-motor_vehicle"; + case HighwayType::RailwayRailMotorVehicle: return "railway-rail-motor_vehicle"; + case HighwayType::HighwayPlatform: return "highway-platform"; + case HighwayType::RouteShuttleTrain: return "route-shuttle_train"; + } +} } // namespace routing diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 0e9a9b6eee..6c6cd7cec7 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -2,7 +2,10 @@ #include "routing_common/maxspeed_conversion.hpp" +#include "base/stl_helpers.hpp" + #include <array> +#include <cstdint> #include <functional> #include <initializer_list> #include <memory> @@ -12,6 +15,8 @@ #include <utility> #include <vector> +#include <boost/optional.hpp> + class Classificator; class FeatureType; @@ -19,6 +24,53 @@ namespace feature { class TypesHolder; } namespace routing { +struct InOutCityFactor; +struct InOutCitySpeedKMpH; + +// Each value is equal to the corresponding type index from types.txt. +// The ascending order is strict. +enum class HighwayType : uint32_t +{ + HighwayResidential = 1, + HighwayService = 2, + HighwayUnclassified = 4, + HighwayFootway = 6, + HighwayTrack = 7, + HighwayTertiary = 8, + HighwaySecondary = 12, + HighwayPath = 15, + HighwayPrimary = 26, + HighwayRoad = 30, + HighwayCycleway = 36, + HighwayMotorwayLink = 43, + HighwayLivingStreet = 54, + HighwayMotorway = 57, + HighwaySteps = 58, + HighwayTrunk = 65, + HighwayPedestrian = 69, + HighwayTrunkLink = 90, + HighwayPrimaryLink = 95, + ManMadePier = 119, + HighwayBridleway = 167, + HighwaySecondaryLink = 176, + RouteFerry = 259, + HighwayTertiaryLink = 272, + RouteFerryMotorcar = 988, + RouteFerryMotorVehicle = 993, + RailwayRailMotorVehicle = 994, + HighwayPlatform = 1008, + RouteShuttleTrain = 1054, +}; + +using SpeedToFactor = std::unordered_map<MaxspeedType /* maxspeed km/h */, InOutCityFactor>; +using HighwayBasedFactors = std::unordered_map<HighwayType, SpeedToFactor, base::EnumClassHash>; +using HighwayBasedMeanSpeeds = + std::unordered_map<HighwayType, InOutCitySpeedKMpH, base::EnumClassHash>; +using CountryToHighwayBasedMeanSpeeds = + std::unordered_map<std::string /* country */, HighwayBasedMeanSpeeds>; +using CountryToHighwayBasedFactors = + std::unordered_map<std::string /* country */, HighwayBasedFactors>; + /// \brief Params for calculation of an approximate speed on a feature. struct SpeedParams { @@ -33,82 +85,146 @@ struct SpeedParams Maxspeed m_maxspeed; }; -class VehicleModelInterface +/// \brief Speeds which are used for edge weight and ETA esimations. +struct SpeedKMpH { -public: - enum class RoadAvailability + constexpr SpeedKMpH() = default; + constexpr SpeedKMpH(double weight) noexcept : m_weight(weight), m_eta(weight) {} + constexpr SpeedKMpH(double weight, double eta) noexcept : m_weight(weight), m_eta(eta) {} + + bool operator==(SpeedKMpH const & rhs) const { - NotAvailable, - Available, - Unknown, - }; + return m_weight == rhs.m_weight && m_eta == rhs.m_eta; + } + bool operator!=(SpeedKMpH const & rhs) const { return !(*this == rhs); } + + bool IsValid() const { return m_weight > 0 && m_eta > 0; } + + double m_weight = 0.0; // KMpH + double m_eta = 0.0; // KMpH +}; - /// Speeds which are used for edge weight and ETA estimations. - struct SpeedKMpH +/// \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 +{ + constexpr SpeedFactor() = default; + constexpr SpeedFactor(double factor) noexcept : m_weight(factor), m_eta(factor) {} + constexpr SpeedFactor(double weight, double eta) noexcept : m_weight(weight), m_eta(eta) {} + + bool operator==(SpeedFactor const & rhs) const { - constexpr SpeedKMpH() = default; - constexpr explicit SpeedKMpH(double weight) noexcept : m_weight(weight), m_eta(weight) {} - constexpr SpeedKMpH(double weight, double eta) noexcept : m_weight(weight), m_eta(eta) {} + return m_weight == rhs.m_weight && m_eta == rhs.m_eta; + } + bool operator!=(SpeedFactor const & rhs) const { return !(*this == rhs); } - bool operator==(SpeedKMpH const & rhs) const - { - return m_weight == rhs.m_weight && m_eta == rhs.m_eta; - } + double m_weight = 1.0; + double m_eta = 1.0; +}; - bool IsValid() const { return m_weight >= 0 && m_eta >= 0; } +inline SpeedKMpH operator*(SpeedFactor const & factor, SpeedKMpH const & speed) +{ + return {speed.m_weight * factor.m_weight, speed.m_eta * factor.m_eta}; +} - double m_weight = 0.0; // KMpH - double m_eta = 0.0; // KMpH - }; +inline SpeedKMpH operator*(SpeedKMpH const & speed, SpeedFactor const & factor) +{ + return {speed.m_weight * factor.m_weight, speed.m_eta * factor.m_eta}; +} - /// \brief Factors which reduce weight and ETA speed on feature regarding maxspeed tag value - /// if the tag is set for the feature. - /// Both should be in range [0.0, 1.0]. - struct MaxspeedFactor +struct InOutCitySpeedKMpH +{ + constexpr InOutCitySpeedKMpH() = default; + constexpr explicit InOutCitySpeedKMpH(SpeedKMpH const & speed) noexcept + : m_inCity(speed), m_outCity(speed) { - constexpr explicit MaxspeedFactor(double weight) noexcept : m_weight(weight), m_eta(weight) {} - constexpr explicit MaxspeedFactor(double weight, double eta) noexcept : m_weight(weight), m_eta(eta) {} + } + constexpr InOutCitySpeedKMpH(SpeedKMpH const & inCity, SpeedKMpH const & outCity) noexcept + : m_inCity(inCity), m_outCity(outCity) + { + } - bool operator==(MaxspeedFactor const & rhs) const { return m_weight == rhs.m_weight && m_eta == rhs.m_eta; } + bool operator==(InOutCitySpeedKMpH const & rhs) const + { + return m_inCity == rhs.m_inCity && m_outCity == rhs.m_outCity; + } - double m_weight; - double m_eta; - }; + SpeedKMpH const & GetSpeed(bool isCity) const { return isCity ? m_inCity : m_outCity; } + + SpeedKMpH m_inCity; + SpeedKMpH m_outCity; +}; - struct InOutCitySpeedKMpH +struct InOutCityFactor +{ + constexpr explicit InOutCityFactor(SpeedFactor const & factor) noexcept + : m_inCity(factor), m_outCity(factor) { - constexpr InOutCitySpeedKMpH(SpeedKMpH const & inCity, SpeedKMpH const & outCity, - MaxspeedFactor const & maxspeedFactor) noexcept - : m_inCity(inCity), m_outCity(outCity), m_maxspeedFactor(maxspeedFactor) - { - } + } + constexpr InOutCityFactor(SpeedFactor const & inCity, SpeedFactor const & outCity) noexcept + : m_inCity(inCity), m_outCity(outCity) + { + } - bool operator==(InOutCitySpeedKMpH const & rhs) const - { - return m_inCity == rhs.m_inCity && m_outCity == rhs.m_outCity && m_maxspeedFactor == rhs.m_maxspeedFactor; - } + bool operator==(InOutCityFactor const & rhs) const + { + return m_inCity == rhs.m_inCity && m_outCity == rhs.m_outCity; + } - SpeedKMpH m_inCity; - SpeedKMpH m_outCity; - // If maxspeed is available it should be multiplied by |m_maxspeedFactor|. - MaxspeedFactor m_maxspeedFactor; - }; + SpeedFactor const & GetFactor(bool isCity) const { return isCity ? m_inCity : m_outCity; } - /// Factors which reduce weight and ETA speed on feature in case of bad pavement. - /// Both should be in range [0.0, 1.0]. - struct SpeedFactor + SpeedFactor m_inCity; + SpeedFactor m_outCity; +}; + +struct HighwayBasedInfo +{ + HighwayBasedInfo(HighwayBasedMeanSpeeds const & speeds, HighwayBasedFactors const & factors) + : m_localSpeeds(speeds) + , m_globalSpeeds(speeds) + , m_localFactors(factors) + , m_globalFactors(factors) { - double m_weight = 1.0; - double m_eta = 1.0; + } + + HighwayBasedInfo(HighwayBasedMeanSpeeds const & localSpeeds, + HighwayBasedMeanSpeeds const & globalSpeeds, + HighwayBasedFactors const & localFactors, + HighwayBasedFactors const & globalFactors) + : m_localSpeeds(localSpeeds) + , m_globalSpeeds(globalSpeeds) + , m_localFactors(localFactors) + , m_globalFactors(globalFactors) + { + } + + HighwayBasedMeanSpeeds const & m_localSpeeds; + HighwayBasedMeanSpeeds const & m_globalSpeeds; + HighwayBasedFactors const & m_localFactors; + HighwayBasedFactors const & m_globalFactors; +}; + +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; + /// @return Maximum model weight speed. + /// All speeds which the model returns must be less than or equal to this speed. virtual double GetMaxWeightSpeed() const = 0; /// @return Offroad speed in KMpH for vehicle. This speed should be used for non-feature routing @@ -145,22 +261,14 @@ public: class VehicleModel : public VehicleModelInterface { public: - using InOutCitySpeedKMpH = VehicleModelInterface::InOutCitySpeedKMpH; - using SpeedFactor = VehicleModelInterface::SpeedFactor; - using SpeedKMpH = VehicleModelInterface::SpeedKMpH; - struct FeatureTypeLimits final { - FeatureTypeLimits(std::vector<std::string> const & types, InOutCitySpeedKMpH const & speed, - bool isPassThroughAllowed) - : m_types(types) - , m_speed(speed) - , m_isPassThroughAllowed(isPassThroughAllowed) + FeatureTypeLimits(std::vector<std::string> const & types, bool isPassThroughAllowed) + : m_types(types), m_isPassThroughAllowed(isPassThroughAllowed) { } std::vector<std::string> m_types; - InOutCitySpeedKMpH m_speed; // Average speed on this road type in and out of cities. bool m_isPassThroughAllowed; // Pass through this road type is allowed. }; @@ -190,7 +298,7 @@ public: using SurfaceInitList = std::initializer_list<FeatureTypeSurface>; VehicleModel(Classificator const & c, LimitsInitList const & featureTypeLimits, - SurfaceInitList const & featureTypeSurface); + SurfaceInitList const & featureTypeSurface, HighwayBasedInfo const & info); /// VehicleModelInterface overrides: SpeedKMpH GetSpeed(FeatureType & f, SpeedParams const & speedParams) const override; @@ -216,7 +324,7 @@ public: bool EqualsForTests(VehicleModel const & rhs) const { - return (m_highwayTypes == rhs.m_highwayTypes) && (m_addRoadTypes == rhs.m_addRoadTypes) && + return (m_roadTypes == rhs.m_roadTypes) && (m_addRoadTypes == rhs.m_addRoadTypes) && (m_onewayType == rhs.m_onewayType); } @@ -243,7 +351,7 @@ protected: /// \brief maximum within all the speed limits set in a model (car model, bicycle modle and so on). /// It shouldn't be mixed with maxspeed value tag which defines maximum legal speed on a feature. - InOutCitySpeedKMpH m_modelMaxSpeed; + InOutCitySpeedKMpH m_maxModelSpeed; private: struct AdditionalRoadType final @@ -253,24 +361,27 @@ private: bool operator==(AdditionalRoadType const & rhs) const { return m_type == rhs.m_type; } uint32_t const m_type; - InOutCitySpeedKMpH m_speed; + InOutCitySpeedKMpH const m_speed; }; - class RoadLimits final + class RoadType final { public: - RoadLimits(InOutCitySpeedKMpH const & speed, bool isPassThroughAllowed); + RoadType(HighwayType hwtype, bool isPassThroughAllowed) + : m_highwayType(hwtype), m_isPassThroughAllowed(isPassThroughAllowed) + { + } - SpeedKMpH const & GetSpeed(bool inCity) const { return inCity ? m_speed.m_inCity : m_speed.m_outCity; }; - MaxspeedFactor const & GetMaxspeedFactor() const { return m_speed.m_maxspeedFactor; } bool IsPassThroughAllowed() const { return m_isPassThroughAllowed; }; - bool operator==(RoadLimits const & rhs) const + HighwayType GetHighwayType() const { return m_highwayType; } + bool operator==(RoadType const & rhs) const { - return (m_speed == rhs.m_speed) && (m_isPassThroughAllowed == rhs.m_isPassThroughAllowed); + return m_highwayType == rhs.m_highwayType && + m_isPassThroughAllowed == rhs.m_isPassThroughAllowed; } private: - InOutCitySpeedKMpH const m_speed; + HighwayType const m_highwayType; bool const m_isPassThroughAllowed; }; @@ -280,9 +391,18 @@ private: SpeedFactor m_factor; }; - std::vector<AdditionalRoadType>::const_iterator FindRoadType(uint32_t type) const; + void GetHighwayType(uint32_t type, boost::optional<HighwayType> & hwType) const; + void GetSurfaceFactor(uint32_t type, SpeedFactor & factor) const; + void GetAdditionalRoadSpeed(uint32_t type, bool isCityRoad, boost::optional<SpeedKMpH> & speed) const; + + SpeedKMpH GetSpeedOnFeatureWithoutMaxspeed(boost::optional<HighwayType> const & type, + SpeedParams const & speedParams) const; + SpeedKMpH GetSpeedOnFeatureWithMaxspeed(boost::optional<HighwayType> const & type, + SpeedParams const & speedParams) const; - std::unordered_map<uint32_t, RoadLimits> m_highwayTypes; + std::vector<AdditionalRoadType>::const_iterator FindAdditionalRoadType(uint32_t type) const; + + std::unordered_map<uint32_t, RoadType> m_roadTypes; // Mapping surface types (psurface|paved_good, psurface|paved_bad, psurface|unpaved_good, // psurface|unpaved_bad) to surface speed factors. // Note. It's an array (not map or unordered_map) because of perfomance reasons. @@ -290,6 +410,8 @@ private: std::vector<AdditionalRoadType> m_addRoadTypes; uint32_t m_onewayType; + + HighwayBasedInfo const m_highwayBasedInfo; }; class VehicleModelFactory : public VehicleModelFactoryInterface @@ -316,6 +438,7 @@ protected: }; std::string DebugPrint(VehicleModelInterface::RoadAvailability const l); -std::string DebugPrint(VehicleModelInterface::SpeedKMpH const & speed); -std::string DebugPrint(VehicleModelInterface::InOutCitySpeedKMpH const & speed); +std::string DebugPrint(SpeedKMpH const & speed); +std::string DebugPrint(InOutCitySpeedKMpH const & speed); +std::string DebugPrint(HighwayType type); } // namespace routing |