
# Changes of Note

- The X, Y and Z dimensions are now always stored internally as double-precision floating point.  This was normally case previously, but it is now enforced. (#2892)
- The interface include file directory is now set for downstream projects using cmake, eliminating the need to explicitly set the location of PDAL header files. (#2262)
- PDAL is now always built using the arbiter library, which is included in the source distribution.
- `filters.python` has been removed from the primary PDAL library and is part of the [PDAL python](https://pdal.io/python.html) library.
- When the `bounds` option of `filters.crop` represents a 3D volume, the filter now does 3D cropping, rather than 2D cropping as in previous releases. (#2904)
- `writers.ply` no longer accepts `default` as a valid value for the `storage_mode` option. (#2385)

# API User Notes

- Support has been added for range-based iteration of PointView objects.  The dereferenced iterator yields a PointRef object.
- We are now providing private header files as part of the distribution.  The API exposed by these files may change or be eliminated in a future release.  Use of these files may require the installation of the header files from other packages.  The symbols for some of these functions may not be public, especially on Windows.
- There are now enumerations for classifications (pdal::ClassLabel).
- N-dimensional KD-tree support has been added.
- There are some small API changes (const changes, for example), but almost all code using the PDAL library should build without modification.
- We do not guarantee ABI compatibility, though in most cases this release should be backward compatible.

# New Stages

- `filters.voxeldownsize` provides streamed support for voxel filtering. (#2699 - Thanks [Helix.re](http://https://helixre.com/)!)
- `filters.separatescanline` splits input into separate output point views based on associated scan lines. (#2724 - Thanks Guilhem Villemin)
- `filters.farthestpointsampling` add points from the input to the output one-at-a-time by selecting the point in the input that is the furthest from any point in the output. (#2761)
- `filters.skewnessbalancing` classifies ground points using the method of Bartels. (#2740)
- `filters.dbscan` provides density-based clustering. (#2748)
- `filters.csf` provides ground classification of points using the cloth simulation method of Zhang. (#2765)
- `readers.hdf` provides generic support for many HDF files. (#2934)
- `filters.hag_nn`, `filters.hag_delaunay` and `filters.hag_dem` have been created to replace `filters.hag`. (#2886)

# Deprecated Stages

- `filters.hag` is deprecated and will be removed in a future release.  Use `filters.hag_nn`, `filters.hag_delaunay` and `filters.hag_dem` instead.

# Removed Stages

- `readers.sqlite` and `writers.sqlite`

# Enhancements

- `readers.ept` now supports the `headers` and `query` options to be forwarded to remote endpoints. (#2690)
- `readers.ept` now supports multipolygons for point filtering. (#2758)
- `readers.ept` now supports asynchronous operation when streaming. (#2772)
- `readers.ept` now supports filtering via OGR queries. (#2295)
- `writers.ept` now supports Zstandard compression. (#2561)
- `writers.gdal` now supports a `power` option that can be used to impact the output of inverse distance weighting mode. (#2550)
- Eliminated an error as exception in `readers.e57` in order to improve performance. (#2721)
- `readers.rxp` now supports reading the `EdgeOfFlightLine` dimension. (#2367)
- `filters.randomize` now has a `seed` option to initialize the random number generator. (#2736)
- `filters.rdb` and `filters.rxp` now support fetching data from remote sources. 
- `filters.hexbin` now has the option `smooth`, to smooth generated geometry, and `preserve_topology` that forces creation of valid geometry during the smoothing operation.
- `filters.transformation` now has a `spatialreference` option to set the spatial reference of output data. (#2796)
- `filters.overlay` now uses the same point-in-polygon algorithm used by `filters.crop`. (#2812)
- `writers.tiledb` now supports TileDB attribute filters. (#2828)
- Output from `pdal translate` can now be directed to the null device by using either `devnull` or `/dev/null` as the output filename. (#2835)
- `filters.transformation` now supports providing a filename as the `matrix` option if the referenced file contains a matrix that matches the format supported inline. (#2856)
- `writers.las` now allows specification of a `filesource_id` as an option. (#2862)
- `readers.text` now handles quoted dimension names in a header line. (#2201)
- `pdal info` now reports the reader used for a file, the current time and the size of the file. (#2900)
- `filters.reprojection` now supports the options `in_axis_ordering` and `out_axis_ordering` to allow the matching feature in GDAL 3+ be accessed. (#2916)
- `filters.normal` added the `refine` option to re-orient normal vectors using a minimum spanning tree. (#2860)

# Bug Fixes

- `readers.e57` and `writers.e57` now build cleanly on Windows.
- `writers.pgpointcloud` no longer uses the wrong schema when creating a new database and there is an existing database using the same SRS. (#2692)
- Fixed a potential crash when destroying logs on shutdown. (#2702)
- Fixed a case where `filters.voxelcentroidnearestneighbor` could return points for a voxel that weren't actually in the voxel. (#2703)
- Fixed a typo in the alternate names of the `NormalY` dimension. (#2723)
- `filters.divider` now handles empty input. (#2727)
- An error in calculating variance, standard deviation, skewness and kurtosis has been fixed in `filters.stats`. (#2790)
- An error where a list of dimensions would be expanded improperly in `writers.ply` under certain API uses. (#2791)
- Crashes in filters using the delaunay triangulation code have been fixed. (#2805)
- `writers.pcd` now always writes dimension names as lowercase. (#2789)
- The extended VLR offset was not being written to LAS files.  This has been fixed. (#2823)
- Fixed some small memory leaks.
- `filters.elm` now works properly when input is an empty point view. (#2921)
- `filters.pmf` now classifies all points either as "Ground" or "Unclassified".  Points are no longer marked as "Created, Never Classified". (#2898)
- LAS VLRs specified in a pipeline are now properly handled by `writers.las`. (#2937)
- When not building with LASzip or LAZperf, `writers.las` would fail to properly set a spatial reference in some cases.  This has been fixed.
- `writers.las` now always uses WKT version 1. In the previous release it may have used WKT version 2 in some cases. (#2943)
- A bug in `pdal tile` where the input spatial reference wasn't set on the output has been fixed. (#2976)
