Skip to content

Commit

Permalink
Add leap speed for cross-MWM routing
Browse files Browse the repository at this point in the history
  • Loading branch information
ldo2 authored and bykoianko committed Nov 27, 2020
1 parent ca6c536 commit 1d71392
Show file tree
Hide file tree
Showing 18 changed files with 157 additions and 39 deletions.
1 change: 1 addition & 0 deletions defines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@

#define COUNTRIES_FILE "countries.txt"
#define COUNTRIES_META_FILE "countries_meta.txt"
#define LEAP_SPEEDS_FILE "leap_speeds.json"

#define WORLD_FILE_NAME "World"
#define WORLD_COASTS_FILE_NAME "WorldCoasts"
Expand Down
4 changes: 2 additions & 2 deletions generator/generator_tests_support/routing_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ void TestGeometryLoader::SetPassThroughAllowed(uint32_t featureId, bool passThro
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(std::shared_ptr<TrafficStash> trafficStash)
{
auto const carModel = CarModelFactory({}).GetVehicleModel();
return EdgeEstimator::Create(VehicleType::Car, *carModel, trafficStash);
return EdgeEstimator::Create(VehicleType::Car, *carModel, trafficStash,
nullptr /* DataSource */, nullptr /* NumMwmIds */);
}

std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(traffic::TrafficCache const & trafficCache)
Expand Down Expand Up @@ -103,4 +104,3 @@ std::unique_ptr<IndexGraph> BuildIndexGraph(std::unique_ptr<TestGeometryLoader>
return graph;
}
} // namespace routing

32 changes: 32 additions & 0 deletions generator/region_meta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ namespace feature
{
bool ReadRegionDataImpl(std::string const & countryName, RegionData & data)
{
try
{
auto crossMwmDataReader = GetPlatform().GetReader(LEAP_SPEEDS_FILE);
std::string crossMwmDataBuffer;
crossMwmDataReader->ReadAsString(crossMwmDataBuffer);
base::Json crossMwmData(crossMwmDataBuffer.data());

json_t const * crossMwmJsonData = nullptr;
FromJSONObjectOptionalField(crossMwmData.get(), countryName, crossMwmJsonData);
if (crossMwmJsonData)
{
double leapSpeed = FromJSONObject<double>(crossMwmJsonData, "leapspeed");
if (leapSpeed > 0.0)
data.SetLeapWeightSpeed(leapSpeed);
}
}
catch (FileAbsentException const & e)
{
LOG(LERROR, ("Error missing file", LEAP_SPEEDS_FILE, ":", e.Msg()));
return false;
}
catch (Reader::Exception const & e)
{
LOG(LWARNING, ("Error reading", LEAP_SPEEDS_FILE, ":", e.Msg()));
return false;
}
catch (base::Json::Exception const & e)
{
LOG(LERROR, ("Error parsing JSON in", LEAP_SPEEDS_FILE, ":", e.Msg()));
return false;
}

try
{
auto reader = GetPlatform().GetReader(COUNTRIES_META_FILE);
Expand Down
5 changes: 3 additions & 2 deletions generator/restriction_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ CreateIndexGraph(std::string const & targetPath,

auto graph = std::make_unique<IndexGraph>(
std::make_shared<Geometry>(GeometryLoader::CreateFromFile(mwmPath, vehicleModel)),
EdgeEstimator::Create(VehicleType::Car, *vehicleModel, nullptr /* trafficStash */));
EdgeEstimator::Create(VehicleType::Car, *vehicleModel, nullptr /* trafficStash */,
nullptr /* dataSource */, nullptr /* numMvmIds */));

DeserializeIndexGraph(mwmValue, VehicleType::Car, *graph);

Expand Down Expand Up @@ -108,7 +109,7 @@ void SerializeRestrictions(RestrictionCollector & restrictionCollector,

CHECK_GREATER_OR_EQUAL(i, 1, ("Unexpected overflow."));
auto const prevType = RestrictionHeader::kRestrictionTypes[i - 1];
header.SetNumberOf(prevType,
header.SetNumberOf(prevType,
base::checked_cast<uint32_t>(std::distance(prevTypeEndIt, firstNextType)));

prevTypeEndIt = firstNextType;
Expand Down
4 changes: 3 additions & 1 deletion generator/routing_index_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,9 @@ void FillWeights(string const & path, string const & mwmFile, string const & cou
routing::IndexGraph graph(make_shared<routing::Geometry>(
routing::GeometryLoader::CreateFromFile(mwmFile, vehicleModel), mwmNumRoads),
routing::EdgeEstimator::Create(routing::VehicleType::Car, *vehicleModel,
nullptr /* trafficStash */));
nullptr /* trafficStash */,
nullptr /* dataSource */,
nullptr /* numMvmIds */));
DeserializeIndexGraph(mwmValue, routing::VehicleType::Car, graph);

map<routing::Segment, map<routing::Segment, routing::RouteWeight>> weights;
Expand Down
16 changes: 15 additions & 1 deletion indexer/feature_meta.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ class RegionData : public MetadataBase
RD_PHONE_FORMAT, // list of strings in "+N NNN NN-NN-NN" format
RD_POSTCODE_FORMAT, // list of strings in "AAA ANN" format
RD_PUBLIC_HOLIDAYS, // fixed PH dates
RD_ALLOW_HOUSENAMES // 'y' if housenames are commonly used
RD_ALLOW_HOUSENAMES, // 'y' if housenames are commonly used
RD_LEAP_WEIGHT_SPEED // speed factor for leap weight computation
};

// Special values for month references in public holiday definitions.
Expand Down Expand Up @@ -234,6 +235,19 @@ class RegionData : public MetadataBase

void AddPublicHoliday(int8_t month, int8_t offset);
// No public holidays getters until we know what to do with these.

void SetLeapWeightSpeed(double speedValue)
{
std::string strValue = std::to_string(speedValue);
MetadataBase::Set(Type::RD_LEAP_WEIGHT_SPEED, strValue);
}

double GetLeapWeightSpeed(double defaultValue) const
{
if (Has(Type::RD_LEAP_WEIGHT_SPEED))
return std::stod(Get(Type::RD_LEAP_WEIGHT_SPEED));
return defaultValue;
}
};

// Prints types in osm-friendly format.
Expand Down
79 changes: 64 additions & 15 deletions routing/edge_estimator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,12 @@ double GetCarClimbPenalty(EdgeEstimator::Purpose /* purpose */, double /* tangen
}

// EdgeEstimator -----------------------------------------------------------------------------------
EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH)
: m_maxWeightSpeedMpS(KMPH2MPS(maxWeightSpeedKMpH)), m_offroadSpeedKMpH(offroadSpeedKMpH)
EdgeEstimator::EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
DataSource * dataSourcePtr, std::shared_ptr<NumMwmIds> numMwmIds)
: m_maxWeightSpeedMpS(KMPH2MPS(maxWeightSpeedKMpH))
, m_offroadSpeedKMpH(offroadSpeedKMpH)
, m_dataSourcePtr(dataSourcePtr)
, m_numMwmIds(numMwmIds)
{
CHECK_GREATER(m_offroadSpeedKMpH.m_weight, 0.0, ());
CHECK_GREATER(m_offroadSpeedKMpH.m_eta, 0.0, ());
Expand All @@ -132,13 +136,49 @@ double EdgeEstimator::CalcHeuristic(ms::LatLon const & from, ms::LatLon const &
return TimeBetweenSec(from, to, m_maxWeightSpeedMpS);
}

double EdgeEstimator::CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to) const
double EdgeEstimator::ComputeDefaultLeapWeightSpeed() const
{
// Let us assume for the time being that
// leap edges will be added with a half of max speed.
// @TODO(bykoianko) It's necessary to gather statistics to calculate better factor(s) instead of
// one below.
return TimeBetweenSec(from, to, m_maxWeightSpeedMpS / 2.0);
// leap edges will be added with a half of max speed
// if no leap speed provided
return m_maxWeightSpeedMpS / 2.0;
}

double EdgeEstimator::LoadLeapWeightSpeed(NumMwmId mwmId)
{
if (m_dataSourcePtr)
{
MwmSet::MwmHandle handle =
m_dataSourcePtr->GetMwmHandleByCountryFile(m_numMwmIds->GetFile(mwmId));
if (!handle.IsAlive())
MYTHROW(RoutingException, ("Mwm", m_numMwmIds->GetFile(mwmId), "cannot be loaded."));

if (handle.GetInfo())
return handle.GetInfo()->GetRegionData().GetLeapWeightSpeed(m_maxWeightSpeedMpS / 2.0);
}

return ComputeDefaultLeapWeightSpeed();
}

double EdgeEstimator::GetLeapWeightSpeed(NumMwmId mwmId)
{
double defaultSpeed = ComputeDefaultLeapWeightSpeed();

if (mwmId != kFakeNumMwmId)
{
auto [speedIt, inserted] = m_leapWeightSpeedMpS.emplace(mwmId, defaultSpeed);
if (inserted)
speedIt->second = LoadLeapWeightSpeed(mwmId);

return speedIt->second;
}

return defaultSpeed;
}

double EdgeEstimator::CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId)
{
return TimeBetweenSec(from, to, GetLeapWeightSpeed(mwmId));
}

double EdgeEstimator::GetMaxWeightSpeedMpS() const { return m_maxWeightSpeedMpS; }
Expand Down Expand Up @@ -216,7 +256,8 @@ class BicycleEstimator final : public EdgeEstimator
class CarEstimator final : public EdgeEstimator
{
public:
CarEstimator(shared_ptr<TrafficStash> trafficStash, double maxWeightSpeedKMpH,
CarEstimator(DataSource * dataSourcePtr, std::shared_ptr<NumMwmIds> numMwmIds,
shared_ptr<TrafficStash> trafficStash, double maxWeightSpeedKMpH,
SpeedKMpH const & offroadSpeedKMpH);

// EdgeEstimator overrides:
Expand All @@ -230,9 +271,11 @@ class CarEstimator final : public EdgeEstimator
shared_ptr<TrafficStash> m_trafficStash;
};

CarEstimator::CarEstimator(shared_ptr<TrafficStash> trafficStash, double maxWeightSpeedKMpH,
CarEstimator::CarEstimator(DataSource * dataSourcePtr, std::shared_ptr<NumMwmIds> numMwmIds,
shared_ptr<TrafficStash> trafficStash, double maxWeightSpeedKMpH,
SpeedKMpH const & offroadSpeedKMpH)
: EdgeEstimator(maxWeightSpeedKMpH, offroadSpeedKMpH), m_trafficStash(move(trafficStash))
: EdgeEstimator(maxWeightSpeedKMpH, offroadSpeedKMpH, dataSourcePtr, numMwmIds)
, m_trafficStash(move(trafficStash))
{
}

Expand All @@ -254,7 +297,8 @@ double CarEstimator::GetFerryLandingPenalty(Purpose purpose) const
{
switch (purpose)
{
case Purpose::Weight: return 40 * 60; // seconds
case Purpose::Weight:
return 40 * 60; // seconds
// Based on https://confluence.mail.ru/display/MAPSME/Ferries
case Purpose::ETA: return 20 * 60; // seconds
}
Expand Down Expand Up @@ -290,7 +334,9 @@ double CarEstimator::CalcSegment(Purpose purpose, Segment const & segment,
// static
shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType, double maxWeighSpeedKMpH,
SpeedKMpH const & offroadSpeedKMpH,
shared_ptr<TrafficStash> trafficStash)
shared_ptr<TrafficStash> trafficStash,
DataSource * dataSourcePtr,
std::shared_ptr<NumMwmIds> numMwmIds)
{
switch (vehicleType)
{
Expand All @@ -300,7 +346,8 @@ shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType, double
case VehicleType::Bicycle:
return make_shared<BicycleEstimator>(maxWeighSpeedKMpH, offroadSpeedKMpH);
case VehicleType::Car:
return make_shared<CarEstimator>(trafficStash, maxWeighSpeedKMpH, offroadSpeedKMpH);
return make_shared<CarEstimator>(dataSourcePtr, numMwmIds, trafficStash, maxWeighSpeedKMpH,
offroadSpeedKMpH);
case VehicleType::Count:
CHECK(false, ("Can't create EdgeEstimator for", vehicleType));
return nullptr;
Expand All @@ -311,9 +358,11 @@ shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType, double
// static
shared_ptr<EdgeEstimator> EdgeEstimator::Create(VehicleType vehicleType,
VehicleModelInterface const & vehicleModel,
shared_ptr<TrafficStash> trafficStash)
shared_ptr<TrafficStash> trafficStash,
DataSource * dataSourcePtr,
std::shared_ptr<NumMwmIds> numMwmIds)
{
return Create(vehicleType, vehicleModel.GetMaxWeightSpeed(), vehicleModel.GetOffroadSpeed(),
trafficStash);
trafficStash, dataSourcePtr, numMwmIds);
}
} // namespace routing
22 changes: 18 additions & 4 deletions routing/edge_estimator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "geometry/point2d.hpp"

#include <memory>
#include <unordered_map>

namespace routing
{
Expand All @@ -27,7 +28,8 @@ class EdgeEstimator
ETA
};

EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH);
EdgeEstimator(double maxWeightSpeedKMpH, SpeedKMpH const & offroadSpeedKMpH,
DataSource * dataSourcePtr = nullptr, std::shared_ptr<NumMwmIds> numMwmIds = nullptr);
virtual ~EdgeEstimator() = default;

double CalcHeuristic(ms::LatLon const & from, ms::LatLon const & to) const;
Expand All @@ -37,7 +39,7 @@ class EdgeEstimator
// (|from|, |to|) in road graph.
// Note 2. The result of the method should be less or equal to CalcHeuristic(|from|, |to|).
// Note 3. It's assumed here that CalcLeapWeight(p1, p2) == CalcLeapWeight(p2, p1).
double CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to) const;
double CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId = kFakeNumMwmId);

double GetMaxWeightSpeedMpS() const;

Expand All @@ -51,15 +53,27 @@ class EdgeEstimator

static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType, double maxWeighSpeedKMpH,
SpeedKMpH const & offroadSpeedKMpH,
std::shared_ptr<TrafficStash>);
std::shared_ptr<TrafficStash>,
DataSource * dataSourcePtr,
std::shared_ptr<NumMwmIds> numMwmIds);

static std::shared_ptr<EdgeEstimator> Create(VehicleType vehicleType,
VehicleModelInterface const & vehicleModel,
std::shared_ptr<TrafficStash>);
std::shared_ptr<TrafficStash>,
DataSource * dataSourcePtr,
std::shared_ptr<NumMwmIds> numMwmIds);

private:
double const m_maxWeightSpeedMpS;
SpeedKMpH const m_offroadSpeedKMpH;

DataSource * m_dataSourcePtr;
std::shared_ptr<NumMwmIds> m_numMwmIds;
std::unordered_map<NumMwmId, double> m_leapWeightSpeedMpS;

double ComputeDefaultLeapWeightSpeed() const;
double GetLeapWeightSpeed(NumMwmId mwmId);
double LoadLeapWeightSpeed(NumMwmId mwmId);
};

double GetPedestrianClimbPenalty(EdgeEstimator::Purpose purpose, double tangent,
Expand Down
3 changes: 2 additions & 1 deletion routing/index_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,8 @@ IndexRouter::IndexRouter(VehicleType vehicleType, bool loadAltitudes,
m_vehicleModelFactory)
, m_estimator(EdgeEstimator::Create(
m_vehicleType, CalcMaxSpeed(*m_numMwmIds, *m_vehicleModelFactory, m_vehicleType),
CalcOffroadSpeed(*m_vehicleModelFactory), m_trafficStash))
CalcOffroadSpeed(*m_vehicleModelFactory), m_trafficStash,
&dataSource, m_numMwmIds))
, m_directionsEngine(CreateDirectionsEngine(m_vehicleType, m_numMwmIds, m_dataSource))
, m_countryParentNameGetterFn(countryParentNameGetterFn)
{
Expand Down
4 changes: 2 additions & 2 deletions routing/leaps_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void LeapsGraph::GetEdgesListFromStart(Segment const & segment, std::vector<Segm
for (auto const & exit : exits)
{
auto const & exitFrontPoint = m_starter.GetPoint(exit, true /* front */);
auto const weight = m_starter.GetGraph().CalcLeapWeight(m_startPoint, exitFrontPoint);
auto const weight = m_starter.GetGraph().CalcLeapWeight(m_startPoint, exitFrontPoint, mwmId);

edges.emplace_back(exit, weight);
}
Expand All @@ -103,7 +103,7 @@ void LeapsGraph::GetEdgesListToFinish(Segment const & segment, std::vector<Segme
for (auto const & enter : enters)
{
auto const & enterFrontPoint = m_starter.GetPoint(enter, true /* front */);
auto const weight = m_starter.GetGraph().CalcLeapWeight(enterFrontPoint, m_finishPoint);
auto const weight = m_starter.GetGraph().CalcLeapWeight(enterFrontPoint, m_finishPoint, mwmId);

edges.emplace_back(enter, weight);
}
Expand Down
7 changes: 4 additions & 3 deletions routing/single_vehicle_world_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ RouteWeight SingleVehicleWorldGraph::CalcSegmentWeight(Segment const & segment,
}

RouteWeight SingleVehicleWorldGraph::CalcLeapWeight(ms::LatLon const & from,
ms::LatLon const & to) const
ms::LatLon const & to,
NumMwmId mwmId) const
{
return RouteWeight(m_estimator->CalcLeapWeight(from, to));
return RouteWeight(m_estimator->CalcLeapWeight(from, to, mwmId));
}

RouteWeight SingleVehicleWorldGraph::CalcOffroadWeight(ms::LatLon const & from,
Expand Down Expand Up @@ -271,7 +272,7 @@ NumMwmId GetCommonMwmInChain(vector<VertexType> const & chain)
}

template <typename VertexType>
bool
bool
SingleVehicleWorldGraph::AreWavesConnectibleImpl(Parents<VertexType> const & forwardParents,
VertexType const & commonVertex,
Parents<VertexType> const & backwardParents,
Expand Down
2 changes: 1 addition & 1 deletion routing/single_vehicle_world_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class SingleVehicleWorldGraph final : public WorldGraph
RouteWeight HeuristicCostEstimate(ms::LatLon const & from, ms::LatLon const & to) override;

RouteWeight CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) override;
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to) const override;
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId) const override;
RouteWeight CalcOffroadWeight(ms::LatLon const & from, ms::LatLon const & to,
EdgeEstimator::Purpose purpose) const override;
double CalculateETA(Segment const & from, Segment const & to) override;
Expand Down
4 changes: 2 additions & 2 deletions routing/transit_world_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ RouteWeight TransitWorldGraph::CalcSegmentWeight(Segment const & segment,
segment, GetRealRoadGeometry(segment.GetMwmId(), segment.GetFeatureId()), purpose));
}

RouteWeight TransitWorldGraph::CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to) const
RouteWeight TransitWorldGraph::CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId) const
{
return RouteWeight(m_estimator->CalcLeapWeight(from, to));
return RouteWeight(m_estimator->CalcLeapWeight(from, to, mwmId));
}

RouteWeight TransitWorldGraph::CalcOffroadWeight(ms::LatLon const & from,
Expand Down
2 changes: 1 addition & 1 deletion routing/transit_world_graph.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class TransitWorldGraph final : public WorldGraph
RouteWeight HeuristicCostEstimate(ms::LatLon const & from, ms::LatLon const & to) override;

RouteWeight CalcSegmentWeight(Segment const & segment, EdgeEstimator::Purpose purpose) override;
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to) const override;
RouteWeight CalcLeapWeight(ms::LatLon const & from, ms::LatLon const & to, NumMwmId mwmId) const override;
RouteWeight CalcOffroadWeight(ms::LatLon const & from, ms::LatLon const & to,
EdgeEstimator::Purpose purpose) const override;
double CalculateETA(Segment const & from, Segment const & to) override;
Expand Down
Loading

0 comments on commit 1d71392

Please sign in to comment.