offset method
Implementation
@override
LatLng offset(dynamic from, double? distanceInMeter, double bearing) {
final latlng = LatLng.from(from);
final latInRad = latlng.latitudeInRad;
final lngInRad = latlng.longitudeInRad;
double alpha1 = degToRadian(bearing);
double sinAlpha1 = sin(alpha1);
double cosAlpha1 = cos(alpha1);
double tanU1 = (1 - FLATTENING) * tan(latInRad);
double cosU1 = 1 / sqrt((1 + tanU1 * tanU1));
double sinU1 = tanU1 * cosU1;
double sigma1 = atan2(tanU1, cosAlpha1);
double sinAlpha = cosU1 * sinAlpha1;
double cosSqAlpha = 1 - sinAlpha * sinAlpha;
double dfUSq = cosSqAlpha *
(EQUATOR_RADIUS * EQUATOR_RADIUS - POLAR_RADIUS * POLAR_RADIUS) /
(POLAR_RADIUS * POLAR_RADIUS);
double a = 1 +
dfUSq / 16384 * (4096 + dfUSq * (-768 + dfUSq * (320 - 175 * dfUSq)));
double b =
dfUSq / 1024 * (256 + dfUSq * (-128 + dfUSq * (74 - 47 * dfUSq)));
double sigma = distanceInMeter! / (POLAR_RADIUS * a);
double sigmaP = 2 * PI;
double sinSigma = 0.0;
double cosSigma = 0.0;
double cos2SigmaM = 0.0;
double deltaSigma;
int maxIterations = 200;
do {
cos2SigmaM = cos(2 * sigma1 + sigma);
sinSigma = sin(sigma);
cosSigma = cos(sigma);
deltaSigma = b *
sinSigma *
(cos2SigmaM +
b /
4 *
(cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) -
b /
6 *
cos2SigmaM *
(-3 + 4 * sinSigma * sinSigma) *
(-3 + 4 * cos2SigmaM * cos2SigmaM)));
sigmaP = sigma;
sigma = distanceInMeter / (POLAR_RADIUS * a) + deltaSigma;
} while ((sigma - sigmaP).abs() > 1e-12 && --maxIterations > 0);
if (maxIterations == 0) {
throw StateError("offset calculation faild to converge!");
}
double tmp = sinU1 * sinSigma - cosU1 * cosSigma * cosAlpha1;
double latitude = atan2(
sinU1 * cosSigma + cosU1 * sinSigma * cosAlpha1,
(1 - FLATTENING) * sqrt(sinAlpha * sinAlpha + tmp * tmp),
);
double lambda = atan2(
sinSigma * sinAlpha1, cosU1 * cosSigma - sinU1 * sinSigma * cosAlpha1);
double c =
FLATTENING / 16 * cosSqAlpha * (4 + FLATTENING * (4 - 3 * cosSqAlpha));
double l = lambda -
(1 - c) *
FLATTENING *
sinAlpha *
(sigma +
c *
sinSigma *
(cos2SigmaM +
c * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
double longitude = lngInRad + l;
if (longitude > PI) {
longitude = longitude - 2 * PI;
}
if (longitude < -1 * PI) {
longitude = longitude + 2 * PI;
}
return LatLng(radianToDeg(latitude), radianToDeg(longitude));
}