Browse Source

Document map_view.rs

Johannes Hofmann 7 years ago
parent
commit
980ce573f1
2 changed files with 59 additions and 27 deletions
  1. 53
    14
      src/map_view.rs
  2. 6
    13
      src/map_view_gl.rs

+ 53
- 14
src/map_view.rs View File

1
 use coord::{MapCoord, ScreenCoord, ScreenRect, TileCoord};
1
 use coord::{MapCoord, ScreenCoord, ScreenRect, TileCoord};
2
 
2
 
3
 
3
 
4
+/// A view of a tiled map with a rectangular viewport and a zoom.
4
 #[derive(Clone, Debug)]
5
 #[derive(Clone, Debug)]
5
 pub struct MapView {
6
 pub struct MapView {
7
+    /// Width of the viewport.
6
     pub width: f64,
8
     pub width: f64,
9
+    /// Height of the viewport.
7
     pub height: f64,
10
     pub height: f64,
11
+    /// Size of each square tile in the same unit as the viewport dimensions (usually pixels).
8
     pub tile_size: u32,
12
     pub tile_size: u32,
13
+    /// The `MapCoord` that corresponds to the center of the viewport.
9
     pub center: MapCoord,
14
     pub center: MapCoord,
10
-    pub zoom2: f64,
15
+    /// The zoom value. The zoom factor is given by 2.0.powf(zoom);
16
+    pub zoom: f64,
17
+    /// Tiles only exist for integer zoom values. The tile zoom value that is used for rendering
18
+    /// is computed by the `tile_zoom` method. Increasing `tile_zoom_offset` increases the number
19
+    /// of visible tiles for a given zoom value.
11
     pub tile_zoom_offset: f64,
20
     pub tile_zoom_offset: f64,
12
 }
21
 }
13
 
22
 
23
+/// The position and size of a specific tile on the screen.
14
 #[derive(Clone, Debug)]
24
 #[derive(Clone, Debug)]
15
 pub struct VisibleTile {
25
 pub struct VisibleTile {
16
     pub tile: TileCoord,
26
     pub tile: TileCoord,
18
 }
28
 }
19
 
29
 
20
 impl MapView {
30
 impl MapView {
21
-    pub fn new(width: f64, height: f64, tile_size: u32) -> MapView {
31
+    /// Constructs a new `MapView`.
32
+    pub fn new(width: f64, height: f64, tile_size: u32, center: MapCoord, zoom: f64) -> MapView {
33
+        MapView {
34
+            width: width,
35
+            height: height,
36
+            tile_size: tile_size,
37
+            center: center,
38
+            zoom: zoom,
39
+            tile_zoom_offset: 0.0,
40
+        }
41
+    }
42
+
43
+    /// Constructs a new `MapView` centered at Null Island with an integer zoom that fills a screen
44
+    /// with the given dimensions.
45
+    pub fn with_filling_zoom(width: f64, height: f64, tile_size: u32) -> MapView {
46
+        let min_dimension = width.min(height);
47
+        let zoom = (min_dimension / f64::from(tile_size)).log2().ceil();
22
         MapView {
48
         MapView {
23
             width: width,
49
             width: width,
24
             height: height,
50
             height: height,
25
             tile_size: tile_size,
51
             tile_size: tile_size,
26
             center: MapCoord::new(0.5, 0.5),
52
             center: MapCoord::new(0.5, 0.5),
27
-            zoom2: 0.0,
53
+            zoom: zoom,
28
             tile_zoom_offset: 0.0,
54
             tile_zoom_offset: 0.0,
29
         }
55
         }
30
     }
56
     }
31
 
57
 
58
+    /// Returns the map coordinate that corresponds to the top-left corner of the viewport.
32
     pub fn top_left_coord(&self) -> MapCoord {
59
     pub fn top_left_coord(&self) -> MapCoord {
33
-        let scale = f64::powf(2.0, -self.zoom2) / f64::from(self.tile_size);
60
+        let scale = f64::powf(2.0, -self.zoom) / f64::from(self.tile_size);
34
 
61
 
35
         let x = self.center.x + -0.5 * self.width * scale;
62
         let x = self.center.x + -0.5 * self.width * scale;
36
         let y = self.center.y + -0.5 * self.height * scale;
63
         let y = self.center.y + -0.5 * self.height * scale;
38
         MapCoord::new(x, y)
65
         MapCoord::new(x, y)
39
     }
66
     }
40
 
67
 
68
+    /// Returns the screen coordinate that corresponds to the given map coordinate.
41
     pub fn map_to_screen_coord(&self, map_coord: MapCoord) -> ScreenCoord {
69
     pub fn map_to_screen_coord(&self, map_coord: MapCoord) -> ScreenCoord {
42
-        let scale = f64::powf(2.0, self.zoom2) * f64::from(self.tile_size);
70
+        let scale = f64::powf(2.0, self.zoom) * f64::from(self.tile_size);
43
 
71
 
44
         let delta_x = map_coord.x - self.center.x;
72
         let delta_x = map_coord.x - self.center.x;
45
         let delta_y = map_coord.y - self.center.y;
73
         let delta_y = map_coord.y - self.center.y;
50
         }
78
         }
51
     }
79
     }
52
 
80
 
81
+    /// Returns the screen coordinate of the top-left corner of a tile.
53
     pub fn tile_screen_position(&self, tile: &TileCoord) -> ScreenCoord {
82
     pub fn tile_screen_position(&self, tile: &TileCoord) -> ScreenCoord {
54
         self.map_to_screen_coord(tile.map_coord_north_west())
83
         self.map_to_screen_coord(tile.map_coord_north_west())
55
     }
84
     }
56
 
85
 
86
+    /// Returns a `Vec` of all tiles that are visible in the current viewport.
57
     pub fn visible_tiles(&self, snap_to_pixel: bool) -> Vec<VisibleTile> {
87
     pub fn visible_tiles(&self, snap_to_pixel: bool) -> Vec<VisibleTile> {
58
         let uzoom = self.tile_zoom();
88
         let uzoom = self.tile_zoom();
59
         let top_left_tile = self.top_left_coord().on_tile_at_zoom(uzoom);
89
         let top_left_tile = self.top_left_coord().on_tile_at_zoom(uzoom);
60
         let mut top_left_tile_screen_coord = self.tile_screen_position(&top_left_tile);
90
         let mut top_left_tile_screen_coord = self.tile_screen_position(&top_left_tile);
61
-        let tile_screen_size = f64::powf(2.0, self.zoom2 - f64::from(uzoom)) * f64::from(self.tile_size);
91
+        let tile_screen_size = f64::powf(2.0, self.zoom - f64::from(uzoom)) * f64::from(self.tile_size);
62
 
92
 
63
         if snap_to_pixel {
93
         if snap_to_pixel {
64
             top_left_tile_screen_coord.snap_to_pixel();
94
             top_left_tile_screen_coord.snap_to_pixel();
93
         visible_tiles
123
         visible_tiles
94
     }
124
     }
95
 
125
 
126
+    /// Returns the tile zoom value that is used for rendering with the current zoom.
96
     pub fn tile_zoom(&self) -> u32 {
127
     pub fn tile_zoom(&self) -> u32 {
97
-        (self.zoom2 + self.tile_zoom_offset).floor().max(0.0) as u32
128
+        (self.zoom + self.tile_zoom_offset).floor().max(0.0) as u32
98
     }
129
     }
99
 
130
 
131
+    /// Returns the tile zoom offset.
100
     pub fn tile_zoom_offset(&self) -> f64 {
132
     pub fn tile_zoom_offset(&self) -> f64 {
101
         self.tile_zoom_offset
133
         self.tile_zoom_offset
102
     }
134
     }
103
 
135
 
136
+    /// Set the tile zoom offset.
104
     pub fn set_tile_zoom_offset(&mut self, offset: f64) {
137
     pub fn set_tile_zoom_offset(&mut self, offset: f64) {
105
         self.tile_zoom_offset = offset;
138
         self.tile_zoom_offset = offset;
106
     }
139
     }
107
 
140
 
141
+    /// Set the viewport size.
108
     pub fn set_size(&mut self, width: f64, height: f64) {
142
     pub fn set_size(&mut self, width: f64, height: f64) {
109
         self.width = width;
143
         self.width = width;
110
         self.height = height;
144
         self.height = height;
111
     }
145
     }
112
 
146
 
147
+    /// Set the zoom value.
113
     pub fn set_zoom(&mut self, zoom: f64) {
148
     pub fn set_zoom(&mut self, zoom: f64) {
114
-        self.zoom2 = zoom;
149
+        self.zoom = zoom;
115
     }
150
     }
116
 
151
 
152
+    /// Change zoom value by `zoom_delta`.
117
     pub fn zoom(&mut self, zoom_delta: f64) {
153
     pub fn zoom(&mut self, zoom_delta: f64) {
118
-        self.zoom2 += zoom_delta;
154
+        self.zoom += zoom_delta;
119
     }
155
     }
120
 
156
 
157
+    /// Change zoom value by `zoom_delta` and zoom to a position given in screen coordinates.
121
     pub fn zoom_at(&mut self, pos: ScreenCoord, zoom_delta: f64) {
158
     pub fn zoom_at(&mut self, pos: ScreenCoord, zoom_delta: f64) {
122
         let delta_x = pos.x - self.width * 0.5;
159
         let delta_x = pos.x - self.width * 0.5;
123
         let delta_y = pos.y - self.height * 0.5;
160
         let delta_y = pos.y - self.height * 0.5;
124
 
161
 
125
         let scale =
162
         let scale =
126
-            (f64::powf(2.0, -self.zoom2) - f64::powf(2.0, -self.zoom2 - zoom_delta))
163
+            (f64::powf(2.0, -self.zoom) - f64::powf(2.0, -self.zoom - zoom_delta))
127
             / f64::from(self.tile_size);
164
             / f64::from(self.tile_size);
128
-        self.zoom2 += zoom_delta;
165
+        self.zoom += zoom_delta;
129
 
166
 
130
         self.center.x += delta_x * scale;
167
         self.center.x += delta_x * scale;
131
         self.center.y += delta_y * scale;
168
         self.center.y += delta_y * scale;
132
     }
169
     }
133
 
170
 
171
+    /// Set a zoom value and zoom to a `position` given in screen coordinates.
134
     pub fn set_zoom_at(&mut self, pos: ScreenCoord, zoom: f64) {
172
     pub fn set_zoom_at(&mut self, pos: ScreenCoord, zoom: f64) {
135
         let delta_x = pos.x - self.width * 0.5;
173
         let delta_x = pos.x - self.width * 0.5;
136
         let delta_y = pos.y - self.height * 0.5;
174
         let delta_y = pos.y - self.height * 0.5;
137
 
175
 
138
-        let scale = (f64::powf(2.0, -self.zoom2) - f64::powf(2.0, -zoom)) / f64::from(self.tile_size);
139
-        self.zoom2 = zoom;
176
+        let scale = (f64::powf(2.0, -self.zoom) - f64::powf(2.0, -zoom)) / f64::from(self.tile_size);
177
+        self.zoom = zoom;
140
 
178
 
141
         self.center.x += delta_x * scale;
179
         self.center.x += delta_x * scale;
142
         self.center.y += delta_y * scale;
180
         self.center.y += delta_y * scale;
143
     }
181
     }
144
 
182
 
183
+    /// Move the center of the viewport by (`delta_x`, `delta_y`) in screen coordinates.
145
     pub fn move_pixel(&mut self, delta_x: f64, delta_y: f64) {
184
     pub fn move_pixel(&mut self, delta_x: f64, delta_y: f64) {
146
-        let scale = f64::powf(2.0, -self.zoom2) / f64::from(self.tile_size);
185
+        let scale = f64::powf(2.0, -self.zoom) / f64::from(self.tile_size);
147
         self.center.x += delta_x * scale;
186
         self.center.x += delta_x * scale;
148
         self.center.y += delta_y * scale;
187
         self.center.y += delta_y * scale;
149
     }
188
     }

+ 6
- 13
src/map_view_gl.rs View File

70
 
70
 
71
         program.before_render();
71
         program.before_render();
72
 
72
 
73
-        let mut map_view = MapView::new(f64::from(initial_size.0), f64::from(initial_size.1), tile_size);
74
-
75
-        // set initial zoom
76
-        {
77
-            let min_dimension = f64::from(initial_size.0.min(initial_size.1));
78
-            let zoom = (min_dimension / f64::from(tile_size)).log2().ceil();
79
-            map_view.set_zoom(zoom);
80
-        }
73
+        let map_view = MapView::with_filling_zoom(f64::from(initial_size.0), f64::from(initial_size.1), tile_size);
81
 
74
 
82
         MapViewGl {
75
         MapViewGl {
83
             cx: cx,
76
             cx: cx,
209
 
202
 
210
     pub fn step_zoom(&mut self, steps: i32, step_size: f64) {
203
     pub fn step_zoom(&mut self, steps: i32, step_size: f64) {
211
         let new_zoom = {
204
         let new_zoom = {
212
-            let z = (self.map_view.zoom2 + f64::from(steps) * step_size) / step_size;
205
+            let z = (self.map_view.zoom + f64::from(steps) * step_size) / step_size;
213
             if steps > 0 {
206
             if steps > 0 {
214
                 z.ceil() * step_size
207
                 z.ceil() * step_size
215
             } else {
208
             } else {
221
     }
214
     }
222
 
215
 
223
     pub fn zoom(&mut self, zoom_delta: f64) {
216
     pub fn zoom(&mut self, zoom_delta: f64) {
224
-        if self.map_view.zoom2 + zoom_delta < 0.0 {
217
+        if self.map_view.zoom + zoom_delta < 0.0 {
225
             self.map_view.set_zoom(0.0);
218
             self.map_view.set_zoom(0.0);
226
-        } else if self.map_view.zoom2 + zoom_delta > 22.0 {
219
+        } else if self.map_view.zoom + zoom_delta > 22.0 {
227
             self.map_view.set_zoom(22.0);
220
             self.map_view.set_zoom(22.0);
228
         } else {
221
         } else {
229
             self.map_view.zoom(zoom_delta);
222
             self.map_view.zoom(zoom_delta);
231
     }
224
     }
232
 
225
 
233
     pub fn zoom_at(&mut self, pos: ScreenCoord, zoom_delta: f64) {
226
     pub fn zoom_at(&mut self, pos: ScreenCoord, zoom_delta: f64) {
234
-        if self.map_view.zoom2 + zoom_delta < 0.0 {
227
+        if self.map_view.zoom + zoom_delta < 0.0 {
235
             self.map_view.set_zoom_at(pos, 0.0);
228
             self.map_view.set_zoom_at(pos, 0.0);
236
-        } else if self.map_view.zoom2 + zoom_delta > 22.0 {
229
+        } else if self.map_view.zoom + zoom_delta > 22.0 {
237
             self.map_view.set_zoom_at(pos, 22.0);
230
             self.map_view.set_zoom_at(pos, 22.0);
238
         } else {
231
         } else {
239
             self.map_view.zoom_at(pos, zoom_delta);
232
             self.map_view.zoom_at(pos, zoom_delta);