diff --git a/generator/generator.pro b/generator/generator.pro index c65fbfeac1..145c6aea36 100644 --- a/generator/generator.pro +++ b/generator/generator.pro @@ -36,6 +36,7 @@ SOURCES += \ osm_id.cpp \ osm_source.cpp \ region_meta.cpp \ + restriction_dumper.cpp \ restrictions.cpp \ routing_generator.cpp \ search_index_builder.cpp \ @@ -74,6 +75,7 @@ HEADERS += \ osm_xml_source.hpp \ polygonizer.hpp \ region_meta.hpp \ + restriction_dumper.hpp \ restrictions.hpp \ routing_generator.hpp \ search_index_builder.hpp \ diff --git a/generator/osm_source.cpp b/generator/osm_source.cpp index e0fdc5f26e..1aeddefe7c 100644 --- a/generator/osm_source.cpp +++ b/generator/osm_source.cpp @@ -27,8 +27,6 @@ #include "coding/file_name_utils.hpp" #include "coding/parse_xml.hpp" -#include "std/fstream.hpp" - #include "defines.hpp" SourceReader::SourceReader() @@ -56,7 +54,6 @@ uint64_t SourceReader::Read(char * buffer, uint64_t bufferSize) return m_file->gcount(); } - namespace { template @@ -302,13 +299,14 @@ class MainFeaturesEmitter : public EmitterBase inline uint32_t Type(TypeIndex i) const { return m_types[i]; } + SyncOfstream m_featureId2osmIds; + public: MainFeaturesEmitter(feature::GenerateInfo const & info) : m_skippedElementsPath(info.GetIntermediateFileName("skipped_elements", ".lst")) , m_failOnCoasts(info.m_failOnCoasts) , m_bookingDataset(info.m_bookingDatafileName, info.m_bookingReferenceDir) , m_opentableDataset(info.m_opentableDatafileName, info.m_opentableReferenceDir) - { Classificator const & c = classif(); @@ -343,6 +341,13 @@ public: if (info.m_createWorld) m_world.reset(new TWorldGenerator(info)); + + // Feature id osm id to map. + string const featureId2OsmIdsFile = info.GetIntermediateFileName("feature_id_to_osm_ids", ".csv"); + LOG(LINFO, ("Saving osm ids to feature ids map to", featureId2OsmIdsFile)); + m_featureId2osmIds.Open(featureId2OsmIdsFile); + if (!m_featureId2osmIds.IsOpened()) + LOG(LWARNING, ("Cannot open", featureId2OsmIdsFile, ". Feature id to osm ids to map won't be saved.")); } void operator()(FeatureBuilder1 & fb) override @@ -443,7 +448,7 @@ public: auto & emitter = m_countries->Parent(); emitter.Start(); - (*m_countries)(fb, GetRestrictionCollector()); + (*m_countries)(fb, m_featureId2osmIds); emitter.Finish(); if (m_coastsHolder) @@ -500,7 +505,7 @@ private: (*m_world)(fb); if (m_countries) - (*m_countries)(fb, GetRestrictionCollector()); + (*m_countries)(fb, m_featureId2osmIds); } void DumpSkippedElements() @@ -527,6 +532,30 @@ private: }; } // anonymous namespace +void SyncOfstream::Open(string const & fullPath) +{ + lock_guard gard(m_mutex); + m_stream.open(fullPath, std::ofstream::out); +} + +bool SyncOfstream::IsOpened() +{ + lock_guard gard(m_mutex); + return m_stream.is_open() && !m_stream.fail(); +} + +void SyncOfstream::Write(uint32_t featureId, vector const & osmIds) +{ + if (!IsOpened()) + return; + + lock_guard gard(m_mutex); + m_stream << featureId << ", "; + for (osm::Id const & osmId : osmIds) + m_stream << osmId.OsmId() << ", "; + m_stream << endl; +} + unique_ptr MakeMainFeatureEmitter(feature::GenerateInfo const & info) { LOG(LINFO, ("Processing booking data from", info.m_bookingDatafileName, "done.")); @@ -691,7 +720,7 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info, EmitterBase & emitter) // TODO(mgsergio): Get rid of EmitterBase template parameter. OsmToFeatureTranslator parser( emitter, cache, info.m_makeCoasts ? classif().GetCoastType() : 0, - info.GetAddressesFileName()); + info.GetAddressesFileName(), info.GetIntermediateFileName("restrictions_in_osm_ids", ".csv")); TagAdmixer tagAdmixer(info.GetIntermediateFileName("ways", ".csv"), info.GetIntermediateFileName("towns", ".csv")); @@ -725,8 +754,6 @@ bool GenerateFeaturesImpl(feature::GenerateInfo & info, EmitterBase & emitter) if (!emitter.Finish()) return false; - emitter.GetRestrictionCollector().ComposeRestrictionsAndSave( - info.GetIntermediateFileName("restrictions", ".csv")); emitter.GetNames(info.m_bucketNames); } catch (Reader::Exception const & ex) diff --git a/generator/osm_source.hpp b/generator/osm_source.hpp index a03b9b7fdf..e2added122 100644 --- a/generator/osm_source.hpp +++ b/generator/osm_source.hpp @@ -2,10 +2,12 @@ #include "generator/generate_info.hpp" #include "generator/osm_element.hpp" -#include "generator/restrictions.hpp" +#include "generator/osm_id.hpp" +#include "std/fstream.hpp" #include "std/function.hpp" #include "std/iostream.hpp" +#include "std/mutex.hpp" #include "std/unique_ptr.hpp" class SourceReader @@ -36,8 +38,6 @@ class FeatureBuilder1; // Emitter is used in OsmElemen to FeatureBuilder translation process. class EmitterBase { - RestrictionCollector m_restrictions; - public: virtual ~EmitterBase() = default; @@ -49,11 +49,17 @@ public: /// Sets buckets (mwm names). // TODO(syershov): Make this topic clear. virtual void GetNames(vector & names) const = 0; +}; - RestrictionCollector & GetRestrictionCollector() - { - return m_restrictions; - } +class SyncOfstream +{ + ofstream m_stream; + mutex m_mutex; + +public: + void Open(string const & fullPath); + bool IsOpened(); + void Write(uint32_t featureId, vector const & osmIds); }; unique_ptr MakeMainFeatureEmitter(feature::GenerateInfo const & info); diff --git a/generator/osm_translator.hpp b/generator/osm_translator.hpp index 2cd5617159..ebfc7face9 100644 --- a/generator/osm_translator.hpp +++ b/generator/osm_translator.hpp @@ -3,7 +3,7 @@ #include "generator/feature_builder.hpp" #include "generator/osm2type.hpp" #include "generator/osm_element.hpp" -#include "generator/restrictions.hpp" +#include "generator/restriction_dumper.hpp" #include "generator/ways_merger.hpp" #include "indexer/classificator.hpp" @@ -29,8 +29,8 @@ namespace class RelationTagsBase { public: - RelationTagsBase(RestrictionCollector & restrictionCollector) - : m_restrictionCollector(restrictionCollector), m_cache(14) {} + RelationTagsBase(RestrictionDumper & restrictionDumper) + : m_restrictionDumper(restrictionDumper), m_cache(14) {} void Reset(uint64_t fID, OsmElement * p) { @@ -75,7 +75,7 @@ protected: protected: uint64_t m_featureID; OsmElement * m_current; - RestrictionCollector & m_restrictionCollector; + RestrictionDumper & m_restrictionDumper; private: my::Cache m_cache; @@ -86,8 +86,8 @@ class RelationTagsNode : public RelationTagsBase using TBase = RelationTagsBase; public: - RelationTagsNode(RestrictionCollector & restrictionCollector) - : RelationTagsBase(restrictionCollector) {} + RelationTagsNode(RestrictionDumper & restrictionDumper) + : RelationTagsBase(restrictionDumper) {} protected: void Process(RelationElement const & e) override @@ -98,7 +98,7 @@ protected: if (type == "restriction") { - m_restrictionCollector.AddRestriction(e); + m_restrictionDumper.Write(e); return; } @@ -127,8 +127,8 @@ protected: class RelationTagsWay : public RelationTagsBase { public: - RelationTagsWay(RestrictionCollector & restrictionCollector) - : RelationTagsBase(restrictionCollector) {} + RelationTagsWay(RestrictionDumper & restrictionDumper) + : RelationTagsBase(restrictionDumper) {} private: using TBase = RelationTagsBase; @@ -155,7 +155,7 @@ protected: if (type == "restriction") { - m_restrictionCollector.AddRestriction(e); + m_restrictionDumper.Write(e); return; } @@ -207,6 +207,8 @@ class OsmToFeatureTranslator uint32_t m_coastType; unique_ptr m_addrWriter; + RestrictionDumper m_restrictionDumper; + RelationTagsNode m_nodeRelations; RelationTagsWay m_wayRelations; @@ -509,11 +511,14 @@ public: public: OsmToFeatureTranslator(TEmitter & emitter, TCache & holder, uint32_t coastType, - string const & addrFilePath = {}) + string const & addrFilePath = {}, string const & restrictionsFilePath = {}) : m_emitter(emitter), m_holder(holder), m_coastType(coastType), - m_nodeRelations(m_emitter.GetRestrictionCollector()), m_wayRelations(m_emitter.GetRestrictionCollector()) + m_nodeRelations(m_restrictionDumper), m_wayRelations(m_restrictionDumper) { if (!addrFilePath.empty()) m_addrWriter.reset(new FileWriter(addrFilePath)); + + if (!restrictionsFilePath.empty()) + m_restrictionDumper.Open(restrictionsFilePath); } }; diff --git a/generator/polygonizer.hpp b/generator/polygonizer.hpp index 6d82656fe4..91449ed4b3 100644 --- a/generator/polygonizer.hpp +++ b/generator/polygonizer.hpp @@ -3,7 +3,7 @@ #include "generator/borders_loader.hpp" #include "generator/feature_builder.hpp" #include "generator/generate_info.hpp" -#include "generator/restrictions.hpp" +#include "generator/osm_source.hpp" #include "indexer/feature_visibility.hpp" #include "indexer/cell_id.hpp" @@ -30,8 +30,6 @@ #include #endif -class RestrictionCollector; - namespace feature { // Groups features according to country polygons @@ -112,7 +110,7 @@ namespace feature } }; - void operator () (FeatureBuilder1 & fb, RestrictionCollector & restrictions) + void operator () (FeatureBuilder1 & fb, SyncOfstream & featureId2osmIds) { buffer_vector vec; m_countries.ForEachInRect(fb.GetLimitRect(), InsertCountriesPtr(vec)); @@ -122,15 +120,15 @@ namespace feature case 0: break; case 1: - EmitFeature(vec[0], fb, restrictions); + EmitFeature(vec[0], fb, featureId2osmIds); break; default: { #if PARALLEL_POLYGONIZER m_ThreadPoolSemaphore.acquire(); - m_ThreadPool.start(new PolygonizerTask(this, vec, fb, restrictions)); + m_ThreadPool.start(new PolygonizerTask(this, vec, fb, featureId2osmIds)); #else - PolygonizerTask task(this, vec, fb, restrictions); + PolygonizerTask task(this, vec, fb, featureId2osmIds); task.RunBase(); #endif } @@ -152,7 +150,7 @@ namespace feature } void EmitFeature(borders::CountryPolygons const * country, FeatureBuilder1 const & fb, - RestrictionCollector & restriction) + SyncOfstream & featureId2osmIds) { #if PARALLEL_POLYGONIZER QMutexLocker mutexLocker(&m_EmitFeatureMutex); @@ -175,7 +173,7 @@ namespace feature CHECK_LESS(0, nextFeatureId, ("GetNextFeatureId() is called before WriteFeatureBase(...)")); if (fb.IsLine()) - restriction.AddFeatureId(fb.GetOsmIds(), nextFeatureId - 1 /* feature id of |fb| */); + featureId2osmIds.Write(nextFeatureId - 1 /* feature id of |fb| */, fb.GetOsmIds()); } vector const & Names() const @@ -194,8 +192,8 @@ namespace feature public: PolygonizerTask(Polygonizer * pPolygonizer, buffer_vector const & countries, - FeatureBuilder1 const & fb, RestrictionCollector & restrictions) - : m_pPolygonizer(pPolygonizer), m_Countries(countries), m_FB(fb), m_restrictions(restrictions) {} + FeatureBuilder1 const & fb, SyncOfstream & featureId2osmIds) + : m_pPolygonizer(pPolygonizer), m_Countries(countries), m_FB(fb), m_featureId2osmIds(featureId2osmIds) {} void RunBase() { @@ -205,7 +203,7 @@ namespace feature m_FB.ForEachGeometryPoint(doCheck); if (doCheck.m_belongs) - m_pPolygonizer->EmitFeature(m_Countries[i], m_FB, m_restrictions); + m_pPolygonizer->EmitFeature(m_Countries[i], m_FB, m_featureId2osmIds); } } @@ -222,7 +220,7 @@ namespace feature Polygonizer * m_pPolygonizer; buffer_vector m_Countries; FeatureBuilder1 m_FB; - RestrictionCollector & m_restrictions; + SyncOfstream & m_featureId2osmIds; }; }; } diff --git a/generator/restriction_dumper.cpp b/generator/restriction_dumper.cpp new file mode 100644 index 0000000000..46cf7ced8e --- /dev/null +++ b/generator/restriction_dumper.cpp @@ -0,0 +1,92 @@ +#include "generator/intermediate_elements.hpp" +#include "generator/osm_id.hpp" +#include "generator/restriction_dumper.hpp" +#include "generator/restrictions.hpp" + +#include "base/logging.hpp" + +#include "std/algorithm.hpp" +#include "std/fstream.hpp" +#include "std/string.hpp" +#include "std/vector.hpp" + +namespace +{ +vector const kRestrictionTypesNo = {"no_right_turn", "no_left_turn", "no_u_turn", + "no_straight_on", "no_entry", "no_exit"}; +vector const kRestrictionTypesOnly = {"only_right_turn", "only_left_turn", "only_straight_on"}; + +/// \brief Converts restriction type form string to RestrictionCollector::Type. +/// \returns Fisrt item is a result of conversion. Second item is true +/// if convertion was successful and false otherwise. +pair TagToType(string const & type) +{ + if (find(kRestrictionTypesNo.cbegin(), kRestrictionTypesNo.cend(), type) != kRestrictionTypesNo.cend()) + return make_pair(RestrictionCollector::Type::No, true); + + if (find(kRestrictionTypesOnly.cbegin(), kRestrictionTypesOnly.cend(), type) != kRestrictionTypesOnly.cend()) + return make_pair(RestrictionCollector::Type::Only, true); + + // Unsupported restriction type. + return make_pair(RestrictionCollector::Type::No, false); +} +} // namespace + +void RestrictionDumper::Open(string const & fullPath) +{ + LOG(LINFO, ("Saving road restrictions in osm id terms to", fullPath)); + m_stream.open(fullPath, std::ofstream::out); + + if (!IsOpened()) + LOG(LINFO, ("Cannot open file", fullPath)); +} + +bool RestrictionDumper::IsOpened() +{ + return m_stream.is_open() && !m_stream.fail(); +} + +void RestrictionDumper::Write(RelationElement const & relationElement) +{ + if (!IsOpened()) + return; + + CHECK_EQUAL(relationElement.GetType(), "restriction", ()); + + // Note. For the time being only line-point-line road restriction is supported. + if (relationElement.nodes.size() != 1 || relationElement.ways.size() != 2) + return; // Unsupported restriction. For example line-line-line. + + // Extracting osm ids of lines and points of the restriction. + auto const findTag = [&relationElement](vector> const & members, string const & tag) + { + auto const it = find_if(members.cbegin(), members.cend(), + [&tag](pair const & p) { return p.second == tag; }); + return it; + }; + + auto const fromIt = findTag(relationElement.ways, "from"); + if (fromIt == relationElement.ways.cend()) + return; // No tag |from| in |relationElement.ways|. + + auto const toIt = findTag(relationElement.ways, "to"); + if (toIt == relationElement.ways.cend()) + return; // No tag |to| in |relationElement.ways|. + + if (findTag(relationElement.nodes,"via") == relationElement.nodes.cend()) + return; // No tag |via| in |relationElement.nodes|. + + // Extracting type of restriction. + auto const tagIt = relationElement.tags.find("restriction"); + if (tagIt == relationElement.tags.end()) + return; // Type of the element is different from "restriction". + + auto const typeResult = TagToType(tagIt->second); + if (typeResult.second == false) + return; // Unsupported restriction type. + + // Adding restriction. + m_stream << ToString(typeResult.first) << ", " // Restriction type + << fromIt->first << ", " + << toIt->first << "," << endl; +} diff --git a/generator/restriction_dumper.hpp b/generator/restriction_dumper.hpp new file mode 100644 index 0000000000..ded3dd731a --- /dev/null +++ b/generator/restriction_dumper.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "std/fstream.hpp" +#include "std/string.hpp" + +class RelationElement; + +class RestrictionDumper +{ + ofstream m_stream; + +public: + void Open(string const & fullPath); + bool IsOpened(); + + /// \brief Writes |relationElement| to |m_stream| if |relationElement| is a supported restriction. + /// \note For the time being only line-point-line restritions are processed. The other restrictions + /// are ignored. + // @TODO(bykoianko) It's necessary to process all kind of restrictions. + void Write(RelationElement const & relationElement); +}; diff --git a/generator/restrictions.cpp b/generator/restrictions.cpp index cc4930d0ed..6af8fcf737 100644 --- a/generator/restrictions.cpp +++ b/generator/restrictions.cpp @@ -1,6 +1,6 @@ -#include "generator/intermediate_elements.hpp" #include "generator/restrictions.hpp" +#include "base/assert.hpp" #include "base/logging.hpp" #include "base/stl_helpers.hpp" @@ -11,24 +11,8 @@ namespace { -vector const kRestrictionTypesNo = {"no_right_turn", "no_left_turn", "no_u_turn", - "no_straight_on", "no_entry", "no_exit"}; -vector const kRestrictionTypesOnly = {"only_right_turn", "only_left_turn", "only_straight_on"}; - -/// \brief Converts restriction type form string to RestrictionCollector::Type. -/// \returns Fisrt item is a result of conversion. Second item is true -/// if convertion was successful and false otherwise. -pair TagToType(string const & type) -{ - if (find(kRestrictionTypesNo.cbegin(), kRestrictionTypesNo.cend(), type) != kRestrictionTypesNo.cend()) - return make_pair(RestrictionCollector::Type::No, true); - - if (find(kRestrictionTypesOnly.cbegin(), kRestrictionTypesOnly.cend(), type) != kRestrictionTypesOnly.cend()) - return make_pair(RestrictionCollector::Type::Only, true); - - // Unsupported restriction type. - return make_pair(RestrictionCollector::Type::No, false); -} +string const kNoStr = "No"; +string const kOnlyStr = "Only"; } // namespace RestrictionCollector::FeatureId const RestrictionCollector::kInvalidFeatureId = @@ -68,50 +52,7 @@ void RestrictionCollector::AddRestriction(vector const & links, Type ty m_restrictions.emplace_back(type, links.size()); size_t const restrictionCount = m_restrictions.size() - 1; for (size_t i = 0; i < links.size(); ++i) - m_restrictionIndex.push_back(make_pair(links[i], Index({restrictionCount, i}))); -} - -void RestrictionCollector::AddRestriction(RelationElement const & relationElement) -{ - CHECK_EQUAL(relationElement.GetType(), "restriction", ()); - - // Note. For the time being only line-point-line road restriction is supported. - if (relationElement.nodes.size() != 1 || relationElement.ways.size() != 2) - return; // Unsupported restriction. For example line-line-line. - - // Extracting osm ids of lines and points of the restriction. - auto const findTag = [&relationElement](vector> const & members, string const & tag) - { - auto const it = find_if(members.cbegin(), members.cend(), - [&tag](pair const & p) { return p.second == tag; }); - return it; - }; - - auto const fromIt = findTag(relationElement.ways, "from"); - if (fromIt == relationElement.ways.cend()) - return; // No tag |from| in |relationElement.ways|. - - auto const toIt = findTag(relationElement.ways, "to"); - if (toIt == relationElement.ways.cend()) - return; // No tag |to| in |relationElement.ways|. - - if (findTag(relationElement.nodes,"via") == relationElement.nodes.cend()) - return; // No tag |via| in |relationElement.nodes|. - - // Extracting type of restriction. - auto const tagIt = relationElement.tags.find("restriction"); - if (tagIt == relationElement.tags.end()) - return; // Type of the element is different from "restriction". - - auto const typeResult = TagToType(tagIt->second); - if (typeResult.second == false) - return; // Unsupported restriction type. - - // Adding restriction. - Type const type = typeResult.first; - osm::Id const fromOsmId = osm::Id::Way(fromIt->first); - osm::Id const toOsmId = osm::Id::Way(toIt->first); - AddRestriction({fromOsmId, toOsmId}, type); + m_restrictionIndex.emplace_back(links[i], Index({restrictionCount, i})); } void RestrictionCollector::AddFeatureId(vector const & osmIds, FeatureId featureId) @@ -148,7 +89,7 @@ void RestrictionCollector::ComposeRestrictions() Restriction & restriction = m_restrictions[index.m_restrictionNumber]; CHECK_LESS(index.m_linkNumber, restriction.m_links.size(), ()); - osm::Id const osmId = osmIdAndIndex.first; + osm::Id const & osmId = osmIdAndIndex.first; // Checking if there's an osm id belongs to a restriction is saved only once as feature id. auto const rangeId = m_osmIds2FeatureId.equal_range(osmId); if (rangeId.first == rangeId.second) @@ -161,7 +102,7 @@ void RestrictionCollector::ComposeRestrictions() if (distance(rangeId.first, rangeId.second) != 1) continue; // |osmId| mentioned in restrictions was included in more than one feature. - FeatureId const featureId = rangeId.first->second; + FeatureId const & featureId = rangeId.first->second; // Adding feature id to restriction coresponded to the osm id. restriction.m_links[index.m_linkNumber] = featureId; } @@ -203,13 +144,29 @@ string ToString(RestrictionCollector::Type const & type) switch (type) { case RestrictionCollector::Type::No: - return "No"; + return kNoStr; case RestrictionCollector::Type::Only: - return "Only"; + return kOnlyStr; } return "Unknown"; } +bool FromString(string const & str, RestrictionCollector::Type & type) +{ + if (str == kNoStr) + { + type = RestrictionCollector::Type::No; + return true; + } + if (str == kOnlyStr) + { + type = RestrictionCollector::Type::Only; + return true; + } + + return false; +} + string DebugPrint(RestrictionCollector::Type const & type) { return ToString(type); @@ -218,6 +175,6 @@ string DebugPrint(RestrictionCollector::Type const & type) string DebugPrint(RestrictionCollector::Restriction const & restriction) { ostringstream out; - out << "m_links:[" << restriction.m_links << "] m_type:" << DebugPrint(restriction.m_type) << " "; + out << "m_links:[" << DebugPrint(restriction.m_links) << "] m_type:" << DebugPrint(restriction.m_type) << " "; return out.str(); } diff --git a/generator/restrictions.hpp b/generator/restrictions.hpp index bda604d79e..4cd2b3bfb5 100644 --- a/generator/restrictions.hpp +++ b/generator/restrictions.hpp @@ -2,6 +2,7 @@ #include "generator/osm_id.hpp" +#include "std/functional.hpp" #include "std/limits.hpp" #include "std/mutex.hpp" #include "std/unordered_map.hpp" @@ -64,13 +65,6 @@ public: size_t m_linkNumber; // Link number for a restriction. It's equal to zero or one for most cases. }; - /// \brief Coverts |relationElement| to Restriction and adds it to |m_restrictions| and - /// |m_restrictionIndex| if |relationElement| is a restriction. - /// \note For the time being only line-point-line restritions are processed. The other restrictions - /// are ignored. - // @TODO(bykoianko) It's necessary to process all kind of restrictions. - void AddRestriction(RelationElement const & relationElement); - /// \brief Adds feature id and corresponding vector of |osmIds| to |m_osmId2FeatureId|. /// \note One feature id (|featureId|) may correspond to several osm ids (|osmIds|). void AddFeatureId(vector const & osmIds, FeatureId featureId); @@ -112,5 +106,6 @@ private: }; string ToString(RestrictionCollector::Type const & type); +bool FromString(string const & str, RestrictionCollector::Type & type); string DebugPrint(RestrictionCollector::Type const & type); string DebugPrint(RestrictionCollector::Restriction const & restriction); diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp index c6473e467e..0503bb0bf7 100644 --- a/generator/world_map_generator.hpp +++ b/generator/world_map_generator.hpp @@ -13,8 +13,6 @@ #include "defines.hpp" -class RestrictionCollector; - namespace { class WaterBoundaryChecker @@ -316,10 +314,10 @@ class CountryMapGenerator public: explicit CountryMapGenerator(feature::GenerateInfo const & info) : m_bucket(info) {} - void operator()(FeatureBuilder1 fb, RestrictionCollector & restrictions) + void operator()(FeatureBuilder1 fb, SyncOfstream & featureId2osmIds) { if (feature::PreprocessForCountryMap(fb)) - m_bucket(fb, restrictions); + m_bucket(fb, featureId2osmIds); } inline FeatureOutT & Parent() { return m_bucket; }