Skip to content

Commit 533cb2a

Browse files
lachlangrosedependabot[bot]rabii-chaaraninoellehmcheng
authored
Merging map2loop plugin into LoopStructural (#51)
* initial commit * adding pyproject.toml for ruff * change linter to ruff * adding release please action * linting * Bump dawidd6/action-download-artifact from 9 to 11 Bumps [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact) from 9 to 11. - [Release notes](https://github.com/dawidd6/action-download-artifact/releases) - [Commits](dawidd6/action-download-artifact@v9...v11) --- updated-dependencies: - dependency-name: dawidd6/action-download-artifact dependency-version: '11' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * ci: fix formatting of release-please * Update linter.yml * Update release-please.yml * fixing syntax * adding release please files * fix: import typo * template for basal contacts processing tool * Update linter.yml * disable qgis testing for now * Update release-please.yml * Update release-please.yml * feature: Implement StratigraphySorterAlgorithm * feature: functions to convert layers to GeoDataFrame and DataFrame * feature: add geodataframe to qgsLayer conversion * refactor: update GeoDataFrameToQgsLayer * fix: GeoDataFrameToQgsLayer to FeatureSink * refactor: clean up imports in vectorLayerWrapper.py * feature: add basal contacts extraction algorithm * refactor: add imports in sorter.py * feature: implement sampler algorithm * feature: add thickness calculator algorithms * fix: correct return value * feature: add support SamplerSpacing * fix: update sampler type strings for consistency * fix: convert dataframe to qgis layer * feature: add dataframe to point sink conversion * fix: add input parameters * refactor: rename to dataframeToQgsLayer * refactor: update thickness calculator parameters and processing logic * update BasalContactsAlgorithm * fix import in vectorLayerWrapper.py * rename unused loop idx in vectorLayerWrapper * rename directory to m2l to avoid import conflicts * fix linter.yml * fix: add QgsPoint import * fix: add QgsPointXY import * fix: enforce str type * refactor: handling of string fields * fix: add missing import for wkb_loads * refactor: implementation and enforce string dtype * fix: QGIS string fields are converted to str * fix: remove type conversion issues * fix: simplify string field handling * fix: ensure string fields are explicitly converted * sampler * fix: enhance contact rextraction tool * fix: update algorithm imports and registration in provider * fix: correct parameter types * fix: standardize algorithm group ID * fix: add user-defined sorting option * input files * fix: change stratigraphic column QgsProcessingParameterFeatureSink description parameter to string * feat add formation column mapping and validation for strat column * delete input files * fix sorter * fix data type of spacing and decimator in sampler * rename unused loop idx in sampler * add dtm to input * add validation in sampler * spacing decimator test * refactor sampler tests for cicd compatibility * update tester.yml workflow for all branches * change image * update testing.txt * install map2loop in tester.yml * tester.yml * input file * test_basal_contacts * fix import in test_basal_contacts.py * fix strati_column in test_basal_contacts * add structure and dtm parameters for SorterObservationProjections and column mapping * add contact as output layer * change contacts_df and relationships_df * add contact layer in sorter * handle dip, dipdir, orientation type for structure in sorter.py * fix syntax in sampler * update basal contact test * update basal contact test to include contacts layer * feat: thickness calculator tool * feat: raster and dataframe handling * fix clean up process for tests * fix remove duplicated units_df in sorter * fix build_input_frames in sorter * add contacts and basal contacts data for testing * add validation in sorter * handle user defined strati column and add validation * add json file output for sorter * refactor: remove user defined column * feat: add qvariantToFloat function * feat: Processing/processing tools sampler (#19) * sampler * fix sorter * fix data type of spacing and decimator in sampler * rename unused loop idx in sampler * add dtm to input * add validation in sampler * spacing decimator test * refactor sampler tests for cicd compatibility * update tester.yml workflow for all branches * change image * update testing.txt * install map2loop in tester.yml * fix: update field types to use QVariant * fix optional dtm parameter in decimator --------- Co-authored-by: Rabii Chaarani <50892556+rabii-chaarani@users.noreply.github.com> * Processing/processing tools basal contacts test (#21) * input files * fix: change stratigraphic column QgsProcessingParameterFeatureSink description parameter to string * feat add formation column mapping and validation for strat column * tester.yml * input file * test_basal_contacts * fix import in test_basal_contacts.py * fix strati_column in test_basal_contacts * removed duplicated input files * fix: fix syntac error * fix: remove redundant parameters in SamplerAlgorithm * fix: remove redundant imports * fix: remove unused QgsSettings * fix: updated tearDownClass * fix: add pass statement * update sampler tests * update sampler * update strati column and bounding box * fix sample contacts data type * add orientation type for structure data * Processing/thickness calculator (#23) * feat: thickness calculator tool * feat: raster and dataframe handling * fix: remove unused QgsSettings * fix: updated tearDownClass * fix: add pass statement * update sampler tests * update sampler --------- Co-authored-by: Noelle Cheng <noelle.cheng@monash.edu> * feat: add UserDefinedStratigraphyAlgorithm to provider * feat: import UserDefinedStratigraphyAlgorithm * refactor: update BasalContactsAlgorithm * refactor: update SamplerAlgorithm * refactor: update sorter * refactor: update ThicknessCalculatorAlgorithm * feat: implement UserDefinedStratigraphyAlgorithm * refactor: remove redundant algo * fix: use correct strati table * fix: correct variable assignment * fix units in ThicknessCalculatorAlgorithm * update extract_basal_contacts and test_basal_contacts * Revert "update extract_basal_contacts and test_basal_contacts" This reverts commit b1bb23f. * fix test_basal_contacts * fix input file name in test_basal_contacts * feat dynamic field handling in Sampler * fix strat column data in ThicknessCalculator * merge with processing/processing_tools * add user defined boundingbox in ThicknessCalculatorAlgorithm * replace QMetaType with QVariant in sampler * change orientation type variable name in ThicknessCalculatorAlgorithm * Initial commit * rename for folder for merge with loopstructural plugin * add agent.md file with initial content. (#53) * Fix: revert building qgs Table * Refactor: remove unnecessary formation field --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: rabii-chaarani <rabii.chaarani@monash.edu> Co-authored-by: Noelle Cheng <noelle.cheng@monash.edu> Co-authored-by: Rabii Chaarani <50892556+rabii-chaarani@users.noreply.github.com> Co-authored-by: noellehmcheng <143368485+noellehmcheng@users.noreply.github.com>
1 parent 7e511a3 commit 533cb2a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+2994
-95
lines changed

.github/labeler.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ tooling:
4545
- .pre-commit-config.yaml
4646
- setup.cfg
4747

48-
4948
UI:
5049
- head-branch:
5150
- ^ui

.github/workflows/linter.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ env:
1919
permissions:
2020
contents: write
2121

22-
2322
jobs:
2423
lint-py:
2524
name: Python 🐍
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
name: "📦 Package & 🚀 Release"
2+
3+
env:
4+
PROJECT_FOLDER: plugin_map2loop
5+
PYTHON_VERSION: 3.9
6+
7+
on:
8+
push:
9+
branches:
10+
- main
11+
paths:
12+
- .github/workflows/package_and_release.yml
13+
- 'docs/**/*'
14+
- "plugin_map2loop/**/*.py"
15+
- "plugin_map2loop/metadata.txt"
16+
tags:
17+
- "*"
18+
19+
# Allow one concurrent deployment per branch/pr
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
translation:
26+
name: "💬 i18n compilation"
27+
runs-on: ubuntu-latest
28+
29+
steps:
30+
- name: Get source code
31+
uses: actions/checkout@v4
32+
33+
- name: Setup Python
34+
uses: actions/setup-python@v5
35+
with:
36+
python-version: ${{ env.PYTHON_VERSION }}
37+
38+
- name: Install translation requirements
39+
run: |
40+
sudo apt update
41+
sudo apt install qt5-qmake qttools5-dev-tools
42+
python3 -m pip install -U pyqt5-tools
43+
44+
- name: Update translations
45+
run: |
46+
python3 scripts/generate_translation_profile.py
47+
pylupdate5 -noobsolete -verbose ${{ env.PROJECT_FOLDER }}/resources/i18n/plugin_translation.pro
48+
49+
- name: Compile translations
50+
run: lrelease ${{ env.PROJECT_FOLDER }}/resources/i18n/*.ts
51+
52+
- uses: actions/upload-artifact@v4
53+
with:
54+
name: translations-build
55+
path: ${{ env.PROJECT_FOLDER }}/**/*.qm
56+
if-no-files-found: error
57+
58+
# -- NO TAGS ----------------------------------------------------------------------
59+
packaging:
60+
name: "📦 Packaging plugin"
61+
runs-on: ubuntu-latest
62+
needs:
63+
- translation
64+
65+
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
66+
67+
steps:
68+
- name: Checkout
69+
uses: actions/checkout@v4
70+
71+
- name: Setup Python
72+
uses: actions/setup-python@v5
73+
with:
74+
cache: "pip"
75+
cache-dependency-path: "requirements/packaging.txt"
76+
python-version: ${{ env.PYTHON_VERSION }}
77+
78+
- name: Install dependencies
79+
run: |
80+
python -m pip install -U pip setuptools wheel
81+
python -m pip install -U -r requirements/packaging.txt
82+
83+
- name: Download translations
84+
uses: actions/download-artifact@v4
85+
with:
86+
name: translations-build
87+
path: ${{ env.PROJECT_FOLDER }}
88+
89+
- name: Amend gitignore to include compiled translations and add it to tracked files
90+
run: |
91+
# include compiled translations
92+
sed -i "s|^*.qm.*| |" .gitignore
93+
94+
# git add full project
95+
git add ${{ env.PROJECT_FOLDER }}/
96+
97+
- name: Package the latest version
98+
env:
99+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
100+
run: |
101+
qgis-plugin-ci package latest \
102+
--allow-uncommitted-changes \
103+
--plugin-repo-url $(gh api "repos/$GITHUB_REPOSITORY/pages" --jq '.html_url')
104+
105+
- uses: actions/upload-artifact@v4
106+
with:
107+
name: ${{ env.PROJECT_FOLDER }}-latest
108+
path: |
109+
plugins.xml
110+
${{ env.PROJECT_FOLDER }}.*.zip
111+
if-no-files-found: error
112+
113+
# -- ONLY TAGS ----------------------------------------------------------------------
114+
release:
115+
name: "🚀 Release on tag"
116+
runs-on: ubuntu-latest
117+
permissions:
118+
contents: write
119+
needs:
120+
- translation
121+
122+
if: startsWith(github.ref, 'refs/tags/')
123+
124+
steps:
125+
- name: Checkout
126+
uses: actions/checkout@v4
127+
128+
- name: Setup Python
129+
uses: actions/setup-python@v5
130+
with:
131+
cache: "pip"
132+
cache-dependency-path: "requirements/packaging.txt"
133+
python-version: ${{ env.PYTHON_VERSION }}
134+
135+
- name: Install project requirements
136+
run: |
137+
python -m pip install -U pip setuptools wheel
138+
python -m pip install -U -r requirements/packaging.txt
139+
140+
- name: Download translations
141+
uses: actions/download-artifact@v4
142+
with:
143+
name: translations-build
144+
path: ${{ env.PROJECT_FOLDER }}
145+
146+
- name: Amend gitignore to include compiled translations and add it to tracked files
147+
run: |
148+
# include compiled translations
149+
sed -i "s|^*.qm.*| |" .gitignore
150+
151+
# git add full project
152+
git add ${{ env.PROJECT_FOLDER }}/
153+
154+
- name: Create GitHub Release
155+
uses: softprops/action-gh-release@v2
156+
with:
157+
fail_on_unmatched_files: true
158+
generate_release_notes: true
159+
160+
- name: Deploy plugin
161+
run: >-
162+
qgis-plugin-ci
163+
release ${GITHUB_REF/refs\/tags\//}
164+
--allow-uncommitted-changes
165+
--create-plugin-repo
166+
--github-token ${{ secrets.GITHUB_TOKEN }}
167+
--osgeo-username ${{ secrets.OSGEO_USER }}
168+
--osgeo-password ${{ secrets.OSGEO_PASSWORD }}

.github/workflows/release-please.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
on:
32
push:
43
branches:

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
".": "0.0.1",
33
"loopstructural": "0.1.11"
4-
}
4+
}

AGENTS.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# AGENTS.md
2+
3+
## Purpose
4+
5+
This document outlines the architectural and development principles for contributors to the `plugin_loopstructural` QGIS plugin. The plugin provides a thin, modular interface to the `map2loop` and `LoopStructural` libraries, enabling geological modeling workflows within QGIS.
6+
7+
---
8+
9+
## Design Philosophy
10+
11+
### 🔹 Thin Interface Layer
12+
- The plugin **must not** reimplement or duplicate functionality from `map2loop` or `LoopStructural`.
13+
- All core logic and enhancements should be contributed upstream to the respective libraries.
14+
- The plugin should focus on **UI integration**, **data flow orchestration**, and **user interaction**.
15+
16+
### 🔹 Modularity
17+
- UI components (dialogs, panels, actions) live under the `loopstructural/gui/` package and should be encapsulated in their own classes.
18+
- Business logic and orchestration are located in `loopstructural/main/` and `loopstructural/toolbelt/` where adapters and services wrap external libraries.
19+
- Processing algorithms and QGIS provider integration are in `loopstructural/processing/` and should be isolated from UI code.
20+
- Avoid tight coupling between components. Use signals/slots or event-driven patterns where appropriate.
21+
22+
### 🔹 Object-Oriented Design
23+
- Use classes with clear responsibilities and interfaces.
24+
- Prefer composition over inheritance unless subclassing is semantically appropriate.
25+
- Encapsulate interactions with external libraries in dedicated adapter or service classes (e.g., `loopstructural.main.Map2LoopService`, `loopstructural.main.LoopStructuralRunner`).
26+
27+
---
28+
29+
## Development Guidelines
30+
31+
### ✅ Code Quality
32+
- All code must pass the repository's pre-commit checks (formatting, linting, import sorting).
33+
- Use type hints and docstrings for all public methods and classes.
34+
- Follow PEP8 and QGIS plugin development best practices.
35+
36+
### 🧪 Testing
37+
- All new code must include **unit tests** and, where applicable, **integration tests**.
38+
- Tests live under the `tests/` package and are runnable with `pytest`.
39+
- Mock external dependencies (`map2loop`, `LoopStructural`) in unit tests.
40+
41+
### 🧩 Current Plugin Structure
42+
43+
```
44+
plugin_loopstructural/
45+
├── loopstructural/ # plugin package
46+
│ ├── __init__.py
47+
│ ├── __about__.py
48+
│ ├── plugin_main.py # QGIS plugin entry and bootstrap
49+
│ ├── gui/ # UI dialogs, widgets, and panels
50+
│ ├── main/ # controllers, managers, adapters (service layer)
51+
│ ├── processing/ # QGIS processing provider and algorithms
52+
│ ├── toolbelt/ # utilities, env parsing, preferences, logging
53+
│ ├── resources/ # icons, translations, help files
54+
│ └── requirements.txt
55+
├── docs/
56+
├── requirements/
57+
├── tests/
58+
└── README.md
59+
```
60+
61+
Notes on mapping older concepts:
62+
- What used to be called `services/` and `controllers/` is implemented across `loopstructural/main/` and `loopstructural/toolbelt/`.
63+
- UI remains in `loopstructural/gui/` (dialogs, `.ui` files, widget classes).
64+
- Processing-specific code and QGIS provider live under `loopstructural/processing/`.
65+
66+
---
67+
68+
## Contribution Workflow
69+
70+
1. Fork the repository and create a feature branch.
71+
2. Implement changes following the design and code quality guidelines.
72+
3. Add or update tests under `tests/` and ensure they run with `pytest`.
73+
4. Run pre-commit hooks (e.g. `pre-commit run --all-files`) and ensure all checks pass.
74+
5. Submit a pull request with a clear description of the changes and rationale. Link to upstream libraries if behavior is moved upstream.
75+
76+
---
77+
78+
## Future Enhancements
79+
80+
- Support for asynchronous or background processing of long-running tasks (consider using QGIS background task framework).
81+
- Improved error handling and user feedback.
82+
- Internationalization (i18n) support and keeping `.ts`/.qm translation files in `loopstructural/resources/i18n/`.
83+
- Better separation of concerns between UI, processing algorithms and adapters to facilitate unit testing.
84+
85+
---
86+
87+
## Contact
88+
89+
For questions or contributions to the upstream libraries:
90+
- `map2loop`
91+
- `LoopStructural`
92+
93+
---

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
GNU GENERAL PUBLIC LICENSE
33
Version 2, June 1991
44

5-
Copyright (c) 2024, Lachlan GROSE / QGIS
5+
Copyright (c) 2025, Lachlan GROSE / QGIS
66
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
77
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
88
Everyone is permitted to copy and distribute verbatim copies

docs/conf.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#!python3
22

3-
"""Configuration for project documentation using Sphinx.
4-
"""
3+
"""Configuration for project documentation using Sphinx."""
54

65
# standard
76
import sys

docs/development/environment.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ Typically on Ubuntu:
88
# create virtual environment linking to system packages (for pyqgis)
99
python3 -m venv .venv --system-site-packages
1010
source .venv/bin/activate
11-
1211
# bump dependencies inside venv
1312
python -m pip install -U pip
1413
python -m pip install -U -r requirements/development.txt
46.1 KB
Loading

0 commit comments

Comments
 (0)