Convert UTM parameters to lat,lon for WSG 84 ellipsoid. If UTM parameters are valid lat and lon references are used to output calculated coordinates. Otherwise function returns empty optional.
| 231 | // If UTM parameters are valid lat and lon references are used to output calculated coordinates. |
| 232 | // Otherwise function returns empty optional. |
| 233 | std::optional<ms::LatLon> UTMtoLatLon(int easting, int northing, int zoneNumber, char zoneLetter) |
| 234 | { |
| 235 | if (zoneNumber < 1 || zoneNumber > 60) |
| 236 | return {}; |
| 237 | |
| 238 | if (easting < 100000 || easting >= 1000000) |
| 239 | return {}; |
| 240 | |
| 241 | if (northing < 0 || northing > 10000000) |
| 242 | return {}; |
| 243 | |
| 244 | if (zoneLetter < 'C' || zoneLetter > 'X' || zoneLetter == 'I' || zoneLetter == 'O') |
| 245 | return {}; |
| 246 | |
| 247 | bool const northern = (zoneLetter >= 'N'); |
| 248 | double const x = easting - 500000.0; |
| 249 | double y = northing; |
| 250 | |
| 251 | if (!northern) |
| 252 | y -= 10000000.0; |
| 253 | |
| 254 | double const m = y / K0; |
| 255 | double const mu = m / (R * M1); |
| 256 | |
| 257 | double const p_rad = (mu + P2 * sin(2.0 * mu) + P3 * sin(4.0 * mu) + P4 * sin(6.0 * mu) + P5 * sin(8.0 * mu)); |
| 258 | |
| 259 | double const p_sin = sin(p_rad); |
| 260 | double const p_sin2 = p_sin * p_sin; |
| 261 | |
| 262 | double const p_cos = cos(p_rad); |
| 263 | |
| 264 | double const p_tan = p_sin / p_cos; |
| 265 | double const p_tan2 = p_tan * p_tan; |
| 266 | double const p_tan4 = p_tan2 * p_tan2; |
| 267 | |
| 268 | double const ep_sin = 1 - E * p_sin2; |
| 269 | double const ep_sin_sqrt = sqrt(1 - E * p_sin2); |
| 270 | |
| 271 | double const n = R / ep_sin_sqrt; |
| 272 | double const r = (1 - E) / ep_sin; |
| 273 | |
| 274 | double const c = E_P2 * p_cos * p_cos; |
| 275 | double const c2 = c * c; |
| 276 | |
| 277 | double const d = x / (n * K0); |
| 278 | double const d2 = d * d; |
| 279 | double const d3 = d2 * d; |
| 280 | double const d4 = d3 * d; |
| 281 | double const d5 = d4 * d; |
| 282 | double const d6 = d5 * d; |
| 283 | |
| 284 | double const latitude = |
| 285 | (p_rad - (p_tan / r) * (d2 / 2.0 - d4 / 24.0 * (5.0 + 3.0 * p_tan2 + 10.0 * c - 4.0 * c2 - 9.0 * E_P2)) + |
| 286 | d6 / 720.0 * (61.0 + 90.0 * p_tan2 + 298.0 * c + 45.0 * p_tan4 - 252.0 * E_P2 - 3.0 * c2)); |
| 287 | |
| 288 | double longitude = (d - d3 / 6.0 * (1.0 + 2.0 * p_tan2 + c) + |
| 289 | d5 / 120.0 * (5.0 - 2.0 * c + 28.0 * p_tan2 - 3.0 * c2 + 8.0 * E_P2 + 24.0 * p_tan4)) / |
| 290 | p_cos; |
no test coverage detected