diff --git a/generator/regions/collector_region_info.cpp b/generator/regions/collector_region_info.cpp index dc7cc63..31b2f11 100644 --- a/generator/regions/collector_region_info.cpp +++ b/generator/regions/collector_region_info.cpp @@ -190,13 +190,12 @@ void CollectorRegionInfo::FillIsoCode(base::GeoObjectId const & osmId, OsmElemen rd.m_osmId = osmId; rd.SetAlpha2(el.GetTag("is_in:country_code")); - + rd.SetAlpha2(el.GetTag("ISO3166-1")); + rd.SetAlpha2(el.GetTag("ISO3166-1:alpha2")); auto const & iso3166_2 = el.GetTag("ISO3166-2"); if (iso3166_2.size() > 3 && iso3166_2[2] == '-') rd.SetAlpha2(iso3166_2.substr(0, 2)); - rd.SetAlpha2(el.GetTag("ISO3166-1")); - rd.SetAlpha2(el.GetTag("ISO3166-1:alpha2")); rd.SetAlpha3(el.GetTag("ISO3166-1:alpha3")); rd.SetNumeric(el.GetTag("ISO3166-1:numeric")); } diff --git a/generator/regions/regions_builder.cpp b/generator/regions/regions_builder.cpp index 197ed88..3fa9c63 100644 --- a/generator/regions/regions_builder.cpp +++ b/generator/regions/regions_builder.cpp @@ -46,8 +46,16 @@ void RegionsBuilder::MoveLabelPlacePoints(PlacePointsMap & placePointsMap, Regio if (auto labelOsmId = region.GetLabelOsmId()) { auto label = placePointsMap.find(*labelOsmId); - if (label != placePointsMap.end()) - region.SetLabel(label->second); + if (label == placePointsMap.end()) + continue; + + if (label->second.GetPlaceType() == PlaceType::Country && + region.GetAdminLevel() != AdminLevel::Two) + { + continue; + } + + region.SetLabel(label->second); } } @@ -106,10 +114,11 @@ RegionsBuilder::StringsList RegionsBuilder::GetCountryInternationalNames() const Node::Ptr RegionsBuilder::BuildCountryRegionTree( Region const & outer, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const { - auto nodes = MakeCountryNodesInAreaOrder(outer, m_regionsInAreaOrder, isoCode, countrySpecifier); + auto nodes = MakeCountryNodesInAreaOrder(outer, m_regionsInAreaOrder, countryCode, + countrySpecifier); for (auto i = std::crbegin(nodes), end = std::crend(nodes); i != end; ++i) { @@ -125,19 +134,19 @@ Node::Ptr RegionsBuilder::BuildCountryRegionTree( std::vector RegionsBuilder::MakeCountryNodesInAreaOrder( Region const & countryOuter, Regions const & regionsInAreaOrder, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const { std::vector nodes{ std::make_shared(LevelRegion{PlaceLevel::Country, countryOuter})}; for (auto const & region : regionsInAreaOrder) { - auto && regionIsoCode = region.GetIsoCode(); - if (regionIsoCode && isoCode && regionIsoCode != isoCode) - continue; - if (countryOuter.ContainsRect(region)) { + auto && regionIsoCode = region.GetIsoCode(); + if (regionIsoCode && countryCode && GetCountryCode(*regionIsoCode) != *countryCode) + continue; + auto level = strings::IsASCIINumeric(region.GetName()) ? PlaceLevel::Unknown : countrySpecifier.GetLevel(region); auto node = std::make_shared(LevelRegion{level, region}); @@ -320,8 +329,8 @@ Node::PtrList RegionsBuilder::BuildCountry(std::string const & countryName) cons countrySpecifier->RectifyBoundary(outers, m_regionsInAreaOrder); - auto isoCode = FindCountryIsoCode(outers); - auto countryTrees = BuildCountryRegionTrees(outers, isoCode, *countrySpecifier); + auto countryCode = FindCountryCode(outers); + auto countryTrees = BuildCountryRegionTrees(outers, countryCode, *countrySpecifier); PlacePointsIntegrator pointsIntegrator{m_placePointsMap, *countrySpecifier}; LOG(LINFO, ("Start integrate place points for", countryName)); @@ -339,25 +348,85 @@ Node::PtrList RegionsBuilder::BuildCountry(std::string const & countryName) cons return countryTrees; } -boost::optional RegionsBuilder::FindCountryIsoCode(Regions const & outers) const +boost::optional RegionsBuilder::FindCountryCode(Regions const & outers) const { for (auto const & outer : outers) { if (auto isoCode = outer.GetIsoCode()) - return isoCode; + return {GetCountryCode(*isoCode)}; } return {}; } +// static +std::string const & RegionsBuilder::GetCountryCode(std::string const & isoCode) +{ + static auto iso2SovereignIso = std::unordered_map{ + {"AX", "FI"}, + {"AS", "US"}, + {"AI", "GB"}, + {"AW", "NL"}, + {"BM", "GB"}, + {"BQ", "NL"}, + {"BV", "NO"}, + {"IO", "GB"}, + {"KY", "GB"}, + {"CX", "AU"}, + {"CC", "AU"}, + {"CK", "NZ"}, + {"CW", "NZ"}, + {"FK", "GB"}, + {"GF", "FR"}, + {"PF", "FR"}, + {"TF", "FR"}, + {"GI", "GB"}, + {"GL", "DK"}, + {"GP", "FR"}, + {"GU", "US"}, + {"HM", "AU"}, + {"HK", "CH"}, + {"MO", "CH"}, + {"MQ", "FR"}, + {"YT", "FR"}, + {"MS", "GB"}, + {"NC", "FR"}, + {"NU", "NZ"}, + {"NF", "AU"}, + {"MO", "US"}, + {"PN", "GB"}, + {"PR", "US"}, + {"RE", "FR"}, + {"BL", "FR"}, + {"SH", "GB"}, + {"MF", "FR"}, + {"PM", "FR"}, + {"SX", "NL"}, + {"GS", "GB"}, + {"SJ", "NO"}, + {"TK", "NZ"}, + {"TC", "GB"}, + {"UM", "US"}, + {"VG", "GB"}, + {"VI", "US"}, + {"WF", "FR"}, + }; + + auto sovereignIso = iso2SovereignIso.find(isoCode); + if (sovereignIso != iso2SovereignIso.end()) + return sovereignIso->second; + + return isoCode; +} + Node::PtrList RegionsBuilder::BuildCountryRegionTrees( Regions const & outers, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const { Node::PtrList trees; for (auto const & outer : outers) { - auto tree = BuildCountryRegionTree(outer, isoCode, countrySpecifier); + auto tree = BuildCountryRegionTree(outer, countryCode, countrySpecifier); trees.push_back(std::move(tree)); } diff --git a/generator/regions/regions_builder.hpp b/generator/regions/regions_builder.hpp index 20d4530..62ff68b 100644 --- a/generator/regions/regions_builder.hpp +++ b/generator/regions/regions_builder.hpp @@ -47,16 +47,17 @@ private: Regions FormRegionsInAreaOrder(Regions && regions); Regions ExtractCountriesOuters(Regions & regions); Node::PtrList BuildCountry(std::string const & countryName) const; - boost::optional FindCountryIsoCode(Regions const & outers) const; + boost::optional FindCountryCode(Regions const & outers) const; + static std::string const & GetCountryCode(std::string const & isoCode); Node::PtrList BuildCountryRegionTrees(Regions const & outers, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const; Node::Ptr BuildCountryRegionTree(Region const & outer, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const; std::vector MakeCountryNodesInAreaOrder( Region const & countryOuter, Regions const & regionsInAreaOrder, - boost::optional const & isoCode, + boost::optional const & countryCode, CountrySpecifier const & countrySpecifier) const; Node::Ptr ChooseParent(std::vector const & nodesInAreaOrder, std::vector::const_reverse_iterator forItem, diff --git a/generator/regions/specs/china.inl b/generator/regions/specs/china.inl index aa5fad3..a253d93 100644 --- a/generator/regions/specs/china.inl +++ b/generator/regions/specs/china.inl @@ -29,11 +29,11 @@ PlaceLevel ChinaSpecifier::GetSpecificCountryLevel(Region const & region) const AdminLevel adminLevel = region.GetAdminLevel(); switch (adminLevel) { - case AdminLevel::Two: return PlaceLevel::Country; // Hong Kong, Macau + case AdminLevel::Three: return PlaceLevel::Region; // Hong Kong, Macau case AdminLevel::Four: return PlaceLevel::Region; // Provinces case AdminLevel::Six: return PlaceLevel::Subregion; // County case AdminLevel::Eight: return PlaceLevel::Subregion; // Township / Town / Subdistrict - case AdminLevel::Ten: return PlaceLevel::Locality; // Village + case AdminLevel::Ten: return PlaceLevel::Locality; // Village default: break; }