Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorДобрый Ээх <bukharaev@gmail.com>2017-03-13 19:24:02 +0300
committerVladimir Byko-Ianko <bykoianko@gmail.com>2017-03-16 14:02:53 +0300
commitc8d09d4c3088d76d2c3e80472ff64a2e9ac16b1d (patch)
tree77f87e504692e61071f2749eb28c4c1885cb4591
parentbf307d05a798bfa56616391b0c1706162e26196b (diff)
[routing] pull request #5584 review fixes
-rw-r--r--coding/file_name_utils.hpp13
-rw-r--r--generator/generator_tool/generator_tool.cpp4
-rw-r--r--generator/routing_index_generator.cpp122
-rw-r--r--routing/CMakeLists.txt4
-rw-r--r--routing/cross_mwm_connector.cpp (renamed from routing/cross_mwm_ramp.cpp)62
-rw-r--r--routing/cross_mwm_connector.hpp (renamed from routing/cross_mwm_ramp.hpp)52
-rw-r--r--routing/cross_mwm_connector_serialization.cpp30
-rw-r--r--routing/cross_mwm_connector_serialization.hpp (renamed from routing/cross_mwm_ramp_serialization.hpp)143
-rw-r--r--routing/cross_mwm_ramp_serialization.cpp30
-rw-r--r--routing/routing.pro8
-rw-r--r--routing/routing_tests/CMakeLists.txt1
-rw-r--r--routing/routing_tests/cross_mwm_connector_test.cpp239
-rw-r--r--routing/routing_tests/cross_mwm_ramp_test.cpp226
-rw-r--r--routing/routing_tests/routing_tests.pro2
-rw-r--r--xcode/routing/routing.xcodeproj/project.pbxproj20
15 files changed, 534 insertions, 422 deletions
diff --git a/coding/file_name_utils.hpp b/coding/file_name_utils.hpp
index 1e3ffe83d1..4bcb32f616 100644
--- a/coding/file_name_utils.hpp
+++ b/coding/file_name_utils.hpp
@@ -3,6 +3,8 @@
#include "std/initializer_list.hpp"
#include "std/string.hpp"
+#include <utility>
+
namespace my
{
/// Remove extension from file name.
@@ -22,10 +24,19 @@ namespace my
/// Get folder separator for specific platform
string GetNativeSeparator();
- /// Create full path from some folder using native folders separator
+ /// @deprecated use JoinPath instead.
string JoinFoldersToPath(const string & folder, const string & file);
string JoinFoldersToPath(initializer_list<string> const & folders, const string & file);
/// Add the terminating slash to the folder path string if it's not already there.
string AddSlashIfNeeded(string const & path);
+
+ inline std::string JoinPath(std::string const & file) { return file; }
+
+ /// Create full path from some folder using native folders separator.
+ template<typename... Args>
+ std::string JoinPath(std::string const & folder, Args&&... args)
+ {
+ return AddSlashIfNeeded(folder) + JoinPath(std::forward<Args>(args)...);
+ }
}
diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp
index cd2d86f292..3cbcd60940 100644
--- a/generator/generator_tool/generator_tool.cpp
+++ b/generator/generator_tool/generator_tool.cpp
@@ -69,9 +69,9 @@ DEFINE_bool(split_by_polygons, false,
// Routing.
DEFINE_string(osrm_file_name, "", "Input osrm file to generate routing info.");
DEFINE_bool(make_routing, false, "Make routing info based on osrm file.");
-DEFINE_bool(make_cross_section, false, "Make cross section in routing file for cross mwm routing (for old OSRM routing).");
+DEFINE_bool(make_cross_section, false, "Make cross section in routing file for cross mwm routing (for OSRM routing).");
DEFINE_bool(make_routing_index, false, "Make sections with the routing information.");
-DEFINE_bool(make_cross_mwm, false, "Make section for cross mwm routing (for new AStar routing).");
+DEFINE_bool(make_cross_mwm, false, "Make section for cross mwm routing (for dynamic indexed routing).");
DEFINE_string(srtm_path, "",
"Path to srtm directory. If set, generates a section with altitude information "
"about roads.");
diff --git a/generator/routing_index_generator.cpp b/generator/routing_index_generator.cpp
index 19c2b33c24..73197f2331 100644
--- a/generator/routing_index_generator.cpp
+++ b/generator/routing_index_generator.cpp
@@ -1,17 +1,20 @@
#include "generator/routing_index_generator.hpp"
+
#include "generator/borders_generator.hpp"
#include "generator/borders_loader.hpp"
+#include "routing/cross_mwm_connector.hpp"
+#include "routing/cross_mwm_connector_serialization.hpp"
#include "routing/index_graph.hpp"
#include "routing/index_graph_serialization.hpp"
#include "routing/vehicle_mask.hpp"
-#include "routing/cross_mwm_ramp.hpp"
-#include "routing/cross_mwm_ramp_serialization.hpp"
#include "routing_common/bicycle_model.hpp"
#include "routing_common/car_model.hpp"
#include "routing_common/pedestrian_model.hpp"
+#include "indexer/coding_params.hpp"
+#include "indexer/data_header.hpp"
#include "indexer/feature.hpp"
#include "indexer/feature_processor.hpp"
#include "indexer/point_to_int64.hpp"
@@ -22,10 +25,10 @@
#include "base/checked_cast.hpp"
#include "base/logging.hpp"
-#include "std/bind.hpp"
-#include "std/shared_ptr.hpp"
-#include "std/unordered_map.hpp"
-#include "std/vector.hpp"
+#include <functional>
+#include <memory>
+#include <unordered_map>
+#include <vector>
using namespace feature;
using namespace platform;
@@ -33,10 +36,10 @@ using namespace routing;
namespace
{
-class VehicleMaskMaker final
+class VehicleMaskBuilder final
{
public:
- explicit VehicleMaskMaker(string const & country)
+ explicit VehicleMaskBuilder(string const & country)
: m_pedestrianModel(PedestrianModelFactory().GetVehicleModelForCountry(country))
, m_bicycleModel(BicycleModelFactory().GetVehicleModelForCountry(country))
, m_carModel(CarModelFactory().GetVehicleModelForCountry(country))
@@ -48,31 +51,31 @@ public:
VehicleMask CalcRoadMask(FeatureType const & f) const
{
- VehicleMask mask = 0;
- if (m_pedestrianModel->IsRoad(f))
- mask |= kPedestrianMask;
- if (m_bicycleModel->IsRoad(f))
- mask |= kBicycleMask;
- if (m_carModel->IsRoad(f))
- mask |= kCarMask;
-
- return mask;
+ return CalcMask(
+ f, [&](IVehicleModel const & model, FeatureType const & f) { return model.IsRoad(f); });
}
VehicleMask CalcOneWayMask(FeatureType const & f) const
{
+ return CalcMask(
+ f, [&](IVehicleModel const & model, FeatureType const & f) { return model.IsOneWay(f); });
+ }
+
+private:
+ template <class Fn>
+ bool CalcMask(FeatureType const & f, Fn && fn) const
+ {
VehicleMask mask = 0;
- if (m_pedestrianModel->IsOneWay(f))
+ if (fn(*m_pedestrianModel, f))
mask |= kPedestrianMask;
- if (m_bicycleModel->IsOneWay(f))
+ if (fn(*m_bicycleModel, f))
mask |= kBicycleMask;
- if (m_carModel->IsOneWay(f))
+ if (fn(*m_carModel, f))
mask |= kCarMask;
return mask;
}
-private:
shared_ptr<IVehicleModel> const m_pedestrianModel;
shared_ptr<IVehicleModel> const m_bicycleModel;
shared_ptr<IVehicleModel> const m_carModel;
@@ -81,8 +84,7 @@ private:
class Processor final
{
public:
- explicit Processor(string const & country) : m_maskMaker(country) {}
-
+ explicit Processor(string const & country) : m_maskBuilder(country) {}
void ProcessAllFeatures(string const & filename)
{
feature::ForEachFromDat(filename, bind(&Processor::ProcessFeature, this, _1, _2));
@@ -102,11 +104,10 @@ public:
}
unordered_map<uint32_t, VehicleMask> const & GetMasks() const { return m_masks; }
-
private:
void ProcessFeature(FeatureType const & f, uint32_t id)
{
- VehicleMask const mask = m_maskMaker.CalcRoadMask(f);
+ VehicleMask const mask = m_maskBuilder.CalcRoadMask(f);
if (mask == 0)
return;
@@ -120,14 +121,14 @@ private:
}
}
- VehicleMaskMaker const m_maskMaker;
+ VehicleMaskBuilder const m_maskBuilder;
unordered_map<uint64_t, Joint> m_posToJoint;
unordered_map<uint32_t, VehicleMask> m_masks;
};
-bool BordersContains(vector<m2::RegionD> const & borders, m2::PointD const & point)
+bool RegionsContain(vector<m2::RegionD> const & regions, m2::PointD const & point)
{
- for (m2::RegionD const & region : borders)
+ for (auto const & region : regions)
{
if (region.Contains(point))
return true;
@@ -137,14 +138,14 @@ bool BordersContains(vector<m2::RegionD> const & borders, m2::PointD const & poi
}
void CalcCrossMwmTransitions(string const & path, string const & mwmFile, string const & country,
- vector<CrossMwmRampSerializer::Transition> & transitions,
- vector<CrossMwmRamp> & ramps)
+ vector<CrossMwmConnectorSerializer::Transition> & transitions,
+ CrossMwmConnectorPerVehicleType & connectors)
{
- string const polyFile = my::JoinFoldersToPath({path, BORDERS_DIR}, country + BORDERS_EXTENSION);
+ string const polyFile = my::JoinPath(path, BORDERS_DIR, country + BORDERS_EXTENSION);
vector<m2::RegionD> borders;
osm::LoadBorders(polyFile, borders);
- VehicleMaskMaker const maskMaker(country);
+ VehicleMaskBuilder const maskMaker(country);
feature::ForEachFromDat(mwmFile, [&](FeatureType const & f, uint32_t featureId) {
VehicleMask const roadMask = maskMaker.CalcRoadMask(f);
@@ -153,51 +154,44 @@ void CalcCrossMwmTransitions(string const & path, string const & mwmFile, string
f.ParseGeometry(FeatureType::BEST_GEOMETRY);
size_t const pointsCount = f.GetPointsCount();
- if (pointsCount <= 0)
+ if (pointsCount == 0)
return;
- bool prevPointIn = BordersContains(borders, f.GetPoint(0));
+ bool prevPointIn = RegionsContain(borders, f.GetPoint(0));
for (size_t i = 1; i < pointsCount; ++i)
{
- bool const pointIn = BordersContains(borders, f.GetPoint(i));
- if (pointIn != prevPointIn)
- {
- uint32_t const segmentIdx = base::asserted_cast<uint32_t>(i - 1);
- VehicleMask const oneWayMask = maskMaker.CalcOneWayMask(f);
+ bool const currPointIn = RegionsContain(borders, f.GetPoint(i));
+ if (currPointIn == prevPointIn)
+ continue;
- transitions.emplace_back(featureId, segmentIdx, roadMask, oneWayMask, pointIn,
- f.GetPoint(i - 1), f.GetPoint(i));
+ uint32_t const segmentIdx = base::asserted_cast<uint32_t>(i - 1);
+ VehicleMask const oneWayMask = maskMaker.CalcOneWayMask(f);
- for (size_t j = 0; j < ramps.size(); ++j)
- {
- VehicleMask const mask = GetVehicleMask(static_cast<VehicleType>(j));
- CrossMwmRampSerializer::AddTransition(transitions.back(), mask, ramps[j]);
- }
+ transitions.emplace_back(featureId, segmentIdx, roadMask, oneWayMask, currPointIn,
+ f.GetPoint(i - 1), f.GetPoint(i));
+
+ for (size_t j = 0; j < connectors.size(); ++j)
+ {
+ VehicleMask const mask = GetVehicleMask(static_cast<VehicleType>(j));
+ CrossMwmConnectorSerializer::AddTransition(transitions.back(), mask, connectors[j]);
}
- prevPointIn = pointIn;
+ prevPointIn = currPointIn;
}
});
}
-void FillWeights(string const & path, string const & country, CrossMwmRamp & ramp)
+void FillWeights(string const & path, string const & country, CrossMwmConnector & connector)
{
shared_ptr<IVehicleModel> vehicleModel = CarModelFactory().GetVehicleModelForCountry(country);
shared_ptr<EdgeEstimator> estimator =
EdgeEstimator::CreateForCar(nullptr /* trafficStash */, vehicleModel->GetMaxSpeed());
- Index index;
- platform::CountryFile countryFile(country);
- index.RegisterMap(LocalCountryFile(path, countryFile, 0));
- MwmSet::MwmHandle handle = index.GetMwmHandleByCountryFile(countryFile);
- CHECK(handle.IsAlive(), ());
-
- Geometry geometry(GeometryLoader::Create(index, handle.GetId(), vehicleModel));
-
- ramp.FillWeights([&](Segment const & enter, Segment const & exit) {
- return estimator->CalcHeuristic(geometry.GetPoint(enter.GetRoadPoint(true)),
- geometry.GetPoint(exit.GetRoadPoint(true)));
+ connector.FillWeights([&](Segment const & enter, Segment const & exit) {
+ // TODO replace fake weights with weights calculated by routing.
+ return estimator->CalcHeuristic(connector.GetPoint(enter, true /* front */),
+ connector.GetPoint(exit, true /* front */));
});
}
} // namespace
@@ -238,12 +232,12 @@ void BuildCrossMwmSection(string const & path, string const & mwmFile, string co
LOG(LINFO, ("Building cross mwm section for", country));
my::Timer timer;
- vector<CrossMwmRamp> ramps(static_cast<size_t>(VehicleType::Count), kFakeNumMwmId);
+ CrossMwmConnectorPerVehicleType connectors;
- vector<CrossMwmRampSerializer::Transition> transitions;
- CalcCrossMwmTransitions(path, mwmFile, country, transitions, ramps);
+ vector<CrossMwmConnectorSerializer::Transition> transitions;
+ CalcCrossMwmTransitions(path, mwmFile, country, transitions, connectors);
- FillWeights(path, country, ramps[static_cast<size_t>(VehicleType::Car)]);
+ FillWeights(path, country, connectors[static_cast<size_t>(VehicleType::Car)]);
FilesContainerW cont(mwmFile, FileWriter::OP_WRITE_EXISTING);
FileWriter writer = cont.GetWriter(CROSS_MWM_FILE_TAG);
@@ -252,7 +246,7 @@ void BuildCrossMwmSection(string const & path, string const & mwmFile, string co
serial::CodingParams const & codingParams = dataHeader.GetDefCodingParams();
auto const startPos = writer.Pos();
- CrossMwmRampSerializer::Serialize(transitions, ramps, codingParams, writer);
+ CrossMwmConnectorSerializer::Serialize(transitions, connectors, codingParams, writer);
auto const sectionSize = writer.Pos() - startPos;
LOG(LINFO, ("Cross mwm section for", country, "generated in", timer.ElapsedSeconds(),
diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt
index be86001356..16b4374e17 100644
--- a/routing/CMakeLists.txt
+++ b/routing/CMakeLists.txt
@@ -18,6 +18,10 @@ set(
bicycle_directions.hpp
car_router.cpp
car_router.hpp
+ cross_mwm_connector.cpp
+ cross_mwm_connector.hpp
+ cross_mwm_connector_serialization.cpp
+ cross_mwm_connector_serialization.hpp
cross_mwm_index_graph.cpp
cross_mwm_index_graph.hpp
cross_mwm_road_graph.cpp
diff --git a/routing/cross_mwm_ramp.cpp b/routing/cross_mwm_connector.cpp
index 8a5e82b301..cf6d62469f 100644
--- a/routing/cross_mwm_ramp.cpp
+++ b/routing/cross_mwm_connector.cpp
@@ -1,4 +1,4 @@
-#include "routing/cross_mwm_ramp.hpp"
+#include "routing/cross_mwm_connector.hpp"
namespace
{
@@ -8,23 +8,23 @@ uint32_t constexpr kFakeId = std::numeric_limits<uint32_t>::max();
namespace routing
{
// static
-CrossMwmRamp::Weight constexpr CrossMwmRamp::kNoRoute;
+CrossMwmConnector::Weight constexpr CrossMwmConnector::kNoRoute;
-void CrossMwmRamp::AddTransition(uint32_t featureId, uint32_t segmentIdx, bool oneWay,
- bool forwardIsEnter, m2::PointD const & backPoint,
- m2::PointD const & frontPoint)
+void CrossMwmConnector::AddTransition(uint32_t featureId, uint32_t segmentIdx, bool oneWay,
+ bool forwardIsEnter, m2::PointD const & backPoint,
+ m2::PointD const & frontPoint)
{
Transition transition(kFakeId, kFakeId, oneWay, forwardIsEnter, backPoint, frontPoint);
if (forwardIsEnter)
{
transition.m_enterIdx = base::asserted_cast<uint32_t>(m_enters.size());
- m_enters.emplace_back(m_mwmId, featureId, segmentIdx, true);
+ m_enters.emplace_back(m_mwmId, featureId, segmentIdx, true /* forward */);
}
else
{
transition.m_exitIdx = base::asserted_cast<uint32_t>(m_exits.size());
- m_exits.emplace_back(m_mwmId, featureId, segmentIdx, true);
+ m_exits.emplace_back(m_mwmId, featureId, segmentIdx, true /* forward */);
}
if (!oneWay)
@@ -32,19 +32,19 @@ void CrossMwmRamp::AddTransition(uint32_t featureId, uint32_t segmentIdx, bool o
if (forwardIsEnter)
{
transition.m_exitIdx = base::asserted_cast<uint32_t>(m_exits.size());
- m_exits.emplace_back(m_mwmId, featureId, segmentIdx, false);
+ m_exits.emplace_back(m_mwmId, featureId, segmentIdx, false /* forward */);
}
else
{
transition.m_enterIdx = base::asserted_cast<uint32_t>(m_enters.size());
- m_enters.emplace_back(m_mwmId, featureId, segmentIdx, false);
+ m_enters.emplace_back(m_mwmId, featureId, segmentIdx, false /* forward */);
}
}
m_transitions[Key(featureId, segmentIdx)] = transition;
}
-bool CrossMwmRamp::IsTransition(Segment const & segment, bool isOutgoing) const
+bool CrossMwmConnector::IsTransition(Segment const & segment, bool isOutgoing) const
{
auto it = m_transitions.find(Key(segment.GetFeatureId(), segment.GetSegmentIdx()));
if (it == m_transitions.cend())
@@ -57,14 +57,14 @@ bool CrossMwmRamp::IsTransition(Segment const & segment, bool isOutgoing) const
return (segment.IsForward() == transition.m_forwardIsEnter) == isOutgoing;
}
-m2::PointD const & CrossMwmRamp::GetPoint(Segment const & segment, bool front) const
+m2::PointD const & CrossMwmConnector::GetPoint(Segment const & segment, bool front) const
{
Transition const & transition = GetTransition(segment);
return segment.IsForward() == front ? transition.m_frontPoint : transition.m_backPoint;
}
-void CrossMwmRamp::GetEdgeList(Segment const & segment, bool isOutgoing,
- std::vector<SegmentEdge> & edges) const
+void CrossMwmConnector::GetEdgeList(Segment const & segment, bool isOutgoing,
+ std::vector<SegmentEdge> & edges) const
{
Transition const & transition = GetTransition(segment);
if (isOutgoing)
@@ -87,22 +87,48 @@ void CrossMwmRamp::GetEdgeList(Segment const & segment, bool isOutgoing,
}
}
-void CrossMwmRamp::AddEdge(Segment const & segment, Weight weight,
- std::vector<SegmentEdge> & edges) const
+bool CrossMwmConnector::WeightsWereLoaded() const
+{
+ switch (m_weightsLoadState)
+ {
+ case WeightsLoadState::Unknown:
+ case WeightsLoadState::ReadyToLoad: return false;
+ case WeightsLoadState::NotExists:
+ case WeightsLoadState::Loaded: return true;
+ }
+}
+
+std::string DebugPrint(CrossMwmConnector::WeightsLoadState state)
+{
+ switch (state)
+ {
+ case CrossMwmConnector::WeightsLoadState::Unknown: return "Unknown";
+ case CrossMwmConnector::WeightsLoadState::ReadyToLoad: return "ReadyToLoad";
+ case CrossMwmConnector::WeightsLoadState::NotExists: return "NotExists";
+ case CrossMwmConnector::WeightsLoadState::Loaded: return "Loaded";
+ }
+}
+
+void CrossMwmConnector::AddEdge(Segment const & segment, Weight weight,
+ std::vector<SegmentEdge> & edges) const
{
if (weight != kNoRoute)
edges.emplace_back(segment, static_cast<double>(weight));
}
-CrossMwmRamp::Transition const & CrossMwmRamp::GetTransition(Segment const & segment) const
+CrossMwmConnector::Transition const & CrossMwmConnector::GetTransition(
+ Segment const & segment) const
{
auto it = m_transitions.find(Key(segment.GetFeatureId(), segment.GetSegmentIdx()));
- CHECK(it != m_transitions.cend(), ("Not transition segment:", segment));
+ CHECK(it != m_transitions.cend(), ("Not a transition segment:", segment));
return it->second;
}
-CrossMwmRamp::Weight CrossMwmRamp::GetWeight(size_t enterIdx, size_t exitIdx) const
+CrossMwmConnector::Weight CrossMwmConnector::GetWeight(size_t enterIdx, size_t exitIdx) const
{
+ ASSERT_LESS(enterIdx, m_enters.size(), ());
+ ASSERT_LESS(exitIdx, m_exits.size(), ());
+
size_t const i = enterIdx * m_exits.size() + exitIdx;
ASSERT_LESS(i, m_weights.size(), ());
return m_weights[i];
diff --git a/routing/cross_mwm_ramp.hpp b/routing/cross_mwm_connector.hpp
index e8ac49101b..22ef84de61 100644
--- a/routing/cross_mwm_ramp.hpp
+++ b/routing/cross_mwm_connector.hpp
@@ -2,10 +2,10 @@
#include "routing/segment.hpp"
-#include "base/assert.hpp"
-
#include "geometry/point2d.hpp"
+#include "base/assert.hpp"
+
#include <cmath>
#include <limits>
#include <unordered_map>
@@ -13,10 +13,12 @@
namespace routing
{
-class CrossMwmRamp final
+class CrossMwmConnector final
{
public:
- CrossMwmRamp(NumMwmId mwmId) : m_mwmId(mwmId) {}
+ CrossMwmConnector() : m_mwmId(kFakeNumMwmId) {}
+ explicit CrossMwmConnector(NumMwmId mwmId) : m_mwmId(mwmId) {}
+
void AddTransition(uint32_t featureId, uint32_t segmentIdx, bool oneWay, bool forwardIsEnter,
m2::PointD const & backPoint, m2::PointD const & frontPoint);
@@ -28,24 +30,28 @@ public:
std::vector<Segment> const & GetEnters() const { return m_enters; }
std::vector<Segment> const & GetExits() const { return m_exits; }
bool HasWeights() const { return !m_weights.empty(); }
- bool WeightsWereLoaded() const { return m_weightsWereLoaded; }
+ bool WeightsWereLoaded() const;
+
template <typename CalcWeight>
void FillWeights(CalcWeight && calcWeight)
{
+ CHECK_EQUAL(m_weightsLoadState, WeightsLoadState::Unknown, ());
CHECK(m_weights.empty(), ());
+
m_weights.reserve(m_enters.size() * m_exits.size());
- for (size_t i = 0; i < m_enters.size(); ++i)
+ for (Segment const & enter : m_enters)
{
- for (size_t j = 0; j < m_exits.size(); ++j)
+ for (Segment const & exit : m_exits)
{
- double const weight = calcWeight(m_enters[i], m_exits[j]);
+ double const weight = calcWeight(enter, exit);
+ // Edges weights should be >= astar heuristic, so use std::ceil.
m_weights.push_back(static_cast<Weight>(std::ceil(weight)));
}
}
}
private:
- // This is internal type used for storing edges weights.
+ // This is an internal type for storing edges weights.
// Weight is the time requred for the route to pass.
// Weight is measured in seconds rounded upwards.
using Weight = uint32_t;
@@ -60,7 +66,7 @@ private:
{
}
- bool operator==(const Key & key) const
+ bool operator==(Key const & key) const
{
return m_featureId == key.m_featureId && m_segmentIdx == key.m_segmentIdx;
}
@@ -71,7 +77,7 @@ private:
struct HashKey
{
- size_t operator()(const Key & key) const
+ size_t operator()(Key const & key) const
{
return std::hash<uint64_t>()((static_cast<uint64_t>(key.m_featureId) << 32) +
static_cast<uint64_t>(key.m_segmentIdx));
@@ -95,13 +101,28 @@ private:
uint32_t m_enterIdx = 0;
uint32_t m_exitIdx = 0;
- m2::PointD m_backPoint = {0.0, 0.0};
- m2::PointD m_frontPoint = {0.0, 0.0};
+ // Endpoints of transition segment.
+ // m_backPoint = points[segmentIdx]
+ // m_frontPoint = points[segmentIdx + 1]
+ m2::PointD m_backPoint = m2::PointD::Zero();
+ m2::PointD m_frontPoint = m2::PointD::Zero();
bool m_oneWay = false;
+ // Transition represents both forward and backward segments with same featureId, segmentIdx.
+ // m_forwardIsEnter == true means: forward segment is enter to mwm:
+ // Enter means: m_backPoint is outside mwm borders, m_frontPoint is inside.
bool m_forwardIsEnter = false;
};
- friend class CrossMwmRampSerializer;
+ enum class WeightsLoadState
+ {
+ Unknown,
+ NotExists,
+ ReadyToLoad,
+ Loaded
+ };
+
+ friend class CrossMwmConnectorSerializer;
+ friend std::string DebugPrint(WeightsLoadState state);
void AddEdge(Segment const & segment, Weight weight, std::vector<SegmentEdge> & edges) const;
Transition const & GetTransition(Segment const & segment) const;
@@ -111,7 +132,8 @@ private:
std::vector<Segment> m_enters;
std::vector<Segment> m_exits;
std::unordered_map<Key, Transition, HashKey> m_transitions;
+ WeightsLoadState m_weightsLoadState = WeightsLoadState::Unknown;
+ uint64_t m_weightsOffset = 0;
std::vector<Weight> m_weights;
- bool m_weightsWereLoaded = false;
};
} // namespace routing
diff --git a/routing/cross_mwm_connector_serialization.cpp b/routing/cross_mwm_connector_serialization.cpp
new file mode 100644
index 0000000000..cdc6c2c4ec
--- /dev/null
+++ b/routing/cross_mwm_connector_serialization.cpp
@@ -0,0 +1,30 @@
+#include "routing/cross_mwm_connector_serialization.hpp"
+
+using namespace std;
+
+namespace routing
+{
+// static
+uint32_t constexpr CrossMwmConnectorSerializer::kLastVersion;
+
+// static
+void CrossMwmConnectorSerializer::WriteTransitions(vector<Transition> const & transitions,
+ serial::CodingParams const & codingParams,
+ uint8_t bitsPerMask, vector<uint8_t> & buffer)
+{
+ MemWriter<vector<uint8_t>> memWriter(buffer);
+
+ for (Transition const & transition : transitions)
+ transition.Serialize(codingParams, bitsPerMask, memWriter);
+}
+
+// static
+void CrossMwmConnectorSerializer::WriteWeights(vector<CrossMwmConnector::Weight> const & weights,
+ vector<uint8_t> & buffer)
+{
+ MemWriter<vector<uint8_t>> memWriter(buffer);
+
+ for (auto weight : weights)
+ WriteToSink(memWriter, weight);
+}
+} // namespace routing
diff --git a/routing/cross_mwm_ramp_serialization.hpp b/routing/cross_mwm_connector_serialization.hpp
index dbc0d7f42b..f21bc74a7d 100644
--- a/routing/cross_mwm_ramp_serialization.hpp
+++ b/routing/cross_mwm_connector_serialization.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "routing/cross_mwm_ramp.hpp"
+#include "routing/cross_mwm_connector.hpp"
#include "routing/routing_exceptions.hpp"
#include "routing/vehicle_mask.hpp"
@@ -14,12 +14,17 @@
#include "base/checked_cast.hpp"
-#include <stdint.h>
+#include <array>
+#include <cstdint>
+#include <limits>
#include <vector>
namespace routing
{
-class CrossMwmRampSerializer final
+using CrossMwmConnectorPerVehicleType =
+ std::array<CrossMwmConnector, static_cast<size_t>(VehicleType::Count)>;
+
+class CrossMwmConnectorSerializer final
{
public:
class Transition final
@@ -50,8 +55,8 @@ public:
serial::SavePoint(sink, m_frontPoint, codingParams);
BitWriter<Sink> writer(sink);
- writer.WriteAtMost32Bits(static_cast<uint32_t>(m_roadMask), bitsPerMask);
- writer.WriteAtMost32Bits(static_cast<uint32_t>(m_oneWayMask), bitsPerMask);
+ writer.WriteAtMost32Bits(base::asserted_cast<uint32_t>(m_roadMask), bitsPerMask);
+ writer.WriteAtMost32Bits(base::asserted_cast<uint32_t>(m_oneWayMask), bitsPerMask);
writer.Write(m_forwardIsEnter ? 0 : 1, 1);
}
@@ -64,8 +69,8 @@ public:
m_frontPoint = serial::LoadPoint(src, codingParams);
BitReader<Source> reader(src);
- m_roadMask = reader.ReadAtMost32Bits(bitsPerMask);
- m_oneWayMask = reader.ReadAtMost32Bits(bitsPerMask);
+ m_roadMask = base::asserted_cast<VehicleMask>(reader.ReadAtMost32Bits(bitsPerMask));
+ m_oneWayMask = base::asserted_cast<VehicleMask>(reader.ReadAtMost32Bits(bitsPerMask));
m_forwardIsEnter = reader.Read(1) == 0;
}
@@ -80,39 +85,39 @@ public:
private:
uint32_t m_featureId = 0;
uint32_t m_segmentIdx = 0;
- m2::PointD m_backPoint = {0.0, 0.0};
- m2::PointD m_frontPoint = {0.0, 0.0};
+ m2::PointD m_backPoint = m2::PointD::Zero();
+ m2::PointD m_frontPoint = m2::PointD::Zero();
VehicleMask m_roadMask = 0;
VehicleMask m_oneWayMask = 0;
bool m_forwardIsEnter = false;
};
- CrossMwmRampSerializer() = delete;
+ CrossMwmConnectorSerializer() = delete;
template <class Sink>
static void Serialize(std::vector<Transition> const & transitions,
- vector<CrossMwmRamp> const & ramps,
+ CrossMwmConnectorPerVehicleType const & connectors,
serial::CodingParams const & codingParams, Sink & sink)
{
- auto const bitsPerMask = static_cast<uint8_t>(VehicleType::Count);
- vector<uint8_t> transitionsBuf;
+ auto const bitsPerMask = GetBitsPerMask<uint8_t>();
+ std::vector<uint8_t> transitionsBuf;
WriteTransitions(transitions, codingParams, bitsPerMask, transitionsBuf);
Header header(base::checked_cast<uint32_t>(transitions.size()),
base::checked_cast<uint64_t>(transitionsBuf.size()), codingParams, bitsPerMask);
- vector<vector<uint8_t>> weightBuffers(ramps.size());
+ std::vector<std::vector<uint8_t>> weightBuffers(connectors.size());
- for (size_t i = 0; i < ramps.size(); ++i)
+ for (size_t i = 0; i < connectors.size(); ++i)
{
- CrossMwmRamp const & ramp = ramps[i];
- if (!ramp.HasWeights())
+ CrossMwmConnector const & connector = connectors[i];
+ if (connector.m_weights.empty())
continue;
- vector<uint8_t> & buffer = weightBuffers[i];
- WriteWeights(ramp.m_weights, buffer);
+ std::vector<uint8_t> & buffer = weightBuffers[i];
+ WriteWeights(connector.m_weights, buffer);
- auto numEnters = base::checked_cast<uint32_t>(ramp.GetEnters().size());
- auto numExits = base::checked_cast<uint32_t>(ramp.GetExits().size());
+ auto const numEnters = base::checked_cast<uint32_t>(connector.GetEnters().size());
+ auto const numExits = base::checked_cast<uint32_t>(connector.GetExits().size());
auto const vehicleType = static_cast<VehicleType>(i);
header.AddSection(Section(buffer.size(), numEnters, numExits, vehicleType));
}
@@ -125,12 +130,15 @@ public:
}
template <class Source>
- static void DeserializeTransitions(VehicleType requiredVehicle, CrossMwmRamp & ramp, Source & src)
+ static void DeserializeTransitions(VehicleType requiredVehicle, CrossMwmConnector & connector,
+ Source & src)
{
+ CHECK(connector.m_weightsLoadState == CrossMwmConnector::WeightsLoadState::Unknown, ());
+
Header header;
header.Deserialize(src);
- uint64_t const transitionsEnd = src.Pos() + header.GetSizeTransitions();
+ uint64_t weightsOffset = src.Pos() + header.GetSizeTransitions();
VehicleMask const requiredMask = GetVehicleMask(requiredVehicle);
auto const numTransitions = base::checked_cast<size_t>(header.GetNumTransitions());
@@ -138,72 +146,76 @@ public:
{
Transition transition;
transition.Deserialize(header.GetCodingParams(), header.GetBitsPerMask(), src);
- AddTransition(transition, requiredMask, ramp);
+ AddTransition(transition, requiredMask, connector);
}
- if (src.Pos() != transitionsEnd)
+ if (src.Pos() != weightsOffset)
{
MYTHROW(CorruptedDataException,
- ("Wrong position", src.Pos(), "after decoding transitions, expected:", transitionsEnd,
- "size:", header.GetSizeTransitions()));
+ ("Wrong position", src.Pos(), "after decoding transitions, expected:",
+ connector.m_weightsOffset, "size:", header.GetSizeTransitions()));
}
- }
-
- template <class Source>
- static void DeserializeWeights(VehicleType requiredVehicle, CrossMwmRamp & ramp, Source & src)
- {
- CHECK(!ramp.WeightsWereLoaded(), ());
-
- Header header;
- header.Deserialize(src);
- src.Skip(header.GetSizeTransitions());
for (Section const & section : header.GetSections())
{
if (section.GetVehicleType() != requiredVehicle)
{
- src.Skip(section.GetSize());
+ weightsOffset += section.GetSize();
continue;
}
- size_t const numEnters = ramp.GetEnters().size();
- size_t const numExits = ramp.GetExits().size();
+ size_t const numEnters = connector.GetEnters().size();
+ size_t const numExits = connector.GetExits().size();
if (base::checked_cast<size_t>(section.GetNumEnters()) != numEnters)
{
- MYTHROW(CorruptedDataException,
- ("Mismatch enters number, section:", section.GetNumEnters(), ", ramp:", numEnters));
+ MYTHROW(CorruptedDataException, ("Mismatch enters number, section:", section.GetNumEnters(),
+ ", connector:", numEnters));
}
if (base::checked_cast<size_t>(section.GetNumExits()) != numExits)
{
- MYTHROW(CorruptedDataException,
- ("Mismatch exits number, section:", section.GetNumExits(), ", ramp:", numExits));
+ MYTHROW(CorruptedDataException, ("Mismatch exits number, section:", section.GetNumExits(),
+ ", connector:", numExits));
}
- size_t const size = numEnters * numExits;
- ramp.m_weights.reserve(size);
- for (size_t i = 0; i < size; ++i)
- {
- auto const weight = ReadPrimitiveFromSource<uint32_t>(src);
- ramp.m_weights.push_back(static_cast<float>(weight));
- }
- break;
+ connector.m_weightsOffset = weightsOffset;
+ connector.m_weightsLoadState = CrossMwmConnector::WeightsLoadState::ReadyToLoad;
+ return;
}
- ramp.m_weightsWereLoaded = true;
+ connector.m_weightsLoadState = CrossMwmConnector::WeightsLoadState::NotExists;
+ }
+
+ template <class Source>
+ static void DeserializeWeights(VehicleType requiredVehicle, CrossMwmConnector & connector,
+ Source & src)
+ {
+ CHECK(connector.m_weightsLoadState == CrossMwmConnector::WeightsLoadState::ReadyToLoad, ());
+
+ src.Skip(connector.m_weightsOffset);
+
+ size_t const amount = connector.GetEnters().size() * connector.GetExits().size();
+ connector.m_weights.reserve(amount);
+ for (size_t i = 0; i < amount; ++i)
+ {
+ auto const weight = ReadPrimitiveFromSource<uint32_t>(src);
+ connector.m_weights.push_back(static_cast<CrossMwmConnector::Weight>(weight));
+ }
+
+ connector.m_weightsLoadState = CrossMwmConnector::WeightsLoadState::Loaded;
}
static void AddTransition(Transition const & transition, VehicleMask requiredMask,
- CrossMwmRamp & ramp)
+ CrossMwmConnector & connector)
{
if ((transition.GetRoadMask() & requiredMask) == 0)
return;
bool const isOneWay = (transition.GetOneWayMask() & requiredMask) != 0;
- ramp.AddTransition(transition.GetFeatureId(), transition.GetSegmentIdx(), isOneWay,
- transition.ForwardIsEnter(), transition.GetBackPoint(),
- transition.GetFrontPoint());
+ connector.AddTransition(transition.GetFeatureId(), transition.GetSegmentIdx(), isOneWay,
+ transition.ForwardIsEnter(), transition.GetBackPoint(),
+ transition.GetFrontPoint());
}
private:
@@ -304,7 +316,7 @@ private:
uint64_t GetSizeTransitions() const { return m_sizeTransitions; }
serial::CodingParams const & GetCodingParams() const { return m_codingParams; }
uint8_t GetBitsPerMask() const { return m_bitsPerMask; }
- vector<Section> const & GetSections() const { return m_sections; }
+ std::vector<Section> const & GetSections() const { return m_sections; }
private:
uint32_t m_version = kLastVersion;
@@ -312,11 +324,20 @@ private:
uint64_t m_sizeTransitions = 0;
serial::CodingParams m_codingParams;
uint8_t m_bitsPerMask = 0;
- vector<Section> m_sections;
+ std::vector<Section> m_sections;
};
+ template <typename T>
+ static T GetBitsPerMask()
+ {
+ static_assert(
+ static_cast<size_t>(VehicleType::Count) <= static_cast<size_t>(numeric_limits<T>::max()),
+ "Can't pack VehicleType::Count into chosen type");
+ return static_cast<T>(VehicleType::Count);
+ }
+
template <class Sink>
- static void FlushBuffer(vector<uint8_t> & buffer, Sink & sink)
+ static void FlushBuffer(std::vector<uint8_t> & buffer, Sink & sink)
{
sink.Write(buffer.data(), buffer.size());
buffer.clear();
@@ -326,7 +347,7 @@ private:
serial::CodingParams const & codingParams, uint8_t bitsPerMask,
std::vector<uint8_t> & buffer);
- static void WriteWeights(std::vector<CrossMwmRamp::Weight> const & weights,
+ static void WriteWeights(std::vector<CrossMwmConnector::Weight> const & weights,
std::vector<uint8_t> & buffer);
};
} // namespace routing
diff --git a/routing/cross_mwm_ramp_serialization.cpp b/routing/cross_mwm_ramp_serialization.cpp
deleted file mode 100644
index 46d1dda389..0000000000
--- a/routing/cross_mwm_ramp_serialization.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "routing/cross_mwm_ramp_serialization.hpp"
-
-using namespace std;
-
-namespace routing
-{
-// static
-uint32_t constexpr CrossMwmRampSerializer::kLastVersion;
-
-// static
-void CrossMwmRampSerializer::WriteTransitions(vector<Transition> const & transitions,
- serial::CodingParams const & codingParams,
- uint8_t bitsPerMask, vector<uint8_t> & buffer)
-{
- MemWriter<vector<uint8_t>> memWriter(buffer);
-
- for (Transition const & transition : transitions)
- transition.Serialize(codingParams, bitsPerMask, memWriter);
-}
-
-// static
-void CrossMwmRampSerializer::WriteWeights(vector<CrossMwmRamp::Weight> const & weights,
- vector<uint8_t> & buffer)
-{
- MemWriter<vector<uint8_t>> memWriter(buffer);
-
- for (auto weight : weights)
- WriteToSink(memWriter, weight);
-}
-} // namespace routing
diff --git a/routing/routing.pro b/routing/routing.pro
index f2aac961f0..7ba284b0a5 100644
--- a/routing/routing.pro
+++ b/routing/routing.pro
@@ -17,9 +17,9 @@ SOURCES += \
base/followed_polyline.cpp \
bicycle_directions.cpp \
car_router.cpp \
+ cross_mwm_connector.cpp \
+ cross_mwm_connector_serialization.cpp \
cross_mwm_index_graph.cpp \
- cross_mwm_ramp.cpp \
- cross_mwm_ramp_serialization.cpp \
cross_mwm_road_graph.cpp \
cross_mwm_router.cpp \
cross_routing_context.cpp \
@@ -69,9 +69,9 @@ HEADERS += \
base/followed_polyline.hpp \
bicycle_directions.hpp \
car_router.hpp \
+ cross_mwm_connector.hpp \
+ cross_mwm_connector_serialization.hpp \
cross_mwm_index_graph.hpp \
- cross_mwm_ramp.hpp \
- cross_mwm_ramp_serialization.hpp \
cross_mwm_road_graph.hpp \
cross_mwm_router.hpp \
cross_routing_context.hpp \
diff --git a/routing/routing_tests/CMakeLists.txt b/routing/routing_tests/CMakeLists.txt
index b960860ef9..9c1af798b4 100644
--- a/routing/routing_tests/CMakeLists.txt
+++ b/routing/routing_tests/CMakeLists.txt
@@ -8,6 +8,7 @@ set(
astar_progress_test.cpp
astar_router_test.cpp
async_router_test.cpp
+ cross_mwm_connector_test.cpp
cross_routing_tests.cpp
cumulative_restriction_test.cpp
followed_polyline_test.cpp
diff --git a/routing/routing_tests/cross_mwm_connector_test.cpp b/routing/routing_tests/cross_mwm_connector_test.cpp
new file mode 100644
index 0000000000..7973ed088c
--- /dev/null
+++ b/routing/routing_tests/cross_mwm_connector_test.cpp
@@ -0,0 +1,239 @@
+#include "testing/testing.hpp"
+
+#include "routing/cross_mwm_connector_serialization.hpp"
+
+#include "coding/writer.hpp"
+
+using namespace routing;
+using namespace std;
+
+namespace
+{
+NumMwmId constexpr mwmId = 777;
+
+void TestConnectorConsistency(CrossMwmConnector const & connector)
+{
+ for (Segment const & enter : connector.GetEnters())
+ {
+ TEST(connector.IsTransition(enter, true /* isOutgoing */), ("enter:", enter));
+ TEST(!connector.IsTransition(enter, false /* isOutgoing */), ("enter:", enter));
+ }
+
+ for (Segment const & exit : connector.GetExits())
+ {
+ TEST(!connector.IsTransition(exit, true /* isOutgoing */), ("exit:", exit));
+ TEST(connector.IsTransition(exit, false /* isOutgoing */), ("exit:", exit));
+ }
+}
+
+void TestEdges(CrossMwmConnector const & connector, Segment const & from, bool isOutgoing,
+ vector<SegmentEdge> const & expectedEdges)
+{
+ vector<SegmentEdge> edges;
+ connector.GetEdgeList(from, isOutgoing, edges);
+ TEST_EQUAL(edges, expectedEdges, ());
+}
+}
+
+namespace routing_test
+{
+UNIT_TEST(OneWayEnter)
+{
+ uint32_t constexpr featureId = 1;
+ uint32_t constexpr segmentIdx = 1;
+ CrossMwmConnector connector(mwmId);
+ connector.AddTransition(featureId, segmentIdx, true /* oneWay */, true /* forwardIsEnter */,
+ {} /* backPoint */, {} /* frontPoint */);
+
+ TestConnectorConsistency(connector);
+ TEST_EQUAL(connector.GetEnters().size(), 1, ());
+ TEST_EQUAL(connector.GetExits().size(), 0, ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ false /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ false /* isOutgoing */),
+ ());
+}
+
+UNIT_TEST(OneWayExit)
+{
+ uint32_t constexpr featureId = 1;
+ uint32_t constexpr segmentIdx = 1;
+ CrossMwmConnector connector(mwmId);
+ connector.AddTransition(featureId, segmentIdx, true /* oneWay */, false /* forwardIsEnter */,
+ {} /* backPoint */, {} /* frontPoint */);
+
+ TestConnectorConsistency(connector);
+ TEST_EQUAL(connector.GetEnters().size(), 0, ());
+ TEST_EQUAL(connector.GetExits().size(), 1, ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ false /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ false /* isOutgoing */),
+ ());
+}
+
+UNIT_TEST(TwoWayEnter)
+{
+ uint32_t constexpr featureId = 1;
+ uint32_t constexpr segmentIdx = 1;
+ CrossMwmConnector connector(mwmId);
+ connector.AddTransition(featureId, segmentIdx, false /* oneWay */, true /* forwardIsEnter */,
+ {} /* backPoint */, {} /* frontPoint */);
+
+ TestConnectorConsistency(connector);
+ TEST_EQUAL(connector.GetEnters().size(), 1, ());
+ TEST_EQUAL(connector.GetExits().size(), 1, ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ false /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ false /* isOutgoing */),
+ ());
+}
+
+UNIT_TEST(TwoWayExit)
+{
+ uint32_t constexpr featureId = 1;
+ uint32_t constexpr segmentIdx = 1;
+ CrossMwmConnector connector(mwmId);
+ connector.AddTransition(featureId, segmentIdx, false /* oneWay */, false /* forwardIsEnter */,
+ {} /* backPoint */, {} /* frontPoint */);
+
+ TestConnectorConsistency(connector);
+ TEST_EQUAL(connector.GetEnters().size(), 1, ());
+ TEST_EQUAL(connector.GetExits().size(), 1, ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
+ false /* isOutgoing */),
+ ());
+ TEST(connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
+ false /* isOutgoing */),
+ ());
+}
+
+UNIT_TEST(Serialization)
+{
+ float constexpr kEdgesWeight = 333;
+
+ vector<uint8_t> buffer;
+ {
+ vector<CrossMwmConnectorSerializer::Transition> transitions = {
+ /* featureId, segmentIdx, roadMask, oneWayMask, forwardIsEnter, backPoint, frontPoint */
+ {10, 1, kCarMask, kCarMask, true, m2::PointD(1.1, 1.2), m2::PointD(1.3, 1.4)},
+ {20, 2, kCarMask, 0, true, m2::PointD(2.1, 2.2), m2::PointD(2.3, 2.4)},
+ {30, 3, kPedestrianMask, kCarMask, true, m2::PointD(3.1, 3.2), m2::PointD(3.3, 3.4)}};
+
+ CrossMwmConnectorPerVehicleType connectors;
+ CrossMwmConnector & carConnector = connectors[static_cast<size_t>(VehicleType::Car)];
+ for (auto const & transition : transitions)
+ CrossMwmConnectorSerializer::AddTransition(transition, kCarMask, carConnector);
+
+ carConnector.FillWeights(
+ [](Segment const & enter, Segment const & exit) { return kEdgesWeight; });
+
+ serial::CodingParams const codingParams;
+ MemWriter<vector<uint8_t>> writer(buffer);
+ CrossMwmConnectorSerializer::Serialize(transitions, connectors, codingParams, writer);
+ }
+
+ CrossMwmConnector connector(mwmId);
+ {
+ MemReader reader(buffer.data(), buffer.size());
+ ReaderSource<MemReader> source(reader);
+ CrossMwmConnectorSerializer::DeserializeTransitions(VehicleType::Car, connector, source);
+ }
+
+ TestConnectorConsistency(connector);
+
+ TEST_EQUAL(connector.GetEnters().size(), 2, ());
+ TEST_EQUAL(connector.GetExits().size(), 1, ());
+
+ TEST(!connector.IsTransition(Segment(mwmId, 0, 0, true), true /* isOutgoing */), ());
+
+ TEST(connector.IsTransition(Segment(mwmId, 10, 1, true /* forward */), true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, 10, 1, true /* forward */), false /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, 10, 1, false /* forward */), true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, 10, 1, false /* forward */), false /* isOutgoing */),
+ ());
+
+ TEST(connector.IsTransition(Segment(mwmId, 20, 2, true /* forward */), true /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, 20, 2, true /* forward */), false /* isOutgoing */),
+ ());
+ TEST(!connector.IsTransition(Segment(mwmId, 20, 2, false /* forward */), true /* isOutgoing */),
+ ());
+ TEST(connector.IsTransition(Segment(mwmId, 20, 2, false /* forward */), false /* isOutgoing */),
+ ());
+
+ TEST(!connector.IsTransition(Segment(mwmId, 30, 3, true /* forward */), true /* isOutgoing */),
+ ());
+
+ TEST(!connector.WeightsWereLoaded(), ());
+ TEST(!connector.HasWeights(), ());
+
+ {
+ MemReader reader(buffer.data(), buffer.size());
+ ReaderSource<MemReader> source(reader);
+ CrossMwmConnectorSerializer::DeserializeWeights(VehicleType::Car, connector, source);
+ }
+ TEST(connector.WeightsWereLoaded(), ());
+ TEST(connector.HasWeights(), ());
+
+ double constexpr eps = 1e-6;
+ TEST(AlmostEqualAbs(
+ connector.GetPoint(Segment(mwmId, 20, 2, true /* forward */), true /* front */),
+ m2::PointD(2.3, 2.4), eps),
+ ());
+ TEST(AlmostEqualAbs(
+ connector.GetPoint(Segment(mwmId, 20, 2, true /* forward */), false /* front */),
+ m2::PointD(2.1, 2.2), eps),
+ ());
+ TEST(AlmostEqualAbs(
+ connector.GetPoint(Segment(mwmId, 20, 2, false /* forward */), true /* front */),
+ m2::PointD(2.1, 2.2), eps),
+ ());
+ TEST(AlmostEqualAbs(
+ connector.GetPoint(Segment(mwmId, 20, 2, true /* forward */), true /* front */),
+ m2::PointD(2.3, 2.4), eps),
+ ());
+
+ TestEdges(connector, Segment(mwmId, 10, 1, true /* forward */), true /* isOutgoing */,
+ {{Segment(mwmId, 20, 2, false /* forward */), kEdgesWeight}});
+
+ TestEdges(connector, Segment(mwmId, 20, 2, true /* forward */), true /* isOutgoing */,
+ {{Segment(mwmId, 20, 2, false /* forward */), kEdgesWeight}});
+
+ TestEdges(connector, Segment(mwmId, 20, 2, false /* forward */), false /* isOutgoing */,
+ {{Segment(mwmId, 10, 1, true /* forward */), kEdgesWeight},
+ {Segment(mwmId, 20, 2, true /* forward */), kEdgesWeight}});
+}
+} // namespace routing_test
diff --git a/routing/routing_tests/cross_mwm_ramp_test.cpp b/routing/routing_tests/cross_mwm_ramp_test.cpp
deleted file mode 100644
index 18ac375124..0000000000
--- a/routing/routing_tests/cross_mwm_ramp_test.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-#include "testing/testing.hpp"
-
-#include "routing/cross_mwm_ramp_serialization.hpp"
-
-#include "coding/writer.hpp"
-
-using namespace routing;
-using namespace std;
-
-namespace
-{
-NumMwmId constexpr mwmId = 777;
-
-void CheckRampConsistency(CrossMwmRamp const & ramp)
-{
- for (Segment const & enter : ramp.GetEnters())
- {
- TEST(ramp.IsTransition(enter, true /* isOutgoing */), ());
- TEST(!ramp.IsTransition(enter, false /* isOutgoing */), ());
- }
-
- for (Segment const & exit : ramp.GetExits())
- {
- TEST(!ramp.IsTransition(exit, true /* isOutgoing */), ());
- TEST(ramp.IsTransition(exit, false /* isOutgoing */), ());
- }
-}
-
-void CheckEdges(CrossMwmRamp const & ramp, Segment const & from, bool isOutgoing,
- vector<SegmentEdge> const & expectedEdges)
-{
- vector<SegmentEdge> edges;
- ramp.GetEdgeList(from, isOutgoing, edges);
- TEST_EQUAL(edges, expectedEdges, ());
-}
-}
-
-namespace routing_test
-{
-UNIT_TEST(OneWayEnter)
-{
- uint32_t constexpr featureId = 1;
- uint32_t constexpr segmentIdx = 1;
- CrossMwmRamp ramp(mwmId);
- ramp.AddTransition(featureId, segmentIdx, true /* oneWay */, true /* forwardIsEnter */,
- {} /* backPoint */, {} /* frontPoint */);
-
- CheckRampConsistency(ramp);
- TEST_EQUAL(ramp.GetEnters().size(), 1, ());
- TEST_EQUAL(ramp.GetExits().size(), 0, ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- true /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- false /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- true /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- false /* isOutgoing */),
- ());
-}
-
-UNIT_TEST(OneWayExit)
-{
- uint32_t constexpr featureId = 1;
- uint32_t constexpr segmentIdx = 1;
- CrossMwmRamp ramp(mwmId);
- ramp.AddTransition(featureId, segmentIdx, true /* oneWay */, false /* forwardIsEnter */,
- {} /* backPoint */, {} /* frontPoint */);
-
- CheckRampConsistency(ramp);
- TEST_EQUAL(ramp.GetEnters().size(), 0, ());
- TEST_EQUAL(ramp.GetExits().size(), 1, ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- true /* isOutgoing */),
- ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- false /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- true /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- false /* isOutgoing */),
- ());
-}
-
-UNIT_TEST(TwoWayEnter)
-{
- uint32_t constexpr featureId = 1;
- uint32_t constexpr segmentIdx = 1;
- CrossMwmRamp ramp(mwmId);
- ramp.AddTransition(featureId, segmentIdx, false /* oneWay */, true /* forwardIsEnter */,
- {} /* backPoint */, {} /* frontPoint */);
-
- CheckRampConsistency(ramp);
- TEST_EQUAL(ramp.GetEnters().size(), 1, ());
- TEST_EQUAL(ramp.GetExits().size(), 1, ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- true /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- false /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- true /* isOutgoing */),
- ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- false /* isOutgoing */),
- ());
-}
-
-UNIT_TEST(TwoWayExit)
-{
- uint32_t constexpr featureId = 1;
- uint32_t constexpr segmentIdx = 1;
- CrossMwmRamp ramp(mwmId);
- ramp.AddTransition(featureId, segmentIdx, false /* oneWay */, false /* forwardIsEnter */,
- {} /* backPoint */, {} /* frontPoint */);
-
- CheckRampConsistency(ramp);
- TEST_EQUAL(ramp.GetEnters().size(), 1, ());
- TEST_EQUAL(ramp.GetExits().size(), 1, ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- true /* isOutgoing */),
- ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, true /* forward */),
- false /* isOutgoing */),
- ());
- TEST(ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- true /* isOutgoing */),
- ());
- TEST(!ramp.IsTransition(Segment(mwmId, featureId, segmentIdx, false /* forward */),
- false /* isOutgoing */),
- ());
-}
-
-UNIT_TEST(Serialization)
-{
- float constexpr kEdgesWeight = 333;
-
- vector<uint8_t> buffer;
- {
- vector<CrossMwmRampSerializer::Transition> transitions = {
- /* featureId, segmentIdx, roadMask, oneWayMask, forwardIsEnter, backPoint, frontPoint */
- {10, 1, kCarMask, kCarMask, true, m2::PointD(1.1, 1.2), m2::PointD(1.3, 1.4)},
- {20, 2, kCarMask, 0, true, m2::PointD(2.1, 2.2), m2::PointD(2.3, 2.4)},
- {30, 3, kPedestrianMask, kCarMask, true, m2::PointD(3.1, 3.2), m2::PointD(3.3, 3.4)}};
-
- vector<CrossMwmRamp> ramps(static_cast<size_t>(VehicleType::Count), mwmId);
-
- CrossMwmRamp & carRamp = ramps[static_cast<size_t>(VehicleType::Car)];
- for (auto const & transition : transitions)
- CrossMwmRampSerializer::AddTransition(transition, kCarMask, carRamp);
-
- carRamp.FillWeights([](Segment const & enter, Segment const & exit) { return kEdgesWeight; });
-
- serial::CodingParams const codingParams;
- MemWriter<vector<uint8_t>> writer(buffer);
- CrossMwmRampSerializer::Serialize(transitions, ramps, codingParams, writer);
- }
-
- CrossMwmRamp ramp(mwmId);
- {
- MemReader reader(buffer.data(), buffer.size());
- ReaderSource<MemReader> source(reader);
- CrossMwmRampSerializer::DeserializeTransitions(VehicleType::Car, ramp, source);
- }
-
- CheckRampConsistency(ramp);
-
- TEST_EQUAL(ramp.GetEnters().size(), 2, ());
- TEST_EQUAL(ramp.GetExits().size(), 1, ());
-
- TEST(!ramp.IsTransition(Segment(mwmId, 0, 0, true), true /* isOutgoing */), ());
-
- TEST(ramp.IsTransition(Segment(mwmId, 10, 1, true /* forward */), true /* isOutgoing */), ());
- TEST(!ramp.IsTransition(Segment(mwmId, 10, 1, true /* forward */), false /* isOutgoing */), ());
- TEST(!ramp.IsTransition(Segment(mwmId, 10, 1, false /* forward */), true /* isOutgoing */), ());
- TEST(!ramp.IsTransition(Segment(mwmId, 10, 1, false /* forward */), false /* isOutgoing */), ());
-
- TEST(ramp.IsTransition(Segment(mwmId, 20, 2, true /* forward */), true /* isOutgoing */), ());
- TEST(!ramp.IsTransition(Segment(mwmId, 20, 2, true /* forward */), false /* isOutgoing */), ());
- TEST(!ramp.IsTransition(Segment(mwmId, 20, 2, false /* forward */), true /* isOutgoing */), ());
- TEST(ramp.IsTransition(Segment(mwmId, 20, 2, false /* forward */), false /* isOutgoing */), ());
-
- TEST(!ramp.IsTransition(Segment(mwmId, 30, 3, true /* forward */), true /* isOutgoing */), ());
-
- TEST(!ramp.WeightsWereLoaded(), ());
- TEST(!ramp.HasWeights(), ());
-
- {
- MemReader reader(buffer.data(), buffer.size());
- ReaderSource<MemReader> source(reader);
- CrossMwmRampSerializer::DeserializeWeights(VehicleType::Car, ramp, source);
- }
- TEST(ramp.WeightsWereLoaded(), ());
- TEST(ramp.HasWeights(), ());
-
- double constexpr eps = 1e-6;
- TEST(AlmostEqualAbs(ramp.GetPoint(Segment(mwmId, 20, 2, true /* forward */), true /* front */),
- m2::PointD(2.3, 2.4), eps),
- ());
- TEST(AlmostEqualAbs(ramp.GetPoint(Segment(mwmId, 20, 2, true /* forward */), false /* front */),
- m2::PointD(2.1, 2.2), eps),
- ());
- TEST(AlmostEqualAbs(ramp.GetPoint(Segment(mwmId, 20, 2, false /* forward */), true /* front */),
- m2::PointD(2.1, 2.2), eps),
- ());
- TEST(AlmostEqualAbs(ramp.GetPoint(Segment(mwmId, 20, 2, true /* forward */), true /* front */),
- m2::PointD(2.3, 2.4), eps),
- ());
-
- CheckEdges(ramp, Segment(mwmId, 10, 1, true /* forward */), true /* isOutgoing */,
- {{Segment(mwmId, 20, 2, false /* forward */), kEdgesWeight}});
-
- CheckEdges(ramp, Segment(mwmId, 20, 2, true /* forward */), true /* isOutgoing */,
- {{Segment(mwmId, 20, 2, false /* forward */), kEdgesWeight}});
-
- CheckEdges(ramp, Segment(mwmId, 20, 2, false /* forward */), false /* isOutgoing */,
- {{Segment(mwmId, 10, 1, true /* forward */), kEdgesWeight},
- {Segment(mwmId, 20, 2, true /* forward */), kEdgesWeight}});
-}
-} // namespace routing_test
diff --git a/routing/routing_tests/routing_tests.pro b/routing/routing_tests/routing_tests.pro
index 3788a26582..5ea3209ae3 100644
--- a/routing/routing_tests/routing_tests.pro
+++ b/routing/routing_tests/routing_tests.pro
@@ -26,7 +26,7 @@ SOURCES += \
astar_progress_test.cpp \
astar_router_test.cpp \
async_router_test.cpp \
- cross_mwm_ramp_test.cpp \
+ cross_mwm_connector_test.cpp \
cross_routing_tests.cpp \
cumulative_restriction_test.cpp \
followed_polyline_test.cpp \
diff --git a/xcode/routing/routing.xcodeproj/project.pbxproj b/xcode/routing/routing.xcodeproj/project.pbxproj
index 4810e0ec8e..e7d736ca87 100644
--- a/xcode/routing/routing.xcodeproj/project.pbxproj
+++ b/xcode/routing/routing.xcodeproj/project.pbxproj
@@ -25,6 +25,11 @@
0C5992E21E433BE600203653 /* num_mwm_id.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5992E11E433BE600203653 /* num_mwm_id.hpp */; };
0C5BC9D11E28FD4E0071BFDD /* index_road_graph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5BC9CF1E28FD4E0071BFDD /* index_road_graph.cpp */; };
0C5BC9D21E28FD4E0071BFDD /* index_road_graph.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5BC9D01E28FD4E0071BFDD /* index_road_graph.hpp */; };
+ 0C5F5D201E798B0400307B98 /* cross_mwm_connector_serialization.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5F5D1C1E798B0400307B98 /* cross_mwm_connector_serialization.cpp */; };
+ 0C5F5D211E798B0400307B98 /* cross_mwm_connector_serialization.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5F5D1D1E798B0400307B98 /* cross_mwm_connector_serialization.hpp */; };
+ 0C5F5D221E798B0400307B98 /* cross_mwm_connector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5F5D1E1E798B0400307B98 /* cross_mwm_connector.cpp */; };
+ 0C5F5D231E798B0400307B98 /* cross_mwm_connector.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5F5D1F1E798B0400307B98 /* cross_mwm_connector.hpp */; };
+ 0C5F5D251E798B3800307B98 /* cross_mwm_connector_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5F5D241E798B3800307B98 /* cross_mwm_connector_test.cpp */; };
0C5FEC541DDE191E0017688C /* edge_estimator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5FEC521DDE191E0017688C /* edge_estimator.cpp */; };
0C5FEC551DDE191E0017688C /* edge_estimator.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 0C5FEC531DDE191E0017688C /* edge_estimator.hpp */; };
0C5FEC5E1DDE192A0017688C /* geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0C5FEC561DDE192A0017688C /* geometry.cpp */; };
@@ -271,6 +276,11 @@
0C5992E11E433BE600203653 /* num_mwm_id.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = num_mwm_id.hpp; sourceTree = "<group>"; };
0C5BC9CF1E28FD4E0071BFDD /* index_road_graph.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = index_road_graph.cpp; sourceTree = "<group>"; };
0C5BC9D01E28FD4E0071BFDD /* index_road_graph.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = index_road_graph.hpp; sourceTree = "<group>"; };
+ 0C5F5D1C1E798B0400307B98 /* cross_mwm_connector_serialization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cross_mwm_connector_serialization.cpp; sourceTree = "<group>"; };
+ 0C5F5D1D1E798B0400307B98 /* cross_mwm_connector_serialization.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cross_mwm_connector_serialization.hpp; sourceTree = "<group>"; };
+ 0C5F5D1E1E798B0400307B98 /* cross_mwm_connector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cross_mwm_connector.cpp; sourceTree = "<group>"; };
+ 0C5F5D1F1E798B0400307B98 /* cross_mwm_connector.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = cross_mwm_connector.hpp; sourceTree = "<group>"; };
+ 0C5F5D241E798B3800307B98 /* cross_mwm_connector_test.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cross_mwm_connector_test.cpp; sourceTree = "<group>"; };
0C5FEC521DDE191E0017688C /* edge_estimator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = edge_estimator.cpp; sourceTree = "<group>"; };
0C5FEC531DDE191E0017688C /* edge_estimator.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = edge_estimator.hpp; sourceTree = "<group>"; };
0C5FEC561DDE192A0017688C /* geometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = geometry.cpp; sourceTree = "<group>"; };
@@ -579,6 +589,7 @@
6742ACA71C68A0B1009CB89E /* astar_progress_test.cpp */,
6742ACA81C68A0B1009CB89E /* astar_router_test.cpp */,
6742ACA91C68A0B1009CB89E /* async_router_test.cpp */,
+ 0C5F5D241E798B3800307B98 /* cross_mwm_connector_test.cpp */,
6742ACAA1C68A0B1009CB89E /* cross_routing_tests.cpp */,
6742ACAB1C68A0B1009CB89E /* followed_polyline_test.cpp */,
0C5FEC6C1DDE19A40017688C /* index_graph_test.cpp */,
@@ -704,6 +715,10 @@
56099E311CC9247E00A7772A /* bicycle_directions.hpp */,
56826BCE1DB51C4E00807C62 /* car_router.cpp */,
56826BCF1DB51C4E00807C62 /* car_router.hpp */,
+ 0C5F5D1E1E798B0400307B98 /* cross_mwm_connector.cpp */,
+ 0C5F5D1F1E798B0400307B98 /* cross_mwm_connector.hpp */,
+ 0C5F5D1C1E798B0400307B98 /* cross_mwm_connector_serialization.cpp */,
+ 0C5F5D1D1E798B0400307B98 /* cross_mwm_connector_serialization.hpp */,
A120B3411B4A7BE5002F3808 /* cross_mwm_road_graph.cpp */,
A120B3421B4A7BE5002F3808 /* cross_mwm_road_graph.hpp */,
A120B3431B4A7BE5002F3808 /* cross_mwm_router.cpp */,
@@ -845,6 +860,7 @@
56099E2A1CC7C97D00A7772A /* routing_result_graph.hpp in Headers */,
A120B3481B4A7BE5002F3808 /* cross_mwm_router.hpp in Headers */,
674F9BD31B0A580E00704FFA /* road_graph_router.hpp in Headers */,
+ 0C5F5D231E798B0400307B98 /* cross_mwm_connector.hpp in Headers */,
675344141A3F644F00A0A8C3 /* osrm_data_facade.hpp in Headers */,
6753441F1A3F644F00A0A8C3 /* turns.hpp in Headers */,
0C5FEC611DDE192A0017688C /* index_graph.hpp in Headers */,
@@ -875,6 +891,7 @@
0C8705051E0182F200BCAF71 /* route_point.hpp in Headers */,
A1876BC71BB19C4300C9C743 /* speed_camera.hpp in Headers */,
56EA2FD51D8FD8590083F01A /* routing_helpers.hpp in Headers */,
+ 0C5F5D211E798B0400307B98 /* cross_mwm_connector_serialization.hpp in Headers */,
0C0DF9221DE898B70055A22F /* index_graph_starter.hpp in Headers */,
0C090C881E4E276700D52AFD /* world_graph.hpp in Headers */,
56099E2F1CC8FBDA00A7772A /* osrm_path_segment_factory.hpp in Headers */,
@@ -1106,6 +1123,7 @@
files = (
0C5FEC641DDE192A0017688C /* joint.cpp in Sources */,
0C090C871E4E276700D52AFD /* world_graph.cpp in Sources */,
+ 0C5F5D201E798B0400307B98 /* cross_mwm_connector_serialization.cpp in Sources */,
56CA09E71E30E73B00D05C9A /* restriction_test.cpp in Sources */,
0C5BC9D11E28FD4E0071BFDD /* index_road_graph.cpp in Sources */,
56826BD01DB51C4E00807C62 /* car_router.cpp in Sources */,
@@ -1121,8 +1139,10 @@
670EE5731B664796001E8064 /* pedestrian_directions.cpp in Sources */,
6753441B1A3F644F00A0A8C3 /* route.cpp in Sources */,
674F9BCA1B0A580E00704FFA /* async_router.cpp in Sources */,
+ 0C5F5D221E798B0400307B98 /* cross_mwm_connector.cpp in Sources */,
675344191A3F644F00A0A8C3 /* osrm2feature_map.cpp in Sources */,
670D049E1B0B4A970013A7AC /* nearest_edge_finder.cpp in Sources */,
+ 0C5F5D251E798B3800307B98 /* cross_mwm_connector_test.cpp in Sources */,
674F9BD61B0A580E00704FFA /* turns_generator.cpp in Sources */,
A17B42981BCFBD0E00A1EAE4 /* osrm_helpers.cpp in Sources */,
674F9BD21B0A580E00704FFA /* road_graph_router.cpp in Sources */,