def distanceTo3(self, other, wrap=False): '''Compute the distance, the initial and final bearing along a geodesic between this and an other point, using Vincenty's inverse method. The distance is in the same units as this point's datum axes, conventially meter. The distance is measured on the surface of the ellipsoid, ignoring this point's height. The initial and final bearing (forward and reverse azimuth) are in compass degrees from North. @param other: Destination point (L{LatLon}). @keyword wrap: Wrap and unroll longitudes (C{bool}). @return: A L{Distance3Tuple}C{(distance, initial, final)}. @raise TypeError: The B{C{other}} point is not L{LatLon}. @raise ValueError: If this and the B{C{other}} point's L{Datum} ellipsoids are not compatible. @raise VincentyError: Vincenty fails to converge for the current L{LatLon.epsilon} and L{LatLon.iterations} limit and/or if this and the B{C{other}} point are coincident or near-antipodal. ''' r = Distance3Tuple(*self._inverse(other, True, wrap)) return self._xnamed(r)
def distanceTo3(self, other, wrap=False): '''Compute the distance, the initial and final bearing along a geodesic between this and an other point, using Karney's Inverse method. The distance is in the same units as this point's datum axes, conventially meter. The distance is measured on the surface of the ellipsoid, ignoring this point's height. The initial and final bearing (forward and reverse azimuth) are in compass degrees from North. @param other: Destination point (L{LatLon}). @keyword wrap: Wrap and unroll longitudes (C{bool}). @return: A L{Distance3Tuple}C{(distance, initial, final)}. @raise ImportError: Package U{geographiclib <https://PyPI.org/project/geographiclib>} not installed or not found. @raise TypeError: The B{C{other}} point is not L{LatLon}. @raise ValueError: If this and the B{C{other}} point's L{Datum} ellipsoids are not compatible. ''' r = Distance3Tuple(*self._inverse(other, True, wrap)) return self._xnamed(r)
def Inverse3(self, lat1, lon1, lat2, lon2): # PYCHOK outmask '''Return the distance in C{meter} and the forward and reverse azimuths in C{degrees}. ''' m = self.DISTANCE | self.AZIMUTH d = self.Inverse(lat1, lon1, lat2, lon2, m) return Distance3Tuple(d.s12, wrap360(d.azi1), wrap360(d.azi2))
def _inverse(self, other, azis, wrap): '''(INTERNAL) Inverse Vincenty method. @raise TypeError: The B{C{other}} point is not L{LatLon}. @raise ValueError: If this and the B{C{other}} point's L{Datum} ellipsoids are not compatible. @raise VincentyError: Vincenty fails to converge for the current L{LatLon.epsilon} and L{LatLon.iterations} limit and/or if this and the B{C{other}} point are coincident or near-antipodal. ''' E = self.ellipsoids(other) c1, s1, _ = _r3(self.lat, E.f) c2, s2, _ = _r3(other.lat, E.f) c1c2, s1c2 = c1 * c2, s1 * c2 c1s2, s1s2 = c1 * s2, s1 * s2 dl, _ = unroll180(self.lon, other.lon, wrap=wrap) ll = dl = radians(dl) for self._iteration in range(self._iterations): ll_ = ll sll, cll = sincos2(ll) ss = hypot(c2 * sll, c1s2 - s1c2 * cll) if ss < EPS: # coincident or antipodal, ... if self.isantipodeTo(other, eps=self._epsilon): t = '%r %sto %r' % (self, _antipodal_, other) raise VincentyError(_ambiguous_, txt=t) # return zeros like Karney, but unlike Veness return Distance3Tuple(0.0, 0, 0) cs = s1s2 + c1c2 * cll s = atan2(ss, cs) sa = c1c2 * sll / ss c2a = 1 - sa**2 if abs(c2a) < EPS: c2a = 0 # equatorial line ll = dl + E.f * sa * s else: c2sm = cs - 2 * s1s2 / c2a ll = dl + _dl(E.f, c2a, sa, s, cs, ss, c2sm) if abs(ll - ll_) < self._epsilon: break # # omitted and applied only after failure to converge below, see footnote # # under Inverse at <https://WikiPedia.org/wiki/Vincenty's_formulae> # # <https://GitHub.com/ChrisVeness/geodesy/blob/master/latlon-vincenty.js> # elif abs(ll) > PI and self.isantipodeTo(other, eps=self._epsilon): # raise VincentyError('%s, %r %sto %r' % ('ambiguous', self, # _antipodal_, other)) else: t = _antipodal_ if self.isantipodeTo(other, eps=self._epsilon) else NN raise VincentyError(_no_convergence_, txt='%r %sto %r' % (self, t, other)) if c2a: # e22 == (a / b)**2 - 1 A, B = _p2(c2a * E.e22) s = A * (s - _ds(B, cs, ss, c2sm)) b = E.b # if self.height or other.height: # b += self._havg(other) d = b * s if azis: # forward and reverse azimuth sll, cll = sincos2(ll) f = degrees360(atan2(c2 * sll, c1s2 - s1c2 * cll)) r = degrees360(atan2(c1 * sll, -s1c2 + c1s2 * cll)) else: f = r = 0 return Distance3Tuple(d, f, r)