Use of this function requires a license for Whitebox Workflows for Python Professional (WbW-Pro). Please visit www.whiteboxgeo.com to purchase a license.
The FilterLidar tool is a very powerful tool for filtering points within a LiDAR point cloud based on point properties. Complex filter statements (statement
) can be used to include or exclude points in the output file (output
).
Note that if the user does not specify the optional input LiDAR file (input
), the tool will search for all valid LiDAR (.las, .laz, *.zlidar) files contained within the current working directory. This feature can be useful for processing a large number of LiDAR files in batch mode. When this batch mode is applied, the output file names will be the same as the input file names but with a '_filtered' suffix added to the end.
Points are either included or excluded from the output file by creating conditional filter statements. Statements must be valid Rust syntax and evaluate to a Boolean. Any of the following variables are acceptable within the filter statement:
Variable Name | Description | |
x | The point x coordinate | |
y | The point y coordinate | |
z | The point z coordinate | |
intensity | The point intensity value | |
ret | The point return number | |
nret | The point number of returns | |
is_only | True if the point is an only return (i.e. ret == nret == 1), otherwise false | |
is_multiple | True if the point is a multiple return (i.e. nret > 1), otherwise false | |
is_early | True if the point is an early return (i.e. ret == 1), otherwise false | |
is_intermediate | True if the point is an intermediate return (i.e. ret > 1 && ret < nret), otherwise false | |
is_late | True if the point is a late return (i.e. ret == nret), otherwise false | |
is_first | True if the point is a first return (i.e. ret == 1 && nret > 1), otherwise false | |
is_last | True if the point is a last return (i.e. ret == nret && nret > 1), otherwise false | |
class | The class value in numeric form, e.g. 0 = Never classified, 1 = Unclassified, 2 = Ground, etc. | |
is_noise | True if the point is classified noise (i.e. class == 7 | class == 18), otherwise false |
is_synthetic | True if the point is synthetic, otherwise false | |
is_keypoint | True if the point is a keypoint, otherwise false | |
is_withheld | True if the point is withheld, otherwise false | |
is_overlap | True if the point is an overlap point, otherwise false | |
scan_angle | The point scan angle | |
scan_direction | True if the scanner is moving from the left towards the right, otherwise false | |
is_flightline_edge | True if the point is situated along the filightline edge, otherwise false | |
user_data | The point user data | |
point_source_id | The point source ID | |
scanner_channel | The point scanner channel | |
time | The point GPS time, if it exists, otherwise 0 | |
red | The point red value, if it exists, otherwise 0 | |
green | The point green value, if it exists, otherwise 0 | |
blue | The point blue value, if it exists, otherwise 0 | |
nir | The point near infrared value, if it exists, otherwise 0 | |
pt_num | The point number within the input file | |
n_pts | The number of points within the file | |
min_x | The file minimum x value | |
mid_x | The file mid-point x value | |
max_x | The file maximum x value | |
min_y | The file minimum y value | |
mid_y | The file mid-point y value | |
max_y | The file maximum y value | |
min_z | The file minimum z value | |
mid_z | The file mid-point z value | |
max_z | The file maximum z value | |
dist_to_pt | The distance from the point to a specified xy or xyz point, e.g. dist_to_pt(562500, 4819500) or dist_to_pt(562500, 4819500, 320) | |
dist_to_line | The distance from the point to the line passing through two xy points, e.g. dist_to_line(562600, 4819500, 562750, 4819750) | |
dist_to_line_seg | The distance from the point to the line segment defined by two xy end-points, e.g. dist_to_line_seg(562600, 4819500, 562750, 4819750) | |
within_rect | 1 if the point falls within the bounds of a 2D or 3D rectangle, otherwise 0. Bounds are defined as within_rect(ULX, ULY, LRX, LRY) or within_rect(ULX, ULY, ULZ, LRX, LRY, LRZ) |
In addition to the point properties defined above, if the user applies the lidar_eigenvalue_features tool on the input LiDAR file, the filter_lidar tool will automatically read in the additional *.eigen file, which include the eigenvalue-based point neighbourhood measures, such as lambda1
, lambda2
, lambda3
, linearity
, planarity
, sphericity
, omnivariance
, eigentropy
, slope, and residual
. See the lidar_eigenvalue_features documentation for details on each of these metrics describing the structure and distribution of points within the neighbourhood surrounding each point in the LiDAR file.
Statements can be as simple or complex as desired. For example, to filter out all points that are classified noise (i.e. class numbers 7 or 18):
!is_noise
The following is a statement to retain only the late returns from the input file (i.e. both last and single returns):
ret == nret
Notice that equality uses the ==
symbol an inequality uses the !=
symbol. As an equivalent to the above statement, we could have used the is_late
point property:
is_late
If we want to remove all points outside of a range of xy values:
x >= 562000 && x <= 562500 && y >= 4819000 && y <= 4819500
Notice how we can combine multiple constraints using the &&
(logical AND) and ||
(logical OR) operators. As an alternative to the above statement, we could have used the within_rect
function:
within_rect(562000, 4819500, 562500, 4819000)
If we want instead to exclude all of the points within this defined region, rather than to retain them, we simply use the !
(logial NOT):
!(x >= 562000 && x <= 562500 && y >= 4819000 && y <= 4819500)
or, simply:
!within_rect(562000, 4819500, 562500, 4819000)
If we need to find all of the ground points within 150 m of (562000, 4819500), we could use:
class == 2 && dist_to_pt(562000, 4819500) <= 150.0
The following statement outputs all non-vegetation classed points in the upper-right quadrant:
!(class == 3 && class != 4 && class != 5) && x < min_x + (max_x - min_x) / 2.0 && y > max_y - (max_y - min_y) / 2.0
As demonstrated above, the filter_lidar tool provides an extremely flexible, powerful, and easy means for retaining and removing points from point clouds based on any of the common LiDAR point attributes.
filter_lidar_classes, filter_lidar_scan_angles, modify_lidar, erase_polygon_from_lidar, clip_lidar_to_polygon, sort_lidar, lidar_eigenvalue_features