示例#1
0
    def nearestOn2(self, points, closed=False, radius=R_M, height=None):
        '''Locate the point on a polygon (with great circle arcs
           joining consecutive points) closest to this point.

           If this point is within the extent of any great circle
           arc, the closest point is on that arc.  Otherwise,
           the closest is the nearest of the arc's end points.

           @param points: The polygon points (L{LatLon}[]).
           @keyword closed: Optionally, close the polygon (C{bool}).
           @keyword radius: Optional, mean earth radius (C{meter}).
           @keyword height: Optional height, overriding the mean height
                            for a point within the arc (C{meter}).

           @return: 2-Tuple (closest, distance) of the closest point
                    (L{LatLon}) on the polygon and the distance to
                    that point from the given point in C{meter}, same
                    units of B{C{radius}}.

           @raise TypeError: Some B{C{points}} are not C{LatLon}.

           @raise ValueError: No B{C{points}}.
        '''
        n, points = self.points2(points, closed=closed)

        i, m = _imdex2(closed, n)
        c = p2 = points[i]
        d = self.distanceTo(c, radius=radius)
        for i in range(m, n):
            p1, p2 = p2, points[i]
            p = self.nearestOn(p1, p2, height=height)
            t = self.distanceTo(p, radius=radius)
            if t < d:
                c, d = p, t
        return c, d
示例#2
0
 def _rads(n, points, closed):  # angular edge lengths in radians
     i, m = _imdex2(closed, n)
     v1 = points[i].toNvector()
     for i in range(m, n):
         v2 = points[i].toNvector()
         yield v1.angleTo(v2)
         v1 = v2
 def _rads(n, points, closed):  # angular edge lengths in radians
     i, m = _imdex2(closed, n)
     a1, b1 = points[i].to2ab()
     for i in range(m, n):
         a2, b2 = points[i].to2ab()
         db, b2 = unrollPI(b1, b2, wrap=wrap)
         yield haversine_(a2, a1, db)
         a1, b1 = a2, b2
 def _rads(n, points, closed):  # angular edge lengths in radians
     i, m = _imdex2(closed, n)
     a1, b1 = points[i].philam
     for i in range(m, n):
         a2, b2 = points[i].philam
         db, b2 = unrollPI(b1, b2, wrap=wrap)
         yield vincentys_(a2, a1, db)
         a1, b1 = a2, b2
示例#5
0
def clipCS3(points,
            lowerleft,
            upperright,
            closed=False,
            inull=False):  # MCCABE 25
    '''Clip a path against a rectangular clip box using the
       U{Cohen-Sutherland
       <https://WikiPedia.org/wiki/Cohen-Sutherland_algorithm>} algorithm.

       @param points: The points (C{LatLon}[]).
       @param lowerleft: Bottom-left corner of the clip box (C{LatLon}).
       @param upperright: Top-right corner of the clip box (C{LatLon}).
       @keyword closed: Optionally, close the path (C{bool}).
       @keyword inull: Optionally, include null edges if inside (C{bool}).

       @return: Yield a L{ClipCS3Tuple}C{(start, end, index)} for each
                edge of the clipped path.

       @raise ValueError: The B{C{lowerleft}} corner is not below and/or
                          not to the left of the B{C{upperright}} corner.
    '''

    cs = _CS(lowerleft, upperright)
    n, points = points2(points, closed=closed)

    i, m = _imdex2(closed, n)
    cmbp = cs.code4(points[i])
    for i in range(m, n):
        c1, m1, b1, p1 = cmbp
        c2, m2, b2, p2 = cmbp = cs.code4(points[i])
        if c1 & c2:  # edge outside
            continue

        if not cs.edge(p1, p2):
            if inull:  # null edge
                if not c1:
                    yield ClipCS3Tuple(p1, p1, i)
                elif not c2:
                    yield ClipCS3Tuple(p2, p2, i)
            continue

        for _ in range(5):
            if c1:  # clip p1
                c1, m1, b1, p1 = m1(b1, p1)
            elif c2:  # clip p2
                c2, m2, b2, p2 = m2(b2, p2)
            else:  # inside
                if inull or _neq(p1, p2):
                    yield ClipCS3Tuple(p1, p2, i)
                break
            if c1 & c2:  # edge outside
                break
        else:  # should never get here
            raise AssertionError('clipCS3.for _')
示例#6
0
def clipCS3(points, lowerleft, upperright, closed=False, inull=False):
    '''Clip a path against a rectangular clip box using the
       U{Cohen-Sutherland
       <https://WikiPedia.org/wiki/Cohen-Sutherland_algorithm>} algorithm.

       @arg points: The points (C{LatLon}[]).
       @arg lowerleft: Bottom-left corner of the clip box (C{LatLon}).
       @arg upperright: Top-right corner of the clip box (C{LatLon}).
       @kwarg closed: Optionally, close the path (C{bool}).
       @kwarg inull: Optionally, include null edges if inside (C{bool}).

       @return: Yield a L{ClipCS3Tuple}C{(start, end, index)} for each
                edge of the clipped path.

       @raise ClipError: The B{C{lowerleft}} and B{C{upperright}} corners
                         specify an invalid clip box.

       @raise PointsError: Insufficient number of B{C{points}}.
    '''

    cs = _CS(lowerleft, upperright, clipCS3.__name__)
    n, pts = _points2(points, closed, inull)

    i, m = _imdex2(closed, n)
    cmbp = cs.code4(pts[i])
    for i in range(m, n):
        c1, m1, b1, p1 = cmbp
        c2, m2, b2, p2 = cmbp = cs.code4(pts[i])
        if c1 & c2:  # edge outside
            continue

        if not cs.edge(p1, p2):
            if inull:  # null edge
                if not c1:
                    yield ClipCS3Tuple(p1, p1, i)
                elif not c2:
                    yield ClipCS3Tuple(p2, p2, i)
            continue

        for _ in range(5):
            if c1:  # clip p1
                c1, m1, b1, p1 = m1(b1, p1)
            elif c2:  # clip p2
                c2, m2, b2, p2 = m2(b2, p2)
            else:  # inside
                if inull or _neq(p1, p2):
                    yield ClipCS3Tuple(p1, p2, i)
                break
            if c1 & c2:  # edge outside
                break
        else:  # PYCHOK no cover
            raise AssertionError(_dot_(cs._name, 'for_else'))
示例#7
0
    def nearestOn3(self, points, closed=False, radius=R_M, height=None):
        '''Locate the point on a polygon (with great circle arcs
           joining consecutive points) closest to this point.

           If this point is within the extent of any great circle
           arc, the closest point is on that arc.  Otherwise,
           the closest is the nearest of the arc's end points.

           @arg points: The polygon points (L{LatLon}[]).
           @kwarg closed: Optionally, close the polygon (C{bool}).
           @kwarg radius: Mean earth radius (C{meter}).
           @kwarg height: Optional height, overriding the mean height
                          for a point within the arc (C{meter}).

           @return: A L{NearestOn3Tuple}C{(closest, distance, angle)} of
                    the C{closest} point (L{LatLon}), the C{distance}
                    between this and the C{closest} point in C{meter},
                    same units as B{C{radius}} and the C{angle} from
                    this to the C{closest} point in compass C{degrees360}.

           @raise TypeError: Some B{C{points}} are not C{LatLon}.

           @raise ValueError: No B{C{points}}.
        '''
        n, points = self.points2(points, closed=closed)

        i, m = _imdex2(closed, n)
        c = p2 = points[i]
        r = self.distanceTo(c, radius=1)  # force radians
        for i in range(m, n):
            p1, p2 = p2, points[i]
            p = self.nearestOn(p1, p2, height=height)
            t = self.distanceTo(p, radius=1)  # force radians
            if t < r:
                c, r = p, t

        return NearestOn3Tuple(c, r * Radius(radius), degrees360(r))
示例#8
0
def clipLB6(points, lowerleft, upperright, closed=False, inull=False):
    '''Clip a path against a rectangular clip box using the U{Liang-Barsky
       <https://www.CSE.UNT.edu/~renka/4230/LineClipping.pdf>} algorithm.

       @arg points: The points (C{LatLon}[]).
       @arg lowerleft: Bottom-left corner of the clip box (C{LatLon}).
       @arg upperright: Top-right corner of the clip box (C{LatLon}).
       @kwarg closed: Optionally, close the path (C{bool}).
       @kwarg inull: Optionally, retain null edges if inside (C{bool}).

       @return: Yield a L{ClipLB6Tuple}C{(start, end, i, fi, fj, j)} for
                each edge of the I{clipped} path.

       @raise ClipError: The B{C{lowerleft}} and B{C{upperright}} corners
                         specify an invalid clip box.

       @raise PointsError: Insufficient number of B{C{points}}.

       @see: U{Liang-Barsky Line Clipping<https://www.CS.Helsinki.FI/group/goa/
             viewing/leikkaus/intro.html>}, U{Liang-Barsky line clipping algorithm
             <https://www.Skytopia.com/project/articles/compsci/clipping.html>}
             and U{Liang–Barsky algorithm<https://WikiPedia.org/wiki/Liang–Barsky_algorithm>}.
    '''
    xmin, ymin, \
    xmax, ymax = _box4(lowerleft, upperright, clipLB6.__name__)

    n, pts = _pts2(points, closed, inull)

    fin = n if closed else None  # wrapping fi [n] to [0]
    _LB = _LBtrim

    i, m = _imdex2(closed, n)
    pi = pts[i]
    for j in range(m, n):
        p1 = pi
        y1 = p1.lat
        x1 = p1.lon

        p2 = pi = pts[j]
        dy = float(p2.lat - y1)
        dx = float(p2.lon - x1)
        if abs(dx) > EPS or abs(dy) > EPS:
            # non-null edge pts[i]...pts[j]
            t = [_0_0, _1_0]
            if _LB(-dx, -xmin + x1, t) and \
               _LB( dx,  xmax - x1, t) and \
               _LB(-dy, -ymin + y1, t) and \
               _LB( dy,  ymax - y1, t):
                # clip edge pts[i]...pts[j]
                # at fractions t[0] to t[1]
                if t[0] > _0_0:  # EPS
                    p1 = p1.classof(y1 + t[0] * dy, x1 + t[0] * dx)
                    fi = i + t[0]
                else:
                    fi = i
                if t[0] < t[1]:
                    if t[1] < _1_0:  # EPS1
                        p2 = p2.classof(y1 + t[1] * dy, x1 + t[1] * dx)
                        fj = i + t[1]
                    else:
                        fj = j
                    fi = FIx(fi, fin=fin)
                    fj = FIx(fj, fin=fin)
                    yield ClipLB6Tuple(p1, p2, i, fi, fj, j)

                elif inull and (t[0] + EPS) > t[1]:
                    fi = FIx(fi, fin=fin)
                    yield ClipLB6Tuple(p1, p1, i, fi, fi, j)


#           else:  # outside
#               pass
        elif inull:  # null edge
            yield ClipLB6Tuple(p1, p2, i, FIx(i, fin=fin), FIx(j, fin=fin), j)
        i = j