def __init__(self, area_id, name, proj_id, proj_dict, x_size, y_size, area_extent, nprocs=1, lons=None, lats=None, dtype=np.float64): if not isinstance(proj_dict, dict): raise TypeError('Wrong type for proj_dict: %s. Expected dict.' % type(proj_dict)) super(AreaDefinition, self).__init__(lons, lats, nprocs) self.area_id = area_id self.name = name self.proj_id = proj_id self.x_size = int(x_size) self.y_size = int(y_size) self.shape = (y_size, x_size) if lons is not None: if lons.shape != self.shape: raise ValueError('Shape of lon lat grid must match ' 'area definition') self.size = y_size * x_size self.ndim = 2 self.pixel_size_x = (area_extent[2] - area_extent[0]) / float(x_size) self.pixel_size_y = (area_extent[3] - area_extent[1]) / float(y_size) self.proj_dict = proj_dict self.area_extent = tuple(area_extent) # Calculate area_extent in lon lat proj = _spatial_mp.Proj(**proj_dict) corner_lons, corner_lats = proj((area_extent[0], area_extent[2]), (area_extent[1], area_extent[3]), inverse=True) self.area_extent_ll = (corner_lons[0], corner_lats[0], corner_lons[1], corner_lats[1]) # Calculate projection coordinates of center of upper left pixel self.pixel_upper_left = \ (float(area_extent[0]) + float(self.pixel_size_x) / 2, float(area_extent[3]) - float(self.pixel_size_y) / 2) # Pixel_offset defines the distance to projection center from origen (UL) # of image in units of pixels. self.pixel_offset_x = -self.area_extent[0] / self.pixel_size_x self.pixel_offset_y = self.area_extent[3] / self.pixel_size_y self._projection_x_coords = None self._projection_y_coords = None self.dtype = dtype
def get_xy_from_lonlat(self, lon, lat): """Retrieve closest x and y coordinates (column, row indices) for the specified geolocation (lon,lat) if inside area. If lon,lat is a point a ValueError is raised if the return point is outside the area domain. If lon,lat is a tuple of sequences of longitudes and latitudes, a tuple of masked arrays are returned. :Input: lon : point or sequence (list or array) of longitudes lat : point or sequence (list or array) of latitudes :Returns: (x, y) : tuple of integer points/arrays """ if isinstance(lon, list): lon = np.array(lon) if isinstance(lat, list): lat = np.array(lat) if ((isinstance(lon, np.ndarray) and not isinstance(lat, np.ndarray)) or (not isinstance(lon, np.ndarray) and isinstance(lat, np.ndarray))): raise ValueError("Both lon and lat needs to be of " + "the same type and have the same dimensions!") if isinstance(lon, np.ndarray) and isinstance(lat, np.ndarray): if lon.shape != lat.shape: raise ValueError("lon and lat is not of the same shape!") pobj = _spatial_mp.Proj(self.proj4_string) upl_x = self.area_extent[0] upl_y = self.area_extent[3] xscale = abs(self.area_extent[2] - self.area_extent[0]) / float(self.x_size) yscale = abs(self.area_extent[1] - self.area_extent[3]) / float(self.y_size) xm_, ym_ = pobj(lon, lat) x__ = (xm_ - upl_x) / xscale y__ = (upl_y - ym_) / yscale if isinstance(x__, np.ndarray) and isinstance(y__, np.ndarray): mask = (((x__ < 0) | (x__ > self.x_size)) | ((y__ < 0) | (y__ > self.y_size))) return (np.ma.masked_array(x__.astype('int'), mask=mask, fill_value=-1), np.ma.masked_array(y__.astype('int'), mask=mask, fill_value=-1)) else: if ((x__ < 0 or x__ > self.x_size) or (y__ < 0 or y__ > self.y_size)): raise ValueError('Point outside area:( %f %f)' % (x__, y__)) return int(x__), int(y__)
def colrow2lonlat(self, cols, rows): """ Return longitudes and latitudes for the given image columns and rows. Both scalars and arrays are supported. To be used with scarse data points instead of slices (see get_lonlats). """ p = _spatial_mp.Proj(self.proj4_string) x = self.proj_x_coords y = self.proj_y_coords return p(y[y.size - cols], x[x.size - rows], inverse=True)
def outer_boundary_corners(self): """Returns the lon,lat of the outer edges of the corner points """ from pyresample.spherical_geometry import Coordinate proj = _spatial_mp.Proj(**self.proj_dict) corner_lons, corner_lats = proj((self.area_extent[0], self.area_extent[2], self.area_extent[2], self.area_extent[0]), (self.area_extent[3], self.area_extent[3], self.area_extent[1], self.area_extent[1]), inverse=True) return [Coordinate(corner_lons[0], corner_lats[0]), Coordinate(corner_lons[1], corner_lats[1]), Coordinate(corner_lons[2], corner_lats[2]), Coordinate(corner_lons[3], corner_lats[3])]
def get_linesample(lons, lats, source_area_def, nprocs=1): """Returns index row and col arrays for resampling Parameters ---------- lons : numpy array Lons. Dimensions must match lats lats : numpy array Lats. Dimensions must match lons source_area_def : object Source definition as AreaDefinition object nprocs : int, optional Number of processor cores to be used Returns ------- (row_indices, col_indices) : tuple of numpy arrays Arrays for resampling area by array indexing """ # Proj.4 definition of source area projection if nprocs > 1: source_proj = _spatial_mp.Proj_MP(**source_area_def.proj_dict) else: source_proj = _spatial_mp.Proj(**source_area_def.proj_dict) # get cartesian projection values from longitude and latitude source_x, source_y = source_proj(lons, lats, nprocs=nprocs) # Find corresponding pixels (element by element conversion of ndarrays) source_pixel_x = (source_area_def.pixel_offset_x + source_x / source_area_def.pixel_size_x).astype(np.int32) source_pixel_y = (source_area_def.pixel_offset_y - source_y / source_area_def.pixel_size_y).astype(np.int32) return source_pixel_y, source_pixel_x
def get_xy_from_lonlat(self, lon, lat): """Retrieve closest x and y coordinates (column, row indices) for the specified geolocation (lon,lat) if inside area. If lon,lat is a point a ValueError is raised if the return point is outside the area domain. If lon,lat is a tuple of sequences of longitudes and latitudes, a tuple of masked arrays are returned. :Input: lon : point or sequence (list or array) of longitudes lat : point or sequence (list or array) of latitudes :Returns: (x, y) : tuple of integer points/arrays """ if isinstance(lon, list): lon = np.array(lon) if isinstance(lat, list): lat = np.array(lat) if ((isinstance(lon, np.ndarray) and not isinstance(lat, np.ndarray)) or (not isinstance(lon, np.ndarray) and isinstance(lat, np.ndarray))): raise ValueError("Both lon and lat needs to be of " + "the same type and have the same dimensions!") if isinstance(lon, np.ndarray) and isinstance(lat, np.ndarray): if lon.shape != lat.shape: raise ValueError("lon and lat is not of the same shape!") pobj = _spatial_mp.Proj(self.proj4_string) xm_, ym_ = pobj(lon, lat) return self.get_xy_from_proj_coords(xm_, ym_)
def get_lonlats(self, nprocs=None, data_slice=None, cache=False, dtype=None): """Returns lon and lat arrays of area. Parameters ---------- nprocs : int, optional Number of processor cores to be used. Defaults to the nprocs set when instantiating object data_slice : slice object, optional Calculate only coordinates for specified slice cache : bool, optional Store result the result. Requires data_slice to be None Returns ------- (lons, lats) : tuple of numpy arrays Grids of area lons and and lats """ if dtype is None: dtype = self.dtype if self.lons is None or self.lats is None: #Data is not cached if nprocs is None: nprocs = self.nprocs # Proj.4 definition of target area projection if nprocs > 1: target_proj = _spatial_mp.Proj_MP(**self.proj_dict) else: target_proj = _spatial_mp.Proj(**self.proj_dict) # Get coordinates of local area as ndarrays target_x, target_y = self.get_proj_coords( data_slice=data_slice, dtype=dtype) # Get corresponding longitude and latitude values lons, lats = target_proj(target_x, target_y, inverse=True, nprocs=nprocs) lons = np.asanyarray(lons, dtype=dtype) lats = np.asanyarray(lats, dtype=dtype) if cache and data_slice is None: # Cache the result if requested self.lons = lons self.lats = lats # Free memory del(target_x) del(target_y) else: #Data is cached if data_slice is None: # Full slice lons = self.lons lats = self.lats else: lons = self.lons[data_slice] lats = self.lats[data_slice] return lons, lats