Instead of writing JSON strings, you can construct pipelines programmatically using Python objects. This approach provides better IDE support, type checking, and code reusability.
Building pipelines with Stage objects
A pipeline constructed with the pipe operator is equivalent to a JSON pipeline:
import pdal
pipeline = pdal.Reader("1.2-with-color.las") | pdal.Filter.sort(dimension="X")
This creates the same pipeline as the JSON example in the basic usage guide.
Stage types
PDAL Python provides three types of stages:
pdal.Reader - Reads data from files or sources
pdal.Filter - Transforms or filters point cloud data
pdal.Writer - Writes data to files or destinations
Creating stages
Stages accept keyword arguments that correspond to PDAL stage options:
# Reader with filename as positional argument
reader = pdal.Reader("input.las")
# Filter with options as keyword arguments
filter_stage = pdal.Filter.sort(dimension="X")
# Writer with multiple options
writer = pdal.Writer.las(
filename="output.las",
offset_x="auto",
offset_y="auto",
scale_x=0.01
)
The filename option for Readers and Writers, and the type option for Filters can be passed as the first positional argument.
Using the pipe operator
The pipe operator (|) connects stages together to form a pipeline:
pipeline = pdal.Reader("1.2-with-color.las") | pdal.Filter.sort(dimension="X")
You can chain multiple stages:
pipeline = reader | filter1 | filter2 | writer
Pipe operator combinations
The pipe operator works with various combinations:
# Stage | Stage
pipeline = stage1 | stage2
# Stage | Pipeline
pipeline = stage1 | existing_pipeline
# Pipeline | Stage
pipeline = existing_pipeline | stage1
# Pipeline | Pipeline
pipeline = pipeline1 | pipeline2
Every application of the pipe operator creates a new Pipeline instance.
Updating pipelines in-place
To update an existing pipeline without creating a new one, use the in-place pipe operator (|=):
# update pipeline in-place
pipeline = pdal.Pipeline()
pipeline |= stage
pipeline |= pipeline2
Stage factory methods
The Reader, Filter, and Writer classes provide static methods for all PDAL drivers. For example:
# These are equivalent
pdal.Filter.head(count=100)
pdal.Filter(type="filters.head", count=100)
These methods are auto-generated by introspecting PDAL, and include docstrings with available options:
>>> help(pdal.Filter.head)
Help on function head in module pdal.pipeline:
head(**kwargs)
Return N points from beginning of the point cloud.
user_data: User JSON
log: Debug output filename
option_file: File from which to read additional options
where: Expression describing points to be passed to this filter
where_merge='auto': If 'where' option is set, describes how skipped points should be merged with kept points in standard mode.
count='10': Number of points to return from beginning. If 'invert' is true, number of points to drop from the beginning.
invert='false': If true, 'count' specifies the number of points to skip from the beginning.
Creating pipelines from stages
You can create a Pipeline instance in several ways:
# From a JSON string
pipeline = pdal.Pipeline(json_string)
# From a sequence of stages
pipeline = pdal.Pipeline([stage1, stage2])
# From a single stage
pipeline = stage.pipeline()
# Empty pipeline
pipeline = pdal.Pipeline()
The inputs option allows you to specify stages that feed into the current stage:
stage = pdal.Filter.merge(inputs=[stage1, stage2])
Inputs can be either:
- String tags of other stages
Stage instances themselves