Browse Source

coord: Fix conversion edge cases

This removes the holes of the globe at the poles.
Johannes Hofmann 7 years ago
parent
commit
f482a08091
1 changed files with 29 additions and 4 deletions
  1. 29
    4
      src/coord.rs

+ 29
- 4
src/coord.rs View File

@@ -289,10 +289,23 @@ impl TileCoord {
289 289
     // Return the LatLonRad coordinate of the top left corner of the current tile.
290 290
     pub fn latlon_rad_north_west(&self) -> LatLonRad {
291 291
         let factor = f64::powi(2.0, -(self.zoom as i32)) * (2.0 * PI);
292
-        LatLonRad::new(
293
-            (PI - f64::from(self.y) * factor).sinh().atan(),
294
-            f64::from(self.x) * factor - PI,
295
-        )
292
+
293
+        if self.y == 0 {
294
+            LatLonRad::new(
295
+                0.5 * PI,
296
+                f64::from(self.x) * factor - PI,
297
+            )
298
+        } else if self.y == Self::get_zoom_level_tiles(self.zoom) {
299
+            LatLonRad::new(
300
+                -0.5 * PI,
301
+                f64::from(self.x) * factor - PI,
302
+            )
303
+        } else {
304
+            LatLonRad::new(
305
+                (PI - f64::from(self.y) * factor).sinh().atan(),
306
+                f64::from(self.x) * factor - PI,
307
+            )
308
+        }
296 309
     }
297 310
 
298 311
     // Return the LatLonRad coordinate of the bottom right corner of the current tile.
@@ -506,4 +519,16 @@ mod tests {
506 519
             assert!(approx_eq(rad.lon, -0.987 * PI));
507 520
         }
508 521
     }
522
+
523
+    #[test]
524
+    fn tile_to_latlon() {
525
+        // Test edge cases at the poles where the longitude is technically undefined.
526
+        let t = TileCoord::new(0, 0, 0);
527
+        let deg = t.latlon_rad_north_west();
528
+        assert!(approx_eq(deg.lat, 0.5 * PI));
529
+        assert!(approx_eq(deg.lon, -PI));
530
+        let deg = t.latlon_rad_south_east();
531
+        assert!(approx_eq(deg.lat, -0.5 * PI));
532
+        assert!(approx_eq(deg.lon, PI));
533
+    }
509 534
 }