/
githubmirror
/
omim
Обзор
Документация
Войти
/
githubmirror
/
omim
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
generator/borders.hpp
167 строк
5 KB
Maksim Andrianov
[cherry-pick][generator] Fixed affiliations.
02 апр 2020, 11:52
02 апр 2020, 11:52
1f0866d
Код
Авторство
О чём код?
#pragma once #include "generator/feature_builder.hpp" #include "storage/storage_defines.hpp" #include "coding/geometry_coding.hpp" #include "coding/reader.hpp" #include "geometry/rect2d.hpp" #include "geometry/region2d.hpp" #include "geometry/tree4d.hpp" #include <memory> #include <mutex> #include <string> #include <unordered_map> #include <unordered_set> #include <utility> #include <vector> #define BORDERS_DIR "borders/" #define BORDERS_EXTENSION ".poly" namespace borders { // The raw borders that we have somehow obtained (probably downloaded from // the OSM and then manually tweaked, but the exact knowledge is lost) are // stored in the BORDERS_DIR. // These are the sources of the mwm borders: each file there corresponds // to exactly one mwm and all mwms except for World and WorldCoasts must // have a borders file to be generated from. // // The file format for raw borders is described at // https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format // // The borders for all mwm files are shipped with the appilication in // the mwm binary format for geometry data (see coding/geometry_coding.hpp). // However, storing every single point turned out to take too much space, // therefore the borders are simplified. This simplification may lead to // unwanted consequences (for example, empty spaces may occur between mwms) // but currently we do not take any action against them. using Polygon = m2::RegionD; using PolygonsTree = m4::Tree<Polygon>; class CountryPolygons { public: CountryPolygons() = default; explicit CountryPolygons(std::string const & name, PolygonsTree const & regions) : m_name(name) , m_polygons(regions) { } CountryPolygons(CountryPolygons && other) = default; CountryPolygons(CountryPolygons const & other) = default; CountryPolygons & operator=(CountryPolygons && other) = default; CountryPolygons & operator=(CountryPolygons const & other) = default; std::string const & GetName() const { return m_name; } bool IsEmpty() const { return m_polygons.IsEmpty(); } void Clear() { m_polygons.Clear(); m_name.clear(); } bool Contains(m2::PointD const & point) const { return m_polygons.ForAnyInRect(m2::RectD(point, point), [&](auto const & rgn) { return rgn.Contains(point); }); } template <typename Do> void ForEachPolygon(Do && fn) const { m_polygons.ForEach(std::forward<Do>(fn)); } template <typename Do> bool ForAnyPolygon(Do && fn) const { return m_polygons.ForAny(std::forward<Do>(fn)); } private: std::string m_name; PolygonsTree m_polygons; }; class CountryPolygonsCollection { public: CountryPolygonsCollection() = default; void Add(CountryPolygons const & countryPolygons) { auto const it = m_countryPolygonsMap.emplace(countryPolygons.GetName(), countryPolygons); countryPolygons.ForEachPolygon([&](auto const & polygon) { m_regionsTree.Add(it.first->second, polygon.GetRect()); }); } size_t GetSize() const { return m_countryPolygonsMap.size(); } template <typename ToDo> void ForEachCountryInRect(m2::RectD const & rect, ToDo && toDo) const { std::unordered_set<CountryPolygons const *> uniq; m_regionsTree.ForEachInRect(rect, [&](auto const & countryPolygons) { if (uniq.emplace(&countryPolygons.get()).second) toDo(countryPolygons); }); } bool HasRegionByName(std::string const & name) const { return m_countryPolygonsMap.count(name) != 0; } CountryPolygons const & GetRegionByName(std::string const & name) const { ASSERT(HasRegionByName(name), ()); return m_countryPolygonsMap.at(name); } private: m4::Tree<std::reference_wrapper<const CountryPolygons>> m_regionsTree; std::unordered_map<std::string, CountryPolygons> m_countryPolygonsMap; }; /// @return false if borderFile can't be opened bool LoadBorders(std::string const & borderFile, std::vector<m2::RegionD> & outBorders); bool GetBordersRect(std::string const & baseDir, std::string const & country, m2::RectD & bordersRect); bool LoadCountriesList(std::string const & baseDir, CountryPolygonsCollection & countries); void GeneratePackedBorders(std::string const & baseDir); template <typename Source> std::vector<m2::RegionD> ReadPolygonsOfOneBorder(Source & src) { auto const count = ReadVarUint<uint32_t>(src); std::vector<m2::RegionD> result(count); for (size_t i = 0; i < count; ++i) { std::vector<m2::PointD> points; serial::LoadOuterPath(src, serial::GeometryCodingParams(), points); result[i] = m2::RegionD(std::move(points)); } return result; } void DumpBorderToPolyFile(std::string const & filePath, storage::CountryId const & mwmName, std::vector<m2::RegionD> const & polygons); void UnpackBorders(std::string const & baseDir, std::string const & targetDir); CountryPolygonsCollection const & GetOrCreateCountryPolygonsTree(std::string const & baseDir); } // namespace borders