def RasterizeLandCoverTile(tile, overwrite=False, **kwargs): """ Calculate one tile of landcover data from BD Topo and RPG """ template_raster = config.datasource('dem').filename landcover_base_tilename = config.tileset().tilename('landcover-cesbio', row=tile.row, col=tile.col) output = config.tileset().tilename('landcover-bdt', row=tile.row, col=tile.col) if os.path.exists(output) and not overwrite: return with rio.open(landcover_base_tilename) as ds: data = ds.read(1) profile = ds.profile.copy() with rio.open(template_raster) as template: window_t = as_window(tile.bounds, template.transform) it = window_t.row_off jt = window_t.col_off height = window_t.height width = window_t.width # data, profile = MkBaseLandCoverTile(tile, window_t) # CESBIO Water -> Open Natural data[data == 0] = 2 transform = template.transform * \ template.transform.translation(jt, it) # RasterizeBDTopoLayer(data, tile, transform, sea_mask) RasterizeBDTopoLayer(data, tile, transform, diffuse_urban) RasterizeBDTopoLayer(data, tile, transform, open_natural) RasterizeBDTopoLayer(data, tile, transform, grassland) RasterizeBDTopoLayer(data, tile, transform, cropland) RasterizeBDTopoLayer(data, tile, transform, forest) RasterizeBDTopoLayer(data, tile, transform, dense_urban) data = features.sieve(data, 50, connectivity=4) RasterizeBDTopoLayer(data, tile, transform, infrastructures) RasterizeBDTopoLayer(data, tile, transform, gravels) RasterizeBDTopoLayer(data, tile, transform, water) profile.update(height=height, width=width, nodata=255, dtype='uint8', transform=transform, compress='deflate') with rio.open(output, 'w', **profile) as dst: dst.write(data, 1)
def RasterizeLandCoverTile(tile): """ Enrich medium-resolution landcover data (CESBIO) with high-resolution data from topographic database (BD Topo) for class 'Water Channel' (0) and 'Gravel Bars' (1) """ rasterfile = config.tileset().tilename( 'landcover-cesbio', row=tile.row, col=tile.col) with rio.open(rasterfile) as ds: data = ds.read(1) profile = ds.profile.copy() profile.update(compress='deflate') transform = ds.transform # reclass unprecise CESBIO water to natural/open vegetation # precise water and gravel bars are going # to be extracted from BD Topo data[data == 0] = 2 layers = [ # extract_sea, gravels, water ] def shapes(fun): """ Generate Landcover Polygons """ with fiona.open(fun(tile.bounds)) as fs: if len(fs) == 0: raise StopIteration for feature in fs: yield feature['geometry'], feature['properties']['landcover'] for layer in layers: try: features.rasterize(shapes(layer), out=data, transform=transform) except RuntimeError: pass with rio.open(rasterfile, 'w', **profile) as dst: dst.write(data, 1)
def RasterizeLandCover(processes=1, **kwargs): tileindex = config.tileset().tileindex arguments = [(RasterizeLandCoverTile, tile, kwargs) for tile in tileindex.values()] with Pool(processes=processes, initializer=setup) as pool: pooled = pool.imap_unordered(starcall, arguments) with click.progressbar(pooled, length=len(arguments)) as iterator: for _ in iterator: pass
def CropOutSeaMask(processes=1, **kwargs): tileset = config.tileset() def arguments(): for tile in tileset.tiles(): yield (CropOutSeaMaskTile, tile, kwargs) with Pool(processes=processes, initializer=setup) as pool: pooled = pool.imap_unordered(starcall, arguments()) with click.progressbar(pooled, length=len(tileset)) as iterator: for _ in iterator: pass
def cli(processes): """ Calculate landcover raster layer """ # config.default() config.auto() tileset = config.tileset() click.secho('Command : %s' % 'rasterize landcover', fg='green') click.secho('FCT version : %s' % version) click.secho('Tileset : %s' % tileset.name) click.secho('# of tiles : %d' % len(tileset)) if processes > 1: click.secho('Run %d parallel processes' % processes, fg='yellow') RasterizeLandCover(processes)
def SeaMask(): coastal_tiles = [(8, 5), (8, 6), (8, 7), (7, 6), (7, 7), (7, 8)] driver = 'ESRI Shapefile' crs = fiona.crs.from_epsg(2154) schema = {'geometry': 'Polygon', 'properties': [('landcover', 'int:2')]} options = dict(driver=driver, crs=crs, schema=schema) output = os.path.join('/media/crousson/Backup/TESTS/TuilesVar', 'SEA_MASK.shp') with fiona.open(output, 'w', **options) as fst: for row, col in coastal_tiles: filename = config.tileset('landcover').tilename('landcover', row=row, col=col) with rio.open(filename) as ds: data = ds.read(1) mask = (data == 0) polygons = features.shapes(data, mask, connectivity=8, transform=ds.transform) for polygon, landcover in polygons: geom = asShape(polygon).buffer(0.0) feature = { 'geometry': geom.__geo_interface__, 'properties': { 'landcover': int(landcover) } } fst.write(feature)
def RasterizeLandCoverTile(tile): rasterfile = config.tileset('landcover').tilename('landcover', row=tile.row, col=tile.col) with rio.open(rasterfile) as ds: data = ds.read(1) profile = ds.profile.copy() profile.update(compress='deflate') transform = ds.transform data[data == 0] = 2 layers = [extract_sea, gravels, water] def shapes(fun): """ Generate Landcover Polygons """ with fiona.open(fun(tile.bounds)) as fs: if len(fs) == 0: raise StopIteration for feature in fs: yield feature['geometry'], feature['properties']['landcover'] for layer in layers: try: features.rasterize(shapes(layer), out=data, transform=transform) except RuntimeError: pass with rio.open(rasterfile, 'w', **profile) as dst: dst.write(data, 1)
def CropOutSeaMaskTile(tile, **kwargs): seamask_file = os.path.join(config.workdir, 'AUX', 'MASQUE_MER.shp') output = config.tileset().tilename('landcover-bdt', row=tile.row, col=tile.col) def shapes(): """ Generate Landcover Polygons """ with fiona.open(seamask_file) as fs: if len(fs) == 0: return for feature in fs: yield feature['geometry'], 1 with rio.open(output) as ds: data = ds.read(1) profile = ds.profile.copy() transform = ds.transform try: mask = np.zeros_like(data, dtype='uint8') features.rasterize(shapes(), out=mask, transform=transform) except RuntimeError: pass data[mask == 1] = ds.nodata profile.update(compress='deflate') with rio.open(output, 'w', **profile) as dst: dst.write(data, 1)