r.in.ahn.laz
Downloads LAZ tiles from the AHN (Actueel Hoogtebestand Nederland (AHN), versions 2–6, and optionally processes each tile with a user-provided script.
r.in.ahn.laz [-k] version=string [vector=name] [directory=name] [laz_files=name] [script=name] [output=name] [memory=memory in MB] [nprocs=integer] [max_inputs=integer] [--overwrite] [--verbose] [--quiet] [--qq] [--ui]
Example:
r.in.ahn.laz version=2
grass.tools.Tools.r_in_ahn_laz(version, vector=None, directory=None, laz_files=None, script=None, output=None, memory=300, nprocs=0, max_inputs=250, flags=None, overwrite=None, verbose=None, quiet=None, superquiet=None)
Example:
tools = Tools()
tools.r_in_ahn_laz(version="2")
This grass.tools API is experimental in version 8.5 and expected to be stable in version 8.6.
grass.script.run_command("r.in.ahn.laz", version, vector=None, directory=None, laz_files=None, script=None, output=None, memory=300, nprocs=0, max_inputs=250, flags=None, overwrite=None, verbose=None, quiet=None, superquiet=None)
Example:
gs.run_command("r.in.ahn.laz", version="2")
Parameters
version=string [required]
AHN version
AHN version to download
Allowed values: 2, 3, 4, 5, 6
vector=name
Vector layer to filter tiles
If provided, only AHN tiles that overlap with this vector layer (and the computational region) will be downloaded and processed.
directory=name
Output directory for LAZ data
Output directory to which the LAZ data is downloaded (default = working directory)
laz_files=name
CSV file with list of downloaded LAZ files
Save the path + names of the downloaded LAZ files to a file
script=name
Python script to run for each LAZ tile
Python script to process each LAZ tile.
output=name
Name of the final patched output raster
If a script is provided, this is used as the base name for the final patched output raster(s). For multi-output scripts, the suffix from each raster is appended.
memory=memory in MB
Maximum memory to be used (in MB)
Cache size for raster rows
Default: 300
nprocs=integer
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
max_inputs=integer
Maximum number of rasters passed to a single r.patch call
Larger values reduce number of intermediate batches but may exceed OS command length limits
Default: 250
-k
Keep downloaded LAZ files
Do not delete LAZ files after processing with the user script. By default, each LAZ file is deleted after the script has been run on it.
--overwrite
Allow output files to overwrite existing files
--help
Print usage summary
--verbose
Verbose module output
--quiet
Quiet module output
--qq
Very quiet module output
--ui
Force launching GUI dialog
version : str, required
AHN version
AHN version to download
Allowed values: 2, 3, 4, 5, 6
vector : str, optional
Vector layer to filter tiles
If provided, only AHN tiles that overlap with this vector layer (and the computational region) will be downloaded and processed.
Used as: input, vector, name
directory : str, optional
Output directory for LAZ data
Output directory to which the LAZ data is downloaded (default = working directory)
Used as: input, dir, name
laz_files : str, optional
CSV file with list of downloaded LAZ files
Save the path + names of the downloaded LAZ files to a file
Used as: output, file, name
script : str | io.StringIO, optional
Python script to run for each LAZ tile
Python script to process each LAZ tile.
Used as: input, file, name
output : str | type(np.ndarray) | type(np.array) | type(gs.array.array), optional
Name of the final patched output raster
If a script is provided, this is used as the base name for the final patched output raster(s). For multi-output scripts, the suffix from each raster is appended.
Used as: output, raster, name
memory : int, optional
Maximum memory to be used (in MB)
Cache size for raster rows
Used as: memory in MB
Default: 300
nprocs : int, optional
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
max_inputs : int, optional
Maximum number of rasters passed to a single r.patch call
Larger values reduce number of intermediate batches but may exceed OS command length limits
Default: 250
flags : str, optional
Allowed values: k
k
Keep downloaded LAZ files
Do not delete LAZ files after processing with the user script. By default, each LAZ file is deleted after the script has been run on it.
overwrite : bool, optional
Allow output files to overwrite existing files
Default: None
verbose : bool, optional
Verbose module output
Default: None
quiet : bool, optional
Quiet module output
Default: None
superquiet : bool, optional
Very quiet module output
Default: None
Returns:
result : grass.tools.support.ToolResult | np.ndarray | tuple[np.ndarray] | None
If the tool produces text as standard output, a ToolResult object will be returned. Otherwise, None will be returned. If an array type (e.g., np.ndarray) is used for one of the raster outputs, the result will be an array and will have the shape corresponding to the computational region. If an array type is used for more than one raster output, the result will be a tuple of arrays.
Raises:
grass.tools.ToolError: When the tool ended with an error.
version : str, required
AHN version
AHN version to download
Allowed values: 2, 3, 4, 5, 6
vector : str, optional
Vector layer to filter tiles
If provided, only AHN tiles that overlap with this vector layer (and the computational region) will be downloaded and processed.
Used as: input, vector, name
directory : str, optional
Output directory for LAZ data
Output directory to which the LAZ data is downloaded (default = working directory)
Used as: input, dir, name
laz_files : str, optional
CSV file with list of downloaded LAZ files
Save the path + names of the downloaded LAZ files to a file
Used as: output, file, name
script : str, optional
Python script to run for each LAZ tile
Python script to process each LAZ tile.
Used as: input, file, name
output : str, optional
Name of the final patched output raster
If a script is provided, this is used as the base name for the final patched output raster(s). For multi-output scripts, the suffix from each raster is appended.
Used as: output, raster, name
memory : int, optional
Maximum memory to be used (in MB)
Cache size for raster rows
Used as: memory in MB
Default: 300
nprocs : int, optional
Number of threads for parallel computing
0: use OpenMP default; >0: use nprocs; <0: use MAX-nprocs
Default: 0
max_inputs : int, optional
Maximum number of rasters passed to a single r.patch call
Larger values reduce number of intermediate batches but may exceed OS command length limits
Default: 250
flags : str, optional
Allowed values: k
k
Keep downloaded LAZ files
Do not delete LAZ files after processing with the user script. By default, each LAZ file is deleted after the script has been run on it.
overwrite : bool, optional
Allow output files to overwrite existing files
Default: None
verbose : bool, optional
Verbose module output
Default: None
quiet : bool, optional
Quiet module output
Default: None
superquiet : bool, optional
Very quiet module output
Default: None
DESCRIPTION
r.in.ahn.laz: Downloads 1 x 1 km LAZ tiles from the AHN (Actueel Hoogtebestand Nederland (AHN), versions 2–6) overlapping with the computational region. Optionally runs a user-provided Python script for each downloaded tile, and patches the resulting raster layers.
Modes of operation
r.in.ahn.laz has two modes of operation, selected by whether the script= option is given. If the script= parameter is not provided, the module just downloads every LAZ tile that intersects the current region and either prints their full paths to standard output or, if laz_files= is given, writes them to that file. No raster output is produced.
If script=, a user Python script, is given, the module download the tile(s), and runs for each tile the script. After all tiles are processed, the per-tile outputs are patched into one or more final maps whose names are built from output= and the suffixes declared by the script (see User script interface below). In this mode, output= is required.
User script interface
A user script is a plain Python file that should have the following structure:
I. The first non-comment, non-blank line must be a SUFFIXES declaration.
This is a list of strings, one per output map the script produces. For example
,if the script creates a dtm and dsm, the line could be:
SUFFIXES = ["_dtm", "_dsm"]. For a single-output script, use
SUFFIXES = [""].
II. The rest of the file is Python code you want to be executed. When the script runs, the following names are pre-injected into its global namespace.
LAZ: Full path to the LAZ tile file that was just downloaded.OUTPUT: Unique per-tile name prefix. Every map the script creates whose name starts withOUTPUT + suffix(where suffix is one of the strings inSUFFIXES) is collected for patching.THREADS: Per-tile thread budget. Scripts that run internally parallel work, for example, a threaded PDAL reader, should size it withTHREADSso that workers x per-tile-threads does not oversubscribe the CPU when nprocs > 1. With nprocs=1 it equals all cores. Scripts that ignoreTHREADSare unaffected.
In addition, os and gs are both pre-imported for convenience, so there is no
need to import them in the script.
The script must produce one raster or vector map per declared suffix, named
exactly OUTPUT + suffix. Maps whose names match OUTPUT* but whose suffix is
not in SUFFIXES are treated as intermediate and removed automatically after
the tile completes (the module warns once, on the first tile, when this
happens). Maps that do not start with OUTPUT are left alone. The user script
is responsible for cleaning those up itself.
After all tiles are processed, each declared suffix produces one patched map
named output + suffix. For a single-output script with SUFFIXES = [""],
the final map is simply output.
NOTE
Projection and extent
The current project must use EPSG:28992 (Amersfoort / RD New). The module aborts otherwise. This is the native AHN CRS; reprojecting LAZ data on the fly is out of scope.
Note that if the computational region extends outside the AHN extent, a warning is emitted and only the overlap is imported. If the region lies entirely outside, the module aborts.
Parallel processing and masks
When a raster mask is active in the mapset, parallel processing is not supported. If nprocs= is set to more than 1 and a mask is active, the module warns and falls back to nprocs=1 for the entire run. Disable the mask if parallel processing is needed.
Disk usage
Each LAZ tile is downloaded to directory= (or the current working directory if not set). By default, each tile is deleted after the user script has processed it. Use -k to keep the LAZ files on disk.
Batching of patch operations
When many tiles are requested, r.in.ahn.laz patches raster outputs in batches
of at most max_inputs= inputs (default 50), recursing until a single mosaic
remains. This avoids hitting the OS command-line length limit and the "too many
open files" limit. If you do hit the latter, lower max_inputs=, lower
nprocs=, or raise your OS file-descriptor limit (ulimit -n).
max_inputs= is not implemented for the patching of vetor outputs. Therefore, vector outputs are patched in a single v.patch call, and max_inputs= has no effect on them. If the number of per-tile vectors is large enough to exceed an OS limit, r.in.ahn.laz aborts with a clear fatal message naming the limit.
Requirements
- GRASS GIS ≥ 8.5 (uses
gs.RegionManager, which was introduced in version 8.5). - Network access to the AHN LAZ object storage bucket.
- Whatever the user script itself needs. For instance, r.in.pdal must be installed if the script uses it.
KNOWN ISSUES
A single failed tile download is reported as a warning and the tile is skipped; the module continues with the remaining tiles. If all downloads fail, the module aborts.
EXAMPLES
All examples assume the current project is in EPSG:28992 and the computational region has been set to an area of interest inside the Netherlands.
Example 1
Download every AHN4 LAZ tile that intersects the current region into /tmp/laz,
and save the list of file paths to ahn_files.txt:
g.region n=436948 s=430912 w=90450 e=98479 res=0.5
r.in.ahn.laz version=4 directory=/tmp/laz laz_files=ahn_files.txt
No GRASS raster is produced; the downloaded files remain on disk.
Example 2
Create a DTM mosaic with the user script make_dtm.py:
SUFFIXES = [""]
gs.run_command(
"r.in.pdal",
input=LAZ,
output=OUTPUT,
method="mean",
resolution=0.5,
class_filter="2",
flags="o",
)
Run it:
g.region n=436948 s=430912 w=90450 e=98479 res=0.5
r.in.ahn.laz \
version=4 \
script=make_dtm.py \
output=ahn4_dtm \
nprocs=4 \
memory=8000
Result: a single raster ahn4_dtm covering the region, patched from per-tile
rasters. The LAZ files are deleted as they are processed. Note, normally one
would want to import the AHN DTM directly using the r.in.ahn module.
Example 3
DTM + DSM in one pass with user script dtm_dsm.py:
SUFFIXES = ["_dtm", "_dsm"]
# DTM from ground points
gs.run_command(
"r.in.pdal",
input=LAZ,
output=OUTPUT + "_dtm",
method="mean",
resolution=0.5,
class_filter="2",
flags="o",
)
# DSM from first returns
gs.run_command(
"r.in.pdal",
input=LAZ,
output=OUTPUT + "_dsm",
method="max",
resolution=0.5,
return_filter="first",
flags="o",
)
Run it:
r.in.ahn.laz \
version=5 \
script=dtm_dsm.py \
output=zuiderpark \
nprocs=8 memory=20000 max_inputs=25
Result: two rasters, zuiderpark_dtm and zuiderpark_dsm. The suffixes
declared in SUFFIXES are appended to output= to form the final map names.
Note, normally one would want to import the AHN DTM and DSM directly using the
r.in.ahn module.
Example 4
If the user script produces extra maps whose suffix is not in SUFFIXES, those
are cleaned up automatically. This lets a script use intermediate maps without
polluting the mapset: user script chm.py:
SUFFIXES = ["_chm"]
# Intermediate DTM (ground points, class 2).
# These are not in SUFFIXES, so they will beremoved
# after this tile.
gs.run_command(
"r.in.pdal",
input=LAZ, output=OUTPUT + "_dtm",
method="mean", resolution=0.5,
class_filter="2",
flags="o",
)
# Intermediate DSM (first returns, highest surface). Also not in SUFFIXES.
gs.run_command(
"r.in.pdal",
input=LAZ, output=OUTPUT + "_dsm",
method="max", resolution=0.5,
return_filter="first",
flags="o",
)
# Final output is the Canopy Height Model = DSM - DTM.
gs.mapcalc(
f"{OUTPUT}_chm = max(0.0, {OUTPUT}_dsm - {OUTPUT}_dtm)",
)
The _dtm and _dsm per-tile rasters are intermediates and get cleaned up
after each tile; only _chm is kept and patched into the final mosaic
output_chm.
r.in.ahn.laz \
version=5 \
script=chm.py \
output=zuiderpark \
nprocs=8 memory=20000 max_inputs=25
Result: a raster zuiderpark_chm. Note, in most cases it will be faster to
use the r.in.ahn module to obtain the CHM. Use the example above if you want
the CHM at an higher resultion.
SEE ALSO
AUTHOR
Paulo van Breugel, HAS green academy, Innovative Biomonitoring research group, Climate-robust Landscapes research group
SOURCE CODE
Available at: r.in.ahn.laz source code
(history)
Latest change: Thursday Aug 06 08:43:21 2026 in commit c9f702f