diff --git a/generator/transit_generator.cpp b/generator/transit_generator.cpp index cdd97820be..2e3f352b16 100644 --- a/generator/transit_generator.cpp +++ b/generator/transit_generator.cpp @@ -8,6 +8,7 @@ #include "routing/index_router.hpp" #include "routing_common/transit_serdes.hpp" +#include "routing_common/transit_speed_limits.hpp" #include "routing_common/transit_types.hpp" #include "storage/country_info_getter.hpp" @@ -16,6 +17,7 @@ #include "indexer/index.hpp" #include "geometry/point2d.hpp" +#include "geometry/mercator.hpp" #include "coding/file_container.hpp" #include "coding/file_name_utils.hpp" @@ -30,7 +32,9 @@ #include "base/logging.hpp" #include "base/macros.hpp" +#include #include +#include #include #include @@ -44,6 +48,22 @@ using namespace std; namespace { +bool CompStopsById(Stop const & s1, Stop const & s2) +{ + return s1.GetId() < s2.GetId(); +} + +/// \returns ref to a stop at |stops| by |stopId|. +Stop const & FindStopById(vector const & stops, StopId stopId) +{ + auto s1Id = equal_range(stops.cbegin(), stops.cend(), + Stop(stopId, kInvalidFeatureId, kInvalidTransferId, {}, m2::PointD(), {}), + CompStopsById); + CHECK(s1Id.first != stops.cend(), ("No a stop with id:", stopId, "in stops:", stops)); + CHECK_EQUAL(distance(s1Id.first, s1Id.second), 1, ("A stop with id:", stopId, "is not unique in stops:", stops)); + return *(s1Id.first); +} + /// Extracts the file name from |filePath| and drops all extensions. string GetFileName(string const & filePath) { @@ -145,6 +165,24 @@ void SerializeObject(my::Json const & root, string const & key, Serializer const & stops, vector & edges) +{ + CHECK(is_sorted(stops.cbegin(), stops.cend(), CompStopsById), ()); + + for (auto & e : edges) + { + Stop const & s1 = FindStopById(stops, e.GetStop1Id()); + Stop const & s2 = FindStopById(stops, e.GetStop2Id()); + double const lengthInMeters = MercatorBounds::DistanceOnEarth(s1.GetPoint(), s2.GetPoint()); + // Note. 3.6 == 3600 (number of seconds in an hour) / 1000 (number of meters in a kilometer). + // In other words: weighInSec = 3600 * lengthInMeters / (1000 * kTransitAverageSpeedKMpH); + double const weighInSec = 3.6 * lengthInMeters / kTransitAverageSpeedKMpH; + e.SetWeight(weighInSec); + } +} } // namespace namespace routing @@ -222,13 +260,21 @@ void BuildTransit(string const & mwmPath, string const & transitDir) Serializer serializer(w); header.Visit(serializer); - SerializeObject(root, "stops", serializer); + vector stops; + DeserializeFromJson(root, "stops", stops); + CHECK(IsValid(stops), ("stops:", stops)); + sort(stops.begin(), stops.end(), CompStopsById); + serializer(stops); header.m_gatesOffset = base::checked_cast(w.Pos() - startOffset); serializer(gates); header.m_edgesOffset = base::checked_cast(w.Pos() - startOffset); - SerializeObject(root, "edges", serializer); + vector edges; + DeserializeFromJson(root, "edges", edges); + CalculateEdgeWeight(stops, edges); + CHECK(IsValid(stops), ("edges:", edges)); + serializer(edges); header.m_transfersOffset = base::checked_cast(w.Pos() - startOffset); SerializeObject(root, "transfers", serializer); diff --git a/routing_common/transit_speed_limits.hpp b/routing_common/transit_speed_limits.hpp index 66516d42a1..fa3241c487 100644 --- a/routing_common/transit_speed_limits.hpp +++ b/routing_common/transit_speed_limits.hpp @@ -4,6 +4,10 @@ namespace routing { namespace transit { - double constexpr kTransitMaxSpeedKMpH = 400; +double constexpr kTransitMaxSpeedKMpH = 400.0; +// @TODO(bykoianko, Zverik) Edge and gate weights should be valid always valid. This weights should come +// from transit graph json. But now it'not so. |kTransitAverageSpeedKMpH| should be used now only for +// weight calculating weight at transit section generation stage and should be removed later. +double constexpr kTransitAverageSpeedKMpH = 40.0; } // namespace transit } // namespace routing diff --git a/routing_common/transit_types.cpp b/routing_common/transit_types.cpp index ea8424b022..ee2515f0cf 100644 --- a/routing_common/transit_types.cpp +++ b/routing_common/transit_types.cpp @@ -170,8 +170,8 @@ bool Edge::IsEqualForTesting(Edge const & edge) const bool Edge::IsValid() const { - // @TODO(bykoianko) |m_weight| should be valid for Edge validity. - return m_stop1Id != kInvalidStopId && m_stop2Id != kInvalidStopId && m_lineId != kInvalidLineId; + return m_stop1Id != kInvalidStopId && m_stop2Id != kInvalidStopId && m_weight != kInvalidWeight && + m_lineId != kInvalidLineId; } // Transfer --------------------------------------------------------------------------------------- diff --git a/routing_common/transit_types.hpp b/routing_common/transit_types.hpp index 28bac43918..a557b4be9f 100644 --- a/routing_common/transit_types.hpp +++ b/routing_common/transit_types.hpp @@ -104,6 +104,7 @@ public: Stop() = default; Stop(StopId id, FeatureId featureId, TransferId transferId, std::vector const & lineIds, m2::PointD const & point, std::vector const & titleAnchors); + bool IsEqualForTesting(Stop const & stop) const; bool IsValid() const; @@ -197,6 +198,7 @@ public: std::vector const & shapeIds); bool IsEqualForTesting(Edge const & edge) const; bool IsValid() const; + void SetWeight(double weight) { m_weight = weight; } StopId GetStop1Id() const { return m_stop1Id; } StopId GetStop2Id() const { return m_stop2Id; }