Quickstart
You will have a GeoPackage that reacts to every INSERT/UPDATE/DELETE in under 5 minutes — no server, no QGIS plugin, just the CLI.
Prerequisites
- Python 3.10+
pipx(install guide) — recommended to isolate the CLI from the system Python
Step 1 — Install the CLI
pipx install gispulseWhy pipx?
pipx installs GISPulse in an isolated environment: no system-Python pollution, no clash with geopandas / pyproj from other projects. On macOS Sonoma+ or recent Debian, a global pip install gispulse fails with error: externally-managed-environment (PEP 668).
If you must use pip: pip install --user gispulse, or activate a virtualenv first.
Verify:
gispulse --helpTry it in 60 seconds
Before writing a single rule, run a bundled demo: GISPulse copies a sample (the cadastral parcels of Muret, 7 MB), runs the cadastre_topology_cleanup preset and writes a result GeoPackage — offline, no configuration.
gispulse demo list # presets that ship a sample dataset
gispulse demo run cadastre_topology_cleanup # ~20 sDemo: cadastre_topology_cleanup — Pipeline de nettoyage topologique d'une coverage polygonale …
Sample: Muret (31): 17 212 parcelles cadastrales
Running 8 step(s) [engine: python]:
[make_valid] repare_geoms
…
Done in 19.2 s — 17 212 feature(s) in, 8 step(s) executed.
Output layers (gispulse-demo/cadastre_topology_cleanup/cadastre_topology_cleanup.gpkg):
issues_report 44 feature(s)
surfaces_finales 17 158 feature(s)Open the GPKG in QGIS (or launch gispulse portal), then replay the pipeline with the regular runner from the pipeline.json written next to the result. The other demos (risques_inondation_parcelles, services_aires_influence) run in under a second. From a pip install, the samples are downloaded once (SHA-256 verified) into ~/.cache/gispulse/demo/.
Step 2 — Grab a sample GeoPackage
For this demo, download a cadastral parcels sample (~7 MB):
mkdir -p demo && cd demo
curl -L "https://raw.githubusercontent.com/imagodata/gispulse/main/examples/datasets/muret_parcels.gpkg" \
-o parcels.gpkg
gispulse info parcels.gpkgFile: parcels.gpkg
Format: GPKG
Size: 6.91 MB
CRS: EPSG:4326
Category: vector
1 layer(s):
- parcels: 17212 features, Polygon, EPSG:4326Step 3 — Install change-tracking
GISPulse installs SQLite AFTER INSERT/UPDATE/DELETE triggers on the target layer. Any modification — by QGIS, ogr2ogr, FME, or any SQL client — gets captured into an internal _gispulse_change_log table.
gispulse track install parcels.gpkg --layer parcelsgpkg_project_bootstrapped: 11 internal tables (schema v2)
change_tracking_installed: parcels (pk=fid, cols=9, geom=geom)
✓ Installed change tracking on 1 layer(s): parcelsVerify the install:
gispulse track list parcels.gpkg Change tracking — parcels.gpkg
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Layer ┃ Tracked ┃ Ops ┃ Pending ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ parcels │ ✓ │ delete,insert,update │ 0 │
└─────────┴─────────┴──────────────────────┴─────────┘Step 4 — Write a YAML trigger
Create triggers.yaml next to the GPKG:
version: 1
gpkg: ./parcels.gpkg
triggers:
- name: tag_high_value_parcels
table: parcels
pk_col: fid
when: [INSERT, UPDATE]
predicate: "surface_cadastrale > 10000"
actions:
- type: set_field
field: owner
value: AUDIT_REQUIRED
runtime:
poll_interval_ms: 1000
max_batch: 200This trigger tags every parcel larger than 1 hectare with owner = "AUDIT_REQUIRED" whenever it is created or updated. The predicate DSL supports == != > < AND OR IN — no eval, no third-party dependency (see docs/TRIGGERS_GUIDE.md).
Validate the config (syntax + schema + layer references):
gispulse triggers validate --config triggers.yamlOK 1 trigger(s) valid against parcels.gpkg.Step 5 — Edit the GPKG from your usual client
Change-tracking captures changes made by any client. Open parcels.gpkg in QGIS (right-click → Toggle Editing), edit a few attributes, save. Or via CLI with ogr2ogr:
ogr2ogr -f GPKG parcels.gpkg parcels.gpkg parcels \
-dialect SQLite -sql "UPDATE parcels SET owner='test' WHERE fid IN (1, 2, 3)" \
-updateCheck the pending changes:
gispulse track list parcels.gpkg Change tracking — parcels.gpkg
┏━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Layer ┃ Tracked ┃ Ops ┃ Pending ┃
┡━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ parcels │ ✓ │ delete,insert,update │ 3 │
└─────────┴─────────┴──────────────────────┴─────────┘Step 6 — Run the runtime
--once mode: drain the change-log once, run the actions, exit. Ideal for cron, AWS Lambda, CI hooks:
gispulse triggers run --config triggers.yaml --once{"event":"runtime_starting","gpkg":"./parcels.gpkg","triggers":1,"mode":"once"}
{"event":"tick_done","processed":3}
OK one tick processed 3 change-log row(s) on parcels.gpkg.--watch mode: a daemon that polls continuously, hot-reloads the YAML on mtime change, shuts down cleanly on SIGINT/SIGTERM (2 s drain):
gispulse watch parcels.gpkg --rules triggers.yamlIn production
For long-running deployments, use packaging/systemd/gispulse-watch@.service or packaging/docker/Dockerfile.watch. See docs/INTEGRATION_MATRIX.md.
Going further
| Goal | Command |
|---|---|
| Diagnose trigger drift | gispulse track doctor parcels.gpkg --auto-fix |
| List installed actions | gispulse triggers list --gpkg parcels.gpkg |
| View latest change-log rows | gispulse track tail parcels.gpkg |
| Uninstall change-tracking | gispulse track uninstall parcels.gpkg --layer parcels |
| Launch the visual portal | gispulse portal |
| List capabilities | gispulse capabilities |
- Full triggers guide — predicate DSL, action types, SQL guardrails, payload v2
- CLI reference
- All capabilities
- Integrations: QGIS · ArcGIS · MapLibre