diff --git a/generator/generator_tests/transit_test.cpp b/generator/generator_tests/transit_test.cpp index 1b13e711fe..2c18796259 100644 --- a/generator/generator_tests/transit_test.cpp +++ b/generator/generator_tests/transit_test.cpp @@ -154,7 +154,16 @@ UNIT_TEST(DeserializerFromJson_Edges) { "stop2_id": 442018445, "line_id": 72551680, - "shape_ids": [5, 7], + "shape_ids": [ + { + "stop1_id": 209186407, + "stop2_id": 209186410 + }, + { + "stop1_id": 209186408, + "stop2_id": 209186411 + } + ], "stop1_id": 442018444, "transfer": false }, @@ -169,10 +178,11 @@ UNIT_TEST(DeserializerFromJson_Edges) ]})"; vector const expected = { - Edge(442018444 /* stop 1 id */, 442018445 /* stop 2 id */, kInvalidWeight /* weight */, - 72551680 /* line id */, false /* transfer */, {5, 7} /* shape ids */), - Edge(442018445 /* stop 1 id */, 442018446 /* stop 2 id */, 345.6 /* weight */, - 72551680 /* line id */, false /* transfer */, {} /* shape ids */)}; + Edge(442018444 /* stop 1 id */, 442018445 /* stop 2 id */, kInvalidWeight /* weight */, + 72551680 /* line id */, false /* transfer */, + {ShapeId(209186407, 209186410), ShapeId(209186408, 209186411)}), + Edge(442018445 /* stop 1 id */, 442018446 /* stop 2 id */, 345.6 /* weight */, + 72551680 /* line id */, false /* transfer */, {} /* shape ids */)}; TestDeserializerFromJson(jsonBuffer, "edges", expected); } @@ -256,9 +266,10 @@ UNIT_TEST(DeserializerFromJson_Shapes) { "shapes": [ { - "id": 1, - "stop1_id": 209186424, - "stop2_id": 248520179, + "id": { + "stop1_id": 209186424, + "stop2_id": 248520179 + }, "polyline": [ { "x": 27.5762295, @@ -279,9 +290,10 @@ UNIT_TEST(DeserializerFromJson_Shapes) ] }, { - "id": 2, - "stop1_id": 209191850, - "stop2_id": 209191851, + "id": { + "stop1_id": 209191850, + "stop2_id": 209191851 + }, "polyline": [ { "x": 27.554025800000002, @@ -295,12 +307,12 @@ UNIT_TEST(DeserializerFromJson_Shapes) } ]})"; - vector const expected = {Shape(1 /* shape id */, 209186424 /* stop 1 id */, 248520179 /* stop 2 id */, + vector const expected = {Shape(ShapeId(209186424 /* stop 1 id */, 248520179 /* stop 2 id */), {m2::PointD(27.5762295, 64.256768574044699), m2::PointD(27.576325736220355, 64.256879325696005), m2::PointD(27.576420780761875, 64.256990221238539), m2::PointD(27.576514659541523, 64.257101255242176)} /* polyline */), - Shape(2 /* shape id */, 209191850 /* stop 1 id */, 209191851 /* stop 2 id */, + Shape(ShapeId(209191850 /* stop 1 id */, 209191851 /* stop 2 id */), {m2::PointD(27.554025800000002, 64.250591911669844), m2::PointD(27.553906184631536, 64.250633404586054)} /* polyline */)}; diff --git a/generator/transit_generator.cpp b/generator/transit_generator.cpp index 9a04bcf1e3..02e7af5647 100644 --- a/generator/transit_generator.cpp +++ b/generator/transit_generator.cpp @@ -206,15 +206,12 @@ DeserializerFromJson::DeserializerFromJson(json_struct_t* node, void DeserializerFromJson::operator()(m2::PointD & p, char const * name) { - json_t * pointItem = nullptr; - if (name == nullptr) - pointItem = m_node; // Array item case - else - pointItem = my::GetJSONObligatoryField(m_node, name); + GetTwoParamDict(name, "x", "y", p.x, p.y); +} - CHECK(json_is_object(pointItem), ()); - FromJSONObject(pointItem, "x", p.x); - FromJSONObject(pointItem, "y", p.y); +void DeserializerFromJson::operator()(ShapeId & id, char const * name) +{ + GetTwoParamDict(name, "stop1_id", "stop2_id", id.m_stop1_id, id.m_stop2_id); } void DeserializerFromJson::operator()(FeatureIdentifiers & id, char const * name) diff --git a/generator/transit_generator.hpp b/generator/transit_generator.hpp index 82ec5f5958..11ee3cb641 100644 --- a/generator/transit_generator.hpp +++ b/generator/transit_generator.hpp @@ -38,6 +38,7 @@ public: void operator()(std::string & s, char const * name = nullptr) { GetField(s, name); } void operator()(m2::PointD & p, char const * name = nullptr); + void operator()(ShapeId & id, char const * name = nullptr); void operator()(FeatureIdentifiers & id, char const * name = nullptr); template @@ -65,6 +66,21 @@ public: } private: + template + void GetTwoParamDict(char const * dictName, std::string const & paramName1, + std::string const & paramName2, T & val1, T & val2) + { + json_t * item = nullptr; + if (dictName == nullptr) + item = m_node; // Array item case + else + item = my::GetJSONObligatoryField(m_node, dictName); + + CHECK(json_is_object(item), ()); + FromJSONObject(item, paramName1, val1); + FromJSONObject(item, paramName2, val2); + } + template void GetField(T & t, char const * name = nullptr) { diff --git a/routing_common/routing_common_tests/transit_test.cpp b/routing_common/routing_common_tests/transit_test.cpp index 3a938817fc..e216ab4d1b 100644 --- a/routing_common/routing_common_tests/transit_test.cpp +++ b/routing_common/routing_common_tests/transit_test.cpp @@ -106,7 +106,7 @@ UNIT_TEST(Transit_GateSerialization) UNIT_TEST(Transit_EdgeSerialization) { Edge edge(1 /* start stop id */, 2 /* finish stop id */, 123.4 /* weight */, 11 /* line id */, - false /* transfer */, {1, 2, 3} /* shape ids */); + false /* transfer */, {ShapeId(1, 2), ShapeId(3, 4), ShapeId(5, 6)} /* shape ids */); TestSerialization(edge); } @@ -134,11 +134,11 @@ UNIT_TEST(Transit_LineSerialization) UNIT_TEST(Transit_ShapeSerialization) { { - Shape shape(1 /* shape id */, 10 /* stop 1 id */, 11 /* stop 2 id */, {} /* polyline */); + Shape shape(ShapeId(10, 20), {} /* polyline */); TestSerialization(shape); } { - Shape shape(1 /* shape id */, 10 /* stop 1 id */, 11 /* stop 2 id */, + Shape shape(ShapeId(11, 21), {m2::PointD(20.0, 20.0), m2::PointD(21.0, 21.0), m2::PointD(22.0, 22.0)} /* polyline */); TestSerialization(shape); } diff --git a/routing_common/transit_types.cpp b/routing_common/transit_types.cpp index bcb9d2fcb7..383e8690fb 100644 --- a/routing_common/transit_types.cpp +++ b/routing_common/transit_types.cpp @@ -148,6 +148,17 @@ bool Gate::IsValid() const return m_weight != kInvalidWeight && (m_entrance || m_exit) && !m_stopIds.empty(); } +// ShapeId ---------------------------------------------------------------------------------------- +bool ShapeId::operator==(ShapeId const & rhs) const +{ + return m_stop1_id == rhs.m_stop1_id && m_stop2_id == rhs.m_stop2_id; +} + +bool ShapeId::IsValid() const +{ + return m_stop1_id != kInvalidLineId && m_stop2_id != kInvalidNetworkId; +} + // Edge ------------------------------------------------------------------------------------------- Edge::Edge(StopId stop1Id, StopId stop2Id, double weight, LineId lineId, bool transfer, std::vector const & shapeIds) @@ -223,18 +234,10 @@ bool Line::IsValid() const } // Shape ------------------------------------------------------------------------------------------ -Shape::Shape(ShapeId id, StopId stop1_id, StopId stop2_id, std::vector const & polyline) - : m_id(id), m_stop1_id(stop1_id), m_stop2_id(stop2_id), m_polyline(polyline) -{ -} - bool Shape::IsEqualForTesting(Shape const & shape) const { - if (!(m_id == shape.m_id && m_stop1_id == shape.m_stop1_id && m_stop2_id == shape.m_stop2_id && - m_polyline.size() == shape.m_polyline.size())) - { + if (!m_id.IsEqualForTesting(shape.m_id) && m_polyline.size() == shape.m_polyline.size()) return false; - } for (size_t i = 0; i < m_polyline.size(); ++i) { @@ -244,12 +247,6 @@ bool Shape::IsEqualForTesting(Shape const & shape) const return true; } -bool Shape::IsValid() const -{ - return m_id != kInvalidShapeId && m_stop1_id != kInvalidStopId && m_stop2_id != kInvalidStopId && - m_polyline.size() > 1; -} - // Network ---------------------------------------------------------------------------------------- Network::Network(NetworkId id, std::string const & title) : m_id(id), m_title(title) diff --git a/routing_common/transit_types.hpp b/routing_common/transit_types.hpp index 9b6eb6ebff..83ad9cf9b3 100644 --- a/routing_common/transit_types.hpp +++ b/routing_common/transit_types.hpp @@ -21,7 +21,6 @@ using TransferId = uint64_t; using NetworkId = uint32_t; using FeatureId = uint32_t; using OsmId = uint64_t; -using ShapeId = uint32_t; using Weight = double; using Anchor = uint8_t; @@ -31,7 +30,6 @@ TransferId constexpr kInvalidTransferId = std::numeric_limits::max() NetworkId constexpr kInvalidNetworkId = std::numeric_limits::max(); FeatureId constexpr kInvalidFeatureId = std::numeric_limits::max(); OsmId constexpr kInvalidOsmId = std::numeric_limits::max(); -ShapeId constexpr kInvalidShapeId = std::numeric_limits::max(); // Note. Weight may be a default param at json. The default value should be saved as uint32_t in mwm anyway. // To convert double to uint32_t at better accuracy |kInvalidWeight| should be close to real weight. Weight constexpr kInvalidWeight = -1.0; @@ -218,6 +216,28 @@ private: m2::PointD m_point; }; +class ShapeId +{ +public: + ShapeId() = default; + ShapeId(StopId stop1_id, StopId stop2_id) : m_stop1_id(stop1_id), m_stop2_id(stop2_id) {} + + bool operator==(ShapeId const & rhs) const; + bool IsEqualForTesting(ShapeId const & rhs) const { return *this == rhs; } + + bool IsValid() const; + StopId GetStop1Id() const { return m_stop1_id; } + StopId GetStop2Id() const { return m_stop2_id; } + +private: + DECLARE_TRANSIT_TYPE_FRIENDS + DECLARE_VISITOR_AND_DEBUG_PRINT(ShapeId, visitor(m_stop1_id, "stop1_id"), + visitor(m_stop2_id, "stop2_id")) + + StopId m_stop1_id = kInvalidStopId; + StopId m_stop2_id = kInvalidStopId; +}; + class Edge { public: @@ -311,23 +331,18 @@ class Shape { public: Shape() = default; - Shape(ShapeId id, StopId stop1_id, StopId stop2_id, std::vector const & polyline); + Shape(ShapeId const & id, std::vector const & polyline) : m_id(id), m_polyline(polyline) {} bool IsEqualForTesting(Shape const & shape) const; - bool IsValid() const; + bool IsValid() const { return m_id.IsValid() && m_polyline.size() > 1; } ShapeId GetId() const { return m_id; } - StopId GetStop1Id() const { return m_stop1_id; } - StopId GetStop2Id() const { return m_stop2_id; } std::vector const & GetPolyline() const { return m_polyline; } private: DECLARE_TRANSIT_TYPE_FRIENDS - DECLARE_VISITOR_AND_DEBUG_PRINT(Shape, visitor(m_id, "id"), visitor(m_stop1_id, "stop1_id"), - visitor(m_stop2_id, "stop2_id"), visitor(m_polyline, "polyline")) + DECLARE_VISITOR_AND_DEBUG_PRINT(Shape, visitor(m_id, "id"), visitor(m_polyline, "polyline")) - ShapeId m_id = kInvalidShapeId; - StopId m_stop1_id = kInvalidStopId; - StopId m_stop2_id = kInvalidStopId; + ShapeId m_id; std::vector m_polyline; };