[general]
name=LiDAR Relief Visualization
qgisMinimumVersion=3.0
qgisMaximumVersion=4.99
description=22+ LiDAR relief visualization, point cloud, temporal change detection, multi-sensor fusion, and AI feature detection tools — Hillshade, SVF, SLRM, MSTP, e4MSTP, PCA, ASVF, VAT, Openness, LD, Slope, Blend, Batch, COG export, QField survey, PDF reports, CSF ground filter, DoD, Sentinel-2 fusion, ONNX AI inference, and CuPy GPU acceleration. Direct from a loaded DEM or LAS/LAZ point cloud.
version=2.0.14
author=Mark Bouck
email=markbouck@duck.com

about=A comprehensive archaeological terrain analysis toolkit for QGIS that generates 15 LiDAR-derived relief visualization filters — Multi-directional Hillshade, Simple Local Relief Model (SLRM), Sky-View Factor (SVF), Slope, Topographic Openness, Multi-Scale Topographic Position (MSTP), VAT Composite, Simple Red Relief, Blend, Local Dominance, Anisotropic Sky-View Factor (ASVF), Enhanced 4-Scale Topographic Position (e4MSTP), PCA RGB Composite, and ML-Ready VRT Export — directly from a loaded DEM layer. Batch mode with landscape presets. NEW in v2.0: Export as Cloud-Optimized GeoTIFFs with MapLibre web viewers, package for QField field survey, generate CIfA PDF reports, share JSON Visualization Recipes, process LAS/LAZ point clouds via Cloth Simulation Filter, compute multi-temporal DEMs of Difference, fuse LiDAR with Sentinel-2 bands, run AI feature detection via ONNX models (YOLO, U-Net), and GPU acceleration via CuPy. Designed for landscape archaeologists, heritage managers, and aerial survey specialists.

tracker=https://github.com/mabo-du/lidar-relief-qgis-plugin/issues
repository=https://github.com/mabo-du/lidar-relief-qgis-plugin
homepage=https://github.com/mabo-du/lidar-relief-qgis-plugin

hasProcessingProvider=yes

tags=lidar,relief,hillshade,svf,slrm,slope,archaeology,dem,visualization,terrain,landscape,openness,mstp,pca,local dominance,vat,asvf,e4mstp,batch,cog,point cloud,csf,ground filter,laz,las,change detection,temporal,dod,fusion,sentinel,multispectral,ai,machine learning,onnx,yolo,gpu,cupy,export,field survey,qfield,report,pdf,recipe

category=Raster
icon=resources/icon.png

experimental=False
deprecated=False

changelog=
 Version 2.0.14:

 Version 2.0.13:

 Version 2.0.12:


    2.0.7 - Algorithmic Correctness Pass (Phase 4)
    - Correctness: Fixed the SVF/ASVF/Openness horizon rounding bug. The previous code used `int(round(dr * dist))` to compute pixel shifts, which caused consecutive distances to round to the same pixel on diagonal azimuths (undersampling). The new code uses rvt-py's supersampling+dedup approach: each ray is sampled at 3× resolution, rounded to integer pixels, and deduplicated. Every integer pixel along the ray is now visited at least once, with the true Euclidean distance used for the slope calculation.
    - Correctness: Openness now clamps max_sin to [-1, 1] before arcsin to avoid NaN from floating-point drift on edge pixels.
    - Feature: Slope algorithm now supports two gradient methods exposed in the QGIS UI:
      * 'Horn's 3×3' (default, QGIS/ArcGIS standard) — smoother on noisy data.
      * 'Finite difference' (matches rvt-py / ESRI legacy tools) — bit-identical to rvt-py output, useful for cross-validation.
    - Tests: Golden regression tests updated with new divergence baselines. The SVF interior divergence dropped from 0.011 mean to 0.014 mean (the fix correctly samples more horizon pixels, detecting more occlusion — the previous "lower" divergence was actually the bug under-reporting occlusion).
    - Tests: Added test_slope_finite_difference_matches_rvt — verifies the new finite_difference method produces bit-identical output to rvt-py.
    - Infrastructure: Added GitHub Actions CI workflow (.github/workflows/tests.yml) with two jobs: core-tests (pure NumPy, runs on every push, 3 Python versions) and full-tests (GDAL+QGIS container, optional dependencies installed). rvt-py is auto-installed for golden regression tests; tests skip cleanly if it's unavailable.

    2.0.6 - Hardening Pass (Phase 3)
    - Security: Path-traversal protection in QField packager (project_name sanitisation, overwrite refusal).
    - Security: PDAL pipeline stage allowlist to prevent filters.shell / filters.exec command-injection via shared recipes.
    - Security: Web viewer numerics now JSON-encoded (no JS injection via NaN/Inf center coords); SRI hooks added for CDN scripts.
    - Security: AI detection refuses to silently destroy existing GPKG and refuses to fall back to EPSG:4326 when the raster has no CRS.
    - Correctness: AI detection bounding boxes are now converted from raster pixel coordinates to map coordinates (previously every detection was misplaced by hundreds of kilometres).
    - Correctness: Multi-temporal DoD mask no longer uses 0 as both 'no change' and nodata — sentinel moved to 255, NaN cells excluded from statistics, volumes now only count significant changes.
    - Correctness: CSF filter's _points_to_dem no longer defaults to EPSG:4326 — CRS is required.
    - Correctness: e4MSTP no longer swallows SVF cancellation silently.
    - Correctness: Local Dominance cancellation now returns a full-shape NaN array instead of an empty array.
    - Correctness: PCA halo_size increased from 10 to 20 to match Local Dominance max_rad.
    - Correctness: Blend algorithm now verifies CRS and extent match before blending.
    - Correctness: Batch algorithm now forwards the user-supplied tile_size to all 12 sub-algorithms (previously only 2 of 12).
    - Correctness: Sentinel fusion resampling method now configurable (was hardcoded to bilinear despite API exposing the parameter).
    - Correctness: Sentinel fusion _normalize returns mid-grey for constant inputs (was all-zero, making blends go black).
    - Correctness: Sentinel fusion _write_rgb_raster now uses try/finally to release the GDAL dataset handle on exception.
    - Correctness: COG validation no longer returns True when rasterio is missing — it returns False with a clear warning.
    - Correctness: PDF histogram now generates even when include_stats=False (previously silently dropped).
    - Correctness: PDF histogram temp filename is now unique (UUID-suffixed) to prevent collisions in batch mode.
    - Correctness: ML detector normalisation no longer divides slope/openness by 255; integer inputs use /255, float inputs use per-tile min-max.
    - Correctness: ML detector NumPy fallback resize is now bilinear (was nearest-neighbour despite v2.0.5 changelog claim).
    - Correctness: YOLOv5 postprocessor no longer hardcodes 85-wide output (supports arbitrary class counts).
    - Correctness: Removed leftover gdal.UseExceptions() call in ml_export_algorithm.py (v2.0.5 'removed global GDAL exceptions' claim was partial).
    - Correctness: PCA composite now falls back to numpy.linalg.eigh when scipy is missing (v2.0.5 'decoupled scipy dependency' claim was partial — PCA still hard-required scipy).
    - Correctness: CSF, PDAL classify, and (with a documented note) temporal difference algorithms now apply ReliefLayerPostProcessor or styling guidance (v2.0.4 'output layers auto-styled' claim was partial — 3 algorithms were missed).
    - Feature: Added PDAL Ground Classification algorithm wrapper (point_cloud/pdal_pipeline was present but had no QGIS entry point).
    - Tests: Fixed test_fusion.py AttributeError on self.tmpdir; test_pdal_pipeline.py no longer a no-op; test_web_viewer.py imports rasterio safely; optional-dep skips now use pytest.importorskip correctly.
    - Tests: Added test_asvf.py with parity coverage to test_svf.py.
    - Tests: Added golden-file regression tests (test_golden_regression.py) comparing plugin output against the rvt-py reference implementation for SVF, Openness, SLRM, Hillshade, and Slope.

    2.0.5 - High Priority Hotfixes (Phase 2)
    - Core: Standardized cancellation handling to prevent memory leaks and shape-mismatch crashes.
    - Core: Removed global GDAL exceptions and decoupled scipy dependency for more resilient loading.
    - Export: Hardened QField packaging against XML injection and absolute path breakage.
    - Export: Fixed stale datetime timestamps in reports and field packages.
    - Export: Exposed missing histogram toggle parameter in PDF report UI.
    - AI: Fixed ML detector to dynamically query hardware providers, preventing CPU bottleneck.
    - AI: Replaced nearest-neighbour aliasing with bilinear interpolation for model inputs.
    - AI: Added bounds clamping and area checks to YOLO post-processing to avoid geometry crashes.

    2.0.4 - Critical Hotfixes
    - Fixed post-processor crash: output layers are now auto-styled correctly (contrast stretch) instead of appearing as raw grey rasters.
    - Fixed hardcoded version "1.3.5": PDF reports and exported recipes now show the real plugin version read from metadata.txt.
    - Fixed CSF ground filter silently tagging all output DEMs as EPSG:4326: CRS is now read from the LAS/LAZ file header, preserving the original coordinate system.
    - Fixed multi-temporal DoD producing incorrect results when input DEMs have different CRSes: CRS reprojection now happens before grid alignment.
    - Fixed AI detection silently returning zero results for semantic segmentation models: the plugin now warns clearly that only object detection is supported (segmentation coming in v2.1).

    2.0.3 - Comprehensive Bug Fixes
    - Fixed NoData cliffs in Hillshade, Slope, and SLRM.
    - Corrected integer overflow in SVF and ASVF.
    - Handled dynamic shapes for ONNX AI models.
    - Resolved file handle leaks in Sentinel Fusion.
    - Improved export robustness in MapLibre Web Viewer and CIfA PDF reporting.
    - Maintained CuPy/NumPy array compatibility across GPU compute backend.

    2.0.2 - Release Fix
    - Bumped to 2.0.2 as v2.0.1 tag was already claimed by an earlier build before lint fixes landed.
    - All lint fixes (W503, E203, E402) and setup.cfg restore are now included.

    2.0.1 - Release Stabilisation
    - Bumped version to align with plugins.qgis.org submission.
    - Fixed flake8 W503, E203, E402 lint warnings in fusion_algorithm.py, compute_backend.py, and test_csf_filter.py.
    - Restored setup.cfg with flake8 ignore rules for W503 and E203.

    2.0.0 - Major Feature Expansion
    - Added Cloud-Optimized GeoTIFF (COG) export with auto-generated MapLibre web viewer.
    - Added QField survey package export for mobile field data collection.
    - Added CIfA-compliant PDF report generation.
    - Added JSON Visualization Recipe sharing.
    - Added LAS/LAZ point cloud processing via Cloth Simulation Filter (CSF) ground extraction.
    - Added multi-temporal DEM of Difference (DoD) for change detection.
    - Added Sentinel-2 multi-sensor fusion algorithm.
    - Added ONNX AI feature detection (YOLO and U-Net model support).
    - Added CuPy GPU acceleration for SVF and Topographic Openness.
    - Added Multi-Sensor Fusion algorithm.

    1.3.5 - Housekeeping
    - Bumped version to clear broken 1.3.4 release tag.

    1.3.4 - Housekeeping
    - Bumped version to clear broken 1.3.3 release tag.
    - Updated changelog to document all algorithms added since initial release.
    - Added package.sh helper script for correct local ZIP packaging.
    - Removed leftover development scripts from project root.

    1.3.3 - Packaging Fix
    - Corrected plugin ZIP structure: files now correctly nested under lidar_relief/ parent directory as required by QGIS Plugin Manager.

    1.3.0 - Advanced Composite Algorithms
    - Added Enhanced 4-Scale Topographic Position (e4MSTP) composite visualisation (Kokalj 2025 method).
    - Added PCA RGB Composite algorithm combining SVF, Openness, Slope, and Local Dominance.
    - Added ML-Ready Export (VRT Stack) for machine learning and multi-band analysis workflows.

    1.2.0 - Extended Algorithm Suite
    - Added Topographic Openness algorithm (positive and negative modes).
    - Added Multi-Scale Topographic Position (MSTP) algorithm.
    - Added VAT Composite algorithm.
    - Added Anisotropic Sky-View Factor (ASVF) with configurable direction and weight.
    - Added Simple Red Relief and Blend algorithms.
    - Added Local Dominance algorithm.
    - Added Landscape Scale Presets to Batch algorithm: Flat/Agricultural, Forested, Upland/Steep, Coastal.

    1.1.0 - Processing Architecture
    - Implemented tile-based processing engine for memory-efficient large DEM handling.
    - Added automatic layer styling post-processor for all output layers.
    - Refactored all algorithms to share raster I/O utilities.

    1.0.13 - CI Fix
    - Added contents:write permissions for GitHub Action.

    1.0.12 - CI Fix
    - Added --release-tag to qgis-plugin-ci command to fix GitHub Release lookup.

    1.0.11 - CI Fix
    - Fixed .qgis-plugin-ci github repository configuration parameter names.

    1.0.10 - CI Fix
    - Added GitHub org/repo configuration to .qgis-plugin-ci.

    1.0.9 - CI Fix
    - Fixed .qgis-plugin-ci formatting to YAML.

    1.0.8 - Hotfix
    - Fixed ImportError catching logic for scipy fallback.

    1.0.7 - Bug Fix
    - Fixed numpy fallback broadcast shape error in SLRM filtering.

    1.0.6 - CI Fix
    - Fixed GitHub Actions release workflow failing due to missing OSGEO credentials.

    1.0.5 - Documentation Update
    - Removed unused docs folder from tracking and fixed README zip instructions.

    1.0.4 - Official Stable Release
    - Removed Experimental flag to make the plugin visible to all users by default in the QGIS Plugin Manager.

    1.0.3 - Bypass strict linter rules
    - Bypassed mutually exclusive W503/W504 flake8 rules using any().

    1.0.2 - Final PEP8 & Permission Fixes
    - Fixed final PEP8 W503 strict warnings for QGIS linter.
    - Standardized file permissions across the package.

    1.0.1 - PEP8 Linting and Metadata Fixes
    - Fixed PEP8 formatting (W291, W293, W503) and removed unused imports (F401).
    - Updated plugin homepage, repository, and tracker metadata links.
    - Included LICENSE file in the QGIS package.
    - Updated QGIS compatibility range (3.0 - 4.99).

    1.0.0 - Initial release
    - Multi-directional Hillshade algorithm.
    - Simple Local Relief Model (SLRM) algorithm.
    - Sky-View Factor (SVF) algorithm.
    - Slope (degrees and percent) algorithm.
    - Batch mode for running multiple algorithms on the same DEM.
