Beispiel #1
0
    def _rhumb3(self, other):
        '''(INTERNAL) Rhumb_ helper function.

           @param other: The other point (spherical LatLon).
        '''
        self.others(other)

        a1, b1 = self.to2ab()
        a2, b2 = other.to2ab()
        # if |db| > 180 take shorter rhumb
        # line across the anti-meridian
        db = wrapPI(b2 - b1)
        dp = log(tanPI_2_2(a2) / tanPI_2_2(a1))
        return (a2 - a1), db, dp
Beispiel #2
0
    def _rhumb3(self, other):
        '''(INTERNAL) Rhumb_ helper function.

           @param other: The other point (spherical LatLon).
        '''
        self.others(other)

        a1 = radians(self.lat)
        a2 = radians(other.lat)
        # if |db| > 180 take shorter rhumb
        # line across the anti-meridian
        db = radiansPI(other.lon - self.lon)
        ds = log(tanPI_2_2(a2) / tanPI_2_2(a1))
        return (a2 - a1), db, ds
Beispiel #3
0
    def rhumbDestination(self, distance, bearing, radius=R_M, height=None):
        '''Return the destination point having travelled along
           a rhumb (loxodrome) line from this point the given
           distance on the given bearing.

           @param distance: Distance travelled (same units as radius).
           @param bearing: Bearing from this point (compass degrees).
           @keyword radius: Optional, mean earth radius (meter).
           @keyword height: Optional height, overriding the default
                            height (meter or same unit as radius).

           @return: The destination point (spherical LatLon).

           @example:

           >>> p = LatLon(51.127, 1.338)
           >>> q = p.rhumbDestination(40300, 116.7)  # 50.9642°N, 001.8530°E

           @JSname: I{rhumbDestinationPoint}
        '''
        a1, b1 = self.to2ab()

        r = float(distance) / float(radius)  # angular distance in radians
        t = radians(bearing)

        da = r * cos(t)
        a2 = a1 + da
        # normalize latitude if past pole
        if a2 > PI_2:
            a2 = PI - a2
        elif a2 < -PI_2:
            a2 = -PI - a2

        dp = log(tanPI_2_2(a2) / tanPI_2_2(a1))
        # E-W course becomes ill-conditioned with 0/0
        if abs(dp) > EPS:
            q = da / dp
        else:
            q = cos(a1)

        if abs(q) > EPS:
            b2 = b1 + r * sin(t) / q
        else:
            b2 = b1

        h = self.height if height is None else height
        return self.classof(degrees90(a2), degrees180(b2), height=h)
Beispiel #4
0
    def rhumbMidpointTo(self, other, height=None):
        '''Return the (loxodromic) midpoint between this and
           an other point.

           @param other: The other point (spherical LatLon).
           @keyword height: Optional height, overriding the mean height
                            (meter or same unit as radius).

           @return: The midpoint (spherical LatLon).

           @raise TypeError: The other point is not spherical.

           @example:

           >>> p = LatLon(51.127, 1.338)
           >>> q = LatLon(50.964, 1.853)
           >>> m = p.rhumb_midpointTo(q)
           >>> m.toStr()  # '51.0455°N, 001.5957°E'
        '''
        self.others(other)

        # see <http://mathforum.org/library/drmath/view/51822.html>
        a1, b1 = self.to2ab()
        a2, b2 = other.to2ab()
        if abs(b2 - b1) > PI:
            b1 += PI2  # crossing anti-meridian

        a3 = favg(a1, a2)
        b3 = favg(b1, b2)

        f1 = tanPI_2_2(a1)
        if abs(f1) > EPS:
            f2 = tanPI_2_2(a2)
            f = f2 / f1
            if abs(f) > EPS:
                f = log(f)
                if abs(f) > EPS:
                    f3 = tanPI_2_2(a3)
                    b3 = fsum_(b1 * log(f2), -b2 * log(f1),
                               (b2 - b1) * log(f3)) / f

        h = self._havg(other) if height is None else height
        return self.classof(degrees90(a3), degrees180(b3), height=h)
Beispiel #5
0
    def rhumbMidpointTo(self, other):
        '''Return the loxodromic midpoint between this and an
           other point.

           @param other: The other point (spherical LatLon).

           @return: The midpoint (spherical LatLon).

           @raise TypeError: The other point is not spherical.

           @example:

           >>> p = LatLon(51.127, 1.338)
           >>> q = LatLon(50.964, 1.853)
           >>> m = p.rhumb_midpointTo(q)
           >>> m.toStr()  # '51.0455°N, 001.5957°E'
        '''
        self.others(other)

        # see http://mathforum.org/library/drmath/view/51822.html
        a1, b1 = self.to2ab()
        a2, b2 = other.to2ab()
        if abs(b2 - b1) > PI:
            b1 += PI2  # crossing anti-meridian

        a3 = (a1 + a2) * 0.5
        b3 = (b1 + b2) * 0.5

        f1 = tanPI_2_2(a1)
        if abs(f1) > EPS:
            f2 = tanPI_2_2(a2)
            f = f2 / f1
            if abs(f) > EPS:
                f = log(f)
                if abs(f) > EPS:
                    f3 = tanPI_2_2(a3)
                    b3 = (b1 * log(f2) - b2 * log(f1) +
                          (b2 - b1) * log(f3)) / f

        return self.topsub(degrees90(a3),
                           degrees180(b3),
                           height=self._alter(other))
Beispiel #6
0
 def _tdef(self, lat):
     '''(INTERNAL) Compute t(lat).
     '''
     return max(0, tanPI_2_2(-lat) / self._pdef(lat))