Skip to content

Commit 2b8904f

Browse files
danpejoboDaniel
andauthored
v.3.3.0 (#16)
* Updated submodule to match upstream * Cleanup algorithm src files * update test package and github test * troubleshoot tests noot running * typo in github actions * errors in github action * remove latest from test * update workflow * edit workflow * update workflow * workflow * Skip points outside the raster bounds in submodule * update tests * introduce postProcess to handle layers * update tests for impactmap * bump version * update metadata * bump version * update typo in metadata * enable on qgis-qt6 * Chore: Fix qgs minimum version to support qgis4 and qt6 * chore: update metadata to reflect new version bump * chore: update github workflow * chore: update docker tags * Update test_plugin.yml chore: update workflow * Update test_plugin.yml Chore: delete obsolete commands * Update test_plugin.yml chore: fixing workflow * Update test_plugin.yml chore: update workflow * Update test_plugin.yml chore: update test runner path * Update test_plugin.yml chore: change test workflow * Update test_plugin.yml chore: update paths in test workflow * Update test_plugin.yml fix: fix config for testing * Create conftest.py fix: add conftest * Update test_plugin.yml fix: formatting errors * Update conftest.py fix: error in pytest_qgis * Update test_plugin.yml * Update test_plugin.yml * Update test_plugin.yml * chore: tidi up test requirements * feature: Create atlas coverage along centerline * fix: import error * chore: Update readme and add example image * chore: add centerline to testdata * chore: add setup bootstrap * fix: bug in the setup process * Add tests for Create Atlas Coverage algorithm (#14) * fix: Typo when doing \n in a help string * Centralize plugin version metadata (#15) * Add pyproject version metadata and sync tooling * Improve plugin version resolution * Chore: update versioning and metadata --------- Co-authored-by: Daniel <[email protected]>
1 parent 60b15e7 commit 2b8904f

21 files changed

+854
-32
lines changed

.github/workflows/test_plugin.yml

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ on:
88
paths:
99
- "geovita_processing_plugin/**"
1010
- ".github/workflows/test_plugin.yml"
11+
- "conftest.py"
1112
pull_request:
1213
branches:
1314
- main
1415
- dev
1516
paths:
1617
- "geovita_processing_plugin/**"
1718
- ".github/workflows/test_plugin.yml"
19+
- "conftest.py"
1820
workflow_dispatch:
1921

2022
env:
2123
# plugin name/directory where the code for the plugin is stored
2224
PLUGIN_NAME: geovita_processing_plugin
23-
# python notation to test running inside plugin
24-
TESTS_RUN_FUNCTION: geovita_processing_plugin.test_suite.test_package
2525
# Docker settings
2626
DOCKER_IMAGE: qgis/qgis
2727

@@ -33,7 +33,7 @@ jobs:
3333

3434
strategy:
3535
matrix:
36-
docker_tags: [release-3_28, release-3_36]
36+
docker_tags: [3.36, 3.44.4, latest]
3737

3838
steps:
3939

@@ -49,11 +49,12 @@ jobs:
4949
5050
- name: Docker set up QGIS
5151
run: |
52-
docker exec qgis-testing-environment sh -c "qgis_setup.sh $PLUGIN_NAME"
53-
docker exec qgis-testing-environment sh -c "cat /root/.local/share/QGIS/QGIS3/profiles/default/QGIS/QGIS3.ini"
52+
docker exec qgis-testing-environment sh -c "mkdir -p /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/"
5453
docker exec qgis-testing-environment sh -c "rm -f /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$PLUGIN_NAME"
5554
docker exec qgis-testing-environment sh -c "ln -s /tests_directory/$PLUGIN_NAME /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$PLUGIN_NAME"
56-
docker exec qgis-testing-environment sh -c "pip3 install -r /tests_directory/REQUIREMENTS_TESTING.txt"
55+
56+
# ENDRING HER: Lagt til 'pytest-qgis' eksplisitt for å være sikker
57+
docker exec qgis-testing-environment sh -c "pip3 install --break-system-packages -r /tests_directory/REQUIREMENTS_TESTING.txt"
5758
5859
docker exec qgis-testing-environment sh -c "ls -l /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/"
5960
docker exec qgis-testing-environment sh -c "ls -l /root/.local/share/QGIS/QGIS3/profiles/default/python/plugins/$PLUGIN_NAME"
@@ -63,15 +64,10 @@ jobs:
6364
docker exec qgis-testing-environment sh -c "touch /tests_directory/$PLUGIN_NAME/REMEDY_GIS_RiskTool/__init__.py"
6465
docker exec qgis-testing-environment ls -la /tests_directory/$PLUGIN_NAME/REMEDY_GIS_RiskTool
6566
66-
- name: Install and start Xvfb inside Docker container
67-
run: |
68-
docker exec qgis-testing-environment apt update
69-
docker exec qgis-testing-environment apt install -y xvfb
70-
docker exec qgis-testing-environment Xvfb :99 -screen 0 1024x768x24 &
71-
7267
- name: Docker run plugin tests
7368
run: |
74-
docker exec qgis-testing-environment sh -c "export DISPLAY=:99; qgis_testrunner.sh $TESTS_RUN_FUNCTION"
69+
# ENDRING HER: Kjører 'python3 -m pytest' for å sikre riktig miljø
70+
docker exec qgis-testing-environment sh -c "cd /tests_directory && xvfb-run python3 -m pytest"
7571
7672
Check-code-quality:
7773
runs-on: ubuntu-latest
@@ -95,4 +91,4 @@ jobs:
9591
run: make pylint
9692

9793
- name: Pycodestyle
98-
run: make pycodestyle
94+
run: make pycodestyle

README.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,36 @@ QGIS Plugin
1515

1616
This provider functions as a QGIS plugin (for QGIS >= 3.28) and is available via the standard QGIS plugins repository, so you can install it directly from within QGIS itself.
1717

18-
The plugin adds a new group to the Processing Toolbox for "Geovita", containing sub-groups with tools and algorithms to perform different geotechnical tasks.
18+
The plugin adds a new group to the Processing Toolbox for "Geovita", containing sub-groups with tools and algorithms to perform different tasks.
1919

2020
If you enconter bugs of any sort, PLEASE consider reporting them through [the bugtracker at GitHub](https://github.com/danpejobo/geovita_processing_plugin/issues). Everyone benefits!
2121

2222
Check it out [here!](/geovita_processing_plugin/)
2323

2424
Overview
2525
========
26-
- Implemented [REMEDY GIS RiskTool](https://github.com/norwegian-geotechnical-institute/REMEDY_GIS_RiskTool) to run from QGIS processing
26+
### REMEDY GIS RiskTool-subgroup
2727

28-
- REMEDY_GIS_RiskTool is an open-source GIS-based tool using the GIBV method to quantify building damage risks from deep excavation, analyzing settlements due to wall deformation and groundwater drawdown, developed under the REMEDY/Begrens Skade 2 research project (2017–2022).
28+
- [REMEDY_GIS_RiskTool](https://github.com/norwegian-geotechnical-institute/REMEDY_GIS_RiskTool) is an open-source GIS-based tool using the GIBV method to quantify building damage risks from deep excavation, analyzing settlements due to wall deformation and groundwater drawdown, developed under the REMEDY/Begrens Skade 2 research project (2017–2022).
2929

3030
## Example results from the REMEDY GIS RiskTool
3131
The following images show some example results. Both the excavation and the tunnel algorithm produces results for short and/or longterm settlements, but uses different calculation methods. The impact map calculates and illustrate total settlements in the impaced soil around the excavation.
3232

3333
| Loaded Layers | Short term | Long term | Impact map |
3434
|---------------|------------|-----------|------------|
3535
| ![Loaded layers](resources/example-short-term-layers.png) <br><br> The symbology of the loaded layers | ![Short term](resources/example-short-term.png) <br><br> Blue hatch is the excavation. Status of corners, walls and buildings | ![Long term](resources/example-long-short-term.png) <br><br> Blue hatch is the excavation. Dark background is the depth to bedrock raster used for long term settlements. | ![Impact map](resources/example-impact-map.png) <br><br> Red hatch is the excavation. The impact map for total settlements around the excavation. |
36+
37+
---
38+
39+
### Geovita-subgroup
40+
41+
#### Create Atlas Coverage
42+
This algorithm automates the creation of a coverage layer for use with the QGIS Atlas feature, which is ideal for generating multi-page "strip maps" along a route (like a road or tunnel).
43+
44+
The tool takes a single line (e.g., a road centerline), your desired map scale, and your paper dimensions to generate two key output layers:
45+
46+
- Atlas Points: A point layer where each point represents the center of a map sheet. This layer contains a crucial angle field, which is automatically calculated to ensure the "long axis" of your paper is aligned with the road.
47+
48+
- Atlas Coverage Polygons: A polygon layer that shows the footprint (the exact rectangular coverage) of each map sheet. This is perfect for creating an index or key map.
49+
50+
<img src="resources\example-create-atlas-coverage.png" alt="Atlas Coverage" width="800"/>

REQUIREMENTS_TESTING.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@ deepdiff
33
mock
44
flake8
55
pep257
6-
pylint
6+
pylint
7+
coverage
8+
pytest-qgis

conftest.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import pytest
2+
from qgis.core import QgsApplication
3+
import os
4+
import sys
5+
6+
# Fortell pytest at den skal laste pytest-qgis-pluginen
7+
pytest_plugins = "pytest_qgis"
8+
9+
# Legg til prosjekt-roten OG submodule-mappen i sys.path
10+
# slik at importer som 'import geovita_processing_plugin' og 'import Utils' fungerer
11+
project_root = os.path.abspath(os.path.dirname(__file__))
12+
submodule_path = os.path.join(project_root, "geovita_processing_plugin", "REMEDY_GIS_RiskTool")
13+
14+
sys.path.insert(0, project_root)
15+
sys.path.insert(0, submodule_path)
16+
17+
@pytest.fixture(scope="session", autouse=True)
18+
def init_qgis_processing(qgis_app):
19+
"""Initialiserer QGIS Processing framework og registrerer plugin-provider."""
20+
21+
print("Initializing QGIS Processing Framework...")
22+
try:
23+
from processing.core.Processing import Processing
24+
Processing.initialize()
25+
print("Processing Framework Initialized.")
26+
except ImportError as e:
27+
print(f"Could not import Processing: {e}")
28+
pytest.skip(f"Failed to import QGIS Processing framework: {e}")
29+
30+
print("Registering Geovita provider...")
31+
try:
32+
# Nå som prosjekt-roten er i sys.path, kan vi importere den direkte
33+
from geovita_processing_plugin.geovita_processing_plugin_provider import Geovita_processing_pluginProvider
34+
provider = Geovita_processing_pluginProvider()
35+
36+
if QgsApplication.processingRegistry().addProvider(provider):
37+
print(f"Successfully added provider: {provider.id()}")
38+
else:
39+
print("Failed to add provider.")
40+
pytest.skip("Failed to add Geovita provider")
41+
except ImportError as e:
42+
print(f"Could not import Geovita provider: {e}")
43+
pytest.skip(f"Failed to import Geovita provider: {e}")
44+
45+
yield
46+
47+
# Nedrigging
48+
print("Deinitializing Processing Framework...")
49+
# Vi må sjekke om 'provider' ble definert i tilfelle importen feilet
50+
if 'provider' in locals() and provider:
51+
QgsApplication.processingRegistry().removeProvider(provider.id())
52+
Processing.deinitialize()

geovita_processing_plugin/README.md

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@ Introduction
22
=====
33
Processing providers and algorithms overview
44

5-
Status and Limitations
5+
6+
REMEDY GIS RiskTool group
67
=====
8+
---
9+
10+
### Status and limitations
711
- [REMEDY GIS RiskTool](https://github.com/norwegian-geotechnical-institute/REMEDY_GIS_RiskTool)
812
- REMEDY_GIS_RiskTool is an open-source GIS-based tool using the GIBV method to quantify building damage risks from deep excavation, analyzing settlements due to wall deformation and groundwater drawdown, developed under the REMEDY/Begrens Skade 2 research project (2017–2022).
913

@@ -13,15 +17,14 @@ Status and Limitations
1317
- Projection of layers:
1418
- All layers `are reprojected on the fly` as they need the same projection
1519

16-
Tools
17-
=====
20+
### Tools
21+
1822
- **REMEDY GIS RiskTool** - These algorithms create a log directory in this location `%user%/Downloads/REMEDY`. For the moment this is hardcoded.
1923
- `Begrens Skade - Excavation` Analyzes building settlement risks in soft clays caused by deep excavation wall deformation, using the GIBV method to calculate vertical greenfield settlements based on empirical data from retaining wall behavior (developed under the REMEDY/Begrens Skade 2 project).
2024
- `Begrens Skade - ImpactMap` Quantifies short- and long-term consolidation settlements from groundwater drawdown during construction pit establishment, employing the GIBV method and empirical datasets to model spatiotemporal risk distribution in soft clays (part of the NFR-funded REMEDY initiative).
2125
- `Begrens Skade - Tunnel` Evaluates subsidence and inclination risks in buildings adjacent to tunnel excavations, leveraging the GIBV framework to predict settlements induced by tunneling activities in soft clay environments (developed through the REMEDY/Begrens Skade 2 research collaboration).
2226

23-
Specifications
24-
==============
27+
### Specifications
2528

2629
It is crucial to understand the limitations of the [REMEDY GIS RiskTool](https://github.com/norwegian-geotechnical-institute/REMEDY_GIS_RiskTool) calculation methods. I would highly suggest reading the paper and the manual within the REMEDY repository.
2730

@@ -44,3 +47,41 @@ If you want to enable `vulnerability analysis` you will need some information on
4447
| D | Wooden piles | Masonry | Bad |
4548
| D | Trepeler | D - Murstein eller spesiell type | D - Dårlig |
4649
| D | D - På løsmasser - Punkt- og trefundamenter (banketter) | - | - |
50+
51+
---
52+
53+
Geovita group
54+
===
55+
56+
---
57+
58+
### `Create Atlas Coverage`
59+
60+
This algorithm automates the creation of a coverage layer for use with the QGIS Atlas feature, which is ideal for generating multi-page "strip maps" along a route (like a road or tunnel).
61+
62+
The tool takes a single line (e.g., a road centerline), your desired map scale, and your paper dimensions to generate two key output layers:
63+
64+
1. **`Atlas Points`**: A point layer where each point represents the center of a map sheet. This layer contains a crucial **`angle`** field, which is automatically calculated to ensure the "long axis" of your paper is aligned with the road.
65+
2. **`Atlas Coverage Polygons`**: A polygon layer that shows the footprint (the exact rectangular coverage) of each map sheet. This is perfect for creating an index or key map.
66+
67+
#### How to use the output:
68+
69+
1. In your QGIS Print Layout, open the **Atlas** panel.
70+
2. Set the **Coverage layer** to the **`Atlas Points`** layer generated by this tool.
71+
3. In your map item's **Item Properties**:
72+
* Check **Controlled by atlas**.
73+
* Set **Scale** to a **Fixed scale** (e.g., `1000` to match the tool input).
74+
* Click the **Data-defined override** icon (ε) for **Rotation** and set it to the field `angle` (or `"angle" + 90` to make the road horizontal).
75+
76+
#### Parameters:
77+
78+
* **`Input Centerline`**: The line layer (e.g., road, rail, tunnel) to follow.
79+
* **`Map Scale`**: The denominator of your desired output scale (e.g., `1000` for 1:1000).
80+
* **`Paper Long Axis (Usable mm)`**: The *usable* length of your paper's long side (in mm). For A3 (420 mm) with 5mm margins, you would enter `410`. This side will be aligned with the road.
81+
* **`Paper Short Axis (Usable mm)`**: The *usable* length of your paper's short side (in mm). For A3 (297 mm) with 5mm margins, you would enter `287`.
82+
* **`Overlap (in meters)`**: The real-world distance you want each map sheet to overlap the previous one (e.g., `50`).
83+
84+
#### Outputs:
85+
86+
* **`Atlas Points`**: The point layer to use as your atlas coverage layer.
87+
* **`Atlas Coverage Polygons`**: The polygon footprints of each map, for use in an index map.

geovita_processing_plugin/__init__.py

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,73 @@
2626
__date__ = '2024-01-17'
2727
__copyright__ = '(C) 2024 by DPE'
2828

29-
__version__ = "3.2.1"
30-
3129
import sys
30+
import configparser
3231
from pathlib import Path
32+
from importlib import metadata
33+
34+
35+
PACKAGE_NAME = 'geovita-processing-plugin'
36+
_FALLBACK_VERSION = '0.0.0'
37+
_PLUGIN_DIR = Path(__file__).resolve().parent
38+
_PYPROJECT_CANDIDATES = (
39+
_PLUGIN_DIR / 'pyproject.toml',
40+
_PLUGIN_DIR.parent / 'pyproject.toml',
41+
)
42+
_METADATA_FILE = _PLUGIN_DIR / 'metadata.txt'
43+
44+
45+
def _read_version_from_pyproject() -> str | None:
46+
"""Return the version declared in pyproject.toml if available."""
47+
48+
try:
49+
import tomllib # type: ignore[attr-defined]
50+
except ModuleNotFoundError: # pragma: no cover - only on Python <3.11 without tomli
51+
try:
52+
import tomli as tomllib # type: ignore[no-redef]
53+
except ModuleNotFoundError:
54+
return None
55+
56+
for candidate in _PYPROJECT_CANDIDATES:
57+
if not candidate.is_file():
58+
continue
59+
with candidate.open('rb') as fh:
60+
data = tomllib.load(fh)
61+
return data.get('project', {}).get('version')
62+
return None
63+
64+
65+
def _read_version_from_metadata() -> str | None:
66+
"""Return the version declared in metadata.txt if available."""
67+
68+
if not _METADATA_FILE.is_file():
69+
return None
70+
71+
parser = configparser.ConfigParser()
72+
parser.optionxform = str
73+
parser.read(_METADATA_FILE, encoding='utf-8')
74+
try:
75+
return parser.get('general', 'version')
76+
except (configparser.NoSectionError, configparser.NoOptionError):
77+
return None
78+
79+
80+
def _determine_version() -> str:
81+
"""Resolve the plugin version from packaging metadata or local files."""
82+
83+
try:
84+
return metadata.version(PACKAGE_NAME)
85+
except metadata.PackageNotFoundError: # type: ignore[attr-defined]
86+
pass
87+
88+
for reader in (_read_version_from_pyproject, _read_version_from_metadata):
89+
version = reader()
90+
if version:
91+
return version
92+
return _FALLBACK_VERSION
93+
94+
95+
__version__ = _determine_version()
3396

3497

3598
# noinspection PyPep8Naming

0 commit comments

Comments
 (0)