def _toZBll(lat, lon): '''(INTERNAL) Return zone, Band and central lat- and longitude. @param lat: Latitude (degrees). @param lon: Longitude (degrees). @return: 4-Tuple (zone, Band, lat, lon). ''' # return zone, Band and central # lat- and longitude (in radians) lat = wrap90(lat) if -80 > lat or lat > 84: raise ValueError('%s outside UTM: %s' % ('lat', lat)) B = _Bands[int(lat + 80) >> 3] lon = wrap180(lon) z = int((lon + 180) / 6) + 1 # longitudinal zone if B == 'X': x = {32: 9, 34: 21, 36: 33}.get(z, None) if x: # Svalbard if lon >= x: z += 1 else: z -= 1 elif B == 'V' and z == 31 and lon >= 3: z += 1 # southern Norway b = radians(lon - _cmlon(z)) # lon off central meridian a = radians(lat) # lat off equator return z, B, a, b
def point(self, ll): '''Create a pseudo-xy. @param ll: Point (I{LatLon}). @return: 3-Tuple (x, y, ll) of (float, float, I{ll}). ''' x, y = ll.lon, ll.lat # note, x, y = lon, lat if self._wrap: x, y = wrap180(x), wrap90(y) if self._deg2m: # convert degrees to meter x, y = x * self._deg2m, y * self._deg2m return x, y, ll
def isenclosedby(latlon, points, wrap=False): # MCCABE 14 '''Determine whether a point is enclosed by a polygon defined by an array, list, sequence, set or tuple of points. @param latlon: The point (I{LatLon} or 2-tuple (lat, lon)). @param points: The points defining the polygon (I{LatLon}[]). @keyword wrap: Wrap lat-, wrap and unroll longitudes (bool). @return: True if I{latlon} is inside the polygon, False otherwise. @raise TypeError: Some I{points} are not I{LatLon}. @raise ValueError: Insufficient number of I{points} or invalid I{latlon}. @see: L{sphericalNvector.LatLon.isEnclosedBy}, L{sphericalTrigonometry.LatLon.isEnclosedBy} and U{MultiDop GeogContainPt<http://github.com/nasa/MultiDop>} (U{Shapiro et al. 2009, JTECH <http://journals.ametsoc.org/doi/abs/10.1175/2009JTECHA1256.1>} and U{Potvin et al. 2012, JTECH <http://journals.ametsoc.org/doi/abs/10.1175/JTECH-D-11-00019.1>}). ''' pts = LatLon2psxy(points, closed=True, radius=None, wrap=wrap) def _xy(i): x, y, _ = pts[i] if not wrap: x %= 360.0 if x < (x0 - 180): x += 360 elif x >= (x0 + 180): x -= 360 return x, y try: y0, x0 = latlon.lat, latlon.lon except AttributeError: try: y0, x0 = latlon[:2] except (IndexError, TypeError, ValueError): raise ValueError('%s invalid: %r' % ('latlon', latlon)) if wrap: x0, y0 = wrap180(x0), wrap90(y0) else: x0 %= 360.0 n = len(pts) e = m = False s = Fsum() x1, y1 = _xy(n - 1) for i in range(n): x2, y2 = _xy(i) dx, x2 = unroll180(x1, x2, wrap=wrap) # determine if polygon edge (x1, y1)..(x2, y2) straddles # point (lat, lon) or is on boundary, but do not count # edges on boundary as more than one crossing if abs(dx) < 180 and (x1 < x0 <= x2 or x2 < x0 <= x1): m = not m dy = (x0 - x1) * (y2 - y1) - (y0 - y1) * dx if (dy > 0 and dx >= 0) or (dy < 0 and dx <= 0): e = not e s.fadd(sin(radians(y2))) x1, y1 = x2, y2 # an odd number of meridian crossings means polygon contains # a pole, assume that is the hemisphere containing the polygon # mean and if polygon contains North Pole, flip the result if m and s.fsum() > 0: e = not e return e
def _2xy(p): # map to flat x-y space return wrap180(p.lon), wrap90(p.lat)