lazproof-geo
Prove that a LAS/LAZ output is an exact, order-preserving spatial subset of its source.
Point counts and bounding boxes are not enough to catch reordered records, changed
attributes, a different Extra Bytes schema, or a subtly modified header.
lazproof independently streams both files and hashes complete structured point
records in order, without cropping the source and without requiring PDAL.
Quick start
python -m pip install lazproof-geo
lazproof verify source.laz result.laz \
--inside boundary.geojson \
--report proof.json
Exit codes are stable:
0: every requested check passed;1: verification completed and found a mismatch;2: the files, geometry, or invocation were invalid.
Reproducible example
Generate a complete suite of tiny synthetic LAZ files, run every verification, and write one JSON report per case:
python examples/run_examples.py
The suite exercises both successful and intentionally failing results:
| scenario | expected result | what it demonstrates |
|---|---|---|
valid |
pass | exact polygon-selected records in source order |
empty |
pass | a valid selection containing zero points |
reordered |
fail | the same records in a different order |
mutated |
fail | one changed intensity value |
missing |
fail | one selected source point omitted |
outside_mask |
fail | an extra result point outside the polygon |
header_mismatch |
fail | different coordinate scales |
crs_mismatch |
fail | different embedded CRS metadata |
schema_mismatch |
fail | an added Extra Bytes dimension |
Generated files are placed under examples/generated/. To run one case through
the CLI instead:
lazproof verify examples/generated/source.laz examples/generated/valid.laz \
--inside examples/generated/mask.wkt \
--report examples/generated/valid-cli.json
A report contains explicit checks:
{
"verified": false,
"expected_points": 5,
"result_points": 5,
"checks": {
"source_unchanged": true,
"header_preserved": true,
"point_count_matches": true,
"dimension_hashes_match": false,
"all_result_points_inside": true
}
}
Python API
from shapely.geometry import box
from lazproof import VerificationReport, verify_subset
report: VerificationReport = verify_subset(
"source.laz",
"result.laz",
box(0, 0, 100, 100),
)
assert report.verified, report.mismatches
verify_subset(source, result, geometry=None, *, chunk_size=250_000) reads data in
bounded chunks. With no geometry, the result must be an exact full copy.
What is proved
- LAS version, point format, dimension schema, scales, offsets, and CRS match.
- The result contains exactly the source records selected by the polygon.
- Every raw point dimension matches in the original record order.
- Every result point lies inside the selection geometry.
- The source file hash is unchanged during verification.
What is not proved
- The source data is correct, authentic, or appropriate for a particular use.
- The CRS describes the real-world location correctly.
- A non-spatial filter was applied as intended.
- The source remained unchanged before or after the verification run.
- Waveform point formats 4, 5, 9, and 10 are supported; version 0.1 rejects them.
Selection geometry may be WKT, .wkt, GeoJSON, or a Fiona-supported vector layer.
Run lazproof --help for all options.
The pre-release and launch checks are listed in
docs/release-checklist.md.
Development
python -m pip install -e ".[test]"
python -m ruff check .
python -m ruff format --check .
python -m pytest
Copyright 2026 Alena Nikitina. Licensed under the Apache License 2.0.
Metadata
Release files for lazproof-geo 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lazproof_geo-0.1.1.tar.gz | 17.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lazproof_geo-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 29.6 kB
Release files / lazproof_geo-0.1.1.tar.gz
| Download URL | lazproof_geo-0.1.1.tar.gz |
|---|---|
| Size | 17.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9cebe3e75e498066ba6890447de89b2b1bf4d6362a5114a61805ccb8d5211d7f
|
|
BLAKE2b-256 checksum How to use checksums |
6068583d20126436aac72993f6da17dcf1bc7f4b813779c0b4b9e1513ae8db04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / lazproof_geo-0.1.1-py3-none-any.whl
| Download URL | lazproof_geo-0.1.1-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
574d66fa62780b9368ce5424ceb9016d76ab1a79c0b60bbc11613659707f36e5
|
|
BLAKE2b-256 checksum How to use checksums |
5374b6e5eb47c9c3c11b6f1d8e775ef4bedc6094d127a8bdf3fba54573b761e4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log