Johannes Hofmann преди 7 години
родител
ревизия
b12e7885ed
променени са 2 файла, в които са добавени 56 реда и са изтрити 31 реда
  1. 9
    31
      src/main.rs
  2. 47
    0
      src/search.rs

+ 9
- 31
src/main.rs Целия файл

@@ -24,6 +24,7 @@ pub mod coord;
24 24
 pub mod map_view;
25 25
 pub mod map_view_gl;
26 26
 pub mod program;
27
+pub mod search;
27 28
 pub mod texture;
28 29
 pub mod tile;
29 30
 pub mod tile_atlas;
@@ -36,11 +37,8 @@ pub mod vertex_attrib;
36 37
 use coord::ScreenCoord;
37 38
 use glutin::{ControlFlow, ElementState, Event, GlContext, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent};
38 39
 use map_view_gl::MapViewGl;
39
-use regex::Regex;
40 40
 use std::error::Error;
41
-use std::path::PathBuf;
42 41
 use std::sync::mpsc;
43
-use std::thread;
44 42
 use std::time::{Duration, Instant};
45 43
 use tile_source::TileSource;
46 44
 
@@ -245,36 +243,16 @@ fn run() -> Result<(), Box<Error>> {
245 243
 
246 244
     let (marker_tx, marker_rx) = mpsc::channel();
247 245
     if let (Some(path), Some(pattern)) = (config.pbf_path(), config.search_pattern()) {
248
-        let pathbuf = PathBuf::from(path);
249
-        let re = Regex::new(pattern).unwrap();
250 246
         let proxy = events_loop.create_proxy();
251 247
 
252
-        thread::spawn(move|| {
253
-            let reader = osmpbf::ElementReader::from_path(&pathbuf).unwrap();
254
-
255
-            // Increment the counter by one for each way.
256
-            reader.for_each(|element| {
257
-                match element {
258
-                    osmpbf::Element::Node(node) => {
259
-                        for (_key, val) in node.tags() {
260
-                            if re.is_match(val) {
261
-                                marker_tx.send((node.lat(), node.lon())).unwrap();
262
-                                proxy.wakeup().unwrap();
263
-                            }
264
-                        }
265
-                    },
266
-                    osmpbf::Element::DenseNode(dnode) => {
267
-                        for (_key, val) in dnode.tags() {
268
-                            if re.is_match(val) {
269
-                                marker_tx.send((dnode.lat(), dnode.lon())).unwrap();
270
-                                proxy.wakeup().unwrap();
271
-                            }
272
-                        }
273
-                    },
274
-                    _ => {},
275
-                }
276
-            }).unwrap();
277
-        });
248
+        search::search_pbf(
249
+            path,
250
+            pattern,
251
+            move |lat, lon| {
252
+                marker_tx.send((lat, lon)).unwrap();
253
+                proxy.wakeup().unwrap();
254
+            },
255
+        )?;
278 256
     }
279 257
 
280 258
     let duration_per_frame = Duration::from_millis((1000.0 / config.fps() - 0.5).max(0.0).floor() as u64);

+ 47
- 0
src/search.rs Целия файл

@@ -0,0 +1,47 @@
1
+use regex::Regex;
2
+use std::path::{Path, PathBuf};
3
+use std::thread;
4
+use osmpbf::{Element, ElementReader};
5
+
6
+
7
+pub fn search_pbf<P, F>(
8
+    pbf_path: P,
9
+    search_pattern: &str,
10
+    update_func: F,
11
+) -> Result<thread::JoinHandle<()>, String>
12
+where P: AsRef<Path>,
13
+      F: Fn(f64, f64) + Send + 'static,
14
+{
15
+    let pathbuf = PathBuf::from(pbf_path.as_ref());
16
+    let re = Regex::new(search_pattern)
17
+        .map_err(|e| format!("{}", e))?;
18
+    let reader = ElementReader::from_path(&pathbuf)
19
+        .map_err(|e| format!("Failed to read PBF file {:?}: {}", pbf_path.as_ref(), e))?;
20
+
21
+    let handle = thread::spawn(move|| {
22
+        //TODO do something about the unwrap()
23
+        reader.for_each(|element| {
24
+            match element {
25
+                Element::Node(node) => {
26
+                    for (_key, val) in node.tags() {
27
+                        if re.is_match(val) {
28
+                            update_func(node.lat(), node.lon());
29
+                            break;
30
+                        }
31
+                    }
32
+                },
33
+                Element::DenseNode(dnode) => {
34
+                    for (_key, val) in dnode.tags() {
35
+                        if re.is_match(val) {
36
+                            update_func(dnode.lat(), dnode.lon());
37
+                            break;
38
+                        }
39
+                    }
40
+                },
41
+                _ => {},
42
+            }
43
+        }).unwrap();
44
+    });
45
+
46
+    Ok(handle)
47
+}