From 1a9c5d3d09b297f1343e12172a8bd0833373a799 Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Sat, 10 Nov 2018 14:52:15 +0300 Subject: [PATCH] [routing] Getting ready VehicleModel for bidirectinal maxspeeds. --- generator/camera_node_processor.cpp | 2 +- generator/generator_tests/maxspeed_tests.cpp | 6 +- .../generator_tests/speed_cameras_test.cpp | 3 +- generator/maxspeed_builder.cpp | 3 +- generator/maxspeed_builder.hpp | 2 +- generator/maxspeed_collector.cpp | 2 +- generator/maxspeed_parser.hpp | 2 +- routing/CMakeLists.txt | 2 - routing/edge_estimator.cpp | 2 +- routing/features_road_graph.cpp | 24 +++++--- routing/features_road_graph.hpp | 16 +++-- routing/geometry.cpp | 61 +++++++++++++------ routing/geometry.hpp | 24 ++++++-- routing/index_graph_loader.cpp | 3 +- routing/maxspeed_serialization.hpp | 5 +- routing/maxspeeds.cpp | 9 ++- routing/maxspeeds.hpp | 3 +- routing/road_graph.cpp | 7 ++- routing/road_graph.hpp | 10 ++- routing/routing_benchmarks/helpers.hpp | 6 +- routing/routing_tests/maxspeed_tests.cpp | 3 +- .../nearest_edge_finder_tests.cpp | 4 +- routing/routing_tests/road_graph_builder.cpp | 8 ++- routing/routing_tests/road_graph_builder.hpp | 8 ++- routing/routing_tests/routing_algorithm.cpp | 7 ++- routing_common/CMakeLists.txt | 2 + .../maxspeed_conversion.cpp | 2 +- .../maxspeed_conversion.hpp | 0 routing_common/vehicle_model.cpp | 5 +- routing_common/vehicle_model.hpp | 9 ++- track_analyzing/track_matcher.cpp | 3 +- 31 files changed, 169 insertions(+), 74 deletions(-) rename {routing => routing_common}/maxspeed_conversion.cpp (99%) rename {routing => routing_common}/maxspeed_conversion.hpp (100%) diff --git a/generator/camera_node_processor.cpp b/generator/camera_node_processor.cpp index 4792a23bb5..e108957c4e 100644 --- a/generator/camera_node_processor.cpp +++ b/generator/camera_node_processor.cpp @@ -2,7 +2,7 @@ #include "generator/maxspeed_parser.hpp" -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "platform/measurement_utils.hpp" diff --git a/generator/generator_tests/maxspeed_tests.cpp b/generator/generator_tests/maxspeed_tests.cpp index a2f509eda8..64bbfb14b3 100644 --- a/generator/generator_tests/maxspeed_tests.cpp +++ b/generator/generator_tests/maxspeed_tests.cpp @@ -5,10 +5,11 @@ #include "generator/maxspeed_builder.hpp" #include "generator/routing_helpers.hpp" -#include "routing/maxspeed_conversion.hpp" #include "routing/maxspeed_serialization.hpp" #include "routing/maxspeeds.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "indexer/classificator_loader.hpp" #include "indexer/data_source.hpp" #include "indexer/feature.hpp" @@ -31,6 +32,7 @@ #include "base/logging.hpp" #include +#include #include #include #include @@ -128,7 +130,7 @@ void TestMaxspeedSection(FeatureVector const & roads, string const & maxspeedCsv } // Note. ParseMaxspeeds() is not tested in TestMaxspeedSection() because it's used twice there. -// So it's important to test the function separate. +// So it's important to test the function separately. bool ParseCsv(string const & maxspeedCsvContent, OsmIdToMaxspeed & mapping) { string const testDirFullPath = base::JoinPath(GetPlatform().WritableDir(), kTestDir); diff --git a/generator/generator_tests/speed_cameras_test.cpp b/generator/generator_tests/speed_cameras_test.cpp index 92c37d8551..63764a284e 100644 --- a/generator/generator_tests/speed_cameras_test.cpp +++ b/generator/generator_tests/speed_cameras_test.cpp @@ -10,9 +10,10 @@ #include "generator/metalines_builder.hpp" #include "generator/osm_source.hpp" -#include "routing/maxspeed_conversion.hpp" #include "routing/speed_camera_ser_des.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "indexer/classificator_loader.hpp" #include "indexer/index_builder.hpp" #include "indexer/map_style_reader.hpp" diff --git a/generator/maxspeed_builder.cpp b/generator/maxspeed_builder.cpp index 9e6c95e52b..abb5e17469 100644 --- a/generator/maxspeed_builder.cpp +++ b/generator/maxspeed_builder.cpp @@ -3,9 +3,10 @@ #include "generator/maxspeed_parser.hpp" #include "generator/routing_helpers.hpp" -#include "routing/maxspeed_conversion.hpp" #include "routing/maxspeed_serialization.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "indexer/feature.hpp" #include "indexer/feature_data.hpp" #include "indexer/feature_processor.hpp" diff --git a/generator/maxspeed_builder.hpp b/generator/maxspeed_builder.hpp index 50c421fb8a..9b1f21418c 100644 --- a/generator/maxspeed_builder.hpp +++ b/generator/maxspeed_builder.hpp @@ -1,5 +1,5 @@ #pragma once -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "platform/measurement_utils.hpp" diff --git a/generator/maxspeed_collector.cpp b/generator/maxspeed_collector.cpp index deeaeda8fb..e37a00fa9f 100644 --- a/generator/maxspeed_collector.cpp +++ b/generator/maxspeed_collector.cpp @@ -2,7 +2,7 @@ #include "generator/maxspeed_parser.hpp" -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "coding/file_writer.hpp" diff --git a/generator/maxspeed_parser.hpp b/generator/maxspeed_parser.hpp index 5301759af7..223b642430 100644 --- a/generator/maxspeed_parser.hpp +++ b/generator/maxspeed_parser.hpp @@ -1,6 +1,6 @@ #pragma once -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "platform/measurement_utils.hpp" diff --git a/routing/CMakeLists.txt b/routing/CMakeLists.txt index 673dec764f..88b5211255 100644 --- a/routing/CMakeLists.txt +++ b/routing/CMakeLists.txt @@ -65,8 +65,6 @@ set( loaded_path_segment.hpp maxspeeds.cpp maxspeeds.hpp - maxspeed_conversion.cpp - maxspeed_conversion.hpp maxspeed_serialization.cpp maxspeed_serialization.hpp nearest_edge_finder.cpp diff --git a/routing/edge_estimator.cpp b/routing/edge_estimator.cpp index 36c3c69455..823f3e7068 100644 --- a/routing/edge_estimator.cpp +++ b/routing/edge_estimator.cpp @@ -66,7 +66,7 @@ double CalcClimbSegment(Purpose purpose, Segment const & segment, RoadGeometry c { Junction const & from = road.GetJunction(segment.GetPointId(false /* front */)); Junction const & to = road.GetJunction(segment.GetPointId(true /* front */)); - VehicleModelInterface::SpeedKMpH const & speed = road.GetSpeed(); + VehicleModelInterface::SpeedKMpH const & speed = road.GetSpeed(segment.IsForward()); double const distance = MercatorBounds::DistanceOnEarth(from.GetPoint(), to.GetPoint()); double const speedMpS = KMPH2MPS(purpose == Purpose::Weight ? speed.m_weight : speed.m_eta); diff --git a/routing/features_road_graph.cpp b/routing/features_road_graph.cpp index de9e90fecb..fa6fcaa99c 100644 --- a/routing/features_road_graph.cpp +++ b/routing/features_road_graph.cpp @@ -49,9 +49,9 @@ FeaturesRoadGraph::CrossCountryVehicleModel::CrossCountryVehicleModel( } VehicleModelInterface::SpeedKMpH FeaturesRoadGraph::CrossCountryVehicleModel::GetSpeed( - FeatureType & f, bool inCity) const + FeatureType & f, bool forward, bool inCity, Maxspeed const & maxspeed) const { - return GetVehicleModel(f.GetID())->GetSpeed(f, inCity); + return GetVehicleModel(f.GetID())->GetSpeed(f, forward, inCity, maxspeed); } double FeaturesRoadGraph::CrossCountryVehicleModel::GetOffroadSpeed() const @@ -142,16 +142,18 @@ private: IRoadGraph::ICrossEdgesLoader & m_edgesLoader; }; -IRoadGraph::RoadInfo FeaturesRoadGraph::GetRoadInfo(FeatureID const & featureId, bool inCity) const +IRoadGraph::RoadInfo FeaturesRoadGraph::GetRoadInfo(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const { - RoadInfo const & ri = GetCachedRoadInfo(featureId, inCity); + RoadInfo const & ri = GetCachedRoadInfo(featureId, forward, inCity, maxspeed); ASSERT_GREATER(ri.m_speedKMPH, 0.0, ()); return ri; } -double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId, bool inCity) const +double FeaturesRoadGraph::GetSpeedKMpH(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const { - double const speedKMPH = GetCachedRoadInfo(featureId, inCity).m_speedKMPH; + double const speedKMPH = GetCachedRoadInfo(featureId, forward, inCity, maxspeed).m_speedKMPH; ASSERT_GREATER(speedKMPH, 0.0, ()); return speedKMPH; } @@ -244,9 +246,10 @@ bool FeaturesRoadGraph::IsRoad(FeatureType & ft) const { return m_vehicleModel.I bool FeaturesRoadGraph::IsOneWay(FeatureType & ft) const { return m_vehicleModel.IsOneWay(ft); } -double FeaturesRoadGraph::GetSpeedKMpHFromFt(FeatureType & ft, bool inCity) const +double FeaturesRoadGraph::GetSpeedKMpHFromFt(FeatureType & ft, bool forward, bool inCity, + Maxspeed const & maxspeed) const { - return m_vehicleModel.GetSpeed(ft, inCity).m_weight; + return m_vehicleModel.GetSpeed(ft, forward, inCity, maxspeed).m_weight; } void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType & ft, @@ -283,7 +286,8 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType } IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId, - bool inCity) const + bool forward, bool inCity, + Maxspeed const & maxspeed) const { bool found = false; RoadInfo & ri = m_cache.Find(featureId, found); @@ -300,7 +304,7 @@ IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID cons ASSERT_EQUAL(ft.GetFeatureType(), feature::GEOM_LINE, ()); - ExtractRoadInfo(featureId, ft, GetSpeedKMpHFromFt(ft, inCity), ri); + ExtractRoadInfo(featureId, ft, GetSpeedKMpHFromFt(ft, forward, inCity, maxspeed), ri); return ri; } diff --git a/routing/features_road_graph.hpp b/routing/features_road_graph.hpp index ebbf4ed363..db6ef75a2f 100644 --- a/routing/features_road_graph.hpp +++ b/routing/features_road_graph.hpp @@ -2,6 +2,7 @@ #include "routing/road_graph.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "routing_common/vehicle_model.hpp" #include "indexer/altitude_loader.hpp" @@ -30,7 +31,8 @@ private: CrossCountryVehicleModel(shared_ptr vehicleModelFactory); // VehicleModelInterface overrides: - VehicleModelInterface::SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const override; + VehicleModelInterface::SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const override; double GetMaxWeightSpeed() const override { return m_maxSpeed; }; double GetOffroadSpeed() const override; bool IsOneWay(FeatureType & f) const override; @@ -68,8 +70,10 @@ public: static int GetStreetReadScale(); // IRoadGraph overrides: - RoadInfo GetRoadInfo(FeatureID const & featureId, bool inCity) const override; - double GetSpeedKMpH(FeatureID const & featureId, bool inCity) const override; + RoadInfo GetRoadInfo(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const override; + double GetSpeedKMpH(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const override; double GetMaxSpeedKMpH() const override; void ForEachFeatureClosestToCross(m2::PointD const & cross, ICrossEdgesLoader & edgesLoader) const override; @@ -97,11 +101,13 @@ private: }; bool IsOneWay(FeatureType & ft) const; - double GetSpeedKMpHFromFt(FeatureType & ft, bool inCity) const; + double GetSpeedKMpHFromFt(FeatureType & ft, bool forward, bool inCity, + Maxspeed const & maxspeed) const; // Searches a feature RoadInfo in the cache, and if does not find then // loads feature from the index and takes speed for the feature from the vehicle model. - RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, bool inCity) const; + RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const; // Searches a feature RoadInfo in the cache, and if does not find then takes passed feature and speed. // This version is used to prevent redundant feature loading when feature speed is known. RoadInfo const & GetCachedRoadInfo(FeatureID const & featureId, FeatureType & ft, diff --git a/routing/geometry.cpp b/routing/geometry.cpp index d6292f7d74..c820191881 100644 --- a/routing/geometry.cpp +++ b/routing/geometry.cpp @@ -1,6 +1,7 @@ #include "routing/geometry.hpp" #include "routing/city_roads.hpp" +#include "routing/maxspeeds.hpp" #include "routing/routing_exceptions.hpp" #include "indexer/altitude_loader.hpp" @@ -28,14 +29,14 @@ class GeometryLoaderImpl final : public GeometryLoader public: GeometryLoaderImpl(DataSource const & dataSource, MwmSet::MwmHandle const & handle, shared_ptr vehicleModel, - unique_ptr cityRoads, bool loadAltitudes); + AttrLoader attrLoader, bool loadAltitudes); // GeometryLoader overrides: void Load(uint32_t featureId, RoadGeometry & road) override; private: shared_ptr m_vehicleModel; - unique_ptr m_cityRoads; + AttrLoader m_attrLoader; FeaturesLoaderGuard m_guard; string const m_country; feature::AltitudeLoader m_altitudeLoader; @@ -45,9 +46,9 @@ private: GeometryLoaderImpl::GeometryLoaderImpl(DataSource const & dataSource, MwmSet::MwmHandle const & handle, shared_ptr vehicleModel, - unique_ptr cityRoads, bool loadAltitudes) + AttrLoader attrLoader, bool loadAltitudes) : m_vehicleModel(move(vehicleModel)) - , m_cityRoads(move(cityRoads)) + , m_attrLoader(move(attrLoader)) , m_guard(dataSource, handle.GetId()) , m_country(handle.GetInfo()->GetCountryName()) , m_altitudeLoader(dataSource, handle.GetId()) @@ -55,7 +56,8 @@ GeometryLoaderImpl::GeometryLoaderImpl(DataSource const & dataSource, { CHECK(handle.IsAlive(), ()); CHECK(m_vehicleModel, ()); - CHECK(m_cityRoads, ()); + CHECK(m_attrLoader.m_cityRoads, ()); + CHECK(m_attrLoader.m_maxspeeds, ()); } void GeometryLoaderImpl::Load(uint32_t featureId, RoadGeometry & road) @@ -71,7 +73,8 @@ void GeometryLoaderImpl::Load(uint32_t featureId, RoadGeometry & road) if (m_loadAltitudes) altitudes = &(m_altitudeLoader.GetAltitudes(featureId, feature.GetPointsCount())); - road.Load(*m_vehicleModel, feature, altitudes, m_cityRoads->IsCityRoad(featureId)); + road.Load(*m_vehicleModel, feature, altitudes, m_attrLoader.m_cityRoads->IsCityRoad(featureId), + m_attrLoader.m_maxspeeds->GetMaxspeed(featureId)); m_altitudeLoader.ClearCache(); } @@ -87,6 +90,7 @@ public: private: FeaturesVectorTest m_featuresVector; CityRoads m_cityRoads; + Maxspeeds m_maxspeeds; shared_ptr m_vehicleModel; }; @@ -96,8 +100,20 @@ FileGeometryLoader::FileGeometryLoader(string const & fileName, , m_vehicleModel(vehicleModel) { auto const cont = FilesContainerR(make_unique(fileName)); - if (cont.IsExist(CITY_ROADS_FILE_TAG)) - LoadCityRoads(fileName, cont.GetReader(CITY_ROADS_FILE_TAG), m_cityRoads); + + try + { + if (cont.IsExist(CITY_ROADS_FILE_TAG)) + LoadCityRoads(fileName, cont.GetReader(CITY_ROADS_FILE_TAG), m_cityRoads); + + if (cont.IsExist(MAXSPEED_FILE_TAG)) + LoadMaxspeeds(cont.GetReader(MAXSPEED_FILE_TAG), m_maxspeeds); + } + catch (Reader::OpenException const & e) + { + LOG(LERROR, ("File", cont.GetFileName(), "Error while reading", CITY_ROADS_FILE_TAG, "or", + MAXSPEED_FILE_TAG, "section.", e.Msg())); + } CHECK(m_vehicleModel, ()); } @@ -109,7 +125,8 @@ void FileGeometryLoader::Load(uint32_t featureId, RoadGeometry & road) feature.ParseGeometry(FeatureType::BEST_GEOMETRY); // Note. If FileGeometryLoader is used for generation cross mwm section for bicycle or // pedestrian routing |altitudes| should be used here. - road.Load(*m_vehicleModel, feature, nullptr /* altitudes */, m_cityRoads.IsCityRoad(featureId)); + road.Load(*m_vehicleModel, feature, nullptr /* altitudes */, m_cityRoads.IsCityRoad(featureId), + m_maxspeeds.GetMaxspeed(featureId)); } } // namespace @@ -118,7 +135,10 @@ namespace routing // RoadGeometry ------------------------------------------------------------------------------------ RoadGeometry::RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedKMpH, Points const & points) - : m_speed{weightSpeedKMpH, etaSpeedKMpH}, m_isOneWay{oneWay}, m_valid{true} + : m_forwardSpeed{weightSpeedKMpH, etaSpeedKMpH} + , m_backwardSpeed(m_forwardSpeed) + , m_isOneWay{oneWay} + , m_valid{true} { ASSERT_GREATER(weightSpeedKMpH, 0.0, ()); ASSERT_GREATER(etaSpeedKMpH, 0.0, ()); @@ -129,13 +149,14 @@ RoadGeometry::RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedK } void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType & feature, - feature::TAltitudes const * altitudes, bool inCity) + feature::TAltitudes const * altitudes, bool inCity, Maxspeed const & maxspeed) { CHECK(altitudes == nullptr || altitudes->size() == feature.GetPointsCount(), ()); m_valid = vehicleModel.IsRoad(feature); m_isOneWay = vehicleModel.IsOneWay(feature); - m_speed = vehicleModel.GetSpeed(feature, inCity); + m_forwardSpeed = vehicleModel.GetSpeed(feature, true /* forward */, inCity, maxspeed); + m_backwardSpeed = vehicleModel.GetSpeed(feature, true /* backward */, inCity, maxspeed); m_isPassThroughAllowed = vehicleModel.IsPassThroughAllowed(feature); m_junctions.clear(); @@ -146,18 +167,24 @@ void RoadGeometry::Load(VehicleModelInterface const & vehicleModel, FeatureType altitudes ? (*altitudes)[i] : feature::kDefaultAltitudeMeters); } - if (m_valid && m_speed.m_weight <= 0.0) + if (m_valid && (!m_forwardSpeed.IsValid() || !m_backwardSpeed.IsValid())) { auto const & id = feature.GetID(); CHECK(!m_junctions.empty(), ("mwm:", id.GetMwmName(), ", featureId:", id.m_index)); auto const begin = MercatorBounds::ToLatLon(m_junctions.front().GetPoint()); auto const end = MercatorBounds::ToLatLon(m_junctions.back().GetPoint()); - LOG(LERROR, ("Invalid speed", m_speed.m_weight, "mwm:", id.GetMwmName(), - ", featureId:", id.m_index, ", begin:", begin, "end:", end)); + LOG(LERROR, + ("Invalid speed m_forwardSpeed:", m_forwardSpeed, "m_backwardSpeed:", m_backwardSpeed, + "mwm:", id.GetMwmName(), ", featureId:", id.m_index, ", begin:", begin, "end:", end)); m_valid = false; } } +VehicleModelInterface::SpeedKMpH const & RoadGeometry::GetSpeed(bool forward) const +{ + return forward ? m_forwardSpeed : m_backwardSpeed; +} + // Geometry ---------------------------------------------------------------------------------------- Geometry::Geometry(unique_ptr loader) : m_loader(move(loader)) @@ -180,11 +207,11 @@ RoadGeometry const & Geometry::GetRoad(uint32_t featureId) unique_ptr GeometryLoader::Create(DataSource const & dataSource, MwmSet::MwmHandle const & handle, shared_ptr vehicleModel, - unique_ptr cityRoads, + AttrLoader attrLoader, bool loadAltitudes) { CHECK(handle.IsAlive(), ()); - return make_unique(dataSource, handle, vehicleModel, move(cityRoads), + return make_unique(dataSource, handle, vehicleModel, move(attrLoader), loadAltitudes); } diff --git a/routing/geometry.hpp b/routing/geometry.hpp index 08a0415b53..4569c519d4 100644 --- a/routing/geometry.hpp +++ b/routing/geometry.hpp @@ -1,9 +1,11 @@ #pragma once #include "routing/city_roads.hpp" -#include "routing/road_point.hpp" +#include "routing/maxspeeds.hpp" #include "routing/road_graph.hpp" +#include "routing/road_point.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "routing_common/vehicle_model.hpp" #include "indexer/feature_altitude.hpp" @@ -30,10 +32,10 @@ public: RoadGeometry(bool oneWay, double weightSpeedKMpH, double etaSpeedKMpH, Points const & points); void Load(VehicleModelInterface const & vehicleModel, FeatureType & feature, - feature::TAltitudes const * altitudes, bool inCity); + feature::TAltitudes const * altitudes, bool inCity, Maxspeed const & maxspeed); bool IsOneWay() const { return m_isOneWay; } - VehicleModelInterface::SpeedKMpH const & GetSpeed() const { return m_speed; } + VehicleModelInterface::SpeedKMpH const & GetSpeed(bool forward) const; bool IsPassThroughAllowed() const { return m_isPassThroughAllowed; } Junction const & GetJunction(uint32_t junctionId) const @@ -65,12 +67,24 @@ public: private: buffer_vector m_junctions; - VehicleModelInterface::SpeedKMpH m_speed; + VehicleModelInterface::SpeedKMpH m_forwardSpeed; + VehicleModelInterface::SpeedKMpH m_backwardSpeed; bool m_isOneWay = false; bool m_valid = false; bool m_isPassThroughAllowed = false; }; +struct AttrLoader +{ + AttrLoader(DataSource const & dataSource, MwmSet::MwmHandle const & handle) + : m_cityRoads(LoadCityRoads(dataSource, handle)), m_maxspeeds(LoadMaxspeeds(dataSource, handle)) + { + } + + std::unique_ptr m_cityRoads; + std::unique_ptr m_maxspeeds; +}; + class GeometryLoader { public: @@ -82,7 +96,7 @@ public: static std::unique_ptr Create(DataSource const & dataSource, MwmSet::MwmHandle const & handle, std::shared_ptr vehicleModel, - std::unique_ptr cityRoads, + AttrLoader attrLoader, bool loadAltitudes); /// This is for stand-alone work. diff --git a/routing/index_graph_loader.cpp b/routing/index_graph_loader.cpp index 652a24e842..f4482c3719 100644 --- a/routing/index_graph_loader.cpp +++ b/routing/index_graph_loader.cpp @@ -2,6 +2,7 @@ #include "routing/city_roads.hpp" #include "routing/index_graph_serialization.hpp" +#include "routing/maxspeeds.hpp" #include "routing/restriction_loader.hpp" #include "routing/road_access_serialization.hpp" #include "routing/route.hpp" @@ -185,7 +186,7 @@ IndexGraphLoaderImpl::GraphAttrs & IndexGraphLoaderImpl::CreateGeometry(NumMwmId auto & graph = m_graphs[numMwmId]; graph.m_geometry = make_shared(GeometryLoader::Create( - m_dataSource, handle, vehicleModel, LoadCityRoads(m_dataSource, handle), m_loadAltitudes)); + m_dataSource, handle, vehicleModel, AttrLoader(m_dataSource, handle), m_loadAltitudes)); return graph; } diff --git a/routing/maxspeed_serialization.hpp b/routing/maxspeed_serialization.hpp index 3981ffe9f8..cfff9fec4d 100644 --- a/routing/maxspeed_serialization.hpp +++ b/routing/maxspeed_serialization.hpp @@ -1,8 +1,9 @@ #pragma once -#include "routing/maxspeed_conversion.hpp" #include "routing/maxspeeds.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "coding/reader.hpp" #include "coding/simple_dense_coding.hpp" #include "coding/succinct_mapper.hpp" @@ -117,7 +118,7 @@ public: LOG(LINFO, ("Serialized", serializedForwardNumber, "forward maxspeeds and", header.m_bidirectionalMaxspeedNumber, - "maxspeeds. Section size:", endOffset - startOffset, "bytes.")); + "bidirectional maxspeeds. Section size:", endOffset - startOffset, "bytes.")); } template diff --git a/routing/maxspeeds.cpp b/routing/maxspeeds.cpp index f0baefd841..9c96347760 100644 --- a/routing/maxspeeds.cpp +++ b/routing/maxspeeds.cpp @@ -63,6 +63,12 @@ bool Maxspeeds::HasBidirectionalMaxspeed(uint32_t fid) const FeatureMaxspeed(fid, measurement_utils::Units::Metric, kInvalidSpeed, kInvalidSpeed)); } +void LoadMaxspeeds(FilesContainerR::TReader const & reader, Maxspeeds & maxspeeds) +{ + ReaderSource src(reader); + MaxspeedSerializer::Deserialize(src, maxspeeds); +} + std::unique_ptr LoadMaxspeeds(DataSource const & dataSource, MwmSet::MwmHandle const & handle) { @@ -73,8 +79,7 @@ std::unique_ptr LoadMaxspeeds(DataSource const & dataSource, try { - ReaderSource src(mwmValue.m_cont.GetReader(MAXSPEED_FILE_TAG)); - MaxspeedSerializer::Deserialize(src, *maxspeeds); + LoadMaxspeeds(mwmValue.m_cont.GetReader(MAXSPEED_FILE_TAG), *maxspeeds); } catch (Reader::OpenException const & e) { diff --git a/routing/maxspeeds.hpp b/routing/maxspeeds.hpp index 8bc900dc21..5b0cf539e7 100644 --- a/routing/maxspeeds.hpp +++ b/routing/maxspeeds.hpp @@ -1,6 +1,6 @@ #pragma once -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "indexer/mwm_set.hpp" @@ -50,5 +50,6 @@ private: std::vector m_bidirectionalMaxspeeds; }; +void LoadMaxspeeds(FilesContainerR::TReader const & reader, Maxspeeds & maxspeeds); std::unique_ptr LoadMaxspeeds(DataSource const & dataSource, MwmSet::MwmHandle const & handle); } // namespace routing diff --git a/routing/road_graph.cpp b/routing/road_graph.cpp index aba03024d4..a2a3e30964 100644 --- a/routing/road_graph.cpp +++ b/routing/road_graph.cpp @@ -290,9 +290,12 @@ void IRoadGraph::AddIngoingFakeEdge(Edge const & e) AddEdge(e.GetEndJunction(), e, m_fakeIngoingEdges); } -double IRoadGraph::GetSpeedKMpH(Edge const & edge, bool inCity) const +double IRoadGraph::GetSpeedKMpH(Edge const & edge, bool forward, bool inCity, + Maxspeed const & maxspeed) const { - double const speedKMpH = (edge.IsFake() ? GetMaxSpeedKMpH() : GetSpeedKMpH(edge.GetFeatureId(), inCity)); + double const speedKMpH = + (edge.IsFake() ? GetMaxSpeedKMpH() + : GetSpeedKMpH(edge.GetFeatureId(), forward, inCity, maxspeed)); ASSERT_LESS_OR_EQUAL(speedKMpH, GetMaxSpeedKMpH(), ()); return speedKMpH; } diff --git a/routing/road_graph.hpp b/routing/road_graph.hpp index d13108f691..90cb3503d4 100644 --- a/routing/road_graph.hpp +++ b/routing/road_graph.hpp @@ -2,6 +2,8 @@ #include "routing/segment.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "geometry/point2d.hpp" #include "base/string_utils.hpp" @@ -275,13 +277,15 @@ public: void AddIngoingFakeEdge(Edge const & e); /// Returns RoadInfo for a road corresponding to featureId. - virtual RoadInfo GetRoadInfo(FeatureID const & featureId, bool inCity) const = 0; + virtual RoadInfo GetRoadInfo(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const = 0; /// Returns speed in KM/H for a road corresponding to featureId. - virtual double GetSpeedKMpH(FeatureID const & featureId, bool inCity) const = 0; + virtual double GetSpeedKMpH(FeatureID const & featureId, bool forward, bool inCity, + Maxspeed const & maxspeed) const = 0; /// Returns speed in KM/H for a road corresponding to edge. - double GetSpeedKMpH(Edge const & edge, bool inCity) const; + double GetSpeedKMpH(Edge const & edge, bool forward, bool inCity, Maxspeed const & maxspeed) const; /// Calls edgesLoader on each feature which is close to cross. virtual void ForEachFeatureClosestToCross(m2::PointD const & cross, diff --git a/routing/routing_benchmarks/helpers.hpp b/routing/routing_benchmarks/helpers.hpp index ced1245825..a204955a98 100644 --- a/routing/routing_benchmarks/helpers.hpp +++ b/routing/routing_benchmarks/helpers.hpp @@ -5,6 +5,7 @@ #include "routing/router.hpp" #include "routing/vehicle_mask.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "routing_common/num_mwm_id.hpp" #include "routing_common/vehicle_model.hpp" @@ -70,9 +71,10 @@ public: // max speed. using SpeedKMpH = typename Model::SpeedKMpH; - SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const override + SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + routing::Maxspeed const & maxspeed) const override { - auto const speed = Model::GetSpeed(f, inCity); + auto const speed = Model::GetSpeed(f, forward, inCity, maxspeed); if (speed.m_weight <= 0.0) return SpeedKMpH(); diff --git a/routing/routing_tests/maxspeed_tests.cpp b/routing/routing_tests/maxspeed_tests.cpp index 7bc44bd915..c330cfc075 100644 --- a/routing/routing_tests/maxspeed_tests.cpp +++ b/routing/routing_tests/maxspeed_tests.cpp @@ -1,9 +1,10 @@ #include "testing/testing.hpp" -#include "routing/maxspeed_conversion.hpp" #include "routing/maxspeed_serialization.hpp" #include "routing/maxspeeds.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "coding/file_name_utils.hpp" #include "coding/reader.hpp" #include "coding/writer.hpp" diff --git a/routing/routing_tests/nearest_edge_finder_tests.cpp b/routing/routing_tests/nearest_edge_finder_tests.cpp index 7a27c5cc42..25666d26af 100644 --- a/routing/routing_tests/nearest_edge_finder_tests.cpp +++ b/routing/routing_tests/nearest_edge_finder_tests.cpp @@ -2,6 +2,7 @@ #include "routing/routing_tests/road_graph_builder.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include "routing/nearest_edge_finder.hpp" #include "base/checked_cast.hpp" @@ -19,7 +20,8 @@ void TestNearestOnMock1(m2::PointD const & point, size_t const candidatesCount, for (size_t i = 0; i < graph->GetRoadCount(); ++i) { FeatureID const featureId = MakeTestFeatureID(base::checked_cast(i)); - auto const & roadInfo = graph->GetRoadInfo(featureId, false /* in city */); + auto const & roadInfo = + graph->GetRoadInfo(featureId, true /* forward */, false /* in city */, Maxspeed()); finder.AddInformationSource(featureId, roadInfo.m_junctions, roadInfo.m_bidirectional); } diff --git a/routing/routing_tests/road_graph_builder.cpp b/routing/routing_tests/road_graph_builder.cpp index f613ece475..252d443406 100644 --- a/routing/routing_tests/road_graph_builder.cpp +++ b/routing/routing_tests/road_graph_builder.cpp @@ -69,13 +69,17 @@ void RoadGraphMockSource::AddRoad(RoadInfo && ri) m_roads.push_back(move(ri)); } -IRoadGraph::RoadInfo RoadGraphMockSource::GetRoadInfo(FeatureID const & featureId, bool /* inCity */) const +IRoadGraph::RoadInfo RoadGraphMockSource::GetRoadInfo(FeatureID const & featureId, bool /* forward */, + bool /* inCity */, + Maxspeed const & maxspeed) const { CHECK_LESS(featureId.m_index, m_roads.size(), ("Invalid feature id.")); return m_roads[featureId.m_index]; } -double RoadGraphMockSource::GetSpeedKMpH(FeatureID const & featureId, bool /* inCity */) const +double RoadGraphMockSource::GetSpeedKMpH(FeatureID const & featureId, bool /* forward */, + bool /* inCity */, + Maxspeed const & maxspeed) const { CHECK_LESS(featureId.m_index, m_roads.size(), ("Invalid feature id.")); return m_roads[featureId.m_index].m_speedKMPH; diff --git a/routing/routing_tests/road_graph_builder.hpp b/routing/routing_tests/road_graph_builder.hpp index 8c367e39b0..3bf0f4df52 100644 --- a/routing/routing_tests/road_graph_builder.hpp +++ b/routing/routing_tests/road_graph_builder.hpp @@ -2,6 +2,8 @@ #include "routing/road_graph.hpp" +#include "routing_common/maxspeed_conversion.hpp" + namespace routing_test { @@ -13,8 +15,10 @@ public: inline size_t GetRoadCount() const { return m_roads.size(); } // routing::IRoadGraph overrides: - RoadInfo GetRoadInfo(FeatureID const & featureId, bool inCity) const override; - double GetSpeedKMpH(FeatureID const & featureId, bool inCity) const override; + RoadInfo GetRoadInfo(FeatureID const & f, bool forward, bool inCity, + routing::Maxspeed const & maxspeed) const override; + double GetSpeedKMpH(FeatureID const & featureId, bool forward, bool inCity, + routing::Maxspeed const & maxspeed) const override; double GetMaxSpeedKMpH() const override; void ForEachFeatureClosestToCross(m2::PointD const & cross, ICrossEdgesLoader & edgeLoader) const override; diff --git a/routing/routing_tests/routing_algorithm.cpp b/routing/routing_tests/routing_algorithm.cpp index da4422ef60..8580c9b30e 100644 --- a/routing/routing_tests/routing_algorithm.cpp +++ b/routing/routing_tests/routing_algorithm.cpp @@ -1,6 +1,7 @@ #include "routing/routing_tests/routing_algorithm.hpp" #include "routing/base/astar_algorithm.hpp" +#include "routing/maxspeeds.hpp" #include "routing/routing_helpers.hpp" #include "geometry/mercator.hpp" @@ -67,7 +68,8 @@ public: { ASSERT_EQUAL(v, e.GetStartJunction(), ()); - double const speedMPS = KMPH2MPS(m_roadGraph.GetSpeedKMpH(e, false /* in city */)); + double const speedMPS = KMPH2MPS( + m_roadGraph.GetSpeedKMpH(e, true /* forward */, false /* in city */, Maxspeed())); adj.emplace_back(e.GetEndJunction(), TimeBetweenSec(e.GetStartJunction(), e.GetEndJunction(), speedMPS)); } } @@ -84,7 +86,8 @@ public: { ASSERT_EQUAL(v, e.GetEndJunction(), ()); - double const speedMPS = KMPH2MPS(m_roadGraph.GetSpeedKMpH(e, false /* in city */)); + double const speedMPS = KMPH2MPS( + m_roadGraph.GetSpeedKMpH(e, true /* forward */, false /* in city */, Maxspeed())); adj.emplace_back(e.GetStartJunction(), TimeBetweenSec(e.GetStartJunction(), e.GetEndJunction(), speedMPS)); } } diff --git a/routing_common/CMakeLists.txt b/routing_common/CMakeLists.txt index 2390fda58f..ca7a735b61 100644 --- a/routing_common/CMakeLists.txt +++ b/routing_common/CMakeLists.txt @@ -10,6 +10,8 @@ set( bicycle_model.hpp car_model.cpp car_model.hpp + maxspeed_conversion.cpp + maxspeed_conversion.hpp num_mwm_id.hpp pedestrian_model.cpp pedestrian_model.hpp diff --git a/routing/maxspeed_conversion.cpp b/routing_common/maxspeed_conversion.cpp similarity index 99% rename from routing/maxspeed_conversion.cpp rename to routing_common/maxspeed_conversion.cpp index 391f957b65..0677fbbf11 100644 --- a/routing/maxspeed_conversion.cpp +++ b/routing_common/maxspeed_conversion.cpp @@ -1,4 +1,4 @@ -#include "routing/maxspeed_conversion.hpp" +#include "routing_common/maxspeed_conversion.hpp" #include #include diff --git a/routing/maxspeed_conversion.hpp b/routing_common/maxspeed_conversion.hpp similarity index 100% rename from routing/maxspeed_conversion.hpp rename to routing_common/maxspeed_conversion.hpp diff --git a/routing_common/vehicle_model.cpp b/routing_common/vehicle_model.cpp index c583c5f122..d9e957d829 100644 --- a/routing_common/vehicle_model.cpp +++ b/routing_common/vehicle_model.cpp @@ -1,5 +1,7 @@ #include "routing_common/vehicle_model.hpp" +#include "routing_common/maxspeed_conversion.hpp" + #include "indexer/classificator.hpp" #include "indexer/feature.hpp" #include "indexer/ftypes_matcher.hpp" @@ -87,7 +89,8 @@ void VehicleModel::SetAdditionalRoadTypes(Classificator const & c, } } -VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, bool inCity) const +VehicleModel::SpeedKMpH VehicleModel::GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const { feature::TypesHolder const types(f); diff --git a/routing_common/vehicle_model.hpp b/routing_common/vehicle_model.hpp index 877f459368..d48c28362c 100644 --- a/routing_common/vehicle_model.hpp +++ b/routing_common/vehicle_model.hpp @@ -16,6 +16,7 @@ namespace feature { class TypesHolder; } namespace routing { +struct Maxspeed; class VehicleModelInterface { @@ -39,6 +40,8 @@ public: return m_weight == rhs.m_weight && m_eta == rhs.m_eta; } + bool IsValid() const { return m_weight >= 0 && m_eta >= 0; } + double m_weight = 0.0; // KMpH double m_eta = 0.0; // KMpH }; @@ -72,7 +75,8 @@ public: /// @return Allowed weight and ETA speed in KMpH. /// 0 means that it's forbidden to move on this feature or it's not a road at all. /// @param inCity is true if |f| lies in a city of town. - virtual SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const = 0; + virtual SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const = 0; virtual double GetMaxWeightSpeed() const = 0; @@ -158,7 +162,8 @@ public: SurfaceInitList const & featureTypeSurface); /// VehicleModelInterface overrides: - SpeedKMpH GetSpeed(FeatureType & f, bool inCity) const override; + SpeedKMpH GetSpeed(FeatureType & f, bool forward, bool inCity, + Maxspeed const & maxspeed) const override; double GetMaxWeightSpeed() const override; bool IsOneWay(FeatureType & f) const override; bool IsRoad(FeatureType & f) const override; diff --git a/track_analyzing/track_matcher.cpp b/track_analyzing/track_matcher.cpp index ae2ca32b65..5553acc146 100644 --- a/track_analyzing/track_matcher.cpp +++ b/track_analyzing/track_matcher.cpp @@ -4,6 +4,7 @@ #include "routing/city_roads.hpp" #include "routing/index_graph_loader.hpp" +#include "routing/maxspeeds.hpp" #include "routing_common/car_model.hpp" @@ -66,7 +67,7 @@ TrackMatcher::TrackMatcher(storage::Storage const & storage, NumMwmId mwmId, MwmSet::MwmHandle const handle = m_dataSource.GetMwmHandleByCountryFile(countryFile); m_graph = make_unique( make_shared(GeometryLoader::Create(m_dataSource, handle, m_vehicleModel, - LoadCityRoads(m_dataSource, handle), + AttrLoader(m_dataSource, handle), false /* loadAltitudes */)), EdgeEstimator::Create(VehicleType::Car, *m_vehicleModel, nullptr /* trafficStash */));