|
|
@@ -59,23 +59,7 @@ impl MapCoord {
|
|
59
|
59
|
|
|
60
|
60
|
}
|
|
61
|
61
|
|
|
62
|
|
-#[test]
|
|
63
|
|
-fn test_normalize() {
|
|
64
|
|
- {
|
|
65
|
|
- let a = MapCoord::new(0.0, 0.0);
|
|
66
|
|
- let mut b = a.clone();
|
|
67
|
|
- assert_eq!(a, b);
|
|
68
|
|
- b.normalize_x();
|
|
69
|
|
- assert_eq!(a, b);
|
|
70
|
|
- }
|
|
71
|
|
- {
|
|
72
|
|
- let mut a = MapCoord::new(1.0, 1.0);
|
|
73
|
|
- let b = MapCoord::new(0.0, 1.0);
|
|
74
|
|
- a.normalize_x();
|
|
75
|
|
- assert_eq!(a, b);
|
|
76
|
|
- }
|
|
77
|
|
-}
|
|
78
|
|
-
|
|
|
62
|
+/// A position on the screen in pixels. Top-left corner is (0.0, 0.0).
|
|
79
|
63
|
#[derive(Copy, Clone, Debug)]
|
|
80
|
64
|
pub struct ScreenCoord {
|
|
81
|
65
|
pub x: f64,
|
|
|
@@ -95,6 +79,7 @@ impl ScreenCoord {
|
|
95
|
79
|
}
|
|
96
|
80
|
}
|
|
97
|
81
|
|
|
|
82
|
+/// A rectangle in screen coordinates.
|
|
98
|
83
|
#[derive(Copy, Clone, Debug)]
|
|
99
|
84
|
pub struct ScreenRect {
|
|
100
|
85
|
pub x: f64,
|
|
|
@@ -117,6 +102,9 @@ impl ScreenRect {
|
|
117
|
102
|
}
|
|
118
|
103
|
}
|
|
119
|
104
|
|
|
|
105
|
+/// A rectangle in texture coordinates.
|
|
|
106
|
+/// Top-left corner is (0.0, 0.0).
|
|
|
107
|
+/// Bottom-right corner is (1.0, 1.0).
|
|
120
|
108
|
#[derive(Copy, Clone, Debug)]
|
|
121
|
109
|
pub struct TextureRect {
|
|
122
|
110
|
pub x1: f64,
|
|
|
@@ -148,6 +136,7 @@ impl TextureRect {
|
|
148
|
136
|
}
|
|
149
|
137
|
}
|
|
150
|
138
|
|
|
|
139
|
+/// A subdivision of a tile. `x` and `y` are in the interval [0, `size` - 1].
|
|
151
|
140
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
152
|
141
|
pub struct SubTileCoord {
|
|
153
|
142
|
pub size: u32,
|
|
|
@@ -165,6 +154,10 @@ impl SubTileCoord {
|
|
165
|
154
|
}
|
|
166
|
155
|
}
|
|
167
|
156
|
|
|
|
157
|
+/// A tile position in a tile pyramid.
|
|
|
158
|
+/// Each zoom level has 2^zoom by 2^zoom tiles.
|
|
|
159
|
+/// `x` and `y` are allowed to be negative or >= 2^zoom but then they will not correspond to a tile
|
|
|
160
|
+/// and `is_on_planet` will return false.
|
|
168
|
161
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
|
169
|
162
|
pub struct TileCoord {
|
|
170
|
163
|
pub zoom: u32,
|
|
|
@@ -287,6 +280,29 @@ impl TileCoord {
|
|
287
|
280
|
//TODO throw error when zoom too big
|
|
288
|
281
|
i32::pow(2, zoom)
|
|
289
|
282
|
}
|
|
|
283
|
+
|
|
|
284
|
+ pub fn to_quadkey(&self) -> Option<String> {
|
|
|
285
|
+ if self.zoom == 0 || self.zoom > 30 || self.x < 0 || self.y < 0 {
|
|
|
286
|
+ return None;
|
|
|
287
|
+ }
|
|
|
288
|
+
|
|
|
289
|
+ let mut quadkey = String::with_capacity(self.zoom as usize);
|
|
|
290
|
+
|
|
|
291
|
+ let len = self.zoom;
|
|
|
292
|
+
|
|
|
293
|
+ for i in (0..len).rev() {
|
|
|
294
|
+ let mask: u32 = 1 << i;
|
|
|
295
|
+
|
|
|
296
|
+ match ((self.x as u32 & mask) != 0, (self.y as u32 & mask) != 0) {
|
|
|
297
|
+ (false, false) => quadkey.push('0'),
|
|
|
298
|
+ (true, false) => quadkey.push('1'),
|
|
|
299
|
+ (false, true) => quadkey.push('2'),
|
|
|
300
|
+ (true, true) => quadkey.push('3'),
|
|
|
301
|
+ }
|
|
|
302
|
+ }
|
|
|
303
|
+
|
|
|
304
|
+ Some(quadkey)
|
|
|
305
|
+ }
|
|
290
|
306
|
}
|
|
291
|
307
|
|
|
292
|
308
|
//TODO include width and height of view rect to determine visibility
|
|
|
@@ -296,3 +312,36 @@ pub struct View {
|
|
296
|
312
|
pub zoom: u32,
|
|
297
|
313
|
pub center: MapCoord,
|
|
298
|
314
|
}
|
|
|
315
|
+
|
|
|
316
|
+#[cfg(test)]
|
|
|
317
|
+mod tests {
|
|
|
318
|
+ use coord::*;
|
|
|
319
|
+
|
|
|
320
|
+ #[test]
|
|
|
321
|
+ fn normalize_mapcoord() {
|
|
|
322
|
+ {
|
|
|
323
|
+ let a = MapCoord::new(0.0, 0.0);
|
|
|
324
|
+ let mut b = a.clone();
|
|
|
325
|
+ assert_eq!(a, b);
|
|
|
326
|
+ b.normalize_x();
|
|
|
327
|
+ assert_eq!(a, b);
|
|
|
328
|
+ }
|
|
|
329
|
+ {
|
|
|
330
|
+ let mut a = MapCoord::new(1.0, 1.0);
|
|
|
331
|
+ let b = MapCoord::new(0.0, 1.0);
|
|
|
332
|
+ a.normalize_x();
|
|
|
333
|
+ assert_eq!(a, b);
|
|
|
334
|
+ }
|
|
|
335
|
+ }
|
|
|
336
|
+
|
|
|
337
|
+ #[test]
|
|
|
338
|
+ fn quadkey() {
|
|
|
339
|
+ assert_eq!(TileCoord::new(0, 0, 0).to_quadkey(), None);
|
|
|
340
|
+ assert_eq!(TileCoord::new(1, 0, 0).to_quadkey(), Some("0".to_string()));
|
|
|
341
|
+ assert_eq!(TileCoord::new(1, 1, 0).to_quadkey(), Some("1".to_string()));
|
|
|
342
|
+ assert_eq!(TileCoord::new(1, 0, 1).to_quadkey(), Some("2".to_string()));
|
|
|
343
|
+ assert_eq!(TileCoord::new(1, 1, 1).to_quadkey(), Some("3".to_string()));
|
|
|
344
|
+ assert_eq!(TileCoord::new(3, 1, 0).to_quadkey(), Some("001".to_string()));
|
|
|
345
|
+ assert_eq!(TileCoord::new(30, 0, 1).to_quadkey(), Some("000000000000000000000000000002".to_string()));
|
|
|
346
|
+ }
|
|
|
347
|
+}
|