浏览代码

Document map_view.rs

Johannes Hofmann 7 年前
父节点
当前提交
980ce573f1
共有 2 个文件被更改,包括 59 次插入27 次删除
  1. 53
    14
      src/map_view.rs
  2. 6
    13
      src/map_view_gl.rs

+ 53
- 14
src/map_view.rs 查看文件

@@ -1,16 +1,26 @@
1 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 5
 #[derive(Clone, Debug)]
5 6
 pub struct MapView {
7
+    /// Width of the viewport.
6 8
     pub width: f64,
9
+    /// Height of the viewport.
7 10
     pub height: f64,
11
+    /// Size of each square tile in the same unit as the viewport dimensions (usually pixels).
8 12
     pub tile_size: u32,
13
+    /// The `MapCoord` that corresponds to the center of the viewport.
9 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 20
     pub tile_zoom_offset: f64,
12 21
 }
13 22
 
23
+/// The position and size of a specific tile on the screen.
14 24
 #[derive(Clone, Debug)]
15 25
 pub struct VisibleTile {
16 26
     pub tile: TileCoord,
@@ -18,19 +28,36 @@ pub struct VisibleTile {
18 28
 }
19 29
 
20 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 48
         MapView {
23 49
             width: width,
24 50
             height: height,
25 51
             tile_size: tile_size,
26 52
             center: MapCoord::new(0.5, 0.5),
27
-            zoom2: 0.0,
53
+            zoom: zoom,
28 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 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 62
         let x = self.center.x + -0.5 * self.width * scale;
36 63
         let y = self.center.y + -0.5 * self.height * scale;
@@ -38,8 +65,9 @@ impl MapView {
38 65
         MapCoord::new(x, y)
39 66
     }
40 67
 
68
+    /// Returns the screen coordinate that corresponds to the given map coordinate.
41 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 72
         let delta_x = map_coord.x - self.center.x;
45 73
         let delta_y = map_coord.y - self.center.y;
@@ -50,15 +78,17 @@ impl MapView {
50 78
         }
51 79
     }
52 80
 
81
+    /// Returns the screen coordinate of the top-left corner of a tile.
53 82
     pub fn tile_screen_position(&self, tile: &TileCoord) -> ScreenCoord {
54 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 87
     pub fn visible_tiles(&self, snap_to_pixel: bool) -> Vec<VisibleTile> {
58 88
         let uzoom = self.tile_zoom();
59 89
         let top_left_tile = self.top_left_coord().on_tile_at_zoom(uzoom);
60 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 93
         if snap_to_pixel {
64 94
             top_left_tile_screen_coord.snap_to_pixel();
@@ -93,57 +123,66 @@ impl MapView {
93 123
         visible_tiles
94 124
     }
95 125
 
126
+    /// Returns the tile zoom value that is used for rendering with the current zoom.
96 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 132
     pub fn tile_zoom_offset(&self) -> f64 {
101 133
         self.tile_zoom_offset
102 134
     }
103 135
 
136
+    /// Set the tile zoom offset.
104 137
     pub fn set_tile_zoom_offset(&mut self, offset: f64) {
105 138
         self.tile_zoom_offset = offset;
106 139
     }
107 140
 
141
+    /// Set the viewport size.
108 142
     pub fn set_size(&mut self, width: f64, height: f64) {
109 143
         self.width = width;
110 144
         self.height = height;
111 145
     }
112 146
 
147
+    /// Set the zoom value.
113 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 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 158
     pub fn zoom_at(&mut self, pos: ScreenCoord, zoom_delta: f64) {
122 159
         let delta_x = pos.x - self.width * 0.5;
123 160
         let delta_y = pos.y - self.height * 0.5;
124 161
 
125 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 164
             / f64::from(self.tile_size);
128
-        self.zoom2 += zoom_delta;
165
+        self.zoom += zoom_delta;
129 166
 
130 167
         self.center.x += delta_x * scale;
131 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 172
     pub fn set_zoom_at(&mut self, pos: ScreenCoord, zoom: f64) {
135 173
         let delta_x = pos.x - self.width * 0.5;
136 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 179
         self.center.x += delta_x * scale;
142 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 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 186
         self.center.x += delta_x * scale;
148 187
         self.center.y += delta_y * scale;
149 188
     }

+ 6
- 13
src/map_view_gl.rs 查看文件

@@ -70,14 +70,7 @@ impl<'a> MapViewGl<'a> {
70 70
 
71 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 75
         MapViewGl {
83 76
             cx: cx,
@@ -209,7 +202,7 @@ impl<'a> MapViewGl<'a> {
209 202
 
210 203
     pub fn step_zoom(&mut self, steps: i32, step_size: f64) {
211 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 206
             if steps > 0 {
214 207
                 z.ceil() * step_size
215 208
             } else {
@@ -221,9 +214,9 @@ impl<'a> MapViewGl<'a> {
221 214
     }
222 215
 
223 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 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 220
             self.map_view.set_zoom(22.0);
228 221
         } else {
229 222
             self.map_view.zoom(zoom_delta);
@@ -231,9 +224,9 @@ impl<'a> MapViewGl<'a> {
231 224
     }
232 225
 
233 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 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 230
             self.map_view.set_zoom_at(pos, 22.0);
238 231
         } else {
239 232
             self.map_view.zoom_at(pos, zoom_delta);