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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
// This file contains the FilterData and FilterElements classes.
// With the help of them, a mechanism is implemented to skip elements from processing according to
// the rules from the configuration file.
// The configuration file is in json format.
// File example:
// {
// "node": {
// "ids": [
// 1435,
// 436
// ],
// "tags": [
// {
// "place": "city"
// },
// {
// "place": "town",
// "capital": "*"
// }
// ]
// },
// "way": {},
// "relation": {}
// }
// This means that we will skip node element if one of the following is true:
// 1. its id equals 1435
// 2. its id equals 436
// 3. if it contains {place:city} in tags
// 4. if it contains {place:city} and {capital:*} in tags.
// '*' - means any value.
// Record format for way and relation is the same as for node.
// This implementation does not support processing of multiple values
// (https://wiki.openstreetmap.org/wiki/Multiple_values).
#pragma once
#include "generator/filter_interface.hpp"
#include "generator/osm_element.hpp"
#include <cstdint>
#include <functional>
#include <list>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "3party/jansson/myjansson.hpp"
namespace generator
{
// This is a helper class for the FilterElements class.
// It works with identifiers and tags at a low level.
class FilterData
{
public:
using Tags = std::vector<OsmElement::Tag>;
void AddSkippedId(uint64_t id);
void AddSkippedTags(Tags const & tags);
bool NeedSkipWithId(uint64_t id) const;
bool NeedSkipWithTags(Tags const & tags) const;
private:
static bool IsMatch(Tags const & elementTags, Tags const & tags);
std::unordered_set<uint64_t> m_skippedIds;
std::unordered_multimap<std::string, std::reference_wrapper<Tags const>> m_skippedTags;
std::list<Tags> m_rulesStorage;
};
// This is the main class that implements the element skipping mechanism.
class FilterElements : public FilterInterface
{
public:
explicit FilterElements(const std::string & filename);
// FilterInterface overrides:
bool IsAccepted(OsmElement const & element) override;
bool NeedSkip(OsmElement const & element) const;
private:
static bool ParseSection(json_t * json, FilterData & fdata);
static bool ParseIds(json_t * json, FilterData & fdata);
static bool ParseTags(json_t * json, FilterData & fdata);
bool NeedSkip(OsmElement const & element, FilterData const & fdata) const;
bool ParseString(std::string const & str);
FilterData m_nodes;
FilterData m_ways;
FilterData m_relations;
};
} // namespace generator
|