Metadata-Version: 2.4
Name: LasBuildSeg
Version: 0.2.1
Summary: Building Footrprint Extraction from Aerial LiDAR data
Home-page: 
Author: MertcanErdem
Author-email: merak908@gmail.com
License: GNU General Public License v2.0
Keywords: Building,Lidar
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Operating System :: Microsoft :: Windows :: Windows 10
Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Classifier: Topic :: Scientific/Engineering :: Image Recognition
Classifier: Topic :: Scientific/Engineering :: Image Processing
Description-Content-Type: text/markdown
License-File: LICENSE.txt
Requires-Dist: pyproj==3.5.0
Requires-Dist: numpy==1.23.5
Requires-Dist: scipy==1.10.1
Requires-Dist: rasterio==1.3.4
Requires-Dist: opencv-python==4.7.0.72
Requires-Dist: laspy==2.0.0
Requires-Dist: lazrs==0.5.0
Requires-Dist: proj==0.2.0
Requires-Dist: shapely>=1.8.4
Requires-Dist: geopandas>=0.13.2
Requires-Dist: cloth-simulation-filter>=1.1.0
Requires-Dist: alphashape>=1.3.1
Requires-Dist: matplotlib>=3.5.0
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: requires-dist
Dynamic: summary

# LasBuildSeg — Building Footprint Extraction from Aerial LiDAR

LasBuildSeg extracts building footprints from airborne LiDAR point clouds.

**v0.2.1 adds an adaptive pipeline.** Instead of fixed thresholds, the package
now estimates its key parameters directly from the data: the CSF cloth settings
are derived from point density and terrain slope, and the building height / TRI
thresholds are derived from a coarse nDHM. The result is a workflow that adapts
to each tile with far less manual tuning. The classic threshold-based functions
are still included and unchanged.

>:white_check_mark: **If you are using this package for scientific research, please cite the paper** <a href=https://dl.acm.org/doi/10.1145/3589132.3625574>`<b>Reproducible Extraction of Building Footprints from Airborne LiDAR Data</b></a>

## Installation

```bash
pip install LasBuildSeg
```

This installs **all** dependencies, including the ones used by the adaptive
pipeline (`cloth-simulation-filter`, `alphashape`, `matplotlib`). Nothing extra
is required to run the full example.

> Note: `cloth-simulation-filter` (the `CSF` module) ships as compiled wheels.
> If `pip` cannot find a wheel for your Python version/platform it will try to
> build from source, which needs a C++ toolchain. The adaptive functions that
> need `CSF` and `alphashape` import them lazily, so the rest of the library
> still works even if those two are unavailable on your platform.

## Dependencies

| Library | Version | Used for |
| --- | --- | --- |
| pyproj | 3.5.0 | CRS handling |
| NumPy | 1.23.5 | arrays |
| SciPy | 1.10.1 | interpolation / filtering |
| Rasterio | 1.3.4 | raster I/O |
| OpenCV-python | 4.7.0.72 | morphology / contours |
| laspy | 2.0.0 | LAS/LAZ reading |
| lazrs | 0.5.0 | LAZ backend |
| PROJ | 0.2.0 | projection data |
| Shapely | >= 1.8.4 | geometry |
| GeoPandas | >= 0.13.2 | vector I/O |
| cloth-simulation-filter | >= 1.1.0 | CSF-based DTM (`CSF` module) |
| alphashape | >= 1.3.1 | alpha-shape footprints |
| matplotlib | >= 3.5.0 | optional mask preview |

## Functions

**Classic workflow:** `generate_dsm`, `generate_dtm`, `generate_ndhm`,
`read_geotiff`, `to_8bit`, `threshold`, `morph_open`, `filter_contours`,
`filter_contoursntri`, `close`, `write_geotiff`, `DSM_transform`,
`building_footprints_to_geojson`, `calculate_average_height`.

**Adaptive additions (v0.2.1):** `laz_pre_analysis`,
`generate_dsm_last_returns`, `generate_dtm_with_csf_last_returns`,
`align_rasters`, `analyze_low_res_ndhm`, `fxaa_like_smoothing`,
`extract_building_footprints_with_alphashape`, `rasterize_geojson`.

## Adaptive pipeline usage

Put your `.laz` file (and, for scoring, a ground-truth `.geojson`) in the same
folder, then:

```python
import os
import geopandas as gpd
import numpy as np
import rasterio
import LasBuildSeg as Lasb

# --- Inputs ---
input_laz = 'tile.laz'
epsg_code = 6457
intermethod = 'nearest'

# --- Manual params ---
kernel_size = 3
alpha = 0.4
min_size, max_size = 50, 5000000
squareness_threshold, width_threshold = 0.3, 3

# 1) Derive CSF params from the raw cloud (point density + terrain slope)
csf_params = Lasb.laz_pre_analysis(input_laz)

# 2) Base rasters: last-return DSM, CSF DTM, aligned, nDHM, reprojected DSM
Lasb.generate_dsm_last_returns(input_laz, epsg_code, intermethod)
Lasb.generate_dtm_with_csf_last_returns(input_laz, epsg_code, 'dsm.tif', csf_params, intermethod)
Lasb.align_rasters('dtm_csf.tif', 'dsm.tif', 'aligned_dtm.tif')
Lasb.generate_ndhm('aligned_dtm.tif', 'dsm.tif')   # -> ndhmtemp.tif (+ ndhm.tif)
Lasb.DSM_transform('dsm.tif')                       # -> dsm3857.tif

# 3) Adaptive height / TRI thresholds from the coarse nDHM
adaptive = Lasb.analyze_low_res_ndhm('ndhmtemp.tif')
tri_threshold = adaptive['tri_threshold']
height_threshold = adaptive['height_threshold']
filter_height_threshold = height_threshold * 0.8

# 4) Alpha-shape footprints, then rasterize onto the EPSG:3857 grid
Lasb.extract_building_footprints_with_alphashape(
    'ndhmtemp.tif', alpha, height_threshold, epsg_code, kernel_size)
Lasb.rasterize_geojson('alpha_shape_buildings.geojson', 'dsm3857.tif', 'alpha_shape_buildings.tif')

# 5) Refine contours (S1 = no TRI, S2 = with adaptive TRI)
mask, profile = Lasb.read_geotiff('alpha_shape_buildings.tif')
dem, _ = Lasb.read_geotiff('dsm3857.tif')

s1 = Lasb.filter_contoursntri(mask, profile, min_size, max_size,
                              squareness_threshold, width_threshold, filter_height_threshold)
s2 = Lasb.filter_contours(mask, dem, profile, min_size, max_size,
                          squareness_threshold, width_threshold, filter_height_threshold, tri_threshold)

# 6) Save results
Lasb.write_geotiff('buildings.tif', s2, profile)
Lasb.building_footprints_to_geojson('buildings.tif', 'buildings.geojson')
print('All steps are complete.')
```

A full, runnable version with output folders, average-height attachment and
IoU scoring is provided in `TestLaz/TestSingleLaz.py` in the source repository.

## Classic (threshold-based) usage

The original workflow still works exactly as before:

```python
import LasBuildSeg as lasb

lasb.generate_dsm(input_laz, epsg_code, intermethod)
lasb.generate_dtm(input_laz, epsg_code, intermethod, multy)
lasb.generate_ndhm('dtm.tif', 'dsm.tif')
img, profile = lasb.read_geotiff('ndhm.tif')
lasb.DSM_transform('dsm.tif')
dem, _ = lasb.read_geotiff('dsm3857.tif')
img_8bit = lasb.to_8bit(img)
img_thresh = lasb.threshold(img_8bit, block_size, constant)
img_open = lasb.morph_open(img_thresh, kernel_size)
building_mask = lasb.filter_contours(img_open, dem, profile, min_size, max_size,
                                     squareness_threshold, width_threshold, height_threshold, tri_threshold)
building_mask_closed = lasb.close(building_mask, CloseKernel_size)
lasb.write_geotiff('buildings.tif', building_mask_closed, profile)
lasb.building_footprints_to_geojson('buildings.tif', 'building.geojson')
```

## Data

The example uses a point cloud dataset provided by GISCUP 2022. If you don't
have your own data, you can use this [dataset](https://sigspatial2022.sigspatial.org/giscup/download.html).
The test script also uses scoring functions adapted from GISCUP 2022's
[eval.py](https://sigspatial2022.sigspatial.org/giscup/submit.html).

## PROJ note

If your `PROJ_LIB` environment variable points to an older PROJ install you may
hit projection errors. Either unset it, point it at the PROJ shipped with pyproj
(find it via `pyproj.datadir.get_data_dir()`), or just run the script in a fresh
environment.
