computeOffsetOrigin static method

LatLng? computeOffsetOrigin(
  1. LatLng to,
  2. num distance,
  3. num heading
)

Returns the location of origin when provided with a LatLng destination, meters travelled and original heading. Headings are expressed in degrees clockwise from North. This function returns null when no solution is available. @param to The destination LatLng. @param distance The distance travelled, in meters. @param heading The heading in degrees clockwise from north.

Implementation

static LatLng? computeOffsetOrigin(LatLng to, num distance, num heading) {
  heading = MathUtil.toRadians(heading);
  distance /= earthRadius;
  // http://lists.maptools.org/pipermail/proj/2008-October/003939.html
  final n1 = cos(distance);
  final n2 = sin(distance) * cos(heading);
  final n3 = sin(distance) * sin(heading);
  final n4 = sin(MathUtil.toRadians(to.latitude));
  // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution
  // results in the latitude outside the [-90, 90] range. We first try one
  // solution and back off to the other if we are outside that range.
  final n12 = n1 * n1;
  final discriminant = n2 * n2 * n12 + n12 * n12 - n12 * n4 * n4;
  if (discriminant < 0) {
    // No real solution which would make sense in LatLng-space.
    return null;
  }
  num b = n2 * n4 + sqrt(discriminant);
  b /= n1 * n1 + n2 * n2;
  final a = (n4 - n2 * b) / n1;
  num fromLatRadians = atan2(a, b);
  if (fromLatRadians < -pi / 2 || fromLatRadians > pi / 2) {
    b = n2 * n4 - sqrt(discriminant);
    b /= n1 * n1 + n2 * n2;
    fromLatRadians = atan2(a, b);
  }
  if (fromLatRadians < -pi / 2 || fromLatRadians > pi / 2) {
    // No solution which would make sense in LatLng-space.
    return null;
  }
  final fromLngRadians = MathUtil.toRadians(to.longitude) -
      atan2(n3, n1 * cos(fromLatRadians) - n2 * sin(fromLatRadians));
  return LatLng(MathUtil.toDegrees(fromLatRadians).toDouble(),
      MathUtil.toDegrees(fromLngRadians).toDouble());
}