-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaddressextract.cpp
134 lines (104 loc) · 4.52 KB
/
addressextract.cpp
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <cstdlib> // for std::exit
#include <cstring> // for std::strcmp
#include <iostream> // for std::cout, std::cerr
// For assembling multipolygons
#include <osmium/area/assembler.hpp>
#include <osmium/area/multipolygon_manager.hpp>
// For the DynamicHandler class
#include <osmium/dynamic_handler.hpp>
// For the Dump handler
#include <osmium/handler/dump.hpp>
// For the NodeLocationForWays handler
#include <osmium/handler/node_locations_for_ways.hpp>
// Allow any format of input files (XML, PBF, ...)
#include <osmium/io/any_input.hpp>
// For the location index. There are different types of indexes available.
// This will work for all input files keeping the index in memory.
#include <osmium/index/map/flex_mem.hpp>
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include "Building.hpp"
#include "Boundary.hpp"
#include "PostCode.hpp"
#include "AreaIndex.hpp"
#include "AddressHandler.hpp"
// The type of index used. This must match the include file above
using index_type = osmium::index::map::FlexMem<osmium::unsigned_object_id_type, osmium::Location>;
// The location handler always depends on the index type
using location_handler_type = osmium::handler::NodeLocationsForWays<index_type>;
#define DEBUG 0
namespace po = boost::program_options;
int main(int argc, char* argv[]) {
bool t_errors=false;
bool t_missing=false;
bool t_nocache=false;
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("errors,e", po::bool_switch(&t_errors), "Do error analysis")
("missing,m", po::bool_switch(&t_missing), "Only add missing postcode and city")
("nocache", po::bool_switch(&t_nocache), "Do not use boundary caching")
("postcoderegex", po::value<std::string>()->default_value("^[0-9]{5}$"), "Postcode validation regex")
("infile,i", po::value<std::string>()->required(), "Input file")
;
po::variables_map vm;
try {
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
} catch(const boost::program_options::error& e) {
std::cerr << "Error: " << e.what() << "\n";
std::cout << desc << std::endl;
exit(-1);
}
if (vm.count("help")) {
std::cout << desc << "\n";
return 1;
}
osmium::io::File input_file{vm["infile"].as<std::string>()};
osmium::area::Assembler::config_type assembler_config;
AreaIndex<Building> buildingindex;
osmium::TagsFilter buildingfilter{false};
buildingfilter.add_rule(true, osmium::TagMatcher{"building"});
osmium::area::MultipolygonManager<osmium::area::Assembler> buildingmp_manager{assembler_config, buildingfilter};
AreaIndex<Boundary> boundaryindex;
osmium::TagsFilter boundaryfilter{false};
boundaryfilter.add_rule(true, "boundary", "administrative");
osmium::area::MultipolygonManager<osmium::area::Assembler> boundarymp_manager{assembler_config, boundaryfilter};
AreaIndex<PostCode> postcodeindex;
osmium::TagsFilter postcodefilter{false};
postcodefilter.add_rule(true, osmium::TagMatcher{"boundary", "postal_code"});
osmium::area::MultipolygonManager<osmium::area::Assembler> postcodemp_manager{assembler_config, postcodefilter};
// We read the input file twice. In the first pass, only relations are
// read and fed into the multipolygon manager.
std::cerr << "Reading relations for boundarys, postcodes and buildings" << std::endl;
osmium::relations::read_relations(input_file, boundarymp_manager, postcodemp_manager, buildingmp_manager);
index_type index;
location_handler_type location_handler{index};
location_handler.ignore_errors();
std::cerr << "Building geometry indexes for boundarys, postcodes and buildings" << std::endl;
osmium::io::Reader reader{input_file};
osmium::io::Header header{reader.header()};
std::cerr << "Timestamp " << header.get("timestamp") << std::endl;
osmium::apply(reader,
location_handler,
boundarymp_manager.handler([&boundaryindex](osmium::memory::Buffer&& buffer) {
osmium::apply(buffer, boundaryindex);
}),
postcodemp_manager.handler([&postcodeindex](osmium::memory::Buffer&& buffer) {
osmium::apply(buffer, postcodeindex);
}),
buildingmp_manager.handler([&buildingindex](osmium::memory::Buffer&& buffer) {
osmium::apply(buffer, buildingindex);
})
);
reader.close();
std::cerr << "Looking for addresses" << std::endl;
AddressHandler ahandler{boundaryindex, postcodeindex, buildingindex,
t_errors, t_missing, t_nocache, header.get("timestamp"), vm["postcoderegex"].as<std::string>()};
osmium::io::Reader readerpass3{input_file};
osmium::apply(readerpass3,
location_handler,
ahandler);
readerpass3.close();
ahandler.dump();
}