Przeglądaj źródła

Display ways in path_layer

Johannes Hofmann 7 lat temu
rodzic
commit
5b15ecdbda
3 zmienionych plików z 63 dodań i 13 usunięć
  1. 46
    6
      src/main.rs
  2. 5
    1
      src/query.rs
  3. 12
    6
      src/search.rs

+ 46
- 6
src/main.rs Wyświetl plik

@@ -49,13 +49,13 @@ pub mod tile_source;
49 49
 pub mod url_template;
50 50
 pub mod vertex_attrib;
51 51
 
52
-use coord::ScreenCoord;
52
+use coord::{LatLonDeg, ScreenCoord};
53 53
 use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
54 54
 use glutin::{ControlFlow, ElementState, Event, GlContext, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent};
55 55
 use map_view_gl::MapViewGl;
56 56
 use path_layer::PathElement;
57 57
 use search::MatchItem;
58
-use std::collections::hash_set::HashSet;
58
+use std::collections::{HashMap, HashSet};
59 59
 use std::error::Error;
60 60
 use std::sync::mpsc;
61 61
 use std::time::{Duration, Instant};
@@ -90,20 +90,55 @@ struct InputState {
90 90
     dpi_factor: f64,
91 91
 }
92 92
 
93
+struct QueryState {
94
+    way_nodes: HashMap<i64, LatLonDeg>,
95
+    incomplete_ways: Vec<Vec<i64>>,
96
+}
97
+
93 98
 fn handle_event(
94 99
     event: &Event,
95 100
     map: &mut MapViewGl,
96 101
     input_state: &mut InputState,
102
+    query_state: &mut QueryState,
97 103
     sources: &mut TileSources,
98 104
     marker_rx: &mpsc::Receiver<HashSet<MatchItem>>,
99 105
 ) -> Action {
100 106
     trace!("{:?}", event);
101 107
     match *event {
102 108
         Event::Awakened => {
109
+            let mut check_ways = false;
103 110
             for item in marker_rx.try_iter().flat_map(|c| c.into_iter()) {
104 111
                 match item {
105 112
                     MatchItem::Node{pos, ..} => map.add_marker(pos.into()),
106
-                    MatchItem::Way{pos, ..} => map.add_path_element(PathElement::MoveTo(pos.into())),
113
+                    MatchItem::WayNode{id, pos} => {
114
+                        query_state.way_nodes.insert(id, pos);
115
+                        check_ways = true;
116
+                    }
117
+                    MatchItem::Way{nodes, ..} => {
118
+                        query_state.incomplete_ways.push(nodes);
119
+                        check_ways = true;
120
+                    },
121
+                }
122
+            }
123
+            if check_ways {
124
+                let mut complete_ways = vec![];
125
+                'outer: for (way_index, way) in query_state.incomplete_ways.iter().enumerate() {
126
+                    for node_id in way {
127
+                        if !query_state.way_nodes.contains_key(&node_id) {
128
+                            continue 'outer;
129
+                        }
130
+                    }
131
+                    complete_ways.push(way_index);
132
+                    // all nodes present
133
+                    if !way.is_empty() {
134
+                        map.add_path_element(PathElement::MoveTo((*query_state.way_nodes.get(&way[0]).unwrap()).into()));
135
+                        for node_id in way.iter().skip(1) {
136
+                            map.add_path_element(PathElement::LineTo((*query_state.way_nodes.get(node_id).unwrap()).into()));
137
+                        }
138
+                    }
139
+                }
140
+                for way_index in complete_ways.into_iter().rev() {
141
+                    query_state.incomplete_ways.swap_remove(way_index);
107 142
                 }
108 143
             }
109 144
             Action::Redraw
@@ -312,6 +347,11 @@ fn run() -> Result<(), Box<Error>> {
312 347
         dpi_factor: window.get_hidpi_factor(),
313 348
     };
314 349
 
350
+    let mut query_state = QueryState {
351
+        way_nodes: HashMap::new(),
352
+        incomplete_ways: vec![],
353
+    };
354
+
315 355
     let mut map = {
316 356
         let proxy = events_loop.create_proxy();
317 357
 
@@ -370,7 +410,7 @@ fn run() -> Result<(), Box<Error>> {
370 410
         let mut action = Action::Nothing;
371 411
 
372 412
         events_loop.run_forever(|event| {
373
-            let a = handle_event(&event, &mut map, &mut input_state, &mut sources, &marker_rx);
413
+            let a = handle_event(&event, &mut map, &mut input_state, &mut query_state, &mut sources, &marker_rx);
374 414
             action.combine_with(a);
375 415
             ControlFlow::Break
376 416
         });
@@ -380,7 +420,7 @@ fn run() -> Result<(), Box<Error>> {
380 420
         }
381 421
 
382 422
         events_loop.poll_events(|event| {
383
-            let a = handle_event(&event, &mut map, &mut input_state, &mut sources, &marker_rx);
423
+            let a = handle_event(&event, &mut map, &mut input_state, &mut query_state, &mut sources, &marker_rx);
384 424
             action.combine_with(a);
385 425
             if action == Action::Close {
386 426
                 return;
@@ -398,7 +438,7 @@ fn run() -> Result<(), Box<Error>> {
398 438
                     std::thread::sleep(dur);
399 439
 
400 440
                     events_loop.poll_events(|event| {
401
-                        let a = handle_event(&event, &mut map, &mut input_state, &mut sources, &marker_rx);
441
+                        let a = handle_event(&event, &mut map, &mut input_state, &mut query_state, &mut sources, &marker_rx);
402 442
                         action.combine_with(a);
403 443
                         if action == Action::Close {
404 444
                             return;

+ 5
- 1
src/query.rs Wyświetl plik

@@ -313,7 +313,11 @@ pub fn find_query_matches<Q: Query>(
313 313
 
314 314
         for way in block.groups().flat_map(|g| g.ways()) {
315 315
             if query.way_matches(&block_index, &way) {
316
-                way_node_ids.insert(way.refs_slice()[0]);
316
+                way_node_ids.extend(way.refs());
317
+                matches.insert(MatchItem::Way{
318
+                    id: way.id(),
319
+                    nodes: way.refs().collect(),
320
+                });
317 321
             }
318 322
         }
319 323
     }

+ 12
- 6
src/search.rs Wyświetl plik

@@ -30,10 +30,11 @@ enum WorkerMessage {
30 30
     DoBlob(Box<Blob>),
31 31
 }
32 32
 
33
-#[derive(Clone, Copy, Debug)]
33
+#[derive(Clone, Debug)]
34 34
 pub enum MatchItem {
35 35
     Node{id: i64, pos: LatLonDeg},
36
-    Way{id: i64, pos: LatLonDeg},
36
+    Way{id: i64, nodes: Vec<i64>},
37
+    WayNode{id: i64, pos: LatLonDeg},
37 38
 }
38 39
 
39 40
 impl Hash for MatchItem {
@@ -43,19 +44,24 @@ impl Hash for MatchItem {
43 44
                 1u64.hash(state);
44 45
                 id.hash(state);
45 46
             },
46
-            MatchItem::Way{id, pos: _} => {
47
+            MatchItem::Way{id, nodes: _} => {
47 48
                 2u64.hash(state);
48 49
                 id.hash(state);
49 50
             },
51
+            MatchItem::WayNode{id, pos: _} => {
52
+                3u64.hash(state);
53
+                id.hash(state);
54
+            },
50 55
         }
51 56
     }
52 57
 }
53 58
 
54 59
 impl PartialEq for MatchItem {
55 60
     fn eq(&self, other: &MatchItem) -> bool {
56
-        match (*self, *other) {
61
+        match (self, other) {
57 62
             (MatchItem::Node{id: a, ..}, MatchItem::Node{id: b, ..}) => a == b,
58 63
             (MatchItem::Way{id: a, ..}, MatchItem::Way{id: b, ..}) => a == b,
64
+            (MatchItem::WayNode{id: a, ..}, MatchItem::WayNode{id: b, ..}) => a == b,
59 65
             _ => false,
60 66
         }
61 67
     }
@@ -153,7 +159,7 @@ where P: AsRef<Path>,
153 159
 
154 160
         for node in block.groups().flat_map(|g| g.nodes()) {
155 161
             if way_node_ids.contains(&node.id()) {
156
-                matches.insert(MatchItem::Way{
162
+                matches.insert(MatchItem::WayNode{
157 163
                     id: node.id(),
158 164
                     pos: LatLonDeg::new(node.lat(), node.lon()),
159 165
                 });
@@ -162,7 +168,7 @@ where P: AsRef<Path>,
162 168
 
163 169
         for node in block.groups().flat_map(|g| g.dense_nodes()) {
164 170
             if way_node_ids.contains(&node.id) {
165
-                matches.insert(MatchItem::Way{
171
+                matches.insert(MatchItem::WayNode{
166 172
                     id: node.id,
167 173
                     pos: LatLonDeg::new(node.lat(), node.lon()),
168 174
                 });