|
4 | 4 | #include "Log.h" |
5 | 5 | #include "Point.h" |
6 | 6 | #include "unstable.h" |
| 7 | +#include "Util.h" |
7 | 8 | namespace fs |
8 | 9 | { |
9 | 10 | class Point; |
@@ -72,24 +73,44 @@ fs::Point to_lat_long(const string_view proj4, const MathSize x, const MathSize |
72 | 73 | } |
73 | 74 | string try_fix_meridian(const string_view proj4) |
74 | 75 | { |
75 | | - const auto zone_pos = proj4.find("+zone="); |
76 | | - // if proj4 is defined by zone then convert to be defined by meridian |
77 | | - if (string::npos != zone_pos && string::npos != proj4.find("+proj=utm")) |
| 76 | + const auto proj = find_value("+proj=", proj4); |
| 77 | + if (0 != strcmp("tmerc", proj.c_str()) && 0 != strcmp("utm", proj.c_str())) |
78 | 78 | { |
79 | | - // NOTE: using proj for actual projections, but we want proj4 strings to use meridian |
80 | | - // and not zone so outputs are consistent regardless of input |
81 | | - // convert from utm zone to tmerc |
82 | | - const string zone_str{proj4.substr(zone_pos + 6)}; |
83 | | - const auto zone = stoi(zone_str); |
84 | | - // zone 15 is -93 and other zones are 6 degrees difference |
85 | | - const auto degrees = fs::utm_central_meridian(zone); |
86 | | - // HACK: assume utm zone is at start |
87 | | - const string proj4_fixed = |
88 | | - ("+proj=tmerc +lat_0=0.000000000 +lon_0=" + to_string(degrees) |
89 | | - + " +k=0.999600 +x_0=500000.000 +y_0=0.000"); |
90 | | - logging::verbose("Adjusted proj4 is %s\n", proj4_fixed.c_str()); |
91 | | - return proj4_fixed; |
| 79 | + logging::debug("try_fix_meridian() has no effect on non utm/tmerc projections"); |
| 80 | + return string(proj4); |
92 | 81 | } |
93 | | - return string(proj4); |
| 82 | + const auto [lat_0, lon_0, k, x_0, y_0] = |
| 83 | + [&]() -> std::tuple<MathSize, MathSize, MathSize, MathSize, MathSize> { |
| 84 | + if (0 == strcmp("utm", proj.c_str())) |
| 85 | + { |
| 86 | + const auto zone = find_value("+zone=", proj4); |
| 87 | + // zone 15 is -93 and other zones are 6 degrees difference |
| 88 | + const auto z = stod(zone); |
| 89 | + const auto lon_0 = fs::utm_central_meridian(z); |
| 90 | + logging::note("UTM zone %s == %f turned into meridian %f", zone.c_str(), z, lon_0); |
| 91 | + logging::debug("Using default values for utm"); |
| 92 | + return {0.0, lon_0, 0.9996, 500000.0, 0.0}; |
| 93 | + } |
| 94 | + logging::debug("Using existing values for tmerc"); |
| 95 | + const auto lat_0 = find_value("+lat_0=", proj4); |
| 96 | + const auto lon_0 = find_value("+lon_0=", proj4); |
| 97 | + const auto k = find_value("+k=", proj4); |
| 98 | + const auto x_0 = find_value("+x_0=", proj4); |
| 99 | + const auto y_0 = find_value("+y_0=", proj4); |
| 100 | + return {stod(lat_0), stod(lon_0), stod(k), stod(x_0), stod(y_0)}; |
| 101 | + }(); |
| 102 | + const auto ellps = find_value("+ellps=", proj4, "GRS80"); |
| 103 | + const auto units = find_value("+units=", proj4, "m"); |
| 104 | + return std::format( |
| 105 | + "+proj={} +lat_0={:0.9f} +lon_0={:0.9f} +k={:0.9f} +x_0={:0.9f} +y_0={:0.9f} +ellps={} +units={}", |
| 106 | + "tmerc", |
| 107 | + lat_0, |
| 108 | + lon_0, |
| 109 | + k, |
| 110 | + x_0, |
| 111 | + y_0, |
| 112 | + ellps, |
| 113 | + units |
| 114 | + ); |
94 | 115 | } |
95 | 116 | } |
0 commit comments