Browse Source

Display ways in path_layer

Johannes Hofmann 7 years ago
parent
commit
5b15ecdbda
3 changed files with 63 additions and 13 deletions
  1. 46
    6
      src/main.rs
  2. 5
    1
      src/query.rs
  3. 12
    6
      src/search.rs

+ 46
- 6
src/main.rs View File

49
 pub mod url_template;
49
 pub mod url_template;
50
 pub mod vertex_attrib;
50
 pub mod vertex_attrib;
51
 
51
 
52
-use coord::ScreenCoord;
52
+use coord::{LatLonDeg, ScreenCoord};
53
 use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
53
 use glutin::dpi::{LogicalPosition, LogicalSize, PhysicalPosition};
54
 use glutin::{ControlFlow, ElementState, Event, GlContext, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent};
54
 use glutin::{ControlFlow, ElementState, Event, GlContext, MouseButton, MouseScrollDelta, VirtualKeyCode, WindowEvent};
55
 use map_view_gl::MapViewGl;
55
 use map_view_gl::MapViewGl;
56
 use path_layer::PathElement;
56
 use path_layer::PathElement;
57
 use search::MatchItem;
57
 use search::MatchItem;
58
-use std::collections::hash_set::HashSet;
58
+use std::collections::{HashMap, HashSet};
59
 use std::error::Error;
59
 use std::error::Error;
60
 use std::sync::mpsc;
60
 use std::sync::mpsc;
61
 use std::time::{Duration, Instant};
61
 use std::time::{Duration, Instant};
90
     dpi_factor: f64,
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
 fn handle_event(
98
 fn handle_event(
94
     event: &Event,
99
     event: &Event,
95
     map: &mut MapViewGl,
100
     map: &mut MapViewGl,
96
     input_state: &mut InputState,
101
     input_state: &mut InputState,
102
+    query_state: &mut QueryState,
97
     sources: &mut TileSources,
103
     sources: &mut TileSources,
98
     marker_rx: &mpsc::Receiver<HashSet<MatchItem>>,
104
     marker_rx: &mpsc::Receiver<HashSet<MatchItem>>,
99
 ) -> Action {
105
 ) -> Action {
100
     trace!("{:?}", event);
106
     trace!("{:?}", event);
101
     match *event {
107
     match *event {
102
         Event::Awakened => {
108
         Event::Awakened => {
109
+            let mut check_ways = false;
103
             for item in marker_rx.try_iter().flat_map(|c| c.into_iter()) {
110
             for item in marker_rx.try_iter().flat_map(|c| c.into_iter()) {
104
                 match item {
111
                 match item {
105
                     MatchItem::Node{pos, ..} => map.add_marker(pos.into()),
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
             Action::Redraw
144
             Action::Redraw
312
         dpi_factor: window.get_hidpi_factor(),
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
     let mut map = {
355
     let mut map = {
316
         let proxy = events_loop.create_proxy();
356
         let proxy = events_loop.create_proxy();
317
 
357
 
370
         let mut action = Action::Nothing;
410
         let mut action = Action::Nothing;
371
 
411
 
372
         events_loop.run_forever(|event| {
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
             action.combine_with(a);
414
             action.combine_with(a);
375
             ControlFlow::Break
415
             ControlFlow::Break
376
         });
416
         });
380
         }
420
         }
381
 
421
 
382
         events_loop.poll_events(|event| {
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
             action.combine_with(a);
424
             action.combine_with(a);
385
             if action == Action::Close {
425
             if action == Action::Close {
386
                 return;
426
                 return;
398
                     std::thread::sleep(dur);
438
                     std::thread::sleep(dur);
399
 
439
 
400
                     events_loop.poll_events(|event| {
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
                         action.combine_with(a);
442
                         action.combine_with(a);
403
                         if action == Action::Close {
443
                         if action == Action::Close {
404
                             return;
444
                             return;

+ 5
- 1
src/query.rs View File

313
 
313
 
314
         for way in block.groups().flat_map(|g| g.ways()) {
314
         for way in block.groups().flat_map(|g| g.ways()) {
315
             if query.way_matches(&block_index, &way) {
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 View File

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