diff --git a/transit/experimental/transit_data.cpp b/transit/experimental/transit_data.cpp index b91b192f16..8f6ec377a9 100644 --- a/transit/experimental/transit_data.cpp +++ b/transit/experimental/transit_data.cpp @@ -254,14 +254,15 @@ std::tuple CalculateIds(base::Json const & obj, // Osm id is present in subway items and is absent in all other public transport items. FromJSONObjectOptionalField(obj.get(), "osm_id", osmId); + FromJSONObjectOptionalField(obj.get(), "id", id); + if (osmId == 0) { - id = GetIdFromJson(obj.get()); osmId = kInvalidOsmId; } else { - featureId = GetIdFromJson(obj.get()); + FromJSONObjectOptionalField(obj.get(), "feature_id", featureId); base::GeoObjectId const geoId(osmId); auto const it = mapping.find(geoId); if (it != mapping.cend()) @@ -322,6 +323,32 @@ void Read(base::Json const & obj, std::vector & lines) lines.emplace_back(id, routeId, shapeLink, title, stopIds, intervals, serviceDays); } +void Read(base::Json const & obj, std::vector & linesMetadata) +{ + TransitId const id = GetIdFromJson(obj.get()); + + json_t * arr = base::GetJSONObligatoryField(obj.get(), "shape_segments"); + + CHECK(json_is_array(arr), ()); + + size_t const count = json_array_size(arr); + LineSegmentsOrder segmentsOrder; + segmentsOrder.reserve(count); + + for (size_t i = 0; i < count; ++i) + { + json_t * item = json_array_get(arr, i); + + LineSegmentOrder lineSegmentOrder; + FromJSONObject(item, "order", lineSegmentOrder.m_order); + FromJSONObject(item, "start_index", lineSegmentOrder.m_segment.m_startIdx); + FromJSONObject(item, "end_index", lineSegmentOrder.m_segment.m_endIdx); + segmentsOrder.emplace_back(lineSegmentOrder); + } + + linesMetadata.emplace_back(id, segmentsOrder); +} + void Read(base::Json const & obj, std::vector & stops, OsmIdToFeatureIdsMap const & mapping) { auto const & [osmId, featureId, id] = CalculateIds(obj, mapping); @@ -379,7 +406,6 @@ void Read(base::Json const & obj, std::vector & transfers) void Read(base::Json const & obj, std::vector & gates, OsmIdToFeatureIdsMap const & mapping) { - // TODO(o.khlopkova) Inject subways to public transport jsons. auto const & [osmId, featureId, id] = CalculateIds(obj, mapping); std::vector const weights = GetWeightsFromJson(obj.get()); @@ -432,6 +458,7 @@ void TransitData::DeserializeFromJson(std::string const & dirWithJsons, ReadData(base::JoinPath(dirWithJsons, kNetworksFile), m_networks); ReadData(base::JoinPath(dirWithJsons, kRoutesFile), m_routes); ReadData(base::JoinPath(dirWithJsons, kLinesFile), m_lines); + ReadData(base::JoinPath(dirWithJsons, kLinesMetadataFile), m_linesMetadata); ReadData(base::JoinPath(dirWithJsons, kStopsFile), m_stops, mapping); ReadData(base::JoinPath(dirWithJsons, kShapesFile), m_shapes); ReadData(base::JoinPath(dirWithJsons, kEdgesFile), m_edges); @@ -465,6 +492,9 @@ void TransitData::Serialize(Writer & writer) m_header.m_linesOffset = base::checked_cast(writer.Pos() - startOffset); serializer(m_lines); + m_header.m_linesMetadataOffset = base::checked_cast(writer.Pos() - startOffset); + serializer(m_linesMetadata); + m_header.m_shapesOffset = base::checked_cast(writer.Pos() - startOffset); serializer(m_shapes); @@ -494,6 +524,7 @@ void TransitData::Deserialize(Reader & reader) ReadEdges(src); ReadTransfers(src); ReadLines(src); + ReadLinesMetadata(src); ReadShapes(src); ReadRoutes(src); ReadNetworks(src); @@ -515,9 +546,12 @@ void TransitData::DeserializeForRendering(Reader & reader) { DeserializeWith(reader, [this](NonOwningReaderSource & src) { ReadStops(src); + src.Skip(m_header.m_edgesOffset - src.Pos()); + ReadEdges(src); src.Skip(m_header.m_transfersOffset - src.Pos()); ReadTransfers(src); ReadLines(src); + ReadLinesMetadata(src); ReadShapes(src); ReadRoutes(src); }); @@ -613,7 +647,13 @@ void TransitData::ReadTransfers(NonOwningReaderSource & src) void TransitData::ReadLines(NonOwningReaderSource & src) { - ReadItems(m_header.m_linesOffset, m_header.m_shapesOffset, "lines", src, m_lines); + ReadItems(m_header.m_linesOffset, m_header.m_linesMetadataOffset, "lines", src, m_lines); +} + +void TransitData::ReadLinesMetadata(NonOwningReaderSource & src) +{ + ReadItems(m_header.m_linesMetadataOffset, m_header.m_shapesOffset, "linesMetadata", src, + m_linesMetadata); } void TransitData::ReadShapes(NonOwningReaderSource & src) diff --git a/transit/experimental/transit_data.hpp b/transit/experimental/transit_data.hpp index 36c071f351..cbb3f544a2 100644 --- a/transit/experimental/transit_data.hpp +++ b/transit/experimental/transit_data.hpp @@ -31,6 +31,7 @@ using OsmIdToFeatureIdsMap = std::map> void Read(base::Json const & obj, std::vector & networks); void Read(base::Json const & obj, std::vector & routes); void Read(base::Json const & obj, std::vector & lines); +void Read(base::Json const & obj, std::vector & linesMetadata); void Read(base::Json const & obj, std::vector & stops, OsmIdToFeatureIdsMap const & mapping); void Read(base::Json const & obj, std::vector & shapes); void Read(base::Json const & obj, std::vector & edges); @@ -63,6 +64,7 @@ public: std::vector const & GetEdges() const { return m_edges; } std::vector const & GetTransfers() const { return m_transfers; } std::vector const & GetLines() const { return m_lines; } + std::vector const & GetLinesMetadata() const { return m_linesMetadata; } std::vector const & GetShapes() const { return m_shapes; } std::vector const & GetRoutes() const { return m_routes; } std::vector const & GetNetworks() const { return m_networks; } @@ -81,6 +83,7 @@ private: void ReadEdges(NonOwningReaderSource & src); void ReadTransfers(NonOwningReaderSource & src); void ReadLines(NonOwningReaderSource & src); + void ReadLinesMetadata(NonOwningReaderSource & src); void ReadShapes(NonOwningReaderSource & src); void ReadRoutes(NonOwningReaderSource & src); void ReadNetworks(NonOwningReaderSource & src); @@ -101,6 +104,7 @@ private: std::vector m_edges; std::vector m_transfers; std::vector m_lines; + std::vector m_linesMetadata; std::vector m_shapes; }; } // namespace experimental diff --git a/transit/experimental/transit_types_experimental.cpp b/transit/experimental/transit_types_experimental.cpp index 9753ecfbf5..9e1223a205 100644 --- a/transit/experimental/transit_types_experimental.cpp +++ b/transit/experimental/transit_types_experimental.cpp @@ -27,9 +27,9 @@ std::string GetTranslation(Translations const & titles) bool TransitHeader::IsValid() const { return m_stopsOffset <= m_gatesOffset && m_gatesOffset <= m_transfersOffset && - m_transfersOffset <= m_linesOffset && m_linesOffset <= m_shapesOffset && - m_shapesOffset <= m_routesOffset && m_routesOffset <= m_networksOffset && - m_networksOffset <= m_endOffset; + m_transfersOffset <= m_linesOffset && m_linesOffset <= m_linesMetadataOffset && + m_linesMetadataOffset <= m_shapesOffset && m_shapesOffset <= m_routesOffset && + m_routesOffset <= m_networksOffset && m_networksOffset <= m_endOffset; } // SingleMwmSegment -------------------------------------------------------------------------------- @@ -174,6 +174,20 @@ std::vector Line::GetIntervals() const { return m_intervals; } osmoh::OpeningHours Line::GetServiceDays() const { return m_serviceDays; } +// LineMetadata ------------------------------------------------------------------------------------ +LineMetadata::LineMetadata(TransitId id, LineSegmentsOrder const & segmentsOrder) + : m_id(id), m_segmentsOrder(segmentsOrder) +{ +} + +bool LineMetadata::operator<(LineMetadata const & rhs) const { return m_id < rhs.GetId(); } +bool LineMetadata::operator==(LineMetadata const & rhs) const { return m_id == rhs.GetId(); } + +bool LineMetadata::IsValid() const { return m_id != kInvalidTransitId; } + +TransitId LineMetadata::GetId() const { return m_id; } +LineSegmentsOrder const & LineMetadata::GetLineSegmentsOrder() const { return m_segmentsOrder; } + // Stop -------------------------------------------------------------------------------------------- Stop::Stop() : m_ids(true /* serializeFeatureIdOnly */) {} @@ -203,12 +217,14 @@ bool Stop::operator==(Stop const & rhs) const if (m_id != kInvalidTransitId || rhs.m_id != kInvalidTransitId) return m_id == rhs.m_id; - return m_ids.GetFeatureId() == rhs.m_ids.GetFeatureId(); + return m_ids.GetFeatureId() == rhs.m_ids.GetFeatureId() && + m_ids.GetOsmId() == rhs.m_ids.GetOsmId(); } bool Stop::IsValid() const { - return ((m_id != kInvalidTransitId) || (m_ids.GetOsmId() != kInvalidOsmId)) && !m_title.empty(); + return ((m_id != kInvalidTransitId) || (m_ids.GetOsmId() != kInvalidOsmId) || + (m_ids.GetFeatureId() != kInvalidFeatureId)); } FeatureId Stop::GetId() const { return m_id; } diff --git a/transit/experimental/transit_types_experimental.hpp b/transit/experimental/transit_types_experimental.hpp index b31b64b177..300904f026 100644 --- a/transit/experimental/transit_types_experimental.hpp +++ b/transit/experimental/transit_types_experimental.hpp @@ -118,9 +118,9 @@ struct TransitHeader TransitHeader, visitor(m_version, "version"), visitor(m_reserve, "reserve"), visitor(m_stopsOffset, "stops"), visitor(m_gatesOffset, "gatesOffset"), visitor(m_edgesOffset, "edgesOffset"), visitor(m_transfersOffset, "transfersOffset"), - visitor(m_linesOffset, "linesOffset"), visitor(m_shapesOffset, "shapesOffset"), - visitor(m_routesOffset, "routesOffset"), visitor(m_networksOffset, "networksOffset"), - visitor(m_endOffset, "endOffset")) + visitor(m_linesOffset, "linesOffset"), visitor(m_linesMetadataOffset, "linesMetadataOffset"), + visitor(m_shapesOffset, "shapesOffset"), visitor(m_routesOffset, "routesOffset"), + visitor(m_networksOffset, "networksOffset"), visitor(m_endOffset, "endOffset")) uint16_t m_version = 0; uint16_t m_reserve = 0; @@ -129,13 +129,14 @@ struct TransitHeader uint32_t m_edgesOffset = 0; uint32_t m_transfersOffset = 0; uint32_t m_linesOffset = 0; + uint32_t m_linesMetadataOffset = 0; uint32_t m_shapesOffset = 0; uint32_t m_routesOffset = 0; uint32_t m_networksOffset = 0; uint32_t m_endOffset = 0; }; -static_assert(sizeof(TransitHeader) == 40, "Wrong header size of transit section."); +static_assert(sizeof(TransitHeader) == 44, "Wrong header size of transit section."); class Network { @@ -229,6 +230,28 @@ private: osmoh::OpeningHours m_serviceDays; }; +class LineMetadata +{ +public: + LineMetadata() = default; + LineMetadata(TransitId id, LineSegmentsOrder const & segmentsOrder); + + bool operator<(LineMetadata const & rhs) const; + bool operator==(LineMetadata const & rhs) const; + + bool IsValid() const; + + TransitId GetId() const; + LineSegmentsOrder const & GetLineSegmentsOrder() const; + +private: + DECLARE_TRANSIT_TYPES_FRIENDS + DECLARE_VISITOR_AND_DEBUG_PRINT(LineMetadata, visitor(m_id, "id"), + visitor(m_segmentsOrder, "segments_order")) + TransitId m_id = kInvalidTransitId; + LineSegmentsOrder m_segmentsOrder; +}; + class Stop { public: