From 10bb44d4bca232cfd63af53d0664400e31b551ea Mon Sep 17 00:00:00 2001 From: Mikhail Gorbushin Date: Fri, 26 Apr 2019 15:40:38 +0300 Subject: [PATCH] [generator] review fixes --- generator/road_access_generator.cpp | 134 +++++++++++++--------------- generator/road_access_generator.hpp | 18 ++-- 2 files changed, 72 insertions(+), 80 deletions(-) diff --git a/generator/road_access_generator.cpp b/generator/road_access_generator.cpp index f3b43c9ae2..06c07c069f 100644 --- a/generator/road_access_generator.cpp +++ b/generator/road_access_generator.cpp @@ -26,6 +26,8 @@ #include #include +#include "boost/optional.hpp" + using namespace routing; using namespace std; @@ -71,6 +73,8 @@ TagMapping const kCarBarriersTagMapping = { // TODO (@gmoryes) The types below should be added. // {OsmElement::Tag("barrier", "chain"), RoadAccess::Type::No}, // {OsmElement::Tag("barrier", "swing_gate"), RoadAccess::Type::Private} +// {OsmElement::Tag("barrier", "log"), RoadAccess::Type::No}, +// {OsmElement::Tag("barrier", "motorcycle_barrier"), RoadAccess::Type::No}, }; TagMapping const kPedestrianTagMapping = { @@ -94,7 +98,8 @@ TagMapping const kBicycleTagMapping = { TagMapping const kBicycleBarriersTagMapping = { {OsmElement::Tag("barrier", "cycle_barrier"), RoadAccess::Type::No}, {OsmElement::Tag("barrier", "gate"), RoadAccess::Type::Private}, - {OsmElement::Tag("barrier", "kissing_gate"), RoadAccess::Type::Private}, +// TODO (@gmoryes) The types below should be added. +// {OsmElement::Tag("barrier", "kissing_gate"), RoadAccess::Type::Private}, }; // Allow everything to keep transit section empty. We'll use pedestrian section for @@ -110,6 +115,21 @@ TagMapping const kDefaultTagMapping = { {OsmElement::Tag("access", "destination"), RoadAccess::Type::Destination}, }; +set const kHighwaysWhereIgnorePrivateAccessForCar = { + {OsmElement::Tag("highway", "motorway")}, + {OsmElement::Tag("highway", "motorway_link")}, + {OsmElement::Tag("highway", "primary")}, + {OsmElement::Tag("highway", "primary_link")}, + {OsmElement::Tag("highway", "secondary")}, + {OsmElement::Tag("highway", "secondary_link")}, + {OsmElement::Tag("highway", "tertiary")}, + {OsmElement::Tag("highway", "tertiary_link")}, + {OsmElement::Tag("highway", "trunk")}, + {OsmElement::Tag("highway", "trunk_link")} +}; + +set const kHighwaysWhereIgnorePrivateAccessEmpty = {}; + bool ParseRoadAccess(string const & roadAccessPath, map const & osmIdToFeatureId, FeaturesVector const & featuresVector, @@ -237,28 +257,30 @@ RoadAccessTagProcessor::RoadAccessTagProcessor(VehicleType vehicleType) switch (vehicleType) { case VehicleType::Car: - m_tagMappings.push_back(&kMotorCarTagMapping); - m_tagMappings.push_back(&kMotorVehicleTagMapping); - m_tagMappings.push_back(&kVehicleTagMapping); - m_tagMappings.push_back(&kDefaultTagMapping); - // Apply barrier tags if we have no {vehicle = ...}, {access = ...} etc. - m_tagMappings.push_back(&kCarBarriersTagMapping); + m_accessMappings.push_back(&kMotorCarTagMapping); + m_accessMappings.push_back(&kMotorVehicleTagMapping); + m_accessMappings.push_back(&kVehicleTagMapping); + m_accessMappings.push_back(&kDefaultTagMapping); + m_barrierMappings.push_back(&kCarBarriersTagMapping); + m_hwIgnoreBarriersWithoutAccess = &kHighwaysWhereIgnorePrivateAccessForCar; break; case VehicleType::Pedestrian: - m_tagMappings.push_back(&kPedestrianTagMapping); - m_tagMappings.push_back(&kDefaultTagMapping); + m_accessMappings.push_back(&kPedestrianTagMapping); + m_accessMappings.push_back(&kDefaultTagMapping); + m_hwIgnoreBarriersWithoutAccess = &kHighwaysWhereIgnorePrivateAccessEmpty; break; case VehicleType::Bicycle: - m_tagMappings.push_back(&kBicycleTagMapping); - m_tagMappings.push_back(&kVehicleTagMapping); - m_tagMappings.push_back(&kDefaultTagMapping); - // Apply barrier tags if we have no {bicycle = ...}, {access = ...} etc. - m_tagMappings.push_back(&kBicycleBarriersTagMapping); + m_accessMappings.push_back(&kBicycleTagMapping); + m_accessMappings.push_back(&kVehicleTagMapping); + m_accessMappings.push_back(&kDefaultTagMapping); + m_barrierMappings.push_back(&kBicycleBarriersTagMapping); + m_hwIgnoreBarriersWithoutAccess = &kHighwaysWhereIgnorePrivateAccessEmpty; break; case VehicleType::Transit: // Use kTransitTagMapping to keep transit section empty. We'll use pedestrian section for // transit + pedestrian combination. - m_tagMappings.push_back(&kTransitTagMapping); + m_accessMappings.push_back(&kTransitTagMapping); + m_hwIgnoreBarriersWithoutAccess = &kHighwaysWhereIgnorePrivateAccessEmpty; break; case VehicleType::Count: CHECK(false, ("Bad vehicle type")); @@ -273,9 +295,8 @@ void RoadAccessTagProcessor::Process(OsmElement const & elem, ofstream & oss) if (elem.type == OsmElement::EntityType::Node) { RoadAccess::Type accessType = GetAccessType(elem); - bool hasCarAccessTag = m_vehicleType == VehicleType::Car ? HasCarAccessTag(elem) : false; if (accessType != RoadAccess::Type::Yes) - m_barriers[elem.id] = {accessType, hasCarAccessTag}; + m_barriers[elem.id] = accessType; return; } @@ -295,66 +316,19 @@ void RoadAccessTagProcessor::Process(OsmElement const & elem, ofstream & oss) if (it == m_barriers.cend()) continue; - RoadAccess::Type roadAccessType; - bool hasCarAccessTag; - tie(roadAccessType, hasCarAccessTag) = it->second; - - if (m_vehicleType == VehicleType::Car && ShouldIgnorePrivateAccess(elem, hasCarAccessTag)) - return; - + RoadAccess::Type const roadAccessType = it->second; // idx == 0 used as wildcard segment Idx, for nodes we store |pointIdx + 1| instead of |pointIdx|. oss << ToString(m_vehicleType) << " " << ToString(roadAccessType) << " " << elem.id << " " << pointIdx + 1 << endl; } } -bool RoadAccessTagProcessor::HasCarAccessTag(OsmElement const & osmElement) const +bool RoadAccessTagProcessor::ShouldIgnoreBarrierWithoutAccess(OsmElement const & osmElement) const { - CHECK_EQUAL(m_vehicleType, VehicleType::Car, ("HasCarAccessTag() works only for Car.")); - CHECK_EQUAL(osmElement.type, OsmElement::EntityType::Node, ()); - - static vector const kAccessTagsWithoutBarrier = { - &kMotorCarTagMapping, &kMotorVehicleTagMapping, &kVehicleTagMapping, - &kDefaultTagMapping - }; - - for (auto const & tagMapping : kAccessTagsWithoutBarrier) - { - for (auto const & tag : osmElement.m_tags) - { - if (tagMapping->count(tag) != 0) - return true; - } - } - - return false; -} - -bool RoadAccessTagProcessor::ShouldIgnorePrivateAccess(OsmElement const & osmElement, - bool hasCarAccessTag) const -{ - CHECK_EQUAL(m_vehicleType, VehicleType::Car, ("Ignore made only for Car.")); - CHECK_EQUAL(osmElement.type, OsmElement::EntityType::Way, ()); - - if (hasCarAccessTag) - return false; - - static set const kHighwaysWhereIgnoresPrivateAccess = { - {OsmElement::Tag("highway", "motorway")}, - {OsmElement::Tag("highway", "motorway_link")}, - {OsmElement::Tag("highway", "primary")}, - {OsmElement::Tag("highway", "primary_link")}, - {OsmElement::Tag("highway", "secondary")}, - {OsmElement::Tag("highway", "secondary_link")}, - {OsmElement::Tag("highway", "tertiary")}, - {OsmElement::Tag("highway", "tertiary_link")}, - {OsmElement::Tag("highway", "trunk")}, - {OsmElement::Tag("highway", "trunk_link")} - }; - + CHECK(m_hwIgnoreBarriersWithoutAccess, ()); for (auto const & tag : osmElement.m_tags) { - if (kHighwaysWhereIgnoresPrivateAccess.count(tag) != 0) + if (m_hwIgnoreBarriersWithoutAccess->count(tag) != 0) return true; } @@ -363,12 +337,28 @@ bool RoadAccessTagProcessor::ShouldIgnorePrivateAccess(OsmElement const & osmEle RoadAccess::Type RoadAccessTagProcessor::GetAccessType(OsmElement const & elem) const { - for (auto const tagMapping : m_tagMappings) + auto const getType = [&](vector const & mapping) { - auto const accessType = GetAccessTypeFromMapping(elem, tagMapping); - if (accessType != RoadAccess::Type::Count) - return accessType; + for (auto const tagMapping : mapping) + { + auto const accessType = GetAccessTypeFromMapping(elem, tagMapping); + if (accessType != RoadAccess::Type::Count) + return boost::optional(accessType); + } + + return boost::optional(); + }; + + if (auto op = getType(m_accessMappings)) + return *op; + + // Apply barrier tags if we have no {vehicle = ...}, {access = ...} etc. + if (auto op = getType(m_barrierMappings)) + { + if (!ShouldIgnoreBarrierWithoutAccess(elem)) + return *op; } + return RoadAccess::Type::Yes; } diff --git a/generator/road_access_generator.hpp b/generator/road_access_generator.hpp index 68fea63d91..4f061ed1ac 100644 --- a/generator/road_access_generator.hpp +++ b/generator/road_access_generator.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #include struct OsmElement; @@ -35,19 +34,22 @@ public: void Process(OsmElement const & elem, std::ofstream & oss); private: - bool HasCarAccessTag(OsmElement const & osmElement) const; - bool ShouldIgnorePrivateAccess(OsmElement const & osmElement, bool hasAccessTag) const; + bool ShouldIgnoreBarrierWithoutAccess(OsmElement const & osmElement) const; RoadAccess::Type GetAccessType(OsmElement const & elem) const; VehicleType m_vehicleType; + + std::vector m_barrierMappings; + // Order of tag mappings in m_tagMappings is from more to less specific. // e.g. for car: motorcar, motorvehicle, vehicle, general access tags. - std::vector m_tagMappings; + std::vector m_accessMappings; - // Tag mapping for barriers. - // Key is barrier node osm id. - // Value is accessType and bool - element car access tag. - std::map> m_barriers; + // We decided to ignore some barriers without access on some type of highways + // because we almost always do not need to add penalty for passes through such nodes. + std::set const * m_hwIgnoreBarriersWithoutAccess; + + std::map m_barriers; }; class RoadAccessWriter : public generator::CollectorInterface