diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp index d7003be681..93937e65c6 100644 --- a/generator/osm2type.cpp +++ b/generator/osm2type.cpp @@ -28,41 +28,45 @@ namespace ftype // NOTE! If you add a new type into classificator, which has a number in it // (like admin_level=1 or capital=2), please don't forget to insert it here too. // Otherwise generated data will not contain your newly added features. - bool isNumber = strings::is_number(v); - return (!isNumber || (isNumber && (k == "admin_level" || k == "capital"))); + return !strings::is_number(v) || k == "admin_level" || k == "capital"; } bool IgnoreTag(string const & k, string const & v) { static string const negativeValues[] = { "no", "false", "-1" }; + // If second component of these pairs is true we need to process this key else ignore it static pair const processedKeys[] = { {"description", true} ,{"cycleway", true} // [highway=primary][cycleway=lane] parsed as [highway=cycleway] ,{"proposed", true} // [highway=proposed][proposed=primary] parsed as [highway=primary] ,{"construction", true} // [highway=primary][construction=primary] parsed as [highway=construction] - ,{"layer", false} // process in any case - ,{"oneway", false} // process in any case + ,{"layer", false} // process in any case + ,{"oneway", false} // process in any case }; - // ignore empty key + // Ignore empty key. if (k.empty()) return true; - // ignore some keys + // Process special keys. for (auto const & key : processedKeys) + { if (k == key.first) return key.second; + } - // ignore keys with negative values + // Ignore keys with negative values. for (auto const & value : negativeValues) + { if (v == value) return true; + } return false; } template - TResult ForEachTag(OsmElement * p, ToDo toDo) + TResult ForEachTag(OsmElement * p, ToDo && toDo) { TResult res = TResult(); for (auto & e : p->m_tags) @@ -78,33 +82,33 @@ namespace ftype } template - TResult ForEachTagEx(OsmElement * p, set & skipTags, ToDo toDo) + TResult ForEachTagEx(OsmElement * p, set & skipTags, ToDo && toDo) { int id = 0; return ForEachTag(p, [&](string const & k, string const & v) { - int current_id = id++; - if (skipTags.count(current_id) != 0) + int currentId = id++; + if (skipTags.count(currentId) != 0) return TResult(); if (string::npos != k.find("name")) { - skipTags.insert(current_id); + skipTags.insert(currentId); return TResult(); } TResult res = toDo(k, v); if (res) - skipTags.insert(current_id); + skipTags.insert(currentId); return res; }); } - class ExtractNames + class NamesExtractor { set m_savedNames; FeatureParams & m_params; public: - ExtractNames(FeatureParams & params) : m_params(params) {} + NamesExtractor(FeatureParams & params) : m_params(params) {} bool GetLangByKey(string const & k, string & lang) { @@ -112,9 +116,12 @@ namespace ftype if (!token) return false; - // this is an international (latin) name + // Is this an international (latin) name. if (*token == "int_name") - return m_savedNames.insert(lang = "int_name").second; + { + lang = *token; + return m_savedNames.insert(lang).second; + } if (*token != "name") return false; @@ -122,11 +129,11 @@ namespace ftype ++token; lang = (token ? *token : "default"); - // replace dummy arabian tag with correct tag + // Replace dummy arabian tag with correct tag. if (lang == "ar1") lang = "ar"; - // avoid duplicating names + // Avoid duplicating names. return m_savedNames.insert(lang).second; } @@ -256,16 +263,20 @@ namespace ftype auto matchTagToClassificator = [&path, ¤t](string const & k, string const & v) -> bool { - // first try to match key + // First try to match key. ClassifObjectPtr elem = current->BinaryFind(k); if (!elem) return false; path.push_back(elem); - // now try to match correspondent value - if (NeedMatchValue(k, v) && (elem = elem->BinaryFind(v))) - path.push_back(elem); + // Now try to match correspondent value. + if (!NeedMatchValue(k, v)) + return true; + + if (ClassifObjectPtr velem = elem->BinaryFind(v)) + path.push_back(velem); + return true; }; @@ -274,17 +285,17 @@ namespace ftype current = classif().GetRoot(); path.clear(); - // find first root object by key + // Find first root object by key. if (!ForEachTagEx(p, skipRows, matchTagToClassificator)) break; CHECK(!path.empty(), ()); do { - // continue find path from last element + // Continue find path from last element. current = path.back().get(); - // next objects trying to find by value first + // Next objects trying to find by value first. ClassifObjectPtr pObj = ForEachTagEx(p, skipRows, [&](string const & k, string const & v) { @@ -299,18 +310,18 @@ namespace ftype } else { - // if no - try find object by key (in case of k = "area", v = "yes") + // If no - try find object by key (in case of k = "area", v = "yes"). if (!ForEachTagEx(p, skipRows, matchTagToClassificator)) break; } } while (true); - // assign type + // Assign type. uint32_t t = ftype::GetEmptyValue(); for (auto const & e : path) ftype::PushValue(t, e.GetIndex()); - // use features only with drawing rules + // Use features only with drawing rules. if (feature::IsDrawableAny(t)) params.AddType(t); @@ -319,7 +330,7 @@ namespace ftype void GetNameAndType(OsmElement * p, FeatureParams & params) { - // Preprocess tags + // Stage1: Preprocess tags. bool hasLayer = false; char const * layer = nullptr; @@ -333,42 +344,42 @@ namespace ftype if (!hasLayer && layer) p->AddTag("layer", layer); - // Process feature name on all languages - ForEachTag(p, ExtractNames(params)); + // Stage2: Process feature name on all languages. + ForEachTag(p, NamesExtractor(params)); - // Base rules for tags processing + // Stage3: Process base feature tags. TagProcessor(p).ApplyRules ({ - { "atm", "yes", [](string &k, string &v) { k.swap(v); k = "amenity"; }}, - { "restaurant", "yes", [](string &k, string &v) { k.swap(v); k = "amenity"; }}, - { "hotel", "yes", [](string &k, string &v) { k.swap(v); k = "tourism"; }}, - { "addr:housename", "*", [¶ms](string &k, string &v) { params.AddHouseName(v); k.clear(); v.clear();}}, - { "addr:street", "*", [¶ms](string &k, string &v) { params.AddStreetAddress(v); k.clear(); v.clear();}}, - { "addr:flats", "*", [¶ms](string &k, string &v) { params.flats = v; k.clear(); v.clear();}}, - { "addr:housenumber", "*", [¶ms](string &k, string &v) + { "atm", "yes", [](string & k, string & v) { k.swap(v); k = "amenity"; }}, + { "restaurant", "yes", [](string & k, string & v) { k.swap(v); k = "amenity"; }}, + { "hotel", "yes", [](string & k, string & v) { k.swap(v); k = "tourism"; }}, + { "addr:housename", "*", [¶ms](string & k, string & v) { params.AddHouseName(v); k.clear(); v.clear();}}, + { "addr:street", "*", [¶ms](string & k, string & v) { params.AddStreetAddress(v); k.clear(); v.clear();}}, + { "addr:flats", "*", [¶ms](string & k, string & v) { params.flats = v; k.clear(); v.clear();}}, + { "addr:housenumber", "*", [¶ms](string & k, string & v) { // Treat "numbers" like names if it's not an actual number. if (!params.AddHouseNumber(v)) params.AddHouseName(v); k.clear(); v.clear(); }}, - { "population", "*", [¶ms](string &k, string &v) + { "population", "*", [¶ms](string & k, string & v) { - // get population rank + // Get population rank. uint64_t n; if (strings::to_uint64(v, n)) params.rank = static_cast(log(double(n)) / log(1.1)); k.clear(); v.clear(); }}, - { "ref", "*", [¶ms](string &k, string &v) + { "ref", "*", [¶ms](string & k, string & v) { - // get reference (we process road numbers only) + // Get reference (we process road numbers only). params.ref = v; k.clear(); v.clear(); }}, - { "layer", "*", [¶ms](string &k, string &v) + { "layer", "*", [¶ms](string & k, string & v) { - // get layer + // Get layer. if (params.layer == 0) { params.layer = atoi(v.c_str()); @@ -378,9 +389,10 @@ namespace ftype }}, }); - // Match tags to classificator for find feature types + // Stage4: Match tags to classificator for find feature types. MatchTypes(p, params); + // Stage5: Postrocess feature types. static CachedTypes const types; if (!params.house.IsEmpty()) @@ -465,7 +477,7 @@ namespace ftype params.FinishAddingTypes(); - // Collect addidtional information about feature such as + // Stage6: Collect addidtional information about feature such as // hotel stars, opening hours, cuisine, ... ForEachTag(p, MetadataTagProcessor(params)); } diff --git a/generator/osm_element.cpp b/generator/osm_element.cpp index cab48fea6a..e80a7f1950 100644 --- a/generator/osm_element.cpp +++ b/generator/osm_element.cpp @@ -29,10 +29,10 @@ string DebugPrint(OsmElement::EntityType e) } } -#define SKIP_KEY(key) if (strncmp(k.data(), key, sizeof(key)-1) == 0) return; void OsmElement::AddTag(string const & k, string const & v) { +#define SKIP_KEY(key) if (strncmp(k.data(), key, sizeof(key)-1) == 0) return; // OSM technical info tags SKIP_KEY("created_by"); SKIP_KEY("source"); @@ -58,7 +58,7 @@ void OsmElement::AddTag(string const & k, string const & v) SKIP_KEY("local_name"); SKIP_KEY("short_name"); SKIP_KEY("official_name"); - +#undef SKIP_KEY m_tags.emplace_back(k, v); } diff --git a/generator/osm_translator.hpp b/generator/osm_translator.hpp index 204c1047d8..24a1aac724 100644 --- a/generator/osm_translator.hpp +++ b/generator/osm_translator.hpp @@ -92,8 +92,8 @@ public: m_current = p; } - template - bool operator() (uint64_t id, ReaderT & reader) + template + bool operator() (uint64_t id, TReader & reader) { bool exists = false; RelationElement & e = m_cache.Find(id, exists); @@ -207,7 +207,7 @@ protected: } }; -} // anonymous namespace +} // namespace /// @param TEmitter Feature accumulating policy /// @param TCache Nodes, ways, relations holder diff --git a/geometry/region2d.hpp b/geometry/region2d.hpp index a8900b1b46..1e3d3563c3 100644 --- a/geometry/region2d.hpp +++ b/geometry/region2d.hpp @@ -4,6 +4,8 @@ #include "geometry/rect2d.hpp" #include "geometry/distance.hpp" +#include "base/math.hpp" + #include "std/vector.hpp" #include "std/algorithm.hpp" #include "std/type_traits.hpp" @@ -18,14 +20,13 @@ namespace m2 template bool EqualPoints(PointT const & p1, PointT const & p2) const { -// return m2::AlmostEqualULPs(p1, p2); - return my::AlmostEqualAbs(p1.x, p2.x, 1e-7) && my::AlmostEqualAbs(p1.y, p2.y, 1e-7); + return my::AlmostEqualAbs(p1.x, p2.x, (typename PointT::value_type)1e-7) && + my::AlmostEqualAbs(p1.y, p2.y, (typename PointT::value_type)1e-7); } template bool EqualZero(CoordT val, CoordT exp) const { - return my::AlmostEqualULPs(val + exp, exp); -// return my::AlmostEqualAbs(val + exp, exp, 1e-7); + return my::AlmostEqualAbs(val, 0.0, exp); } };