USGS needs to be able to verify and validate the breakline geometries provided against point cloud data. This process has currently been a combination of manual inspection via visualization and can be quite time consuming. The intent of this article is to demonstrate how PDAL can be used to generate statistics that could be used for verification of breakline geometry levels in relation to the point clouds in the near-shore boundary.
The approach uses a couple of different ideas, but they're pretty basic GIS concepts:
- Buffer each breakline to a given threshold (I picked 20m)
- Select points within the buffer using 2d intersection by using
readers.copc
'sogr
query block. - Label each point within that buffer with its 2d distance to the breakline. We
can do this by using PDAL's
filters.geomdistance
filter, which will take each point and compute the distance-to-segment. - Apply some simple expressions with
filters.expression
to select points within the buffer and plot them with matplotlib.

I chose USGS_LPC_WI_Statewide_2019_A19_0344
in WI_Adams_2019
which has a few closed-form waterbodies in it. The example waterbody that was chosen was the one on the middle left of the tile.
Looking at the classification values of the data (click the image for a live preview), it contains the following classification in the near-shore:
- unclassified (0)
- ground (2)
- high vegetation (6)
- noise (7)
- water (9)
- ignored ground (20)

GDAL provides sophisticated utilities for manipulating vector geometry on the command line. Two key features are VRT and the GDAL SQL dialects.
snake.sh
is used to prepare our waterbody geometry for interaction with
PDAL. We need to do a couple of things:
- Buffer the breakline to 20m and add an attribute called
InBuffer
with its value set to 1 - Union the breakline to a closed-form polygon.
./snake.sh waterbody.geojson 20
The script currently assumes the data are in EPSG:7587
due to the WI_Adams_2019
project. This
will need to be adjusted if it matters to you.
The pipeline at pipeline.json
provides a full workflow for extracting the buffered
points around a breakline. Be sure to review it for detailed comments on how each filter works.
Once we have the data, we can extract some statistics from it and plot some pictures with matplotlib.

Once we have usgs-breakline-eval.copc.laz
that is output by the pipeline, we can plot some simple histogram to compare the given water level of the breakline with the Z values of the points themselves.
The following histogram shows the ignored ground (20)
points that are closest to the breakline. The script could be adapted to select for different classifications, or more interestingly, dilate or erode the distance to/from the breakline using the distance
dimension that was added to the points by filters.geomdistance
.