def mask_cells_with_polygon(self, polyverts, use_centroids=True, min_nodes=3, inside=True, use_existing=True, triangles=False): """ Create mask for the cells of the ModelGrid with a polygon. Parameters ---------- polyverts : sequence of a polygon's vertices A sequence of x-y pairs for each vertex of the polygon. use_centroids : bool (default = True) When True, the cell centroid will be used to determine whether the cell is "inside" the polygon. If False, the nodes are used instead. min_nodes : int (default = 3) Only used when ``use_centroids`` is False. This is the minimum number of nodes inside the polygon required to mark the cell as "inside". Must be greater than 0, but no more than 4. inside : bool (default = True) Toggles masking of cells either *inside* (True) or *outside* (False) the polygon. triangles : bool Not yet implemented. use_existing : bool (default = True) When True, the newly computed mask is combined (via a bit-wise `or` operation) with the existing ``cell_mask`` attribute of the MdoelGrid. Returns ------- masked : ModelGrid A new :class:`~ModelGrid` wit the final mask to be applied to the cells. """ if triangles: raise NotImplementedError("triangles are not yet implemented.") if use_centroids: cell_mask = misc.mask_with_polygon(self.xc, self.yc, polyverts, inside=inside) else: if min_nodes <= 0 or min_nodes > 4: raise ValueError("`min_nodes` must be greater than 0 and no more than 4.") _node_mask = misc.mask_with_polygon(self.xn, self.yn, polyverts, inside=inside).astype(int) cell_mask = ( _node_mask[1:, 1:] + _node_mask[:-1, :-1] + _node_mask[:-1, 1:] + _node_mask[1:, :-1] ) >= min_nodes cell_mask = cell_mask.astype(bool) if use_existing: cell_mask = np.bitwise_or(self.cell_mask, cell_mask) return self.update_cell_mask(mask=cell_mask)
def mask_centroids(self, polyverts, inside=True, use_existing=True): """ Create mask for the cells of the ModelGrid with a polygon. Parameters ---------- polyverts : sequence of a polygon's vertices A sequence of x-y pairs for each vertex of the polygon. inside : bool (default = True) Toggles masking of cells either *inside* (True) or *outside* (False) the polygon. use_existing : bool (default = True) When True, the newly computed mask is combined (via a bit-wise `or` operation) with the existing ``cell_mask`` attribute of the MdoelGrid. Returns ------- masked : ModelGrid A new :class:`~ModelGrid` wit the final mask to be applied to the cells. """ cell_mask = misc.mask_with_polygon(self.xc, self.yc, polyverts, inside=inside) return self.update_cell_mask(mask=cell_mask, merge_existing=use_existing)
def mask_centroids(self, inside=None, outside=None, use_existing=True): """ Create mask for the cells of the ModelGrid with a polygon. Parameters ---------- inside, outside : GeoDataFrame, optional GeoDataFrames of Polygons or MultiPolygons inside or outside of which nodes will be masked, respectively. use_existing : bool (default = True) When True, the newly computed mask is combined (via a bit-wise `or` operation) with the existing ``cell_mask`` attribute of the ModelGrid. Returns ------- masked : ModelGrid A new :class:`~ModelGrid` wit the final mask to be applied to the cells. """ if inside is None and outside is None: raise ValueError( "must provide at least one of `inside` or `outside`") if inside is not None: poly = validate.simple_polygon_gdf(inside).geometry.tolist() inside_cell_mask = misc.mask_with_polygon(self.xc, self.yc, *poly, inside=True) else: inside_cell_mask = numpy.zeros_like(self.xc).astype(bool) if outside is not None: poly = validate.simple_polygon_gdf(outside).geometry.tolist() outside_cell_mask = misc.mask_with_polygon(self.xc, self.yc, *poly, inside=False) else: outside_cell_mask = numpy.zeros_like(self.xc).astype(bool) cell_mask = numpy.bitwise_or(inside_cell_mask, outside_cell_mask) return self.update_cell_mask(mask=cell_mask, merge_existing=use_existing)
def test_mask_with_polygon(inside, expected): y, x = numpy.mgrid[:5, :5] polyverts = [ (0.5, 2.5), (3.5, 2.5), (3.5, 0.5), (0.5, 0.5), ] mask = misc.mask_with_polygon(x, y, polyverts, inside=inside) nptest.assert_array_equal(mask, expected)
def mask_nodes(self, polyverts, min_nodes=3, inside=False, use_existing=False, triangles=False): """ Create mask the ModelGrid based on its nodes with a polygon . Parameters ---------- polyverts : sequence of a polygon's vertices A sequence of x-y pairs for each vertex of the polygon. min_nodes : int (default = 3) Only used when ``use_centroids`` is False. This is the minimum number of nodes inside the polygon required to mark the cell as "inside". Must be greater than 0, but no more than 4. inside : bool (default = True) Toggles masking of cells either *inside* (True) or *outside* (False) the polygon. use_existing : bool (default = True) When True, the newly computed mask is combined (via a bit-wise `or` operation) with the existing ``cell_mask`` attribute of the ModelGrid. Returns ------- masked : ModelGrid A new :class:`~ModelGrid` wit the final mask to be applied to the cells. """ if triangles: raise NotImplementedError( "triangular cells are not yet implemented") if min_nodes <= 0 or min_nodes > 4: raise ValueError( "`min_nodes` must be greater than 0 and no more than 4.") _node_mask = misc.mask_with_polygon(self.xn, self.yn, polyverts, inside=inside).astype(int) cell_mask = (_node_mask[1:, 1:] + _node_mask[:-1, :-1] + _node_mask[:-1, 1:] + _node_mask[1:, :-1]) >= min_nodes cell_mask = cell_mask.astype(bool) return self.update_cell_mask(mask=cell_mask, merge_existing=use_existing)
def mask_nodes(self, inside=None, outside=None, min_nodes=3, use_existing=False, triangles=False): """ Create mask the ModelGrid based on its nodes with a polygon. Parameters ---------- inside, outside : GeoDataFrame, optional GeoDataFrames of Polygons or MultiPolygons inside or outside of which nodes will be masked, respectively. min_nodes : int (default = 3) Only used when ``use_centroids`` is False. This is the minimum number of nodes inside the polygon required to mark the cell as "inside". Must be greater than 0, but no more than 4. use_existing : bool (default = True) When True, the newly computed mask is combined (via a bit-wise `or` operation) with the existing ``cell_mask`` attribute of the ModelGrid. Returns ------- masked : ModelGrid A new :class:`~ModelGrid` with the final mask to be applied to the cells. """ if inside is None and outside is None: raise ValueError( "must provide at least one of `inside` or `outside`") if triangles: raise NotImplementedError( "triangular cells are not yet implemented") if min_nodes <= 0 or min_nodes > 4: raise ValueError( "`min_nodes` must be greater than 0 and no more than 4.") if inside is not None: poly = validate.simple_polygon_gdf(inside).geometry.tolist() inside_node_mask = misc.mask_with_polygon(self.xn, self.yn, *poly, inside=True) else: inside_node_mask = numpy.zeros_like(self.xn).astype(bool) if outside is not None: poly = validate.simple_polygon_gdf(outside).geometry.tolist() outside_node_mask = misc.mask_with_polygon(self.xn, self.yn, *poly, inside=False) else: outside_node_mask = numpy.zeros_like(self.xn).astype(bool) node_mask = numpy.bitwise_or(inside_node_mask, outside_node_mask) cell_mask = (misc.padded_sum(node_mask.astype(int), window=1) >= min_nodes).astype(bool) return self.update_cell_mask(mask=cell_mask, merge_existing=use_existing)
def test_outside(self): mask = misc.mask_with_polygon(self.x, self.y, self.polyverts, inside=False) nptest.assert_array_equal(mask, self.known_outside_mask)
def test_default_inside(self): mask = misc.mask_with_polygon(self.x, self.y, self.polyverts) nptest.assert_array_equal(mask, self.known_inside_mask)