Metadata-Version: 2.5
Name: pylynceus
Version: 0.1.0.dev0
Summary: Open-source photogrammetry and LiDAR processing suite
Project-URL: Homepage, https://github.com/pyLynceus/pylynceus
Project-URL: Issues, https://github.com/pyLynceus/pylynceus/issues
Author: Bryon Jordan
License: MIT
License-File: LICENSE
Keywords: dem,geospatial,lidar,photogrammetry,point-cloud,remote-sensing,sfm,surveying
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.10
Requires-Dist: laspy[laszip]>=2.5
Requires-Dist: numpy>=1.24
Requires-Dist: pyproj>=3.6
Provides-Extra: all
Requires-Dist: matplotlib>=3.8; extra == 'all'
Requires-Dist: opencv-python-headless>=4.8; extra == 'all'
Requires-Dist: rasterio>=1.3; extra == 'all'
Requires-Dist: scipy>=1.11; extra == 'all'
Provides-Extra: dev
Requires-Dist: matplotlib>=3.8; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: opencv-python-headless>=4.8; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: rasterio>=1.3; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: scipy>=1.11; extra == 'dev'
Provides-Extra: raster
Requires-Dist: rasterio>=1.3; extra == 'raster'
Provides-Extra: sfm
Requires-Dist: opencv-python-headless>=4.8; extra == 'sfm'
Requires-Dist: scipy>=1.11; extra == 'sfm'
Provides-Extra: viz
Requires-Dist: matplotlib>=3.8; extra == 'viz'
Description-Content-Type: text/markdown

<p align="center">
  <img src="docs/assets/pylynceus-logo.svg" alt="pyLynceus" width="640"/>
</p>

<p align="center">
  <em>Open-source photogrammetry and LiDAR processing.</em>
</p>

<p align="center">
  <a href="https://pypi.org/project/pylynceus/"><img alt="PyPI" src="https://img.shields.io/pypi/v/pylynceus"></a>
  <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-green"></a>
  <img alt="Python" src="https://img.shields.io/badge/python-3.10%2B-blue">
</p>

---

**pyLynceus** is named for the lookout of the Argonauts, whose sight was so
sharp he could see through the earth itself — which is more or less what a
good LiDAR pipeline does through canopy. The project aims to be a practical,
production-minded toolkit for people who process aerial mapping data for a
living: point cloud I/O and filtering, georeferencing and datum work, terrain
products, and (on the roadmap) structure-from-motion.

## Why another geospatial library?

Existing open tools are excellent at what they do (PDAL for pipelines, OpenDroneMap
for end-to-end SfM, laspy for I/O). pyLynceus sits in the gap between them: a
**Python-native, importable library** for the workflows a working
photogrammetrist actually runs — classification filtering, spatial
deduplication of obstacle datasets, control point residual reporting,
CRS/datum transforms, and quick DEM gridding — without leaving a script or
notebook.

## Install

```bash
pip install pylynceus            # core: numpy, laspy, pyproj
pip install "pylynceus[all]"     # + rasterio, opencv, scipy, matplotlib
```

## Quickstart

```python
from pylynceus.io.las import read_las, write_las
from pylynceus.cloud.filters import by_class, dedup_xy, GROUND
from pylynceus.georef.transform import reproject
from pylynceus.terrain.grid import grid_dem

# Read a LAZ tile
cloud = read_las("tile.laz")
print(cloud)                     # PointCloud(4,213,880 points, crs=2240, ...)

# Ground points only, deduplicated within 1 cm in XY
ground = dedup_xy(by_class(cloud, GROUND), tolerance=0.01)

# Reproject and grid a 1-unit DEM
ground = reproject(ground, dst_epsg=6447)
dem, origin = grid_dem(ground, cell_size=1.0)

write_las(ground, "ground.laz")
```

Or from the command line:

```bash
lynceus info tile.laz
```

## Module map

| Module | Purpose | Status |
|---|---|---|
| `pylynceus.io` | LAS/LAZ read/write, file summaries | working |
| `pylynceus.cloud` | PointCloud model, class filters, XY dedup | working |
| `pylynceus.georef` | CRS reprojection, control residual stats | working |
| `pylynceus.terrain` | Binned DEM gridding (min/mean/max) | working |
| `pylynceus.sfm` | Camera models, matching, bundle adjustment | roadmap |

## Roadmap

- [ ] Vertical datum transforms (ellipsoid ↔ orthometric via geoid grids)
- [ ] TIN and IDW DEM interpolation; contour extraction
- [ ] Tiled/streaming processing for datasets larger than memory
- [ ] Feature extraction & matching (SfM pipeline, `sfm` extra)
- [ ] Obstacle analysis helpers (surface penetration against OIS-style surfaces)
- [ ] QGIS plugin wrapper

## Development

```bash
git clone https://github.com/pyLynceus/pylynceus
cd pylynceus
pip install -e ".[dev]"
pytest
ruff check src tests
```

Contributions welcome — this project is young and the API is still settling.
Open an issue before large PRs.

## License

MIT. See [LICENSE](LICENSE).
