|
|
@@ -2,6 +2,7 @@ use coord::LatLon;
|
|
2
|
2
|
use osmpbf::{Blob, BlobDecode, BlobReader, PrimitiveBlock};
|
|
3
|
3
|
use regex::Regex;
|
|
4
|
4
|
use scoped_threadpool::Pool;
|
|
|
5
|
+use std::collections::hash_set::HashSet;
|
|
5
|
6
|
use std::path::{Path, PathBuf};
|
|
6
|
7
|
use std::sync::mpsc::sync_channel;
|
|
7
|
8
|
use std::thread;
|
|
|
@@ -60,8 +61,9 @@ where P: AsRef<Path>,
|
|
60
|
61
|
.map_err(|e| format!("{}", e))?;
|
|
61
|
62
|
let re = &re;
|
|
62
|
63
|
|
|
63
|
|
- let search = move |block: &PrimitiveBlock, _: &()| {
|
|
|
64
|
+ let first_pass = move |block: &PrimitiveBlock, _: &()| {
|
|
64
|
65
|
let mut matches = vec![];
|
|
|
66
|
+ let mut way_node_ids = vec![];
|
|
65
|
67
|
|
|
66
|
68
|
for node in block.groups().flat_map(|g| g.nodes()) {
|
|
67
|
69
|
for (_key, val) in node.tags() {
|
|
|
@@ -83,13 +85,59 @@ where P: AsRef<Path>,
|
|
83
|
85
|
}
|
|
84
|
86
|
}
|
|
85
|
87
|
|
|
|
88
|
+ for way in block.groups().flat_map(|g| g.ways()) {
|
|
|
89
|
+ for (_key, val) in way.tags() {
|
|
|
90
|
+ if re.is_match(val) && !way.refs_slice().is_empty() {
|
|
|
91
|
+ //TODO take middle node, not first one
|
|
|
92
|
+ way_node_ids.push(way.refs_slice()[0]);
|
|
|
93
|
+ break;
|
|
|
94
|
+ }
|
|
|
95
|
+ }
|
|
|
96
|
+ }
|
|
|
97
|
+
|
|
|
98
|
+ (matches, way_node_ids)
|
|
|
99
|
+ };
|
|
|
100
|
+
|
|
|
101
|
+ let mut way_node_ids: HashSet<i64> = HashSet::new();
|
|
|
102
|
+
|
|
|
103
|
+ par_iter_blobs(
|
|
|
104
|
+ &pbf_path,
|
|
|
105
|
+ || {},
|
|
|
106
|
+ first_pass,
|
|
|
107
|
+ |(matches, node_ids)| {
|
|
|
108
|
+ way_node_ids.extend(&node_ids);
|
|
|
109
|
+ found_func(matches)
|
|
|
110
|
+ },
|
|
|
111
|
+ )?;
|
|
|
112
|
+
|
|
|
113
|
+ let way_node_ids = &way_node_ids;
|
|
|
114
|
+
|
|
|
115
|
+ let second_pass = move |block: &PrimitiveBlock, _: &()| {
|
|
|
116
|
+ let mut matches = vec![];
|
|
|
117
|
+
|
|
|
118
|
+ for node in block.groups().flat_map(|g| g.nodes()) {
|
|
|
119
|
+ if way_node_ids.contains(&node.id()) {
|
|
|
120
|
+ let pos = LatLon::new(node.lat(), node.lon());
|
|
|
121
|
+ matches.push(pos);
|
|
|
122
|
+ break;
|
|
|
123
|
+ }
|
|
|
124
|
+ }
|
|
|
125
|
+
|
|
|
126
|
+ for node in block.groups().flat_map(|g| g.dense_nodes()) {
|
|
|
127
|
+ if way_node_ids.contains(&node.id) {
|
|
|
128
|
+ let pos = LatLon::new(node.lat(), node.lon());
|
|
|
129
|
+ matches.push(pos);
|
|
|
130
|
+ break;
|
|
|
131
|
+ }
|
|
|
132
|
+ }
|
|
|
133
|
+
|
|
86
|
134
|
matches
|
|
87
|
135
|
};
|
|
88
|
136
|
|
|
89
|
137
|
par_iter_blobs(
|
|
90
|
|
- pbf_path,
|
|
|
138
|
+ &pbf_path,
|
|
91
|
139
|
|| {},
|
|
92
|
|
- search,
|
|
|
140
|
+ second_pass,
|
|
93
|
141
|
found_func,
|
|
94
|
142
|
)
|
|
95
|
143
|
}
|
|
|
@@ -98,12 +146,12 @@ fn par_iter_blobs<P, D, R, IF, CF, RF>(
|
|
98
|
146
|
pbf_path: P,
|
|
99
|
147
|
init_func: IF,
|
|
100
|
148
|
compute_func: CF,
|
|
101
|
|
- result_func: RF,
|
|
|
149
|
+ mut result_func: RF,
|
|
102
|
150
|
) -> Result<(), String>
|
|
103
|
151
|
where P: AsRef<Path>,
|
|
104
|
152
|
IF: Fn() -> D,
|
|
105
|
153
|
CF: Fn(&PrimitiveBlock, &D) -> R + Send + Sync,
|
|
106
|
|
- RF: Fn(R) -> ControlFlow + Send + 'static,
|
|
|
154
|
+ RF: FnMut(R) -> ControlFlow,
|
|
107
|
155
|
R: Send,
|
|
108
|
156
|
D: Send,
|
|
109
|
157
|
{
|