diff --git a/generator/generator_tests/transit_test.cpp b/generator/generator_tests/transit_test.cpp index 55bcf489a9..82b9cb578a 100644 --- a/generator/generator_tests/transit_test.cpp +++ b/generator/generator_tests/transit_test.cpp @@ -7,6 +7,7 @@ #include "base/assert.hpp" #include +#include #include using namespace routing; @@ -21,7 +22,7 @@ void TestDeserializerFromJson(string const & jsonBuffer, string const & name, ve my::Json root(jsonBuffer.c_str()); CHECK(root.get() != nullptr, ("Cannot parse the json.")); - DeserializerFromJson deserializer(root.get()); + DeserializerFromJson deserializer(root.get(), make_shared()); vector objects; deserializer(objects, name.c_str()); diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index 277cb80c73..8f444958ae 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -308,7 +308,7 @@ int main(int argc, char ** argv) routing::BuildRoadAltitudes(datFile, FLAGS_srtm_path); if (!FLAGS_transit_path.empty()) - routing::transit::BuildTransit(datFile, FLAGS_transit_path); + routing::transit::BuildTransit(datFile, osmToFeatureFilename, FLAGS_transit_path); if (FLAGS_make_routing_index) { diff --git a/generator/transit_generator.cpp b/generator/transit_generator.cpp index ada7975549..101deb88fc 100644 --- a/generator/transit_generator.cpp +++ b/generator/transit_generator.cpp @@ -28,6 +28,7 @@ #include "platform/local_country_file_utils.hpp" #include "platform/platform.hpp" +#include "base/assert.hpp" #include "base/checked_cast.hpp" #include "base/logging.hpp" #include "base/macros.hpp" @@ -83,17 +84,18 @@ string GetFileName(string const & filePath) } template -void DeserializeFromJson(my::Json const & root, string const & key, vector & items) +void DeserializeFromJson(my::Json const & root, string const & key, + shared_ptr const & osmIdToFeatureIdsMap, vector & items) { items.clear(); - DeserializerFromJson deserializer(root.get()); + DeserializerFromJson deserializer(root.get(), osmIdToFeatureIdsMap); deserializer(items, key.c_str()); } void DeserializeGatesFromJson(my::Json const & root, string const & mwmDir, string const & countryId, - vector & gates) + shared_ptr const & osmIdToFeatureIdsMap, vector & gates) { - DeserializeFromJson(root, "gates", gates); + DeserializeFromJson(root, "gates", osmIdToFeatureIdsMap, gates); // Creating IndexRouter. SingleMwmIndex index(my::JoinFoldersToPath(mwmDir, countryId + DATA_FILE_EXTENSION)); @@ -154,10 +156,11 @@ bool IsValid(vector const & items) /// \brief Reads from |root| (json) and serializes an array to |serializer|. template -void SerializeObject(my::Json const & root, string const & key, Serializer & serializer) +void SerializeObject(my::Json const & root, string const & key, + shared_ptr const & osmIdToFeatureIdsMap, Serializer & serializer) { vector items; - DeserializeFromJson(root, key, items); + DeserializeFromJson(root, key, osmIdToFeatureIdsMap, items); CHECK(IsValid(items), ("key:", key, "items:", items)); serializer(items); } @@ -179,6 +182,15 @@ void CalculateEdgeWeight(vector const & stops, vector & edg e.SetWeight(lengthInMeters / kTransitAverageSpeedMPS); } } + +void FillOsmIdToFeatureIdMap(string const & osmIdsToFeatureIdPath, OsmIdToFeatureIdsMap & map) +{ + CHECK(ForEachOsmId2FeatureId(osmIdsToFeatureIdPath, + [&map](osm::Id const & osmId, uint32_t featureId) { + map[osmId].push_back(featureId); + }), + ()); +} } // namespace namespace routing @@ -198,8 +210,14 @@ void DeserializerFromJson::operator()(m2::PointD & p, char const * name) FromJSONObject(pointItem, "x", p.x); FromJSONObject(pointItem, "y", p.y); } +DeserializerFromJson::DeserializerFromJson(json_struct_t * node, + shared_ptr const & osmIdToFeatureIds) + : m_node(node), m_osmIdToFeatureIds(osmIdToFeatureIds) +{ +} -void BuildTransit(string const & mwmPath, string const & transitDir) +void BuildTransit(string const & mwmPath, string const & osmIdsToFeatureIdPath, + string const & transitDir) { LOG(LERROR, ("This method is under construction and should not be used for building production mwm " "sections.")); @@ -241,10 +259,13 @@ void BuildTransit(string const & mwmPath, string const & transitDir) my::Json root(jsonBuffer.c_str()); CHECK(root.get() != nullptr, ("Cannot parse the json file:", graphFullPath)); + auto mapping = make_shared(); + FillOsmIdToFeatureIdMap(osmIdsToFeatureIdPath, *mapping); + // Note. |gates| has to be deserialized from json before starting writing transit section to mwm since // the mwm is used to filled |gates|. vector gates; - DeserializeGatesFromJson(root, my::GetDirectory(mwmPath), countryId, gates); + DeserializeGatesFromJson(root, my::GetDirectory(mwmPath), countryId, mapping, gates); CHECK(IsValid(gates), (gates)); FilesContainerW cont(mwmPath, FileWriter::OP_WRITE_EXISTING); @@ -257,7 +278,7 @@ void BuildTransit(string const & mwmPath, string const & transitDir) header.Visit(serializer); vector stops; - DeserializeFromJson(root, "stops", stops); + DeserializeFromJson(root, "stops", mapping, stops); CHECK(IsValid(stops), ("stops:", stops)); sort(stops.begin(), stops.end(), LessById); serializer(stops); @@ -267,22 +288,22 @@ void BuildTransit(string const & mwmPath, string const & transitDir) header.m_edgesOffset = base::checked_cast(w.Pos() - startOffset); vector edges; - DeserializeFromJson(root, "edges", edges); + DeserializeFromJson(root, "edges", mapping, edges); CalculateEdgeWeight(stops, edges); CHECK(IsValid(stops), ("edges:", edges)); serializer(edges); header.m_transfersOffset = base::checked_cast(w.Pos() - startOffset); - SerializeObject(root, "transfers", serializer); + SerializeObject(root, "transfers", mapping, serializer); header.m_linesOffset = base::checked_cast(w.Pos() - startOffset); - SerializeObject(root, "lines", serializer); + SerializeObject(root, "lines", mapping, serializer); header.m_shapesOffset = base::checked_cast(w.Pos() - startOffset); - SerializeObject(root, "shapes", serializer); + SerializeObject(root, "shapes", mapping, serializer); header.m_networksOffset = base::checked_cast(w.Pos() - startOffset); - SerializeObject(root, "networks", serializer); + SerializeObject(root, "networks", mapping, serializer); header.m_endOffset = base::checked_cast(w.Pos() - startOffset); // Rewriting header info. diff --git a/generator/transit_generator.hpp b/generator/transit_generator.hpp index 06d45a3ab8..b0c23c3812 100644 --- a/generator/transit_generator.hpp +++ b/generator/transit_generator.hpp @@ -1,5 +1,9 @@ #pragma once +#include "generator/osm_id.hpp" + +#include "routing_common/transit_types.hpp" + #include "geometry/point2d.hpp" #include "base/macros.hpp" @@ -7,6 +11,8 @@ #include "3party/jansson/myjansson.hpp" #include +#include +#include #include #include #include @@ -15,10 +21,12 @@ namespace routing { namespace transit { +using OsmIdToFeatureIdsMap = std::map>; + class DeserializerFromJson { public: - DeserializerFromJson(json_struct_t * node) : m_node(node) {} + DeserializerFromJson(json_struct_t* node, std::shared_ptr const & osmIdToFeatureIds); template typename std::enable_if::value || std::is_enum::value || std::is_same::value>::type @@ -43,7 +51,7 @@ public: vs.resize(sz); for (size_t i = 0; i < sz; ++i) { - DeserializerFromJson arrayItem(json_array_get(arr, i)); + DeserializerFromJson arrayItem(json_array_get(arr, i), m_osmIdToFeatureIds); arrayItem(vs[i]); } } @@ -77,6 +85,7 @@ private: } json_struct_t * m_node; + std::shared_ptr m_osmIdToFeatureIds; }; /// \brief Builds the transit section in the mwm. @@ -86,6 +95,7 @@ private: /// \note An mwm pointed by |mwmPath| should contain: /// * feature geometry /// * index graph (ROUTING_FILE_TAG) -void BuildTransit(std::string const & mwmPath, std::string const & transitDir); +void BuildTransit(std::string const & mwmPath, std::string const & osmIdsToFeatureIdPath, + std::string const & transitDir); } // namespace transit } // namespace routing diff --git a/routing_common/transit_types.hpp b/routing_common/transit_types.hpp index 62106a0bde..965f5cc7f3 100644 --- a/routing_common/transit_types.hpp +++ b/routing_common/transit_types.hpp @@ -40,7 +40,9 @@ Anchor constexpr kInvalidAnchor = std::numeric_limits::max(); template friend class Deserializer; \ friend class DeserializerFromJson; \ friend class routing::TransitGraphLoader; \ - friend void BuildTransit(std::string const & mwmPath, std::string const & transitDir); \ + friend void BuildTransit(std::string const & mwmPath, \ + std::string const & osmIdsToFeatureIdPath, \ + std::string const & transitDir); \ template friend void TestSerialization(Obj const & obj); \ struct TransitHeader