Skip to content

Commit d5a7015

Browse files
committed
release 0.12.20: parseable metadata, grouped output layers, curated committed settings
1 parent 7abd9ee commit d5a7015

9 files changed

Lines changed: 38 additions & 35 deletions

File tree

.claude/settings.json

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,17 @@
11
{
22
"permissions": {
33
"allow": [
4-
"Bash(uv run ruff check *)",
5-
"Bash(uv run poe typecheck)",
6-
"Bash(uv run poe lint)",
7-
"Bash(uv run ty check *)",
8-
"Bash(uv run poe audit)",
9-
"Bash(uv run coverage report *)",
4+
"Bash(.venv/bin/ruff check *)",
5+
"Bash(.venv/bin/python -m pytest *)",
6+
"Bash(.venv/bin/python scripts/verify.py)",
7+
"Bash(.venv/bin/python scripts/prose_lint.py *)",
108
"Bash(.venv/bin/python scripts/render_scenario_gallery.py)",
11-
"Bash(bash /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/temp/slope_batch.sh)",
12-
"Bash(bash /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/temp/rerender_batch.sh)",
13-
"Bash(bash /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/temp/dlbar_batch.sh)",
14-
"Bash(bash /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/temp/wrap_batch.sh)",
15-
"Bash(/Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/.venv/bin/python /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/temp/wrap.py)",
16-
"Bash(git -C /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin log --oneline -15)",
17-
"Bash(git -C /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin tag)",
18-
"Bash(gh api *)",
9+
"Bash(.venv/bin/python website/scripts/diagrams.py)",
10+
"Bash(.venv/bin/python website/scripts/demonstrators.py)",
1911
"Bash(cargo test *)",
20-
"Bash(git -C /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin log --oneline -S \"member_offset\" -- core)",
21-
"Bash(unzip -l /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/website/public/scenarios/cambourne.zip)",
22-
"Bash(curl -s \"https://api.github.com/repos/mitochevole/isobenefit-cities/git/trees/master?recursive=1\")",
23-
"Bash(curl -s \"https://raw.githubusercontent.com/mitochevole/isobenefit-cities/master/src/land_map.py\" -o /private/tmp/claude-502/-Users-dev-repos-ucl-BSP-isobenefit-qgis-plugin/f25e95a8-8860-4c14-a856-d62e715444a1/scratchpad/land_map.py)",
24-
"Bash(curl -s \"https://raw.githubusercontent.com/mitochevole/isobenefit-cities/master/src/simulation.py\" -o /private/tmp/claude-502/-Users-dev-repos-ucl-BSP-isobenefit-qgis-plugin/f25e95a8-8860-4c14-a856-d62e715444a1/scratchpad/simulation.py)",
25-
"Bash(curl -s \"https://raw.githubusercontent.com/mitochevole/isobenefit-cities/master/README.md\" -o /private/tmp/claude-502/-Users-dev-repos-ucl-BSP-isobenefit-qgis-plugin/f25e95a8-8860-4c14-a856-d62e715444a1/scratchpad/orig_README.md)",
26-
"Bash(.venv/bin/python -m pytest core/tests_py -q)",
27-
"Read(//Users/dev/.local/share/uv/python/cpython-3.10.20-macos-aarch64-none/bin/**)",
28-
"Bash(/Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/.venv/bin/python -c \"import isobenefit; print\\(isobenefit.__version__\\)\")",
29-
"Bash(git -C /Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin tag --sort=-creatordate)",
30-
"Bash(/Users/dev/repos/ucl/BSP-isobenefit-qgis-plugin/.venv/bin/python /private/tmp/claude-502/-Users-dev-repos-ucl-BSP-isobenefit-qgis-plugin/f25e95a8-8860-4c14-a856-d62e715444a1/scratchpad/check_periphery.py)",
31-
"WebFetch(domain:pubmed.ncbi.nlm.nih.gov)"
12+
"Bash(cargo fmt *)",
13+
"Bash(cargo clippy *)",
14+
"Bash(npm run build)"
3215
]
3316
},
3417
"hooks": {

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,3 +140,7 @@ _overpass_cache.xml
140140

141141
# scenario data ZIPs are published site content, not build artefacts
142142
!website/public/scenarios/*.zip
143+
144+
# Claude Code per-user grants and worktrees stay local
145+
.claude/settings.local.json
146+
.claude/worktrees/

core/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "isobenefit"
3-
version = "0.12.19"
3+
version = "0.12.20"
44
edition = "2021"
55
license = "AGPL-3.0-or-later"
66
description = "Rust simulation core for the Isobenefit Urbanism QGIS plugin"

isobenefit_qgis/metadata.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name=Isobenefit Urbanism
33
qgisMinimumVersion=4.0
44
qgisMaximumVersion=4.99
55
description=Sketch walkable urban growth scenarios on real-world data, after D'Acci's Isobenefit Urbanism: every new home within a walk of a mixed-use centre and of green space.
6-
version=0.12.19
6+
version=0.12.20
77
author=Gareth Simons
88
email=gareth.simons@ucl.ac.uk
99

@@ -22,13 +22,14 @@ deprecated=False
2222
server=False
2323

2424
changelog=
25+
0.12.20 Metadata made parseable by the plugin repository (a stray percent sign rejected the 0.12.19 upload); the release check now parses it the same way the repository does. A run's output layers load as one group named for the output folder and run, so successive runs stay organised in the layers pane.
2526
0.12.19 The run dialog, the message bar and the guide all point at the Isobenefit tab of the Log Messages panel, where a running simulation reports per-stage progress and warnings.
26-
0.12.18 Post-processing candidates run about twice as fast again (component labelling joins the walk field in the engine; the placement stack caches its columns), and the progress bar now gives the selection stage the 40-99% band it actually occupies.
27+
0.12.18 Post-processing candidates run about twice as fast again (component labelling joins the walk field in the engine; the placement stack caches its columns), and the progress bar now gives the selection stage the larger share of the bar it actually occupies.
2728
0.12.17 Post-processing is engine-accelerated and barrier-aware: the walk field is computed by the Rust engine (a large window post-processes in under a minute), and scoring walks now detour around water and carved corridors exactly as growth does (they previously crossed them). Requires engine 0.12.17; the plugin prompts for the upgrade.
2829
0.12.16 With an OSM download in the project, the run dialog pre-fills the output folder as a scenarios folder beside the downloaded data, numbered upward when earlier runs exist. A chosen folder is never overwritten.
2930
0.12.15 One distance model: bounded grid walks everywhere, in growth and in scoring. Street-network routing removed (a new settlement has no streets yet, so a network metric measured new and existing fabric on different terms); the streets layer stays as map context and the source of carved barrier corridors. Centre placement is settlement-local: a centre is positioned only by homes in its own contiguous settlement, so it cannot be dragged to a periphery cell facing a green gap. Scenario panels colour slope-excluded land tan, distinct from water and corridors. Plugin unload no longer errors after a finished run.
3031
0.12.14 Centre refinement caches walk fields by coordinate across the whole ensemble: post-processing a many-centre window drops from ~40 s to ~3 s per candidate with identical results. Selection progress logs every candidate.
31-
0.12.13 The post-processing selection reports progress, honours Cancel, and runs in two phases when a street network is supplied (every run ranked by the grid walk, the leaders re-scored along the network), so large windows finish in minutes rather than sitting silent at 90%.
32+
0.12.13 The post-processing selection reports progress, honours Cancel, and runs in two phases when a street network is supplied (every run ranked by the grid walk, the leaders re-scored along the network), so large windows finish in minutes rather than sitting silent near the end of the bar.
3233
0.12.12 Defaults grounded in practice: 800 m centre walk (a ten-minute walk) and 400 m green walk (the WHO/Natural England everyday-green reach); the minimum settlement is now a population (default 1,000 people) rather than an area; new development must earn its own mixed-use centres (a nearby existing centre no longer stands in, so growth cannot sprawl centre-free along existing fabric); scenario downloads fixed on the website; one consolidated Dnipro scenario; distances, barriers and station handling documented in the guide.
3334
0.12.11 Growth no longer stands off carved road, rail and river corridors: a green strip bounded by unbuildable land is exempt from the minimum-span rule, so development can build up to a barrier while green corridors between developments stay protected. Seeding diagrams and probability mechanics documented on the website; growth troubleshooting added to the guide.
3435
0.12.10 First public beta, for QGIS 4. Earlier development history is recorded in the repository.

isobenefit_qgis/sim_runner.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ def __init__(
8989
self.pre_path = str(Path(out_dir_path) / f"{out_file_name}_pre.tif") # raw CA, pre-processing
9090
self.existing_path = str(Path(out_dir_path) / f"{out_file_name}_existing.tif") # pre-simulation fabric
9191
self.report_path = str(Path(out_dir_path) / f"{out_file_name}_report.txt") # human-readable run record
92+
# the output layers group under "<folder> - <run>", so successive runs (scenarios,
93+
# scenarios_2, ...) stay organised by their folder in the layers pane
94+
self.group_name = f"{Path(out_dir_path).name} \u2014 {out_file_name}"
9295
self.target_crs = target_crs
9396
# snapshot every input layer while still on the main thread (see _snapshot)
9497
self.extents_layer = _snapshot(extents_layer)
@@ -627,7 +630,7 @@ def finished(self, result: bool) -> None:
627630
return
628631
if self.is_ensemble:
629632
root = QgsProject.instance().layerTreeRoot()
630-
group = root.insertGroup(0, f"{self.out_file_name} likelihood")
633+
group = root.insertGroup(0, self.group_name)
631634
group.setExpanded(True)
632635
for band, label in [(1, "built"), (2, "green")]:
633636
lyr = QgsRasterLayer(self.out_path, f"{self.out_file_name}{label} likelihood", "gdal")
@@ -680,7 +683,11 @@ def finished(self, result: bool) -> None:
680683
tprops.setFixedRangePerBand(ranges)
681684
tprops.setIsActive(True)
682685

683-
QgsProject.instance().addMapLayer(layer)
686+
root = QgsProject.instance().layerTreeRoot()
687+
group = root.insertGroup(0, self.group_name)
688+
group.setExpanded(True)
689+
QgsProject.instance().addMapLayer(layer, addToLegend=False)
690+
group.addLayer(layer)
684691
self._setup_temporal_controller(start, n)
685692
self._log(
686693
f"Loaded '{self.out_file_name}' with {n} temporal steps — press play in the Temporal Controller.",

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "isobenefit-qgis-plugin"
3-
version = "0.12.19"
3+
version = "0.12.20"
44
description = "QGIS plugin for Isobenefit Urbanism simulation (thin wrapper over the isobenefit engine)."
55
authors = [{ name = "Gareth Simons", email = "gareth.simons@ucl.ac.uk" }]
66
requires-python = ">=3.9"

scripts/verify.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@
2323
("cargo test", ["cargo", "test", "--manifest-path", "core/Cargo.toml"], REPO),
2424
("ruff", [RUFF, "check", "isobenefit_qgis", "tests", "scripts"], REPO),
2525
("prose lint", [PY, "scripts/prose_lint.py", "--all"], REPO),
26+
# plugins.qgis.org parses metadata.txt with configparser (interpolation ON), so a bare
27+
# % in any value rejects the upload; parsing here catches that before a tag
28+
("metadata parse", [
29+
PY, "-c",
30+
"import configparser; c = configparser.ConfigParser(); "
31+
"c.read('isobenefit_qgis/metadata.txt'); "
32+
"[c.get('general', k) for k in c.options('general')]",
33+
], REPO),
2634
("pytest", [PY, "-m", "pytest", "tests", "core/tests_py", "-q"], REPO),
2735
("astro check", ["npx", "astro", "check"], WEB),
2836
("astro build", ["npm", "run", "build"], WEB),

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)