Ver código fonte

Add orthografic_view::tile_neighbors and tests

Johannes Hofmann 7 anos atrás
pai
commit
eefea571ea
1 arquivos alterados com 129 adições e 0 exclusões
  1. 129
    0
      src/orthografic_view.rs

+ 129
- 0
src/orthografic_view.rs Ver arquivo

@@ -5,6 +5,95 @@ use std::f32::consts::{PI, FRAC_1_PI};
5 5
 use std::f64;
6 6
 
7 7
 
8
+#[derive(Copy, Clone, Debug, PartialEq)]
9
+pub enum TileNeighbor {
10
+    Coord(TileCoord),
11
+    NorthPole,
12
+    SouthPole,
13
+}
14
+
15
+/// Tile neighbors using sphere topology
16
+pub fn tile_neighbors(origin: TileCoord, result: &mut Vec<TileNeighbor>) {
17
+    result.clear();
18
+
19
+    let zoom_level_tiles = TileCoord::get_zoom_level_tiles(origin.zoom);
20
+
21
+    if origin.y < 0 || origin.y >= zoom_level_tiles {
22
+        // Tile is out of bounds
23
+        return;
24
+    }
25
+
26
+    // Normalize x coordinate
27
+    let origin = TileCoord {
28
+        zoom: origin.zoom,
29
+        x: ((origin.x % zoom_level_tiles) + zoom_level_tiles) % zoom_level_tiles,
30
+        y: origin.y,
31
+    };
32
+
33
+    match (origin.zoom, origin.y) {
34
+        (0, _) => {},
35
+        (1, _) => {
36
+            result.extend(&[
37
+                TileNeighbor::Coord(TileCoord::new(
38
+                    origin.zoom,
39
+                    (origin.x + 1) % zoom_level_tiles,
40
+                    origin.y)
41
+                ),
42
+                TileNeighbor::Coord(TileCoord::new(
43
+                    origin.zoom,
44
+                    origin.x,
45
+                    (origin.y + 1) % zoom_level_tiles),
46
+                ),
47
+            ]);
48
+        },
49
+        (_, 0) => {
50
+            result.extend(&[
51
+                TileNeighbor::NorthPole,
52
+                TileNeighbor::Coord(TileCoord::new(
53
+                    origin.zoom,
54
+                    origin.x,
55
+                    origin.y + 1,
56
+                )),
57
+            ]);
58
+        },
59
+        (_, y) if y == zoom_level_tiles - 1 => {
60
+            result.extend(&[
61
+                TileNeighbor::SouthPole,
62
+                TileNeighbor::Coord(TileCoord::new(
63
+                    origin.zoom,
64
+                    origin.x,
65
+                    origin.y - 1,
66
+                )),
67
+            ]);
68
+        },
69
+        _ => {
70
+            result.extend(&[
71
+                TileNeighbor::Coord(TileCoord::new(
72
+                    origin.zoom,
73
+                    origin.x,
74
+                    origin.y + 1,
75
+                )),
76
+                TileNeighbor::Coord(TileCoord::new(
77
+                    origin.zoom,
78
+                    origin.x,
79
+                    origin.y - 1,
80
+                )),
81
+                TileNeighbor::Coord(TileCoord::new(
82
+                    origin.zoom,
83
+                    (origin.x + 1) % zoom_level_tiles,
84
+                    origin.y,
85
+                )),
86
+                TileNeighbor::Coord(TileCoord::new(
87
+                    origin.zoom,
88
+                    (origin.x + zoom_level_tiles - 1) % zoom_level_tiles,
89
+                    origin.y,
90
+                )),
91
+            ]);
92
+        },
93
+    }
94
+}
95
+
96
+
8 97
 #[derive(Clone, Debug)]
9 98
 pub struct OrthograficView {
10 99
 }
@@ -175,3 +264,43 @@ impl OrthograficView {
175 264
         transform
176 265
     }
177 266
 }
267
+
268
+#[cfg(test)]
269
+mod tests {
270
+    use orthografic_view::*;
271
+
272
+    #[test]
273
+    fn tilecoord_neighbors() {
274
+        let mut result = vec![];
275
+
276
+        tile_neighbors(TileCoord::new(0, 0, 0), &mut result);
277
+        assert!(result.is_empty());
278
+
279
+        tile_neighbors(TileCoord::new(0, 0, -1), &mut result);
280
+        assert!(result.is_empty());
281
+
282
+        tile_neighbors(TileCoord::new(3, 0, -1), &mut result);
283
+        assert!(result.is_empty());
284
+
285
+        tile_neighbors(TileCoord::new(1, 0, 0), &mut result);
286
+        assert_eq!(result.len(), 2);
287
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(1, 1, 0))).is_some());
288
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(1, 0, 1))).is_some());
289
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(1, 1, 1))).is_none());
290
+
291
+        tile_neighbors(TileCoord::new(2, 0, 0), &mut result);
292
+        assert_eq!(result.len(), 2);
293
+        assert!(result.iter().find(|&&x| x == TileNeighbor::NorthPole).is_some());
294
+
295
+        tile_neighbors(TileCoord::new(2, 0, 3), &mut result);
296
+        assert_eq!(result.len(), 2);
297
+        assert!(result.iter().find(|&&x| x == TileNeighbor::SouthPole).is_some());
298
+
299
+        tile_neighbors(TileCoord::new(2, 3, 1), &mut result);
300
+        assert_eq!(result.len(), 4);
301
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(2, 2, 1))).is_some());
302
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(2, 0, 1))).is_some());
303
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(2, 3, 0))).is_some());
304
+        assert!(result.iter().find(|&&x| x == TileNeighbor::Coord(TileCoord::new(2, 3, 2))).is_some());
305
+    }
306
+}