ossama-othman / MaRC

MaRC - Map Reprojections and Conversions
GNU Lesser General Public License v2.1
1 stars 0 forks source link

Inaccurate lat/lon at center of Orthographic projection #103

Open ossama-othman opened 5 years ago

ossama-othman commented 5 years ago

Describe the bug The specified latitude and longitude at the center of an Orthographic projection are off-center if they do not match the sub-observation latitude and longitude, respectively. The values have been observed to be off by several degrees, apparently depending on how far the sub-observation latitude differs from the equator, as well as the eccentricity of the body. That is not acceptable.

To Reproduce Steps to reproduce the behavior:

  1. Generate an orthographic projection using the following will MaRC input:

    MAP:    test_map_ortho.fits
        BODY:   Jupiter
        EQ_RAD:         71492
        POL_RAD:        66854
        ROTATION:       PROGRADE
    
        DATA_TYPE:      FLOAT
        TYPE:           ORTHO
                        OPTIONS:
                                SUB_OBSERV_LAT: -15
                                SUB_OBSERV_LON: 50
                                POSITION_ANGLE: 45
                KM_PER_PIXEL: 100
                                LAT_AT_CENTER: 20
                                LON_AT_CENTER: 75
    
        SAMPLES:        1001
        LINES:          1001
    
        PLANE:
                LATITUDE : CENTRIC
    
        PLANE:
                LONGITUDE
  2. Check the latitude value at the center of plane 1 using a FITS image viewer, such as ds9.

  3. Similarly, check the longitude value

Expected behavior The latitude value should be equal, or at least very close (e.g. 20.000001), to the LAT_AT_CENTER value set in the above MaRC input, but it is not. For example, the latitude value at the center (500, 500) is 21.2677 instead of the expected 20.

Similarly, the longitude value at the center is also off. Instead of the expected value of 75 the value is 76.1545.

Note: The desired latitude and longitude at the center do have the expected values when they match the sub-observation latitude and longitude.

Desktop (please complete the following information):

ossama-othman commented 5 years ago

This is a patch to tests/Orthographic_Test.cpp file in the ortho_updates branch that shows lat/lon at center values off by over 20 degrees:

diff --git a/tests/Orthographic_Test.cpp b/tests/Orthographic_Test.cpp
index 031be70..140810b 100644
--- a/tests/Orthographic_Test.cpp
+++ b/tests/Orthographic_Test.cpp
@@ -42,16 +42,16 @@ namespace
     constexpr double sub_observ_lon = 160;
     constexpr double position_angle = 35;
     constexpr double km_per_pixel   = -1;  // Choose automatically.
+    constexpr double lat_at_center  = 20;
+    constexpr double lon_at_center  = 130;

     // Place the sub-observation point at the center of the map.
-    constexpr MaRC::OrthographicCenter center(MaRC::LAT_LON_GIVEN,
-                                              sub_observ_lat,
-                                              sub_observ_lon);
+    MaRC::OrthographicCenter const center;

     std::shared_ptr<MaRC::OblateSpheroid> body =
         std::make_shared<MaRC::OblateSpheroid>(prograde, eq_rad, pol_rad);

-    auto projection =
+    auto const projection =
         std::make_unique<MaRC::Orthographic>(body,
                                              sub_observ_lat,
                                              sub_observ_lon,
@@ -148,7 +148,15 @@ bool test_make_map()

     MaRC::plot_info info(*image, minimum, maximum, blank);

-    auto const map =
+    constexpr auto center_sample = samples / 2;
+    constexpr auto center_line   = lines / 2;
+    constexpr auto center_offset = center_line * samples + center_sample;
+
+    // -----------------------------------------------------------------
+    // Case 1: Sub-observeration point at center of image (the default).
+    // -----------------------------------------------------------------
+
+    auto map =
         projection->template make_map<data_type>(info, samples, lines);

     if (map.empty())
@@ -168,19 +176,38 @@ bool test_make_map()
     if (non_blank == std::cend(map))
         return false;  // All blank!

-    constexpr auto sub_observation_sample = samples / 2;
-    constexpr auto sub_observation_line   = lines / 2;
-    constexpr auto sub_observation_offset =
-        sub_observation_line * samples + sub_observation_sample;
+    auto const sub_observation_data =
+        map[center_offset] * image->scale() + image->offset();
+
+    // -----------------------------------------------------------------
+    // Case 2: Latitude and longitude at center of image provided.
+    // -----------------------------------------------------------------
+
+    // Place the chosen latitude and longitue at the center of the
+    // map translating the body in the projection, accordingly.
+    constexpr MaRC::OrthographicCenter center2(MaRC::LAT_LON_GIVEN,
+                                               lat_at_center,
+                                               lon_at_center);
+
+    auto const p =
+        std::make_unique<MaRC::Orthographic>(body,
+                                             sub_observ_lat,
+                                             sub_observ_lon,
+                                             position_angle,
+                                             km_per_pixel,
+                                             center2);
+
+    map = p->template make_map<data_type>(info, samples, lines);

-    auto const     sub_observation_data   =
-        map[sub_observation_offset] * image->scale() + image->offset();
+    auto const lat_at_center_data =
+        map[center_offset] * image->scale() + image->offset();

     constexpr int ulps = 2;

     return
         !map.empty()
-        && MaRC::almost_equal(sub_observation_data, sub_observ_lat, ulps);
+        && MaRC::almost_equal(sub_observation_data, sub_observ_lat, ulps)
+        && MaRC::almost_equal(lat_at_center_data, lat_at_center, ulps);
 }

 /**

See commit 88ad28b.