forked from organicmaps/organicmaps
Saving restrictions in osm id term and mapping feature id to osm ids to separate files.
This commit is contained in:
parent
1e1ec10912
commit
d53fc617be
10 changed files with 221 additions and 120 deletions
|
@ -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 \
|
||||
|
|
|
@ -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 <class TNodesHolder, cache::EMode TMode>
|
||||
|
@ -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<mutex> gard(m_mutex);
|
||||
m_stream.open(fullPath, std::ofstream::out);
|
||||
}
|
||||
|
||||
bool SyncOfstream::IsOpened()
|
||||
{
|
||||
lock_guard<mutex> gard(m_mutex);
|
||||
return m_stream.is_open() && !m_stream.fail();
|
||||
}
|
||||
|
||||
void SyncOfstream::Write(uint32_t featureId, vector<osm::Id> const & osmIds)
|
||||
{
|
||||
if (!IsOpened())
|
||||
return;
|
||||
|
||||
lock_guard<mutex> gard(m_mutex);
|
||||
m_stream << featureId << ", ";
|
||||
for (osm::Id const & osmId : osmIds)
|
||||
m_stream << osmId.OsmId() << ", ";
|
||||
m_stream << endl;
|
||||
}
|
||||
|
||||
unique_ptr<EmitterBase> 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<EmitterBase, TDataCache> 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)
|
||||
|
|
|
@ -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<string> & 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<osm::Id> const & osmIds);
|
||||
};
|
||||
|
||||
unique_ptr<EmitterBase> MakeMainFeatureEmitter(feature::GenerateInfo const & info);
|
||||
|
|
|
@ -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<uint64_t, RelationElement> 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<FileWriter> 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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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 <QtCore/QMutexLocker>
|
||||
#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<borders::CountryPolygons const *, 32> 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<string> const & Names() const
|
||||
|
@ -194,8 +192,8 @@ namespace feature
|
|||
public:
|
||||
PolygonizerTask(Polygonizer * pPolygonizer,
|
||||
buffer_vector<borders::CountryPolygons const *, 32> 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<borders::CountryPolygons const *, 32> m_Countries;
|
||||
FeatureBuilder1 m_FB;
|
||||
RestrictionCollector & m_restrictions;
|
||||
SyncOfstream & m_featureId2osmIds;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
92
generator/restriction_dumper.cpp
Normal file
92
generator/restriction_dumper.cpp
Normal file
|
@ -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<string> const kRestrictionTypesNo = {"no_right_turn", "no_left_turn", "no_u_turn",
|
||||
"no_straight_on", "no_entry", "no_exit"};
|
||||
vector<string> 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<RestrictionCollector::Type, bool> 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<pair<uint64_t, string>> const & members, string const & tag)
|
||||
{
|
||||
auto const it = find_if(members.cbegin(), members.cend(),
|
||||
[&tag](pair<uint64_t, string> 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;
|
||||
}
|
21
generator/restriction_dumper.hpp
Normal file
21
generator/restriction_dumper.hpp
Normal file
|
@ -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);
|
||||
};
|
|
@ -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<string> const kRestrictionTypesNo = {"no_right_turn", "no_left_turn", "no_u_turn",
|
||||
"no_straight_on", "no_entry", "no_exit"};
|
||||
vector<string> 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<RestrictionCollector::Type, bool> 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<osm::Id> 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<pair<uint64_t, string>> const & members, string const & tag)
|
||||
{
|
||||
auto const it = find_if(members.cbegin(), members.cend(),
|
||||
[&tag](pair<uint64_t, string> 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<osm::Id> 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();
|
||||
}
|
||||
|
|
|
@ -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<osm::Id> 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);
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Add table
Reference in a new issue