def test_extract_from_array(): """Extract subdata from array.""" in_tile = BufferedTilePyramid("geodetic", metatiling=4).tile(5, 5, 5) shape = (in_tile.shape[0] // 2, in_tile.shape[1]) data = ma.masked_array(np.concatenate([np.ones(shape), np.ones(shape) * 2])) # intersecting at top out_tile = BufferedTilePyramid("geodetic").tile(5, 20, 20) out_array = extract_from_array(in_raster=data, in_affine=in_tile.affine, out_tile=out_tile) assert isinstance(out_array, np.ndarray) assert np.all(np.where(out_array == 1, True, False)) # intersecting at bottom out_tile = BufferedTilePyramid("geodetic").tile(5, 22, 20) out_array = extract_from_array(in_raster=data, in_affine=in_tile.affine, out_tile=out_tile) assert isinstance(out_array, np.ndarray) assert np.all(np.where(out_array == 2, True, False)) # not intersecting out_tile = BufferedTilePyramid("geodetic").tile(5, 15, 20) with pytest.raises(ValueError): out_array = extract_from_array(in_raster=data, in_affine=in_tile.affine, out_tile=out_tile)
def read(self, **kwargs): """ Read existing output data from a previous run. Returns ------- process output : NumPy array (raster) or feature iterator (vector) """ if self.tile.pixelbuffer > self.config.output.pixelbuffer: output_tiles = list( self.config.output_pyramid.tiles_from_bounds( self.tile.bounds, self.tile.zoom)) else: output_tiles = self.config.output_pyramid.intersecting(self.tile) if self.config.output.METADATA["data_type"] == "raster": return raster.extract_from_array(in_raster=raster.create_mosaic([ (output_tile, self.config.output.read(output_tile)) for output_tile in output_tiles ]), out_tile=self.tile) elif self.config.output.METADATA["data_type"] == "vector": return list( chain.from_iterable([ self.config.output.read(output_tile) for output_tile in output_tiles ]))
def write(self, process_tile, data): """ Write data from process tiles into GeoTIFF file(s). Parameters ---------- process_tile : ``BufferedTile`` must be member of process ``TilePyramid`` """ data = prepare_array(data, masked=True, nodata=self.output_params["nodata"], dtype=self.profile(process_tile)["dtype"]) if data.mask.all(): logger.debug("data empty, nothing to write") else: # Convert from process_tile to output_tiles and write for tile in self.pyramid.intersecting(process_tile): out_tile = BufferedTile(tile, self.pixelbuffer) write_window = from_bounds( *out_tile.bounds, transform=self.rio_file.transform, height=self.rio_file.height, width=self.rio_file.width).round_lengths( pixel_precision=0).round_offsets(pixel_precision=0) if _window_in_out_file(write_window, self.rio_file): logger.debug("write data to window: %s", write_window) self.rio_file.write( extract_from_array(in_raster=data, in_affine=process_tile.affine, out_tile=out_tile) if process_tile != out_tile else data, window=write_window, )
def _read_existing_output(self, tile, output_tiles): if self.config.output.METADATA["data_type"] == "raster": mosaic, affine = raster.create_mosaic([ (output_tile, self.read(output_tile)) for output_tile in output_tiles ]) return raster.extract_from_array(mosaic, affine, tile) elif self.config.output.METADATA["data_type"] == "vector": return list( chain.from_iterable( [self.read(output_tile) for output_tile in output_tiles]))
def _extract(self, in_tile=None, in_data=None, out_tile=None): """Extract data from tile.""" if self.config.output.METADATA["data_type"] == "raster": return raster.extract_from_array(in_raster=raster.prepare_array( in_data, nodata=self.config.output.nodata, dtype=self.config.output.output_params["dtype"]), in_affine=in_tile.affine, out_tile=out_tile) elif self.config.output.METADATA["data_type"] == "vector": return [ feature for feature in in_data if shape(feature["geometry"]).intersects(out_tile.bbox) ]
def extract_subset(self, input_data_tiles=None, out_tile=None): """ Extract subset from multiple tiles. input_data_tiles : list of (``Tile``, process data) tuples out_tile : ``Tile`` Returns ------- NumPy array or list of features. """ if self.METADATA["data_type"] == "raster": mosaic = create_mosaic(input_data_tiles) return extract_from_array(in_raster=prepare_array( mosaic.data, nodata=self.output_params["nodata"], dtype=self.output_params["dtype"]), in_affine=mosaic.affine, out_tile=out_tile) elif self.METADATA["data_type"] == "vector": return [ feature for feature in list( chain.from_iterable( [features for _, features in input_data_tiles])) if shape(feature["geometry"]).intersects(out_tile.bbox) ]