|
|
@@ -1,16 +1,32 @@
|
|
|
1
|
+use osmpbf::{Element, ElementReader};
|
|
1
|
2
|
use regex::Regex;
|
|
2
|
3
|
use std::path::{Path, PathBuf};
|
|
3
|
4
|
use std::thread;
|
|
4
|
|
-use osmpbf::{Element, ElementReader};
|
|
5
|
5
|
|
|
|
6
|
+#[derive(Debug, Eq, PartialEq)]
|
|
|
7
|
+pub enum ControlFlow {
|
|
|
8
|
+ Continue,
|
|
|
9
|
+ Break,
|
|
|
10
|
+}
|
|
|
11
|
+
|
|
|
12
|
+impl<T, E> From<Result<T, E>> for ControlFlow
|
|
|
13
|
+{
|
|
|
14
|
+ fn from(result: Result<T, E>) -> Self {
|
|
|
15
|
+ match result {
|
|
|
16
|
+ Ok(_) => ControlFlow::Continue,
|
|
|
17
|
+ Err(_) => ControlFlow::Break,
|
|
|
18
|
+ }
|
|
|
19
|
+ }
|
|
|
20
|
+}
|
|
6
|
21
|
|
|
|
22
|
+//TODO Add callbacks for other events: search finished, on error, ...
|
|
7
|
23
|
pub fn search_pbf<P, F>(
|
|
8
|
24
|
pbf_path: P,
|
|
9
|
25
|
search_pattern: &str,
|
|
10
|
26
|
update_func: F,
|
|
11
|
27
|
) -> Result<thread::JoinHandle<()>, String>
|
|
12
|
28
|
where P: AsRef<Path>,
|
|
13
|
|
- F: Fn(f64, f64) + Send + 'static,
|
|
|
29
|
+ F: Fn(f64, f64) -> ControlFlow + Send + 'static,
|
|
14
|
30
|
{
|
|
15
|
31
|
let pathbuf = PathBuf::from(pbf_path.as_ref());
|
|
16
|
32
|
let re = Regex::new(search_pattern)
|
|
|
@@ -19,13 +35,14 @@ where P: AsRef<Path>,
|
|
19
|
35
|
.map_err(|e| format!("Failed to read PBF file {:?}: {}", pbf_path.as_ref(), e))?;
|
|
20
|
36
|
|
|
21
|
37
|
let handle = thread::spawn(move|| {
|
|
22
|
|
- //TODO do something about the unwrap()
|
|
23
|
38
|
reader.for_each(|element| {
|
|
24
|
39
|
match element {
|
|
25
|
40
|
Element::Node(node) => {
|
|
26
|
41
|
for (_key, val) in node.tags() {
|
|
27
|
42
|
if re.is_match(val) {
|
|
28
|
|
- update_func(node.lat(), node.lon());
|
|
|
43
|
+ if update_func(node.lat(), node.lon()) == ControlFlow::Break {
|
|
|
44
|
+ return;
|
|
|
45
|
+ }
|
|
29
|
46
|
break;
|
|
30
|
47
|
}
|
|
31
|
48
|
}
|
|
|
@@ -33,7 +50,9 @@ where P: AsRef<Path>,
|
|
33
|
50
|
Element::DenseNode(dnode) => {
|
|
34
|
51
|
for (_key, val) in dnode.tags() {
|
|
35
|
52
|
if re.is_match(val) {
|
|
36
|
|
- update_func(dnode.lat(), dnode.lon());
|
|
|
53
|
+ if update_func(dnode.lat(), dnode.lon()) == ControlFlow::Break {
|
|
|
54
|
+ return;
|
|
|
55
|
+ }
|
|
37
|
56
|
break;
|
|
38
|
57
|
}
|
|
39
|
58
|
}
|