From 20da8a4fcf29c39c6cbd7bd36d51a1c3d7fe575b Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Mon, 18 Apr 2016 13:20:57 +0300 Subject: [PATCH] [bicycle routing] Adding bicycle profile for using AStar bidirectional routing. --- routing/bicycle_model.cpp | 680 ++++++++++++++++++++++++++++++++++ routing/bicycle_model.hpp | 53 +++ routing/road_graph_router.cpp | 11 + routing/road_graph_router.hpp | 2 +- routing/router.cpp | 1 + routing/router.hpp | 5 +- routing/routing.pro | 3 + routing/routing_settings.hpp | 7 + 8 files changed, 759 insertions(+), 3 deletions(-) create mode 100644 routing/bicycle_model.cpp create mode 100644 routing/bicycle_model.hpp diff --git a/routing/bicycle_model.cpp b/routing/bicycle_model.cpp new file mode 100644 index 0000000000..ae37fbf235 --- /dev/null +++ b/routing/bicycle_model.cpp @@ -0,0 +1,680 @@ +#include "bicycle_model.hpp" + +#include "base/assert.hpp" +#include "base/macros.hpp" +#include "base/logging.hpp" + +#include "indexer/classificator.hpp" +#include "indexer/feature.hpp" + +namespace +{ + +// See model specifics in different countries here: +// http://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, +// but not listed in tables in the document. For example, steps are not listed, paths, roads and services features also +// can be treated as ready for bicycle routing. +// Kinds of roads which we assume are ready for bicycles are marked by // * below. + +// See road types here: +// http://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 +// not marked as "hwtag=nobicycle" in OSM. + +double constexpr kSpeedTrunkKMpH = 3.0; +double constexpr kSpeedTrunkLinkKMpH = 3.0; +double constexpr kSpeedPrimaryKMpH = 5.0; +double constexpr kSpeedPrimaryLinkKMpH = 5.0; +double constexpr kSpeedSecondaryKMpH = 15.0; +double constexpr kSpeedSecondaryLinkKMpH = 15.0; +double constexpr kSpeedTertiaryKMpH = 15.0; +double constexpr kSpeedTertiaryLinkKMpH = 15.0; +double constexpr kSpeedServiceKMpH = 12.0; +double constexpr kSpeedUnclassifiedKMpH = 12.0; +double constexpr kSpeedRoadKMpH = 10.0; +double constexpr kSpeedTrackKMpH = 8.0; +double constexpr kSpeedPathKMpH = 6.0; +double constexpr kSpeedBridlewayKMpH = 4.0; +double constexpr kSpeedCyclewayKMpH = 15.0; +double constexpr kSpeedResidentialKMpH = 8.0; +double constexpr kSpeedLivingStreetKMpH = 7.0; +double constexpr kSpeedStepsKMpH = 1.0; +double constexpr kSpeedPedestrianKMpH = 5.0; +double constexpr kSpeedFootwayKMpH = 7.0; +double constexpr kSpeedPlatformKMpH = 3.0; + +// Default +routing::VehicleModel::InitListT const s_bicycleLimits_Default = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedPedestrianKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// All options available. +routing::VehicleModel::InitListT const s_bicycleLimits_All = +{ + { {"highway", "trunk"}, kSpeedPedestrianKMpH }, + { {"highway", "trunk_link"}, kSpeedPedestrianKMpH }, + { {"highway", "primary"}, kSpeedPedestrianKMpH }, + { {"highway", "primary_link"}, kSpeedPedestrianKMpH }, + { {"highway", "secondary"}, kSpeedPedestrianKMpH }, + { {"highway", "secondary_link"}, kSpeedPedestrianKMpH }, + { {"highway", "tertiary"}, kSpeedPedestrianKMpH }, + { {"highway", "tertiary_link"}, kSpeedPedestrianKMpH }, + { {"highway", "service"}, kSpeedPedestrianKMpH }, + { {"highway", "unclassified"}, kSpeedPedestrianKMpH }, + { {"highway", "road"}, kSpeedPedestrianKMpH }, + { {"highway", "track"}, kSpeedPedestrianKMpH }, + { {"highway", "path"}, kSpeedPedestrianKMpH }, + { {"highway", "bridleway"}, kSpeedPedestrianKMpH }, + { {"highway", "cycleway"}, kSpeedPedestrianKMpH }, + { {"highway", "residential"}, kSpeedPedestrianKMpH }, + { {"highway", "living_street"}, kSpeedPedestrianKMpH }, + { {"highway", "steps"}, kSpeedPedestrianKMpH }, + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPedestrianKMpH }, +}; + +// Australia +routing::VehicleModel::InitListT const s_bicycleLimits_Australia = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, // * + { {"highway", "bridleway"}, kSpeedBridlewayKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Austria +routing::VehicleModel::InitListT const s_bicycleLimits_Austria = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Belarus +routing::VehicleModel::InitListT const s_bicycleLimits_Belarus = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, // * + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Belgium +routing::VehicleModel::InitListT const s_bicycleLimits_Belgium = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, // * + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, // * + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Brazil +routing::VehicleModel::InitListT const s_bicycleLimits_Brazil = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "bridleway"}, kSpeedBridlewayKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Denmark +routing::VehicleModel::InitListT const s_bicycleLimits_Denmark = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// France +routing::VehicleModel::InitListT const s_bicycleLimits_France = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Finland +routing::VehicleModel::InitListT const s_bicycleLimits_Finland = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Germany +routing::VehicleModel::InitListT const s_bicycleLimits_Germany = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Hungary +routing::VehicleModel::InitListT const s_bicycleLimits_Hungary = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, // * + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Netherlands +routing::VehicleModel::InitListT const s_bicycleLimits_Netherlands = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Norway +routing::VehicleModel::InitListT const s_bicycleLimits_Norway = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "bridleway"}, kSpeedBridlewayKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Poland +routing::VehicleModel::InitListT const s_bicycleLimits_Poland = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Romania +routing::VehicleModel::InitListT const s_bicycleLimits_Romania = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Russia +routing::VehicleModel::InitListT const s_bicycleLimits_Russia = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Slovakia +routing::VehicleModel::InitListT const s_bicycleLimits_Slovakia = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Switzerland +routing::VehicleModel::InitListT const s_bicycleLimits_Switzerland = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Turkey +routing::VehicleModel::InitListT const s_bicycleLimits_Turkey = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// Ukraine +routing::VehicleModel::InitListT const s_bicycleLimits_Ukraine = +{ + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "footway"}, kSpeedFootwayKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// United Kingdom +routing::VehicleModel::InitListT const s_bicycleLimits_UK = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, // * + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "bridleway"}, kSpeedBridlewayKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +// USA +routing::VehicleModel::InitListT const s_bicycleLimits_USA = +{ + { {"highway", "trunk"}, kSpeedTrunkKMpH }, + { {"highway", "trunk_link"}, kSpeedTrunkLinkKMpH }, + { {"highway", "primary"}, kSpeedPrimaryKMpH }, + { {"highway", "primary_link"}, kSpeedPrimaryLinkKMpH }, + { {"highway", "secondary"}, kSpeedSecondaryKMpH }, + { {"highway", "secondary_link"}, kSpeedSecondaryLinkKMpH }, + { {"highway", "tertiary"}, kSpeedTertiaryKMpH }, + { {"highway", "tertiary_link"}, kSpeedTertiaryLinkKMpH }, + { {"highway", "service"}, kSpeedServiceKMpH }, // * + { {"highway", "unclassified"}, kSpeedUnclassifiedKMpH }, + { {"highway", "road"}, kSpeedRoadKMpH }, + { {"highway", "track"}, kSpeedTrackKMpH }, // * + { {"highway", "path"}, kSpeedPathKMpH }, + { {"highway", "bridleway"}, kSpeedBridlewayKMpH }, + { {"highway", "cycleway"}, kSpeedCyclewayKMpH }, + { {"highway", "residential"}, kSpeedResidentialKMpH }, + { {"highway", "living_street"}, kSpeedLivingStreetKMpH }, + { {"highway", "steps"}, kSpeedStepsKMpH }, // * + { {"highway", "pedestrian"}, kSpeedPedestrianKMpH }, + { {"highway", "platform"}, kSpeedPlatformKMpH }, // * +}; + +} // namespace + +namespace routing +{ + +// If one of feature types will be disabled for bicycles, features of this type will be simplyfied +// in generator. Look FeatureBuilder1::IsRoad() for more details. +BicycleModel::BicycleModel() : VehicleModel(classif(), s_bicycleLimits_All) +{ + Init(); +} + +BicycleModel::BicycleModel(VehicleModel::InitListT const & speedLimits) + : VehicleModel(classif(), speedLimits) +{ + Init(); +} + +void BicycleModel::Init() +{ + // @TODO(bykoianko) Uncomment line below what tags hwtag=nobicycle and hwtag=yesbicycle + // will be added to classificator.txt. (https://jira.mail.ru/browse/MAPSME-858) +// m_noBicycleType = classif().GetTypeByPath({ "hwtag", "nobicycle" }); +// m_yesBicycleType = classif().GetTypeByPath({ "hwtag", "yesbicycle" }); + + initializer_list arr[] = + { + { "route", "ferry" }, + { "man_made", "pier" }, + }; + + SetAdditionalRoadTypes(classif(), arr, ARRAY_SIZE(arr)); +} + +bool BicycleModel::IsNoBicycle(feature::TypesHolder const & types) const +{ + return find(types.begin(), types.end(), m_noBicycleType) != types.end(); +} + +bool BicycleModel::IsYesBicycle(feature::TypesHolder const & types) const +{ + return find(types.begin(), types.end(), m_yesBicycleType) != types.end(); +} + +double BicycleModel::GetSpeed(FeatureType const & f) const +{ + feature::TypesHolder types(f); + + if (IsYesBicycle(types)) + return VehicleModel::GetMaxSpeed(); + if (!IsNoBicycle(types) && IsRoad(types)) + return VehicleModel::GetSpeed(types); + + return 0.0; +} + +BicycleModelFactory::BicycleModelFactory() +{ + m_models[string()] = make_shared(s_bicycleLimits_Default); + m_models["Australia"] = make_shared(s_bicycleLimits_Australia); + m_models["Austria"] = make_shared(s_bicycleLimits_Austria); + m_models["Belarus"] = make_shared(s_bicycleLimits_Belarus); + m_models["Belgium"] = make_shared(s_bicycleLimits_Belgium); + m_models["Brazil"] = make_shared(s_bicycleLimits_Brazil); + m_models["Denmark"] = make_shared(s_bicycleLimits_Denmark); + m_models["France"] = make_shared(s_bicycleLimits_France); + m_models["Finland"] = make_shared(s_bicycleLimits_Finland); + m_models["Germany"] = make_shared(s_bicycleLimits_Germany); + m_models["Hungary"] = make_shared(s_bicycleLimits_Hungary); + m_models["Netherlands"] = make_shared(s_bicycleLimits_Netherlands); + m_models["Norway"] = make_shared(s_bicycleLimits_Norway); + m_models["Poland"] = make_shared(s_bicycleLimits_Poland); + m_models["Romania"] = make_shared(s_bicycleLimits_Romania); + m_models["Russia"] = make_shared(s_bicycleLimits_Russia); + m_models["Slovakia"] = make_shared(s_bicycleLimits_Slovakia); + m_models["Switzerland"] = make_shared(s_bicycleLimits_Switzerland); + m_models["Turkey"] = make_shared(s_bicycleLimits_Turkey); + m_models["Ukraine"] = make_shared(s_bicycleLimits_Ukraine); + m_models["UK"] = make_shared(s_bicycleLimits_UK); + m_models["USA"] = make_shared(s_bicycleLimits_USA); +} + +shared_ptr BicycleModelFactory::GetVehicleModel() const +{ + auto const itr = m_models.find(string()); + ASSERT(itr != m_models.end(), ()); + return itr->second; +} + +shared_ptr BicycleModelFactory::GetVehicleModelForCountry(string const & country) const +{ + auto const itr = m_models.find(country); + if (itr != m_models.end()) + { + LOG(LDEBUG, ("Bicycle model was found:", country)); + return itr->second; + } + LOG(LDEBUG, ("Bicycle model wasn't found, default model is used instead:", country)); + return BicycleModelFactory::GetVehicleModel(); +} +} // routing diff --git a/routing/bicycle_model.hpp b/routing/bicycle_model.hpp new file mode 100644 index 0000000000..71ef1c43a7 --- /dev/null +++ b/routing/bicycle_model.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include "std/shared_ptr.hpp" +#include "std/unordered_map.hpp" + +#include "vehicle_model.hpp" + +namespace routing +{ + +class BicycleModel : public VehicleModel +{ +public: + BicycleModel(); + BicycleModel(VehicleModel::InitListT const & speedLimits); + + /// @name Overrides from VehicleModel. + //@{ + double GetSpeed(FeatureType const & f) const override; + bool IsOneWay(FeatureType const &) const override { return false; } + //@} + +private: + void Init(); + + /// @return true if road is prohibited for bicycle, + /// but if function returns false, real prohibition is unknown. + bool IsNoBicycle(feature::TypesHolder const & types) const; + + /// @return true if road is allowed for bicycle, + /// but if function returns false, real allowance is unknown. + bool IsYesBicycle(feature::TypesHolder const & types) const; + + uint32_t m_noBicycleType; + uint32_t m_yesBicycleType; +}; + +class BicycleModelFactory : public IVehicleModelFactory +{ +public: + BicycleModelFactory(); + + /// @name Overrides from IVehicleModelFactory. + //@{ + shared_ptr GetVehicleModel() const override; + shared_ptr GetVehicleModelForCountry(string const & country) const override; + //@} + +private: + unordered_map> m_models; +}; + +} // namespace routing diff --git a/routing/road_graph_router.cpp b/routing/road_graph_router.cpp index 36b2b9a631..2f1edb152f 100644 --- a/routing/road_graph_router.cpp +++ b/routing/road_graph_router.cpp @@ -1,3 +1,4 @@ +#include "routing/bicycle_model.hpp" #include "routing/features_road_graph.hpp" #include "routing/nearest_edge_finder.hpp" #include "routing/pedestrian_directions.hpp" @@ -279,4 +280,14 @@ unique_ptr CreatePedestrianAStarBidirectionalRouter(Index & index, TCou return router; } +unique_ptr CreateBicycleAStarBidirectionalRouter(Index & index, TCountryFileFn const & countryFileFn) +{ + unique_ptr vehicleModelFactory(new BicycleModelFactory()); + unique_ptr algorithm(new AStarBidirectionalRoutingAlgorithm()); + unique_ptr directionsEngine(new PedestrianDirectionsEngine()); + unique_ptr router(new RoadGraphRouter("astar-bidirectional-bicycle", index, countryFileFn, move(vehicleModelFactory), + move(algorithm), move(directionsEngine))); + return router; +} + } // namespace routing diff --git a/routing/road_graph_router.hpp b/routing/road_graph_router.hpp index 0e8dda7159..17127bb124 100644 --- a/routing/road_graph_router.hpp +++ b/routing/road_graph_router.hpp @@ -54,6 +54,6 @@ private: }; unique_ptr CreatePedestrianAStarRouter(Index & index, TCountryFileFn const & countryFileFn); - unique_ptr CreatePedestrianAStarBidirectionalRouter(Index & index, TCountryFileFn const & countryFileFn); +unique_ptr CreateBicycleAStarBidirectionalRouter(Index & index, TCountryFileFn const & countryFileFn); } // namespace routing diff --git a/routing/router.cpp b/routing/router.cpp index 946a12c8ae..2cfd491360 100644 --- a/routing/router.cpp +++ b/routing/router.cpp @@ -9,6 +9,7 @@ string ToString(RouterType type) { case RouterType::Vehicle: return "Vehicle"; case RouterType::Pedestrian: return "Pedestrian"; + case RouterType::Bicycle: return "Bicycle"; } ASSERT(false, ()); return "Error"; diff --git a/routing/router.hpp b/routing/router.hpp index 919fef89cf..667521b432 100644 --- a/routing/router.hpp +++ b/routing/router.hpp @@ -19,8 +19,9 @@ class Route; /// Routing engine type. enum class RouterType { - Vehicle = 0, /// For OSRM vehicle routing - Pedestrian /// For A star pedestrian routing + Vehicle = 0, /// For OSRM vehicle routing + Pedestrian, /// For A star pedestrian routing + Bicycle, /// For A star bicycle routing }; string ToString(RouterType type); diff --git a/routing/routing.pro b/routing/routing.pro index 6ee5a75461..c779012e28 100644 --- a/routing/routing.pro +++ b/routing/routing.pro @@ -15,6 +15,7 @@ INCLUDEPATH += $$ROOT_DIR/3party/jansson/src \ SOURCES += \ async_router.cpp \ base/followed_polyline.cpp \ + bicycle_model.cpp \ car_model.cpp \ cross_mwm_road_graph.cpp \ cross_mwm_router.cpp \ @@ -49,6 +50,7 @@ HEADERS += \ async_router.hpp \ base/astar_algorithm.hpp \ base/followed_polyline.hpp \ + bicycle_model.cpp \ car_model.hpp \ cross_mwm_road_graph.hpp \ cross_mwm_router.hpp \ @@ -81,3 +83,4 @@ HEADERS += \ turns_sound_settings.hpp \ turns_tts_text.hpp \ vehicle_model.hpp \ + bicycle_model.hpp diff --git a/routing/routing_settings.hpp b/routing/routing_settings.hpp index 1eba59bb9f..338d660ed2 100644 --- a/routing/routing_settings.hpp +++ b/routing/routing_settings.hpp @@ -50,4 +50,11 @@ inline RoutingSettings GetCarRoutingSettings() 50. /* m_matchingThresholdM */, false /* m_keepPedestrianInfo */, true /* m_showTurnAfterNext */, true /* m_speedCameraWarning*/}); } + +inline RoutingSettings GetBicycleRoutingSettings() +{ + return RoutingSettings({ false /* m_matchRoute */, false /* m_soundDirection */, + 20. /* m_matchingThresholdM */, true /* m_keepPedestrianInfo */, + false /* m_showTurnAfterNext */, false /* m_speedCameraWarning*/}); +} } // namespace routing