diff options
author | Sergey Yershov <syershov@maps.me> | 2019-04-22 18:29:24 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-22 18:29:24 +0300 |
commit | 6316937a10f0d6622890b607774b6d6668cd49f2 (patch) | |
tree | 190acc4e5e0f3440cc1a8c620c6eeab6a2339b54 /generator | |
parent | 4f98a9cf8cd600647b57150b428bbe0ad629be12 (diff) | |
parent | e7243ce30f196dab249c48c0f1333c9c8815e249 (diff) |
Merge pull request #10729 from cc-engineering/generator.geo_objects.reproduced-streets
[generator:geo_objects] Generate surrogate streets for KV by POI
Diffstat (limited to 'generator')
-rw-r--r-- | generator/geo_objects/streets_builder.cpp | 92 | ||||
-rw-r--r-- | generator/geo_objects/streets_builder.hpp | 21 |
2 files changed, 91 insertions, 22 deletions
diff --git a/generator/geo_objects/streets_builder.cpp b/generator/geo_objects/streets_builder.cpp index f96cf4051f..813e21daca 100644 --- a/generator/geo_objects/streets_builder.cpp +++ b/generator/geo_objects/streets_builder.cpp @@ -20,22 +20,62 @@ StreetsBuilder::StreetsBuilder(RegionInfoGetter const & regionInfoGetter) void StreetsBuilder::Build(std::string const & pathInGeoObjectsTmpMwm, std::ostream & streamGeoObjectsKv) { auto const transform = [this, &streamGeoObjectsKv](FeatureBuilder1 & fb, uint64_t /* currPos */) { - if (!IsStreet(fb)) + if (IsStreet(fb)) + { + AddStreet(fb); return; + } - auto const region = FindStreetRegionOwner(fb); - if (!region) - return; + auto streetName = fb.GetParams().GetStreet(); + if (!streetName.empty()) + AddStreetBinding(std::move(streetName), fb); + }; + feature::ForEachFromDatRawFormat(pathInGeoObjectsTmpMwm, transform); - if (!InsertStreet(*region, fb)) - return; + SaveStreetGeoObjects(streamGeoObjectsKv); +} + +void StreetsBuilder::SaveStreetGeoObjects(std::ostream & streamGeoObjectsKv) +{ + for (auto const & region : m_regions) + SaveRegionStreetGeoObjects(streamGeoObjectsKv, region.first, region.second); +} - auto const value = MakeStreetValue(fb, *region); - auto const id = static_cast<int64_t>(fb.GetMostGenericOsmId().GetEncodedId()); +void StreetsBuilder::SaveRegionStreetGeoObjects(std::ostream & streamGeoObjectsKv, uint64_t regionId, + RegionStreets const & streets) +{ + auto const & regionsStorage = m_regionInfoGetter.GetStorage(); + auto const && regionObject = regionsStorage.Find(regionId); + ASSERT(regionObject, ()); + + for (auto const & street : streets) + { + auto streetId = street.second; + if (base::GeoObjectId::Type::Invalid == streetId.GetType()) + streetId = NextOsmSurrogateId(); + + auto const id = static_cast<int64_t>(streetId.GetEncodedId()); + auto const value = MakeStreetValue(regionId, *regionObject, street.first); streamGeoObjectsKv << id << " " << value.get() << "\n"; - }; + } +} - feature::ForEachFromDatRawFormat(pathInGeoObjectsTmpMwm, transform); +void StreetsBuilder::AddStreet(FeatureBuilder1 & fb) +{ + auto const region = FindStreetRegionOwner(fb); + if (!region) + return; + + InsertStreet(*region, fb.GetName(), fb.GetMostGenericOsmId()); +} + +void StreetsBuilder::AddStreetBinding(std::string && streetName, FeatureBuilder1 & fb) +{ + auto const region = FindStreetRegionOwner(fb.GetKeyPoint()); + if (!region) + return; + + InsertSurrogateStreet(*region, std::move(streetName)); } boost::optional<KeyValue> StreetsBuilder::FindStreetRegionOwner(FeatureBuilder1 & fb) @@ -78,25 +118,36 @@ boost::optional<KeyValue> StreetsBuilder::FindStreetRegionOwner(m2::PointD const return m_regionInfoGetter.FindDeepest(point, isStreetAdministrator); } -bool StreetsBuilder::InsertStreet(KeyValue const & region, FeatureBuilder1 & fb) +bool StreetsBuilder::InsertStreet(KeyValue const & region, std::string && streetName, base::GeoObjectId id) { - auto & regionStreets = m_regionsStreets[region.first]; - auto emplace = regionStreets.emplace(fb.GetName()); + auto & regionStreets = m_regions[region.first]; + auto emplace = regionStreets.emplace(std::move(streetName), id); + + if (!emplace.second && base::GeoObjectId::Type::Invalid == emplace.first->second.GetType()) + emplace.first->second = id; + + return emplace.second; +} + +bool StreetsBuilder::InsertSurrogateStreet(KeyValue const & region, std::string && streetName) +{ + auto & regionStreets = m_regions[region.first]; + auto emplace = regionStreets.emplace(std::move(streetName), base::GeoObjectId{}); return emplace.second; } std::unique_ptr<char, JSONFreeDeleter> StreetsBuilder::MakeStreetValue( - FeatureBuilder1 const & fb, KeyValue const & region) + uint64_t regionId, base::Json const regionObject, std::string const & streetName) { - auto const && regionProperties = base::GetJSONObligatoryField(region.second.get(), "properties"); + auto const && regionProperties = base::GetJSONObligatoryField(regionObject.get(), "properties"); auto const && regionAddress = base::GetJSONObligatoryField(regionProperties, "address"); auto address = base::JSONPtr{json_deep_copy(regionAddress)}; - ToJSONObject(*address, "street", fb.GetName()); + ToJSONObject(*address, "street", streetName); auto properties = base::NewJSONObject(); ToJSONObject(*properties, "address", std::move(address)); - ToJSONObject(*properties, "name", fb.GetName()); - ToJSONObject(*properties, "pid", region.first); + ToJSONObject(*properties, "name", streetName); + ToJSONObject(*properties, "pid", regionId); auto streetObject = base::NewJSONObject(); ToJSONObject(*streetObject, "properties", std::move(properties)); @@ -105,6 +156,11 @@ std::unique_ptr<char, JSONFreeDeleter> StreetsBuilder::MakeStreetValue( return std::unique_ptr<char, JSONFreeDeleter>{value}; } +base::GeoObjectId StreetsBuilder::NextOsmSurrogateId() +{ + return base::GeoObjectId{base::GeoObjectId::Type::OsmSurrogate, ++m_osmSurrogateCounter}; +} + // static bool StreetsBuilder::IsStreet(OsmElement const & element) { diff --git a/generator/geo_objects/streets_builder.hpp b/generator/geo_objects/streets_builder.hpp index e15e1f3502..7f5bb2a397 100644 --- a/generator/geo_objects/streets_builder.hpp +++ b/generator/geo_objects/streets_builder.hpp @@ -9,12 +9,13 @@ #include "geometry/point2d.hpp" +#include "base/geo_object_id.hpp" + #include <memory> #include <ostream> #include <stdint.h> #include <string> #include <unordered_map> -#include <unordered_set> #include <boost/optional.hpp> @@ -33,13 +34,25 @@ public: static bool IsStreet(FeatureBuilder1 const & fb); private: + using RegionStreets = std::unordered_map<std::string, base::GeoObjectId>; + + void SaveStreetGeoObjects(std::ostream & streamGeoObjectsKv); + void SaveRegionStreetGeoObjects(std::ostream & streamGeoObjectsKv, uint64_t regionId, + RegionStreets const & streets); + + void AddStreet(FeatureBuilder1 & fb); + void AddStreetBinding(std::string && streetName, FeatureBuilder1 & fb); boost::optional<KeyValue> FindStreetRegionOwner(FeatureBuilder1 & fb); boost::optional<KeyValue> FindStreetRegionOwner(m2::PointD const & point); - bool InsertStreet(KeyValue const & region, FeatureBuilder1 & fb); - std::unique_ptr<char, JSONFreeDeleter> MakeStreetValue(FeatureBuilder1 const & fb, KeyValue const & region); + bool InsertStreet(KeyValue const & region, std::string && streetName, base::GeoObjectId id); + bool InsertSurrogateStreet(KeyValue const & region, std::string && streetName); + std::unique_ptr<char, JSONFreeDeleter> MakeStreetValue(uint64_t regionId, base::Json const regionObject, + std::string const & streetName); + base::GeoObjectId NextOsmSurrogateId(); - std::unordered_map<uint64_t, std::unordered_set<std::string>> m_regionsStreets; + std::unordered_map<uint64_t, RegionStreets> m_regions; RegionInfoGetter const & m_regionInfoGetter; + uint64_t m_osmSurrogateCounter{0}; }; } // namespace geo_objects } // namespace generator |