]> git.mxchange.org Git - simgear.git/commitdiff
Revise SGBucket::get_width_m
authorJames Turner <zakalawe@mac.com>
Thu, 13 Feb 2014 18:49:16 +0000 (18:49 +0000)
committerJames Turner <zakalawe@mac.com>
Thu, 13 Feb 2014 18:49:38 +0000 (18:49 +0000)
- remove the 0.5 degree offset away from the equator, which was
  causing wrap-around at the poles
- add a new helper to get the highest latitude of a tile (which may
  be +/- 90 for the polar cap tiles), and use this to compute radius
- special case the polar-caps and return a fixed, small width so
  the tile-manager loads all tiles.

simgear/bucket/newbucket.cxx
simgear/bucket/newbucket.hxx
simgear/bucket/test_bucket.cxx

index e300def11f7f83382b332dfd3fa405d4f17f9fde..beb20d087f47ee9c14c4c0ce0c1ca10df9802aee 100644 (file)
@@ -236,17 +236,32 @@ double SGBucket::get_height() const {
     return SG_BUCKET_SPAN;
 }
 
-
-// return width of the tile in meters
-double SGBucket::get_width_m() const {
-    double clat = (int)get_center_lat();
-    if ( clat > 0 ) {
-       clat = (int)clat + 0.5;
-    } else {
-       clat = (int)clat - 0.5;
+double SGBucket::get_highest_lat() const
+{
+    unsigned char adjustedY = y;
+    if (lat >= 0) {
+        // tile is north of the equator, so we want the top edge. Add one
+        // to y to achieve this.
+        ++adjustedY;
     }
-    double clat_rad = clat * SGD_DEGREES_TO_RADIANS;
+    
+       return lat + (adjustedY / 8.0);
+}
+
+
+// return width of the tile in meters. This function is used by the
+// tile-manager to estimate how many tiles are in the view distance, so
+// we care about the smallest width, which occurs at the highest latitude.
+double SGBucket::get_width_m() const
+{
+    double clat_rad = get_highest_lat() * SGD_DEGREES_TO_RADIANS;
     double cos_lat = cos( clat_rad );
+    if (fabs(cos_lat) < SG_EPSILON) {
+        // happens for polar tiles, since we pass in a latitude of 90
+        // return an arbitrary small value so all tiles are loaded
+        return 10.0;
+    }
+    
     double local_radius = cos_lat * SG_EQUATORIAL_RADIUS_M;
     double local_perimeter = local_radius * SGD_2PI;
     double degree_width = local_perimeter / 360.0;
index b891ef398416fabea87fc70d15e539b83cc95bc5..605171a3d15e2927e0d8a7ee1b298ab6ae2a9356 100644 (file)
@@ -206,6 +206,13 @@ public:
        return lat + y / 8.0 + SG_HALF_BUCKET_SPAN;
     }
 
+    /**
+     * @return the highest (furthest from the equator) latitude of this
+     * tile. This is the top edge for tiles north of the equator, and
+     * the bottom edge for tiles south
+     */
+    double get_highest_lat() const;
+    
     /**
      * @return the width of the tile in degrees.
      */
index 481f97e2e1b856da0e00e0ce776624723753c0de..b2bd8d085dcd5c6c5887af62d6bced5febfadfcc 100644 (file)
@@ -110,6 +110,9 @@ void testPolar()
     COMPARE(b1.get_x(), 0);
     COMPARE(b1.get_y(), 7);
     
+    COMPARE_EP(b1.get_highest_lat(), 90.0);
+    COMPARE_EP(b1.get_width_m(), 10.0);
+    
     COMPARE(b2.get_chunk_lat(), 89);
     COMPARE(b2.get_chunk_lon(), 0);
     COMPARE(b2.get_x(), 0);
@@ -137,6 +140,8 @@ void testPolar()
     COMPARE(b5.get_x(), 0);
     COMPARE(b5.get_y(), 0);
     COMPARE(b5.gen_index(), b6.gen_index());
+    COMPARE_EP(b5.get_highest_lat(), -90.0);
+    COMPARE_EP(b5.get_width_m(), 10.0);
     
     SGGeod actualSouthPole1 = b5.get_corner(0);
     SGGeod actualSouthPole2 = b5.get_corner(1);