Bladeren bron

coord: Add TileCoord::globe_norm

Johannes Hofmann 7 jaren geleden
bovenliggende
commit
c8959c4fdc
1 gewijzigde bestanden met toevoegingen van 54 en 6 verwijderingen
  1. 54
    6
      src/coord.rs

+ 54
- 6
src/coord.rs Bestand weergeven

@@ -126,15 +126,15 @@ impl MapCoord {
126 126
         TileCoord { zoom, x, y }
127 127
     }
128 128
 
129
+    /// Wrap around in x-direction.
130
+    /// Do not wrap around in y-direction. The poles don't touch.
129 131
     pub fn normalize_x(&mut self) {
130
-        // Wrap around in x-direction.
131
-        // Do not wrap around in y-direction. The poles don't touch.
132 132
         self.x = (self.x.fract() + 1.0).fract();
133 133
     }
134 134
 
135
+    /// Wrap around in x-direction.
136
+    /// Restrict y coordinates to interval [0.0, 1.0]
135 137
     pub fn normalize_xy(&mut self) {
136
-        // Wrap around in x-direction.
137
-        // Restrict y coordinates to interval [0.0, 1.0]
138 138
         self.x = (self.x.fract() + 1.0).fract();
139 139
         self.y = 0.0f64.max(1.0f64.min(self.y));
140 140
     }
@@ -414,6 +414,28 @@ impl TileCoord {
414 414
         ((coord % max) + max) % max
415 415
     }
416 416
 
417
+    /// Wrap around in x-direction.
418
+    /// Values for y that are out-of-bounds "rotate" around the globe and also influence the
419
+    /// x-coordinate.
420
+    pub fn globe_norm(&self) -> Self {
421
+        let max = Self::get_zoom_level_tiles(self.zoom);
422
+        let period = max * 2;
423
+
424
+        let yp = ((self.y % period) + period) % period;
425
+        let side = yp / max;
426
+
427
+        let x = self.x + side * (max / 2);
428
+        let x = ((x % max) + max) % max;
429
+
430
+        let y = (1 - side) * yp + side * (period - 1 - yp);
431
+
432
+        TileCoord {
433
+            zoom: self.zoom,
434
+            x: x,
435
+            y: y,
436
+        }
437
+    }
438
+
417 439
     #[inline]
418 440
     pub fn get_zoom_level_tiles(zoom: u32) -> i32 {
419 441
         //TODO throw error when zoom too big
@@ -589,7 +611,33 @@ mod tests {
589 611
             assert_eq!(a1, b1);
590 612
             assert_eq!(a2, b2);
591 613
         }
592
-        assert_eq!(t.children_iter(1).collect::<Vec<_>>().len(), 4);
593
-        assert_eq!(t.children_iter(2).collect::<Vec<_>>().len(), 16);
614
+        assert_eq!(t.children_iter(0).count(), 1);
615
+        assert_eq!(t.children_iter(0).next(), Some((t, SubTileCoord{ size: 1, x: 0, y: 0 })));
616
+        assert_eq!(t.children_iter(1).count(), 4);
617
+        assert_eq!(t.children_iter(2).count(), 16);
618
+    }
619
+
620
+    #[test]
621
+    fn globe_norm() {
622
+        assert_eq!(TileCoord::new(0, 0, 0).globe_norm(), TileCoord::new(0, 0, 0));
623
+        assert_eq!(TileCoord::new(0, -1, 0).globe_norm(), TileCoord::new(0, 0, 0));
624
+        assert_eq!(TileCoord::new(0, -1, -1).globe_norm(), TileCoord::new(0, 0, 0));
625
+        assert_eq!(TileCoord::new(0, 0, 1).globe_norm(), TileCoord::new(0, 0, 0));
626
+
627
+        assert_eq!(TileCoord::new(2, 0, 0).globe_norm(), TileCoord::new(2, 0, 0));
628
+        assert_eq!(TileCoord::new(2, 0, 3).globe_norm(), TileCoord::new(2, 0, 3));
629
+        assert_eq!(TileCoord::new(2, 0, 4).globe_norm(), TileCoord::new(2, 2, 3));
630
+        assert_eq!(TileCoord::new(2, 0, 5).globe_norm(), TileCoord::new(2, 2, 2));
631
+        assert_eq!(TileCoord::new(2, 0, 8).globe_norm(), TileCoord::new(2, 0, 0));
632
+
633
+        assert_eq!(TileCoord::new(2, 3, 0).globe_norm(), TileCoord::new(2, 3, 0));
634
+        assert_eq!(TileCoord::new(2, 3, 3).globe_norm(), TileCoord::new(2, 3, 3));
635
+        assert_eq!(TileCoord::new(2, 3, 4).globe_norm(), TileCoord::new(2, 1, 3));
636
+        assert_eq!(TileCoord::new(2, 3, 5).globe_norm(), TileCoord::new(2, 1, 2));
637
+        assert_eq!(TileCoord::new(2, 3, 8).globe_norm(), TileCoord::new(2, 3, 0));
638
+
639
+        assert_eq!(TileCoord::new(2, -1, 0).globe_norm(), TileCoord::new(2, 3, 0));
640
+        assert_eq!(TileCoord::new(2, 0, -1).globe_norm(), TileCoord::new(2, 2, 0));
641
+        assert_eq!(TileCoord::new(2, 0, -5).globe_norm(), TileCoord::new(2, 0, 3));
594 642
     }
595 643
 }