exeqpdal 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exeqpdal-0.1.0a1/.github/workflows/ci.yml +44 -0
- exeqpdal-0.1.0a1/.github/workflows/publish.yml +72 -0
- exeqpdal-0.1.0a1/.gitignore +149 -0
- exeqpdal-0.1.0a1/CHANGELOG.md +42 -0
- exeqpdal-0.1.0a1/CONTRIBUTING.md +77 -0
- exeqpdal-0.1.0a1/LICENSE +34 -0
- exeqpdal-0.1.0a1/PKG-INFO +184 -0
- exeqpdal-0.1.0a1/README.md +148 -0
- exeqpdal-0.1.0a1/docs/examples.md +171 -0
- exeqpdal-0.1.0a1/docs/exeqpdal_dev.md +318 -0
- exeqpdal-0.1.0a1/docs/publishing.md +68 -0
- exeqpdal-0.1.0a1/docs/troubleshooting.md +400 -0
- exeqpdal-0.1.0a1/exeqpdal/__init__.py +151 -0
- exeqpdal-0.1.0a1/exeqpdal/apps/__init__.py +30 -0
- exeqpdal-0.1.0a1/exeqpdal/apps/info.py +151 -0
- exeqpdal-0.1.0a1/exeqpdal/apps/pipeline_apps.py +178 -0
- exeqpdal-0.1.0a1/exeqpdal/apps/translate.py +89 -0
- exeqpdal-0.1.0a1/exeqpdal/core/__init__.py +26 -0
- exeqpdal-0.1.0a1/exeqpdal/core/config.py +269 -0
- exeqpdal-0.1.0a1/exeqpdal/core/executor.py +280 -0
- exeqpdal-0.1.0a1/exeqpdal/core/pipeline.py +309 -0
- exeqpdal-0.1.0a1/exeqpdal/exceptions.py +82 -0
- exeqpdal-0.1.0a1/exeqpdal/py.typed +2 -0
- exeqpdal-0.1.0a1/exeqpdal/stages/__init__.py +27 -0
- exeqpdal-0.1.0a1/exeqpdal/stages/base.py +184 -0
- exeqpdal-0.1.0a1/exeqpdal/stages/filters.py +468 -0
- exeqpdal-0.1.0a1/exeqpdal/stages/readers.py +236 -0
- exeqpdal-0.1.0a1/exeqpdal/stages/writers.py +163 -0
- exeqpdal-0.1.0a1/exeqpdal/types/__init__.py +17 -0
- exeqpdal-0.1.0a1/exeqpdal/types/dimensions.py +187 -0
- exeqpdal-0.1.0a1/pyproject.toml +149 -0
- exeqpdal-0.1.0a1/quickstart.py +192 -0
- exeqpdal-0.1.0a1/tests/conftest.py +368 -0
- exeqpdal-0.1.0a1/tests/test_apps_info.py +210 -0
- exeqpdal-0.1.0a1/tests/test_apps_pipeline_apps.py +183 -0
- exeqpdal-0.1.0a1/tests/test_apps_translate.py +184 -0
- exeqpdal-0.1.0a1/tests/test_copc_workflows.py +315 -0
- exeqpdal-0.1.0a1/tests/test_data_laz/DATASET.md +71 -0
- exeqpdal-0.1.0a1/tests/test_denoising_workflows.py +424 -0
- exeqpdal-0.1.0a1/tests/test_docs_examples.py +184 -0
- exeqpdal-0.1.0a1/tests/test_edge_cases.py +176 -0
- exeqpdal-0.1.0a1/tests/test_executor_real.py +320 -0
- exeqpdal-0.1.0a1/tests/test_integration_workflows.py +526 -0
- exeqpdal-0.1.0a1/tests/test_laz_to_database_writers.py +144 -0
- exeqpdal-0.1.0a1/tests/test_laz_to_raster_writers.py +117 -0
- exeqpdal-0.1.0a1/tests/test_laz_to_special_writers.py +105 -0
- exeqpdal-0.1.0a1/tests/test_laz_to_standard_writers.py +167 -0
- exeqpdal-0.1.0a1/tests/test_laz_to_text_writers.py +162 -0
- exeqpdal-0.1.0a1/tests/test_performance_benchmarks.py +439 -0
- exeqpdal-0.1.0a1/tests/test_pipeline_execution.py +170 -0
- exeqpdal-0.1.0a1/tests/test_spatial_operations.py +375 -0
- exeqpdal-0.1.0a1/tests/unit/test_config.py +48 -0
- exeqpdal-0.1.0a1/tests/unit/test_filter_factory.py +35 -0
- exeqpdal-0.1.0a1/tests/unit/test_pipeline.py +121 -0
- exeqpdal-0.1.0a1/tests/unit/test_reader_factory.py +41 -0
- exeqpdal-0.1.0a1/tests/unit/test_stage_base.py +89 -0
- exeqpdal-0.1.0a1/tests/unit/test_types_and_exceptions.py +52 -0
- exeqpdal-0.1.0a1/tests/unit/test_writer_factory.py +49 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Lint, type check, tests
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout repository
|
|
15
|
+
uses: actions/checkout@v5
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v6
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
cache: "pip"
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
- name: Ruff format
|
|
29
|
+
run: ruff format . --check
|
|
30
|
+
|
|
31
|
+
- name: Ruff check
|
|
32
|
+
run: ruff check .
|
|
33
|
+
|
|
34
|
+
- name: Mypy
|
|
35
|
+
run: mypy exeqpdal
|
|
36
|
+
|
|
37
|
+
- name: Pytest (unit)
|
|
38
|
+
run: pytest -m "not integration" tests/
|
|
39
|
+
|
|
40
|
+
- name: Build package
|
|
41
|
+
run: |
|
|
42
|
+
rm -rf dist/
|
|
43
|
+
python -m build
|
|
44
|
+
twine check dist/*
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types:
|
|
6
|
+
- published
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build:
|
|
11
|
+
name: Build distribution
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Checkout repository
|
|
15
|
+
uses: actions/checkout@v5
|
|
16
|
+
|
|
17
|
+
- name: Set up Python
|
|
18
|
+
uses: actions/setup-python@v6
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
cache: "pip"
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: |
|
|
25
|
+
python -m pip install --upgrade pip
|
|
26
|
+
pip install -e ".[dev]"
|
|
27
|
+
|
|
28
|
+
- name: Ruff format
|
|
29
|
+
run: ruff format . --check
|
|
30
|
+
|
|
31
|
+
- name: Ruff check
|
|
32
|
+
run: ruff check .
|
|
33
|
+
|
|
34
|
+
- name: Mypy
|
|
35
|
+
run: mypy exeqpdal
|
|
36
|
+
|
|
37
|
+
- name: Pytest (unit)
|
|
38
|
+
run: pytest -m "not integration" tests/
|
|
39
|
+
|
|
40
|
+
- name: Build distribution
|
|
41
|
+
run: |
|
|
42
|
+
rm -rf dist/
|
|
43
|
+
python -m build
|
|
44
|
+
twine check dist/*
|
|
45
|
+
|
|
46
|
+
- name: Upload distribution artifact
|
|
47
|
+
uses: actions/upload-artifact@v4
|
|
48
|
+
with:
|
|
49
|
+
name: dist
|
|
50
|
+
path: dist/
|
|
51
|
+
|
|
52
|
+
publish:
|
|
53
|
+
name: Publish to PyPI
|
|
54
|
+
needs: build
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
environment:
|
|
57
|
+
name: pypi
|
|
58
|
+
url: https://pypi.org/project/exeqpdal/
|
|
59
|
+
permissions:
|
|
60
|
+
id-token: write
|
|
61
|
+
contents: read
|
|
62
|
+
steps:
|
|
63
|
+
- name: Download distribution artifact
|
|
64
|
+
uses: actions/download-artifact@v5
|
|
65
|
+
with:
|
|
66
|
+
name: dist
|
|
67
|
+
path: dist/
|
|
68
|
+
|
|
69
|
+
- name: Publish release
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
71
|
+
with:
|
|
72
|
+
packages-dir: dist/
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Python Artifacts
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Build & Packaging Outputs
|
|
8
|
+
.Python
|
|
9
|
+
*.egg
|
|
10
|
+
*.egg-info/
|
|
11
|
+
*.manifest
|
|
12
|
+
*.spec
|
|
13
|
+
*.zip
|
|
14
|
+
.eggs/
|
|
15
|
+
.installed.cfg
|
|
16
|
+
MANIFEST
|
|
17
|
+
build/
|
|
18
|
+
builds/
|
|
19
|
+
develop-eggs/
|
|
20
|
+
dist/
|
|
21
|
+
downloads/
|
|
22
|
+
eggs/
|
|
23
|
+
lib/
|
|
24
|
+
lib64/
|
|
25
|
+
parts/
|
|
26
|
+
sdist/
|
|
27
|
+
share/python-wheels/
|
|
28
|
+
var/
|
|
29
|
+
wheels/
|
|
30
|
+
|
|
31
|
+
# Dependency Management
|
|
32
|
+
.pdm-build/
|
|
33
|
+
.pdm-python
|
|
34
|
+
.pdm.toml
|
|
35
|
+
Pipfile.lock
|
|
36
|
+
poetry.lock
|
|
37
|
+
uv.lock
|
|
38
|
+
__pypackages__/
|
|
39
|
+
|
|
40
|
+
# Virtual Environments
|
|
41
|
+
.env
|
|
42
|
+
.venv/
|
|
43
|
+
ENV/
|
|
44
|
+
env/
|
|
45
|
+
env.bak/
|
|
46
|
+
venv/
|
|
47
|
+
venv.bak/
|
|
48
|
+
|
|
49
|
+
# Testing & Coverage
|
|
50
|
+
.coverage
|
|
51
|
+
.coverage.*
|
|
52
|
+
.hypothesis/
|
|
53
|
+
.nox/
|
|
54
|
+
.pytest_cache/
|
|
55
|
+
.tox/
|
|
56
|
+
.cache
|
|
57
|
+
cover/
|
|
58
|
+
coverage.*
|
|
59
|
+
coverage.xml
|
|
60
|
+
htmlcov/
|
|
61
|
+
nosetests.xml
|
|
62
|
+
*.cover
|
|
63
|
+
*.py,cover
|
|
64
|
+
|
|
65
|
+
# Type Checkers & Linters
|
|
66
|
+
.dmypy.json
|
|
67
|
+
.mypy_cache/
|
|
68
|
+
.pyre/
|
|
69
|
+
.pytype/
|
|
70
|
+
.ruff_cache/
|
|
71
|
+
dmypy.json
|
|
72
|
+
|
|
73
|
+
# Editor & IDE Settings
|
|
74
|
+
.vscode/
|
|
75
|
+
|
|
76
|
+
# Jupyter / IPython Artifacts
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
ipython_config.py
|
|
79
|
+
profile_default/
|
|
80
|
+
|
|
81
|
+
# Logs & Temporary Files
|
|
82
|
+
*.log
|
|
83
|
+
*~
|
|
84
|
+
.*.swp
|
|
85
|
+
pip-delete-this-directory.txt
|
|
86
|
+
pip-log.txt
|
|
87
|
+
|
|
88
|
+
# Framework & Task Queue State
|
|
89
|
+
celerybeat-schedule
|
|
90
|
+
celerybeat.pid
|
|
91
|
+
db.sqlite3
|
|
92
|
+
db.sqlite3-journal
|
|
93
|
+
instance/
|
|
94
|
+
local_settings.py
|
|
95
|
+
.scrapy
|
|
96
|
+
.webassets-cache
|
|
97
|
+
|
|
98
|
+
# Documentation Outputs
|
|
99
|
+
docs/_build/
|
|
100
|
+
/site
|
|
101
|
+
|
|
102
|
+
# Translations
|
|
103
|
+
*.mo
|
|
104
|
+
*.pot
|
|
105
|
+
|
|
106
|
+
# Miscellaneous Python
|
|
107
|
+
*.sage.py
|
|
108
|
+
|
|
109
|
+
# PyPI Credentials
|
|
110
|
+
.pypirc
|
|
111
|
+
|
|
112
|
+
# QGIS Plugin Artifacts
|
|
113
|
+
*_ui.py
|
|
114
|
+
*.qgs~
|
|
115
|
+
*.qgz~
|
|
116
|
+
resources.py
|
|
117
|
+
symbology-style.db
|
|
118
|
+
|
|
119
|
+
# Operating System Artifacts
|
|
120
|
+
.DS_Store
|
|
121
|
+
|
|
122
|
+
# Project-Specific Artifacts
|
|
123
|
+
.archive/
|
|
124
|
+
*/.archive/
|
|
125
|
+
**/.archive/
|
|
126
|
+
.backup/
|
|
127
|
+
*/.backup/
|
|
128
|
+
**/.backup/
|
|
129
|
+
.conf/
|
|
130
|
+
.pwsh/
|
|
131
|
+
.python-version
|
|
132
|
+
.specify/
|
|
133
|
+
AGENTS.m
|
|
134
|
+
AGENTS.md
|
|
135
|
+
CLAUDE.md
|
|
136
|
+
GEMINI.md
|
|
137
|
+
logs/
|
|
138
|
+
|
|
139
|
+
# Workflow Automation
|
|
140
|
+
.claude/
|
|
141
|
+
.gemini/
|
|
142
|
+
.remote-workflow/
|
|
143
|
+
docs/claude/
|
|
144
|
+
docs/gemini/
|
|
145
|
+
|
|
146
|
+
# LAZ-to-writers Test Outputs
|
|
147
|
+
tests/laz_to_writers/outputs/*
|
|
148
|
+
!tests/laz_to_writers/outputs/.gitkeep
|
|
149
|
+
!tests/laz_to_writers/outputs/README.md
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and
|
|
6
|
+
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0a1] - 2025-10-16
|
|
11
|
+
|
|
12
|
+
`exeqpdal 0.1.0a1` is under active development and has not yet been published to PyPI.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Pipeline orchestration with the `Pipeline` class, including `validate`, metadata access, and point
|
|
16
|
+
count parsing.
|
|
17
|
+
- Stage factories covering the most frequently used PDAL drivers (~40 readers, 80+ filters, 25
|
|
18
|
+
writers).
|
|
19
|
+
- High-level wrappers for PDAL CLI applications: `info`, `translate`/`convert`, `merge`, `split`,
|
|
20
|
+
`tile`, and `tindex`.
|
|
21
|
+
- PDAL discovery and configuration utilities (`set_pdal_path`, `get_pdal_version`, `validate_pdal`,
|
|
22
|
+
`set_verbose`).
|
|
23
|
+
- Custom exception hierarchy (`PDALError`, `PipelineError`, `PDALExecutionError`, etc.).
|
|
24
|
+
- Packaging metadata with `py.typed` for downstream type checkers.
|
|
25
|
+
|
|
26
|
+
### Testing
|
|
27
|
+
- Pytest suite covering pipeline assembly, stage factories, and application wrappers.
|
|
28
|
+
- Integration tests gated by `@pytest.mark.integration` and the `EXEQPDAL_TEST_DATA` fixture
|
|
29
|
+
directory.
|
|
30
|
+
- Strict typing enforced via `mypy --strict`.
|
|
31
|
+
|
|
32
|
+
### Tooling
|
|
33
|
+
- Added GitHub Actions for CI (`ci.yml`) and publishing (`publish.yml`), plus a release guide
|
|
34
|
+
(`docs/publishing.md`) and supporting development dependencies.
|
|
35
|
+
|
|
36
|
+
### Known Limitations
|
|
37
|
+
- `Pipeline.arrays` is not yet implemented and currently returns an empty list.
|
|
38
|
+
- Stage factories do not yet expose every PDAL driver; unsupported stages can be invoked with custom
|
|
39
|
+
JSON.
|
|
40
|
+
- First PyPI upload is still pending while the initial alpha stabilises.
|
|
41
|
+
|
|
42
|
+
---
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Contributing to exeqpdal
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to `exeqpdal`! All contributions are welcome, from bug reports to new features.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
1. Fork and clone the repository:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git clone https://github.com/YOUR-USERNAME/exeqpdal.git
|
|
11
|
+
cd exeqpdal
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
2. Create a virtual environment and install dependencies. We recommend
|
|
15
|
+
[`uv`](https://github.com/astral-sh/uv):
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv pip install -e ".[dev]"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
When `uv` is not available, fall back to standard tooling:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
python -m venv .venv
|
|
25
|
+
source .venv/bin/activate
|
|
26
|
+
pip install -e ".[dev]"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. Verify the toolchain by running the default formatting, linting, typing, and test commands:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ruff format .
|
|
33
|
+
ruff check .
|
|
34
|
+
mypy exeqpdal
|
|
35
|
+
pytest tests/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Integration tests require the PDAL CLI and LAZ/COPC test datasets in `tests/test_data_laz/`.
|
|
39
|
+
Tests automatically skip when PDAL or test data are unavailable. Add `-m "not integration"`
|
|
40
|
+
to skip integration tests entirely.
|
|
41
|
+
|
|
42
|
+
## Development Workflow
|
|
43
|
+
|
|
44
|
+
- Create a new branch for your changes.
|
|
45
|
+
- Make your changes and add tests for them.
|
|
46
|
+
- Make sure all tests pass, including the linters and type checkers:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ruff format .
|
|
50
|
+
ruff check .
|
|
51
|
+
mypy exeqpdal
|
|
52
|
+
pytest tests/
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Use `pytest -m "not integration"` to skip tests requiring PDAL and test datasets. Keep test
|
|
56
|
+
outputs (especially under `tests/laz_to_writers/outputs/`) out of commits.
|
|
57
|
+
|
|
58
|
+
- Commit your changes using the existing Conventional Commit prefixes (for example,
|
|
59
|
+
`fix: handle PDAL path lookup`) and push them to your fork.
|
|
60
|
+
- Open a pull request that explains the scenario, any data prerequisites, and how you validated the
|
|
61
|
+
change.
|
|
62
|
+
|
|
63
|
+
## Release Management
|
|
64
|
+
|
|
65
|
+
Maintainers preparing a PyPI upload should follow the checklist in `docs/publishing.md`. It covers
|
|
66
|
+
versioning, changelog updates, local validation (`ruff`, `mypy`, `pytest`, `python -m build`), and
|
|
67
|
+
the GitHub Actions workflow that publishes releases through PyPI's Trusted Publisher integration.
|
|
68
|
+
|
|
69
|
+
## Code Style
|
|
70
|
+
|
|
71
|
+
This project uses `ruff` for both formatting and linting with the settings defined in
|
|
72
|
+
`pyproject.toml`. Four-space indentation, 100-character lines, and double-quoted strings are applied
|
|
73
|
+
by `ruff format`.
|
|
74
|
+
|
|
75
|
+
## License
|
|
76
|
+
|
|
77
|
+
By contributing to this project, you agree that your contributions will be licensed under the MIT License.
|
exeqpdal-0.1.0a1/LICENSE
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 exeqpdal contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This project includes software developed by the PDAL project (https://pdal.io/).
|
|
26
|
+
Copyright (c) 2025, Hobu, Inc. (howard@hobu.co)
|
|
27
|
+
All rights reserved.
|
|
28
|
+
|
|
29
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
30
|
+
|
|
31
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
32
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
33
|
+
|
|
34
|
+
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: exeqpdal
|
|
3
|
+
Version: 0.1.0a1
|
|
4
|
+
Summary: Python API for executing PDAL CLI commands with native syntax support
|
|
5
|
+
Project-URL: Homepage, https://github.com/elgorrion/exeqpdal
|
|
6
|
+
Project-URL: Documentation, https://github.com/elgorrion/exeqpdal#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/elgorrion/exeqpdal
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/elgorrion/exeqpdal/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/elgorrion/exeqpdal/blob/main/CHANGELOG.md
|
|
10
|
+
Project-URL: Source Code, https://github.com/elgorrion/exeqpdal
|
|
11
|
+
Author-email: ElGorrion <elgorrion.eu@gmail.com>
|
|
12
|
+
License: MIT
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Keywords: geospatial,lidar,pdal,pointcloud,qgis
|
|
15
|
+
Classifier: Development Status :: 3 - Alpha
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Intended Audience :: Science/Research
|
|
18
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
19
|
+
Classifier: Natural Language :: English
|
|
20
|
+
Classifier: Operating System :: OS Independent
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Python: >=3.12
|
|
27
|
+
Requires-Dist: numpy>=1.26.4
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build>=1.3.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: mypy>=1.18.2; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.4.2; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.14.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: twine>=6.2.0; extra == 'dev'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# exeqpdal
|
|
38
|
+
|
|
39
|
+
Alpha-stage, typed Python API for driving the PDAL command-line interface (CLI).
|
|
40
|
+
|
|
41
|
+
`exeqpdal` focuses on being a reliable subprocess wrapper around the PDAL CLI so that Python
|
|
42
|
+
projects – including QGIS plugins – can assemble and run PDAL pipelines without shipping
|
|
43
|
+
C++ bindings. The current release series is `0.1.0a*` and is still stabilising APIs and
|
|
44
|
+
coverage.
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- **Pythonic pipelines** – build PDAL JSON using `Reader`, `Filter`, and `Writer`
|
|
49
|
+
factories chained with the `|` operator, then execute with `Pipeline`.
|
|
50
|
+
- **CLI-first design** – no native extensions; every operation delegates to the PDAL
|
|
51
|
+
executable via `subprocess.run`.
|
|
52
|
+
- **Strict typing** – the package ships `py.typed`, is developed under `mypy --strict`,
|
|
53
|
+
and exposes typed factory helpers.
|
|
54
|
+
- **Convenience apps** – wrappers for PDAL tools such as `info`, `translate`, `merge`, `split`,
|
|
55
|
+
`tile`, and `tindex`.
|
|
56
|
+
- **Broad stage coverage** – factories currently expose ~40 readers, 80+ filters, and 25 writers.
|
|
57
|
+
Coverage is expanding; unsupported drivers can still be addressed through custom JSON.
|
|
58
|
+
- **QGIS-friendly** – automatic PDAL discovery checks PATH, `PDAL_EXECUTABLE`, and
|
|
59
|
+
common QGIS 3.4x Windows installs.
|
|
60
|
+
|
|
61
|
+
## Prerequisites
|
|
62
|
+
|
|
63
|
+
- Python 3.12+
|
|
64
|
+
- PDAL CLI installed and accessible (system PATH, `PDAL_EXECUTABLE`, or detected in QGIS on
|
|
65
|
+
Windows)
|
|
66
|
+
|
|
67
|
+
## Installation
|
|
68
|
+
|
|
69
|
+
The first public alpha will be published to PyPI using GitHub Actions. Once the release is
|
|
70
|
+
live, you can install it directly (include `--pre` while the project is in alpha):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install --pre exeqpdal
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Until the package is uploaded, install from a local clone:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# From the project root
|
|
80
|
+
pip install -e .
|
|
81
|
+
|
|
82
|
+
# Or install with development extras
|
|
83
|
+
uv pip install -e ".[dev]"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
### Convert a File
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
import exeqpdal as pdal
|
|
92
|
+
|
|
93
|
+
pdal.translate("input.las", "output.laz")
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Filter Ground Points
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
import exeqpdal as pdal
|
|
100
|
+
|
|
101
|
+
pipeline = (
|
|
102
|
+
pdal.Reader.las("input.las")
|
|
103
|
+
| pdal.Filter.range(limits="Classification[2:2]")
|
|
104
|
+
| pdal.Writer.las("ground_only.las")
|
|
105
|
+
)
|
|
106
|
+
pipeline.execute()
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Get File Information
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from exeqpdal import info
|
|
113
|
+
|
|
114
|
+
info_data = info("input.las", stats=True)
|
|
115
|
+
print(info_data)
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
For more examples, see the [examples documentation](docs/examples.md).
|
|
119
|
+
|
|
120
|
+
## Supported Components
|
|
121
|
+
|
|
122
|
+
Factory helpers cover the most commonly used PDAL readers, writers, and filters. For the
|
|
123
|
+
definitive driver reference, consult the
|
|
124
|
+
[PDAL documentation](https://pdal.io/en/stable/stages/stages.html). If a driver is
|
|
125
|
+
missing, you can still run it by injecting raw dictionaries into a `Pipeline`.
|
|
126
|
+
|
|
127
|
+
## Error Handling
|
|
128
|
+
|
|
129
|
+
`exeqpdal` raises custom exceptions to surface PDAL CLI failures and configuration issues.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import exeqpdal as pdal
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
pipeline = pdal.Pipeline(
|
|
136
|
+
pdal.Reader.las("non_existent_file.las") | pdal.Writer.las("output.las")
|
|
137
|
+
)
|
|
138
|
+
pipeline.execute()
|
|
139
|
+
except pdal.PipelineError as exc:
|
|
140
|
+
print(f"Pipeline execution failed: {exc}")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Configuration
|
|
144
|
+
|
|
145
|
+
### Custom PDAL Path
|
|
146
|
+
|
|
147
|
+
If PDAL is not in your system's PATH, you can set the path to the `pdal` executable manually:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
import exeqpdal as pdal
|
|
151
|
+
|
|
152
|
+
pdal.set_pdal_path("/path/to/your/pdal")
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Verbose Output
|
|
156
|
+
|
|
157
|
+
Enable verbose output to see the PDAL command being executed and its output:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
import exeqpdal as pdal
|
|
161
|
+
|
|
162
|
+
pdal.set_verbose(True)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Project Status & Limitations
|
|
166
|
+
|
|
167
|
+
- `Pipeline.arrays` is not yet implemented – it currently returns an empty list even after
|
|
168
|
+
execution.
|
|
169
|
+
- Integration tests use six LAZ/COPC test datasets in `tests/test_data_laz/` covering various
|
|
170
|
+
scenarios (filtered/non-filtered data, small/mid/large sizes, LAS/COPC formats). Tests
|
|
171
|
+
automatically skip when PDAL or test data are unavailable. See `tests/test_data_laz/DATASET.md`
|
|
172
|
+
for dataset details.
|
|
173
|
+
- Stage coverage is broad but incomplete. Missing drivers can be added by extending the factory
|
|
174
|
+
modules or by building custom JSON.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
`exeqpdal` is licensed under the MIT License.
|
|
179
|
+
|
|
180
|
+
This project is a wrapper around the PDAL command-line tool, which is licensed under the
|
|
181
|
+
BSD license. When using `exeqpdal`, you are also using PDAL, and you should be aware of
|
|
182
|
+
its license.
|
|
183
|
+
|
|
184
|
+
If you are using `exeqpdal` in a QGIS plugin, you should also be aware of the QGIS license (GPLv2+).
|