[transit] Lines metadata (de)serialization.

This commit is contained in:
Olga Khlopkova 2020-08-21 11:34:39 +03:00 committed by ldo2
parent 4d9b4304bb
commit fe35a2d8fc
4 changed files with 96 additions and 13 deletions

View file

@ -254,14 +254,15 @@ std::tuple<OsmId, FeatureId, TransitId> 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<Line> & lines)
lines.emplace_back(id, routeId, shapeLink, title, stopIds, intervals, serviceDays);
}
void Read(base::Json const & obj, std::vector<LineMetadata> & 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<Stop> & stops, OsmIdToFeatureIdsMap const & mapping)
{
auto const & [osmId, featureId, id] = CalculateIds(obj, mapping);
@ -379,7 +406,6 @@ void Read(base::Json const & obj, std::vector<Transfer> & transfers)
void Read(base::Json const & obj, std::vector<Gate> & gates, OsmIdToFeatureIdsMap const & mapping)
{
// TODO(o.khlopkova) Inject subways to public transport jsons.
auto const & [osmId, featureId, id] = CalculateIds(obj, mapping);
std::vector<TimeFromGateToStop> 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<uint32_t>(writer.Pos() - startOffset);
serializer(m_lines);
m_header.m_linesMetadataOffset = base::checked_cast<uint32_t>(writer.Pos() - startOffset);
serializer(m_linesMetadata);
m_header.m_shapesOffset = base::checked_cast<uint32_t>(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)

View file

@ -31,6 +31,7 @@ using OsmIdToFeatureIdsMap = std::map<base::GeoObjectId, std::vector<FeatureId>>
void Read(base::Json const & obj, std::vector<Network> & networks);
void Read(base::Json const & obj, std::vector<Route> & routes);
void Read(base::Json const & obj, std::vector<Line> & lines);
void Read(base::Json const & obj, std::vector<LineMetadata> & linesMetadata);
void Read(base::Json const & obj, std::vector<Stop> & stops, OsmIdToFeatureIdsMap const & mapping);
void Read(base::Json const & obj, std::vector<Shape> & shapes);
void Read(base::Json const & obj, std::vector<Edge> & edges);
@ -63,6 +64,7 @@ public:
std::vector<Edge> const & GetEdges() const { return m_edges; }
std::vector<Transfer> const & GetTransfers() const { return m_transfers; }
std::vector<Line> const & GetLines() const { return m_lines; }
std::vector<LineMetadata> const & GetLinesMetadata() const { return m_linesMetadata; }
std::vector<Shape> const & GetShapes() const { return m_shapes; }
std::vector<Route> const & GetRoutes() const { return m_routes; }
std::vector<Network> 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<Edge> m_edges;
std::vector<Transfer> m_transfers;
std::vector<Line> m_lines;
std::vector<LineMetadata> m_linesMetadata;
std::vector<Shape> m_shapes;
};
} // namespace experimental

View file

@ -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<LineInterval> 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; }

View file

@ -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: