Add rasterize helper function
This commit is contained in:
parent
553a896e36
commit
74be7c1a56
@ -14,10 +14,13 @@ exemple on the use of idefix package and other packages (sap, rasterio,
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
from scipy.interpolate import griddata
|
from scipy.interpolate import griddata
|
||||||
from rasterio import fill
|
from rasterio import fill
|
||||||
|
import rasterio as rio
|
||||||
import sap
|
import sap
|
||||||
import higra as hg
|
import higra as hg
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from .vxl import get_grid, bin, squash
|
from .vxl import get_grid, bin, squash, fit_bbox
|
||||||
|
from .io import load_pc
|
||||||
|
|
||||||
def interpolate(raster, method='linear'):
|
def interpolate(raster, method='linear'):
|
||||||
"""Interpolate masked raster.
|
"""Interpolate masked raster.
|
||||||
@ -135,3 +138,93 @@ def dtm_dh_filter(dsm, sigma=.5, epsilon=20000, alpha=2):
|
|||||||
|
|
||||||
return dtm
|
return dtm
|
||||||
|
|
||||||
|
def write_raster(raster, bbox, crs, fname):
|
||||||
|
"""Write a GeoTiff
|
||||||
|
"""
|
||||||
|
west, east = bbox[:,0]
|
||||||
|
south, north = bbox[:,1]
|
||||||
|
width, height = raster.shape
|
||||||
|
|
||||||
|
west, east, south, north, width, height
|
||||||
|
|
||||||
|
transform = rio.transform.from_bounds(west, south, east, north, width, height)
|
||||||
|
dtype = raster.dtype
|
||||||
|
|
||||||
|
with rio.open(fname,
|
||||||
|
mode='w',
|
||||||
|
driver='GTiff',
|
||||||
|
width=raster.shape[0],
|
||||||
|
height=raster.shape[1],
|
||||||
|
count=1,
|
||||||
|
crs=crs,
|
||||||
|
dtype=dtype,
|
||||||
|
transform=transform,
|
||||||
|
compress='lzw') as out_tif:
|
||||||
|
out_tif.write(raster[None])
|
||||||
|
|
||||||
|
def rasterize(pc_file, feature='elevation', resolution=1.,
|
||||||
|
bin_structure='voxel', bin_method='mean',
|
||||||
|
squash_method='top', interpolation='idw',
|
||||||
|
out_dir=None, crs=None):
|
||||||
|
"""Rasterize a point cloud file.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
pc_file : Path
|
||||||
|
Path of the point cloud file.
|
||||||
|
feature : str
|
||||||
|
'elevation' or LiDAR feature name contained in the point cloud
|
||||||
|
file.
|
||||||
|
resolution : float
|
||||||
|
The spatial resolution of the raster.
|
||||||
|
bin_structure : str
|
||||||
|
'voxel' or 'pixel'.
|
||||||
|
bin_method : str
|
||||||
|
'mean', 'density' or 'mode'.
|
||||||
|
squash_method : str or tuple of str
|
||||||
|
'top', 'center', 'bottom', 'min', 'max', 'mean', 'median', 'std'
|
||||||
|
interpolation : str
|
||||||
|
'idw', 'nearest', 'linear', 'cubic'
|
||||||
|
out_dir : Path or str or None
|
||||||
|
Path of the directory for the result files. Optional.
|
||||||
|
crs : str or None
|
||||||
|
The coordinate reference system of the point cloud. Required if
|
||||||
|
out_dir is defined to write the GeoTiff.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
raster : ndarray
|
||||||
|
Raster.
|
||||||
|
"""
|
||||||
|
pc = load_pc(pc_file)
|
||||||
|
|
||||||
|
steps = resolution if bin_structure == 'voxel' else (resolution, resolution, None)
|
||||||
|
|
||||||
|
bbox = fit_bbox(pc.spatial)
|
||||||
|
grid = get_grid(bbox, steps)
|
||||||
|
#ix.vxl.insight(grid, method=bin_method, verbose=True)
|
||||||
|
|
||||||
|
fval = pc.spatial[:,2] if feature == 'elevation' else getattr(pc.feature, feature)
|
||||||
|
|
||||||
|
vxl = bin(grid, pc.spatial, fval, bin_method)
|
||||||
|
|
||||||
|
squash_method = squash_method if isinstance(squash_method, tuple) else (squash_method,)
|
||||||
|
|
||||||
|
rasters = []
|
||||||
|
for s in squash_method:
|
||||||
|
raster = squash(vxl, s)
|
||||||
|
raster = interpolate(raster, interpolation)
|
||||||
|
if out_dir:
|
||||||
|
format_dict = {'name': Path(pc_file).stem,
|
||||||
|
'feature': feature,
|
||||||
|
'resolution': resolution,
|
||||||
|
'bin_structure': bin_structure,
|
||||||
|
'bin_method': bin_method,
|
||||||
|
'squash_method': s,
|
||||||
|
'interpolation': interpolation}
|
||||||
|
out_tif_name = Path(out_dir) / \
|
||||||
|
'{name}_{feature}_{resolution}_{bin_structure}_{bin_method}_{squash_method}_{interpolation}.tif'.format(**format_dict)
|
||||||
|
write_raster(raster, bbox, crs, out_tif_name)
|
||||||
|
rasters += [raster]
|
||||||
|
|
||||||
|
return np.array(rasters)
|
||||||
|
|||||||
@ -44,3 +44,16 @@ def test_dtm(ma_raster):
|
|||||||
dtm = helpers.dtm_dh_filter(ma_raster)
|
dtm = helpers.dtm_dh_filter(ma_raster)
|
||||||
|
|
||||||
assert dtm is not None, 'Did not return anything...'
|
assert dtm is not None, 'Did not return anything...'
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('params', [
|
||||||
|
{},
|
||||||
|
{'bin_structure': 'pixel'},
|
||||||
|
{'out_dir': True, 'crs': 'EPSG:26910'}])
|
||||||
|
def test_rasterize(datadir, params):
|
||||||
|
# Workaround for out_dir with pytest
|
||||||
|
if 'out_dir' in params:
|
||||||
|
params['out_dir'] = datadir
|
||||||
|
|
||||||
|
raster = helpers.rasterize(datadir.join('test.npz'), **params)
|
||||||
|
|
||||||
|
assert raster is not None, 'Did not return anything...'
|
||||||
|
|||||||
BIN
test/test_helpers/test.npz
Normal file
BIN
test/test_helpers/test.npz
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user