From 9109a6fa795607c774606e81ce3fe84496c8b4d3 Mon Sep 17 00:00:00 2001 From: Maxim Pimenov Date: Thu, 27 Apr 2017 17:14:42 +0300 Subject: [PATCH] [routing] Switched from RouterType to VehicleMask in RoadAccess. --- .../generator_tests/road_access_test.cpp | 29 ++++---- generator/road_access_generator.cpp | 71 ++++++++++++------ generator/road_access_generator.hpp | 5 +- routing/road_access.cpp | 72 ++++++++++--------- routing/road_access.hpp | 20 +++--- routing/road_access_serialization.hpp | 14 ++-- routing/routing_tests/road_access_test.cpp | 4 +- routing/vehicle_mask.hpp | 22 ++++++ 8 files changed, 145 insertions(+), 92 deletions(-) diff --git a/generator/generator_tests/road_access_test.cpp b/generator/generator_tests/road_access_test.cpp index 2b76fc4c46..f0b7b94a63 100644 --- a/generator/generator_tests/road_access_test.cpp +++ b/generator/generator_tests/road_access_test.cpp @@ -125,33 +125,28 @@ UNIT_TEST(RoadAccess_Smoke) UNIT_TEST(RoadAccess_AccessPrivate) { - string const roadAccessContent = R"(vehicle Private 0)"; + string const roadAccessContent = R"(Car Private 0)"; string const osmIdsToFeatureIdsContent = R"(0, 0,)"; auto const roadAccess = SaveAndLoadRoadAccess(roadAccessContent, osmIdsToFeatureIdsContent); - TEST_EQUAL(roadAccess.GetType(RouterType::Vehicle, Segment(0, 0, 0, false)), - RoadAccess::Type::Private, ()); + TEST_EQUAL(roadAccess.GetType(kCarMask, Segment(0, 0, 0, false)), RoadAccess::Type::Private, ()); } -UNIT_TEST(RoadAccess_Access_Multiple_Router_Types) +UNIT_TEST(RoadAccess_Access_Multiple_Vehicle_Masks) { - string const roadAccessContent = R"(vehicle Private 10 - vehicle Private 20 - bicycle No 30 - vehicle Destination 40)"; + string const roadAccessContent = R"(Car Private 10 + Car Private 20 + Bicycle No 30 + Car Destination 40)"; string const osmIdsToFeatureIdsContent = R"(10, 1, 20, 2, 30, 3, 40, 4,)"; auto const roadAccess = SaveAndLoadRoadAccess(roadAccessContent, osmIdsToFeatureIdsContent); - TEST_EQUAL(roadAccess.GetType(RouterType::Vehicle, Segment(0, 1, 0, false)), - RoadAccess::Type::Private, ()); - TEST_EQUAL(roadAccess.GetType(RouterType::Vehicle, Segment(0, 2, 2, true)), - RoadAccess::Type::Private, ()); - TEST_EQUAL(roadAccess.GetType(RouterType::Vehicle, Segment(0, 3, 1, true)), RoadAccess::Type::Yes, - ()); - TEST_EQUAL(roadAccess.GetType(RouterType::Vehicle, Segment(0, 4, 3, false)), - RoadAccess::Type::Destination, ()); - TEST_EQUAL(roadAccess.GetType(RouterType::Bicycle, Segment(0, 3, 0, false)), RoadAccess::Type::No, + TEST_EQUAL(roadAccess.GetType(kCarMask, Segment(0, 1, 0, false)), RoadAccess::Type::Private, ()); + TEST_EQUAL(roadAccess.GetType(kCarMask, Segment(0, 2, 2, true)), RoadAccess::Type::Private, ()); + TEST_EQUAL(roadAccess.GetType(kCarMask, Segment(0, 3, 1, true)), RoadAccess::Type::Yes, ()); + TEST_EQUAL(roadAccess.GetType(kCarMask, Segment(0, 4, 3, false)), RoadAccess::Type::Destination, ()); + TEST_EQUAL(roadAccess.GetType(kBicycleMask, Segment(0, 3, 0, false)), RoadAccess::Type::No, ()); } } // namespace diff --git a/generator/road_access_generator.cpp b/generator/road_access_generator.cpp index b2dfd0cad2..277288b409 100644 --- a/generator/road_access_generator.cpp +++ b/generator/road_access_generator.cpp @@ -5,7 +5,6 @@ #include "routing/road_access.hpp" #include "routing/road_access_serialization.hpp" -#include "routing/router.hpp" #include "indexer/classificator.hpp" #include "indexer/feature.hpp" @@ -33,6 +32,9 @@ using namespace std; namespace { char constexpr kDelim[] = " \t\r\n"; +string const kCar = "Car"; +string const kPedestrian = "Pedestrian"; +string const kBicycle = "Bicycle"; using TagMapping = routing::RoadAccessTagProcessor::TagMapping; @@ -53,6 +55,30 @@ TagMapping const kBicycleTagMapping = { {OsmElement::Tag("bicycle", "no"), RoadAccess::Type::No}, }; +VehicleMask ReadVehicleMaskFromString(string const & s) +{ + if (s == kCar) + return kCarMask; + if (s == kPedestrian) + return kPedestrianMask; + if (s == kBicycle) + return kBicycleMask; + LOG(LERROR, ("Could not read vehicle mask from the string", s)); + return kAllVehiclesMask; +} + +string WriteVehicleMaskToString(VehicleMask vehicleMask) +{ + if (vehicleMask == kCarMask) + return kCar; + if (vehicleMask == kPedestrianMask) + return kPedestrian; + if (vehicleMask == kBicycleMask) + return kBicycle; + LOG(LERROR, ("Unsupported vehicle mask", vehicleMask)); + return "Unsupported VehicleMask"; +} + bool ParseRoadAccess(string const & roadAccessPath, map const & osmIdToFeatureId, FeaturesVector const & featuresVector, RoadAccess & roadAccess) { @@ -65,11 +91,11 @@ bool ParseRoadAccess(string const & roadAccessPath, map const vector privateRoads; - map segmentType[static_cast(RouterType::Count)]; + map> segmentType; - auto addSegment = [&](Segment const & segment, RouterType routerType, + auto addSegment = [&](Segment const & segment, VehicleMask vehicleMask, RoadAccess::Type roadAccessType, uint64_t osmId) { - auto & m = segmentType[static_cast(routerType)]; + auto & m = segmentType[vehicleMask]; auto const emplaceRes = m.emplace(segment, roadAccessType); if (!emplaceRes.second) LOG(LWARNING, ("duplicate road access info for", osmId)); @@ -88,7 +114,7 @@ bool ParseRoadAccess(string const & roadAccessPath, map const LOG(LERROR, ("Error when parsing road access: empty line", lineNo)); return false; } - RouterType const routerType = FromString(*iter); + VehicleMask const vehicleMask = ReadVehicleMaskFromString(*iter); ++iter; if (!iter) @@ -126,15 +152,15 @@ bool ParseRoadAccess(string const & roadAccessPath, map const // Set this road access type for the entire feature. for (uint32_t segmentIdx = 0; segmentIdx < numSegments; ++segmentIdx) { - addSegment(Segment(kFakeNumMwmId, featureId, segmentIdx, true /* isForward */), routerType, + addSegment(Segment(kFakeNumMwmId, featureId, segmentIdx, true /* isForward */), vehicleMask, roadAccessType, osmId); - addSegment(Segment(kFakeNumMwmId, featureId, segmentIdx, false /* isForward */), routerType, + addSegment(Segment(kFakeNumMwmId, featureId, segmentIdx, false /* isForward */), vehicleMask, roadAccessType, osmId); } } - for (auto const routerType : RoadAccess::GetSupportedRouterTypes()) - roadAccess.SetTypes(routerType, segmentType[static_cast(routerType)]); + for (auto const vehicleMask : RoadAccess::GetSupportedVehicleMasks()) + roadAccess.SetTypes(vehicleMask, segmentType[vehicleMask]); return true; } @@ -143,17 +169,17 @@ bool ParseRoadAccess(string const & roadAccessPath, map const namespace routing { // RoadAccessTagProcessor -------------------------------------------------------------------------- -RoadAccessTagProcessor::RoadAccessTagProcessor(RouterType routerType) - : m_routerType(routerType), m_tagMapping(nullptr) +RoadAccessTagProcessor::RoadAccessTagProcessor(VehicleMask vehicleMask) + : m_vehicleMask(vehicleMask), m_tagMapping(nullptr) { - switch (routerType) - { - case RouterType::Vehicle: m_tagMapping = &kCarTagMapping; break; - case RouterType::Pedestrian: m_tagMapping = &kPedestrianTagMapping; break; - case RouterType::Bicycle: m_tagMapping = &kBicycleTagMapping; break; - case RouterType::Taxi: CHECK(false, ("Road access info is not supported for taxi")); break; - case RouterType::Count: CHECK(false, ("Bad router type")); break; - } + if (vehicleMask == kCarMask) + m_tagMapping = &kCarTagMapping; + else if (vehicleMask == kPedestrianMask) + m_tagMapping = &kPedestrianTagMapping; + else if (vehicleMask == kBicycleMask) + m_tagMapping = &kBicycleTagMapping; + else + CHECK(false, ("Road access info is not supported for this vehicle mask", vehicleMask)); } void RoadAccessTagProcessor::Process(OsmElement const & elem, ofstream & oss) const @@ -167,15 +193,16 @@ void RoadAccessTagProcessor::Process(OsmElement const & elem, ofstream & oss) co auto const it = m_tagMapping->find(tag); if (it == m_tagMapping->cend()) continue; - oss << ToString(m_routerType) << " " << ToString(it->second) << " " << elem.id << endl; + oss << WriteVehicleMaskToString(m_vehicleMask) << " " << ToString(it->second) << " " << elem.id + << endl; } } // RoadAccessWriter ------------------------------------------------------------ RoadAccessWriter::RoadAccessWriter() { - for (auto const routerType : RoadAccess::GetSupportedRouterTypes()) - m_tagProcessors.emplace_back(routerType); + for (auto const vehicleMask : RoadAccess::GetSupportedVehicleMasks()) + m_tagProcessors.emplace_back(vehicleMask); } void RoadAccessWriter::Open(string const & filePath) diff --git a/generator/road_access_generator.hpp b/generator/road_access_generator.hpp index 4e0f457fb9..0a4bba5cc5 100644 --- a/generator/road_access_generator.hpp +++ b/generator/road_access_generator.hpp @@ -4,6 +4,7 @@ #include "generator/osm_element.hpp" #include "routing/road_access.hpp" +#include "routing/vehicle_mask.hpp" #include #include @@ -24,12 +25,12 @@ class RoadAccessTagProcessor public: using TagMapping = map; - explicit RoadAccessTagProcessor(RouterType routerType); + explicit RoadAccessTagProcessor(VehicleMask vehicleMask); void Process(OsmElement const & elem, std::ofstream & oss) const; private: - RouterType m_routerType; + VehicleMask m_vehicleMask; TagMapping const * m_tagMapping; }; diff --git a/routing/road_access.cpp b/routing/road_access.cpp index 034f273583..114d10687e 100644 --- a/routing/road_access.cpp +++ b/routing/road_access.cpp @@ -11,29 +11,37 @@ string const kNames[] = {"No", "Private", "Destination", "Yes", "Count"}; // *NOTE* Order may be important for users (such as serializers). // Add new types to the end of the list. -vector const kSupportedRouterTypes = { - routing::RouterType::Vehicle, - routing::RouterType::Pedestrian, - routing::RouterType::Bicycle, -}; +vector const kSupportedVehicleMasks = { + routing::kPedestrianMask, + routing::kBicycleMask, + routing::kCarMask, +}; } // namespace namespace routing { // RoadAccess -------------------------------------------------------------------------------------- -// static -vector const & RoadAccess::GetSupportedRouterTypes() { return kSupportedRouterTypes; } - -// static -bool RoadAccess::IsSupportedRouterType(RouterType r) +RoadAccess::RoadAccess() { - return find(kSupportedRouterTypes.begin(), kSupportedRouterTypes.end(), r) != - kSupportedRouterTypes.end(); + for (auto const vehicleMask : kSupportedVehicleMasks) + m_types.emplace(vehicleMask, map()); +} +// static +vector const & RoadAccess::GetSupportedVehicleMasks() +{ + return kSupportedVehicleMasks; } -RoadAccess::Type const RoadAccess::GetType(RouterType routerType, Segment const & segment) const +// static +bool RoadAccess::IsSupportedVehicleMask(VehicleMask vehicleMask) { - auto const & types = GetTypes(routerType); + return find(kSupportedVehicleMasks.begin(), kSupportedVehicleMasks.end(), vehicleMask) != + kSupportedVehicleMasks.end(); +} + +RoadAccess::Type const RoadAccess::GetType(VehicleMask vehicleMask, Segment const & segment) const +{ + auto const & types = GetTypes(vehicleMask); Segment key(kFakeNumMwmId, segment.GetFeatureId(), segment.GetSegmentIdx(), segment.IsForward()); auto const it = types.find(key); if (it != types.end()) @@ -42,32 +50,28 @@ RoadAccess::Type const RoadAccess::GetType(RouterType routerType, Segment const return RoadAccess::Type::Yes; } -map const & RoadAccess::GetTypes(RouterType routerType) const +map const & RoadAccess::GetTypes(VehicleMask vehicleMask) const { - ASSERT(IsSupportedRouterType(routerType), ()); - return m_types[static_cast(routerType)]; + ASSERT(IsSupportedVehicleMask(vehicleMask), ()); + auto it = m_types.find(vehicleMask); + CHECK(it != m_types.end(), ()); + return it->second; } void RoadAccess::Clear() { - for (size_t i = 0; i < static_cast(RouterType::Count); ++i) - m_types[i].clear(); + for (auto & kv : m_types) + kv.second.clear(); } void RoadAccess::Swap(RoadAccess & rhs) { - for (size_t i = 0; i < static_cast(RouterType::Count); ++i) - m_types[i].swap(rhs.m_types[i]); + m_types.swap(rhs.m_types); } bool RoadAccess::operator==(RoadAccess const & rhs) const { - for (size_t i = 0; i < static_cast(RouterType::Count); ++i) - { - if (m_types[i] != rhs.m_types[i]) - return false; - } - return true; + return m_types == rhs.m_types; } // Functions --------------------------------------------------------------------------------------- @@ -100,14 +104,16 @@ string DebugPrint(RoadAccess const & r) size_t const kMaxIdsToShow = 10; ostringstream oss; oss << "RoadAccess ["; - for (size_t i = 0; i < static_cast(RouterType::Count); ++i) + bool firstMask = true; + for (auto const vehicleMask : RoadAccess::GetSupportedVehicleMasks()) { - if (i > 0) + if (!firstMask) oss << ", "; - auto const routerType = static_cast(i); - oss << DebugPrint(routerType) << " ["; + firstMask = false; + auto const & types = r.GetTypes(vehicleMask); + oss << DebugPrint(vehicleMask) << " ["; size_t id = 0; - for (auto const & kv : r.GetTypes(routerType)) + for (auto const & kv : types) { if (id > 0) oss << ", "; @@ -116,7 +122,7 @@ string DebugPrint(RoadAccess const & r) if (id == kMaxIdsToShow) break; } - if (r.GetTypes(routerType).size() > kMaxIdsToShow) + if (types.size() > kMaxIdsToShow) oss << "..."; oss << "]"; } diff --git a/routing/road_access.hpp b/routing/road_access.hpp index 7d86d0904c..dfc6bec9a6 100644 --- a/routing/road_access.hpp +++ b/routing/road_access.hpp @@ -1,7 +1,7 @@ #pragma once -#include "routing/router.hpp" #include "routing/segment.hpp" +#include "routing/vehicle_mask.hpp" #include "base/assert.hpp" @@ -40,18 +40,20 @@ public: Count }; - static std::vector const & GetSupportedRouterTypes(); - static bool IsSupportedRouterType(RouterType r); + RoadAccess(); - Type const GetType(RouterType routerType, Segment const & segment) const; + static std::vector const & GetSupportedVehicleMasks(); + static bool IsSupportedVehicleMask(VehicleMask vehicleMask); - std::map const & GetTypes(RouterType routerType) const; + Type const GetType(VehicleMask vehicleMask, Segment const & segment) const; + + std::map const & GetTypes(VehicleMask vehicleMask) const; template - void SetTypes(RouterType routerType, V && v) + void SetTypes(VehicleMask vehicleMask, V && v) { - CHECK(IsSupportedRouterType(routerType), ()); - m_types[static_cast(routerType)] = std::forward(v); + CHECK(IsSupportedVehicleMask(vehicleMask), ()); + m_types[vehicleMask] = std::forward(v); } void Clear(); @@ -63,7 +65,7 @@ public: private: // todo(@m) Segment's NumMwmId is not used here. Decouple it from // segment and use only (fid, idx, forward) in the map. - std::map m_types[static_cast(RouterType::Count)]; + std::map> m_types; }; std::string ToString(RoadAccess::Type type); diff --git a/routing/road_access_serialization.hpp b/routing/road_access_serialization.hpp index 61c3e84fa2..96da0e881a 100644 --- a/routing/road_access_serialization.hpp +++ b/routing/road_access_serialization.hpp @@ -33,8 +33,8 @@ public: uint32_t const header = kLatestVersion; WriteToSink(sink, header); - for (auto const routerType : RoadAccess::GetSupportedRouterTypes()) - SerializeOneRouterType(sink, roadAccess.GetTypes(routerType)); + for (auto const vehicleMask : RoadAccess::GetSupportedVehicleMasks()) + SerializeOneVehicleMask(sink, roadAccess.GetTypes(vehicleMask)); } template @@ -43,17 +43,17 @@ public: uint32_t const header = ReadPrimitiveFromSource(src); CHECK_EQUAL(header, kLatestVersion, ()); - for (auto const routerType : RoadAccess::GetSupportedRouterTypes()) + for (auto const vehicleMask : RoadAccess::GetSupportedVehicleMasks()) { RoadAccessTypesMap m; - DeserializeOneRouterType(src, m); - roadAccess.SetTypes(routerType, std::move(m)); + DeserializeOneVehicleMask(src, m); + roadAccess.SetTypes(vehicleMask, std::move(m)); } } private: template - static void SerializeOneRouterType(Sink & sink, RoadAccessTypesMap const & m) + static void SerializeOneVehicleMask(Sink & sink, RoadAccessTypesMap const & m) { std::array, static_cast(RoadAccess::Type::Count)> segmentsByRoadAccessType; @@ -68,7 +68,7 @@ private: } template - static void DeserializeOneRouterType(Source & src, RoadAccessTypesMap & m) + static void DeserializeOneVehicleMask(Source & src, RoadAccessTypesMap & m) { m.clear(); for (size_t i = 0; i < static_cast(RoadAccess::Type::Count); ++i) diff --git a/routing/routing_tests/road_access_test.cpp b/routing/routing_tests/road_access_test.cpp index 66f8552f66..09cdde14e9 100644 --- a/routing/routing_tests/road_access_test.cpp +++ b/routing/routing_tests/road_access_test.cpp @@ -32,8 +32,8 @@ UNIT_TEST(RoadAccess_Serialization) }; RoadAccess roadAccess; - roadAccess.SetTypes(RouterType::Vehicle, m0); - roadAccess.SetTypes(RouterType::Pedestrian, m1); + roadAccess.SetTypes(kCarMask, m0); + roadAccess.SetTypes(kPedestrianMask, m1); vector buf; { diff --git a/routing/vehicle_mask.hpp b/routing/vehicle_mask.hpp index d201f9805a..52abfb9088 100644 --- a/routing/vehicle_mask.hpp +++ b/routing/vehicle_mask.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace routing @@ -37,4 +38,25 @@ inline std::string DebugPrint(VehicleType vehicleType) case VehicleType::Count: return "Count"; } } + +inline std::string DebugPrint(VehicleMask vehicleMask) +{ + std::ostringstream oss; + oss << "VehicleMask ["; + bool first = true; + for (size_t i = 0; i < static_cast(VehicleType::Count); ++i) + { + auto const vt = static_cast(i); + if ((vehicleMask & GetVehicleMask(vt)) == 0) + continue; + + if (!first) + oss << ", "; + first = false; + + oss << DebugPrint(vt); + } + oss << "]"; + return oss.str(); +} } // namespace routing