Last active
January 31, 2025 23:27
-
-
Save doraneko94/52f475099522317ba297dda6adf2b5bd to your computer and use it in GitHub Desktop.
緯度経度と平面直角座標を相互に変換するDart(Flutter)コード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:latlong2/latlong.dart'; | |
import 'dart:math'; | |
const f = 298.257222; | |
const r = 6378137.0; | |
const m0 = 0.9999; | |
const n1 = 1 / (2 * f - 1); | |
const alpha = [ | |
1.0, | |
0.0008377318250120707, | |
7.608527853531295e-7, | |
1.1976455014483125e-9, | |
2.429150263945317e-12, | |
5.750164393844325e-15 | |
]; | |
const beta = [ | |
1.0, | |
0.0008377321684455561, | |
5.905870215034071e-8, | |
1.6734826778558678e-10, | |
2.1648237340373555e-13, | |
3.7940918853103374e-16 | |
]; | |
const a = [ | |
1.0000007049454083, | |
-0.0025188297049783238, | |
2.643542951117491e-6, | |
-3.4526259108208313e-9, | |
4.891830431025234e-12, | |
-7.228726058073925e-15 | |
]; | |
const delta = [ | |
1.0, | |
0.003356551486742219, | |
6.5719224858971644e-6, | |
1.764640439081273e-8, | |
5.387753897315289e-11, | |
1.764007518903401e-13, | |
6.056074067532996e-16 | |
]; | |
const aBar = m0 * r / (1 + n1) * 1.0000007049454083; | |
const tsnopn = 2.0 * 0.040978291755 / (1.0 + n1); | |
double rad2deg(double rad) { | |
return rad * 180 / pi; | |
} | |
double atanh(double x) { | |
return log((1 + x) / (1 - x)) / 2; | |
} | |
double sinh(double x) { | |
return (exp(x) - exp(-x)) / 2; | |
} | |
double cosh(double x) { | |
return (exp(x) + exp(-x)) / 2; | |
} | |
double tanh(double x) { | |
return (exp(x) - exp(-x)) / (exp(x) + exp(-x)); | |
} | |
double sBarCalc(double lat0) { | |
double sBar = lat0; | |
for (int j = 1; j <= 5; j++) { | |
sBar += a[j] * sin(2 * j * lat0); | |
} | |
sBar *= aBar; | |
return sBar; | |
} | |
class XY { | |
const XY({ | |
required this.x, | |
required this.y, | |
required this.source, | |
required this.reference, | |
}); | |
final double x; | |
final double y; | |
final LatLng source; | |
final LatLng reference; | |
XY zero(LatLng reference) { | |
return XY(x: 0, y: 0, source: reference, reference: reference); | |
} | |
static XY fromLatLng(LatLng source, LatLng reference) { | |
final lat = source.latitudeInRad; | |
final lng = source.longitudeInRad; | |
final lat0 = reference.latitudeInRad; | |
final lng0 = reference.longitudeInRad; | |
final t = sinh(atanh(sin(lat)) - tsnopn * atanh(tsnopn * sin(lat))); | |
final tBar = sqrt(1 + t * t); | |
final lngC = cos(lng - lng0); | |
final lngS = sin(lng - lng0); | |
final xi = atan(t / lngC); | |
final eta = atanh(lngS / tBar); | |
final sBar = sBarCalc(lat0); | |
double x = xi; | |
for (int j = 1; j <= 5; j++) { | |
x += alpha[j] * sin(2 * j * xi) * cosh(2 * j * eta); | |
} | |
x = aBar * x - sBar; | |
double y = eta; | |
for (int j = 1; j <= 5; j++) { | |
y += alpha[j] * cos(2 * j * xi) * sinh(2 * j * eta); | |
} | |
y *= aBar; | |
return XY(x: x, y: y, source: source, reference: reference); | |
} | |
static XY fromXY(double x, double y, LatLng reference) { | |
final lat0 = reference.latitudeInRad; | |
final lng0 = reference.longitudeInRad; | |
final sBar = sBarCalc(lat0); | |
final xi = (x + sBar) / aBar; | |
final eta = y / aBar; | |
double xi_ = xi; | |
for (int j = 1; j <= 5; j++) { | |
xi_ -= beta[j] * sin(2 * j * xi) * cosh(2 * j * eta); | |
} | |
double eta_ = eta; | |
for (int j = 1; j <= 5; j++) { | |
eta_ -= beta[j] * cos(2 * j * xi) * sinh(2 * j * eta); | |
} | |
final chi = asin(sin(xi_) / cosh(eta_)); | |
double lat = chi; | |
for (int j = 1; j <= 6; j++) { | |
lat += delta[j] * sin(2 * j * chi); | |
} | |
final lng = lng0 + atan(sinh(eta_) / cos(xi_)); | |
return XY( | |
x: x, | |
y: y, | |
source: LatLng(rad2deg(lat), rad2deg(lng)), | |
reference: reference); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment