blob: 424022103672959895be62fc01d4caa84bae322f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
#include "generator/holes.hpp"
#include "generator/intermediate_data.hpp"
#include "generator/osm_element.hpp"
#include <utility>
namespace generator
{
HolesAccumulator::HolesAccumulator(cache::IntermediateDataReader & holder) :
m_merger(holder)
{
}
FeatureBuilder1::Geometry & HolesAccumulator::GetHoles()
{
ASSERT(m_holes.empty(), ("It is allowed to call only once."));
m_merger.ForEachArea(false, [this](FeatureBuilder1::PointSeq const & v,
std::vector<uint64_t> const & /* way osm ids */)
{
m_holes.push_back(std::move(v));
});
return m_holes;
}
HolesProcessor::HolesProcessor(uint64_t id, cache::IntermediateDataReader & holder) :
m_id(id),
m_holes(holder)
{
}
base::ControlFlow HolesProcessor::operator() (uint64_t /* id */, RelationElement const & e)
{
std::string const type = e.GetType();
if (!(type == "multipolygon" || type == "boundary"))
return base::ControlFlow::Continue;
std::string role;
if (e.FindWay(m_id, role) && role == "outer")
{
e.ForEachWay(*this);
// Stop processing. Assume that "outer way" exists in one relation only.
return base::ControlFlow::Break;
}
return base::ControlFlow::Continue;
}
void HolesProcessor::operator() (uint64_t id, std::string const & role)
{
if (id != m_id && role == "inner")
m_holes(id);
}
HolesRelation::HolesRelation(cache::IntermediateDataReader & holder) :
m_holes(holder),
m_outer(holder)
{
}
void HolesRelation::Build(OsmElement const * p)
{
// Iterate ways to get 'outer' and 'inner' geometries.
for (auto const & e : p->Members())
{
if (e.type != OsmElement::EntityType::Way)
continue;
if (e.role == "outer")
m_outer.AddWay(e.ref);
else if (e.role == "inner")
m_holes(e.ref);
}
}
} // namespace generator
|