Skip to content

Instantly share code, notes, and snippets.

@doraneko94
Last active January 31, 2025 23:27
Show Gist options
  • Save doraneko94/52f475099522317ba297dda6adf2b5bd to your computer and use it in GitHub Desktop.
Save doraneko94/52f475099522317ba297dda6adf2b5bd to your computer and use it in GitHub Desktop.
緯度経度と平面直角座標を相互に変換するDart(Flutter)コード
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