def get_roi(self, minlon, maxlon, minlat, maxlat): """Return numpy array of data specified by its geographical bounds Parameters ---------- minlon : int or float Western longitude bound [degrees]. maxlon : int or float Eastern longitude bound [degrees]. minlat : int or float Southern latitude bound [degrees]. maxlat : int or float Northern latitude bound [degrees]. Returns ------- roi : numpy 2D array Numpy array specified by extent given. Examples -------- # TODO """ if (not self.inbounds(minlat, minlon) or not self.inbounds(maxlat, maxlon)): raise DataImportError("Roi extent out of dataset bounds.") topind = ch.deg2pix(self.nlat - maxlat, self.ppd) height = ch.deg2pix(maxlat - minlat, self.ppd) if self.is_global() and (minlon < self.wlon or maxlon > self.elon): roi = self._wrap_roi_360(minlon, maxlon, topind, height) else: leftind = ch.deg2pix(minlon - self.wlon, self.ppd) width = ch.deg2pix(maxlon - minlon, self.ppd) roi = self.ReadAsArray(leftind, topind, width, height) return roi.astype(float)
def test_deg2pix(self): """Test deg2pix function""" actual = ch.deg2pix(10, 20) expected = 200 self.assertEqual(actual, expected) actual = ch.deg2pix(5.5, 2.5) expected = 13 self.assertEqual(actual, expected)
def polygon_mask(croi, poly_verts): """Mask the region inside a polygon given by poly_verts. Uses the matplotlib.Path module and included contains_points() method to calculate the interior of a polygon specified as a list of (lat, lon) vertices. Parameters ========== croi : CraterRoi Crater region of interest being masked. poly_verts : list of tuple List of (lon, lat) polygon vertices. Returns ------- mask : numpy 2D array Example ======= >>> import os.path as p >>> f = p.join(p.dirname(p.abspath('__file__')), 'examples', 'moon.tif') >>> cds = CraterpyDataset(f, radius=1737) >>> croi = CraterRoi(cds, -27.2, 80.9, 207) # Humboldt crater >>> poly = [[-27.5, 80.5], [-28, 80.5], [-28, 81], [-27.5, 81]] >>> mask = polygon_mask(cds, roi, extent, poly) >>> croi.mask(mask) >>> croi.plot() """ from matplotlib.path import Path minlon, maxlon, minlat, maxlat = croi.extent # Create grid nlat, nlon = croi.roi.shape x, y = np.meshgrid(np.arange(nlon), np.arange(nlat)) x, y = x.flatten(), y.flatten() gridpoints = np.vstack((x, y)).T poly_pix = [(ch.deg2pix(lon - minlon, croi.cds.ppd), ch.deg2pix(lat - minlat, croi.cds.ppd)) for lon, lat in poly_verts] path = Path(poly_pix) mask = path.contains_points(gridpoints).reshape((nlat, nlon)) return mask
def _wrap_roi_360(self, minlon, maxlon, topind, height): """Return roi that is split by the 360 degree edge of a global dataset. Read the left and right sub-arrays and then concatenate them into the full roi. Parameters ---------- minlon : int or float Western longitude bound [degrees]. maxlon : int or float Eastern longitude bound [degrees]. topind : int Top index of returned roi. height : int Height of returned roi. Returns -------- roi: 2Darray Concatenated roi wrapped around lon bound. """ if minlon < self.wlon: leftind = ch.deg2pix(minlon - (self.wlon - 360), self.ppd) leftwidth = ch.deg2pix(self.wlon - minlon, self.ppd) rightind = 0 rightwidth = ch.deg2pix(maxlon - self.wlon, self.ppd) elif maxlon > self.elon: leftind = ch.deg2pix(self.elon - minlon, self.ppd) leftwidth = ch.deg2pix(self.elon - minlon, self.ppd) rightind = 0 rightwidth = ch.deg2pix(maxlon - self.elon, self.ppd) left_roi = self.ReadAsArray(leftind, topind, leftwidth, height) right_roi = self.ReadAsArray(rightind, topind, rightwidth, height) return np.concatenate((left_roi, right_roi), axis=1)