Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.26.1.
Query a spatial registry from QGIS
For the data publisher and operator
If you are evaluating Base Registry Engine’s spatial read path, this tutorial starts a synthetic
service-site registry on PostGIS and connects QGIS as a read-only installation client. PostGIS is the
PostgreSQL extension that adds geometry types and spatial predicates. Base Registry Engine requires it
only when a profile that lists records also declares a bounding box query, and the --spatial launcher
flag supplies it by starting a PostGIS image in place of the plain PostgreSQL one. You will
display authorized Point records, pan within a bounded map area, import one record through the
normal API, and see the new Point after QGIS renews its Registry Mint credential.
Before you start
Section titled “Before you start”Create and query your first registry installs breg, bregctl, and mint and clones
the repository at the tag that matches them. Open a terminal at the root of that breg-tutorial
checkout and confirm the binaries answer:
bregctl --versionmint --versionRun every shell command from the root of that clone. Keep two terminals open: the first runs Base Registry Engine and Registry Mint, while the second performs the refresh write. What this tutorial adds to that setup is QGIS, which needs a desktop session.
The quickstart creates local keys, tokens, and a disposable database under
products/breg/quickstart/.run/. A later quickstart run replaces that directory.
Do not put production data or credentials in this exercise.
Start the spatial registry
Section titled “Start the spatial registry”In the first terminal, start the spatial quickstart:
products/breg/quickstart/run.sh --installed --spatialThe --installed flag makes the launcher use the breg, bregctl, and mint you installed
rather than building them from the checkout. The launcher first prints
== Using installed breg, bregctl, and mint from PATH with the three paths it resolved. The first
run also downloads the pinned PostGIS image. Wait for this banner; the ports, the operator token
suffix, and the absolute paths vary:
Base Registry Engine spatial service-site quickstart is ready. Base Registry Engine: http://127.0.0.1:<breg-port> Registry Mint: http://127.0.0.1:<mint-port> Project: <clone>/products/breg/quickstart/.run/project Runtime config: <clone>/products/breg/quickstart/.run/runtime.yaml QGIS OAPIF URL: http://127.0.0.1:<breg-port>/v1/gis Collection: service-site.installation-map-reader QGIS client id: qgis-installation-central QGIS secret: <clone>/products/breg/quickstart/.run/secrets/qgis-client-secret Operator token: <clone>/products/breg/quickstart/.run/secrets/operator-token-<suffix> Map token: <clone>/products/breg/quickstart/.run/secrets/map-token Logs: <clone>/products/breg/quickstart/.run/logsThis tutorial uses the QGIS OAPIF URL, the collection, the client id, and the client secret. The operator and map tokens are the launcher’s own short-lived credentials; the import step mints a fresh one instead of reusing them.
Leave the first terminal running. The launcher has compiled, tested, packaged, and applied the synthetic service-site project. It has also seeded Point records and checked native JSON, GeoJSON, and the QGIS-compatible collection route. QGIS calls this provider OAPIF, short for Open Geospatial Consortium (OGC) API Features. Base Registry Engine exposes only the compatibility routes named in this tutorial and publishes an empty conformance list.
Set a bounded QGIS map view
Section titled “Set a bounded QGIS map view”Start an empty QGIS project. Select the project coordinate reference system control in the bottom-right corner and choose OGC:CRS84 (WGS 84 (CRS84)).
In the QGIS Locator, enter go 100.55,13.75 and select the result in the current project
coordinate reference system. Set the status-bar Scale to 1:5000. Switch the coordinate
display to Extents and confirm that the longitude span is less than 0.24 degrees and the
latitude span is less than 0.19 degrees.
The installation-map-reader profile caps a bounding box at 0.25 longitude degrees by 0.20
latitude degrees. The cap limits how much of the map one query may ask for. It does not decide
which records you may see: that is the profile’s row boundary, which compares each record’s
zone with the service_zones claim in the installation credential. The smaller view leaves
room for QGIS decimal serialization and for canvas aspect-ratio changes. A world view exceeds the
cap and Base Registry Engine refuses the query with query.invalid.
Store the installation credential in QGIS
Section titled “Store the installation credential in QGIS”- Open Settings > Options > Authentication > Configurations, then select Add a new authentication configuration. Set a QGIS master password if prompted.
- Name the configuration
Base Registry Engine spatial quickstart. Set Resource URL to the printed Base Registry Engine origin without/v1/gis. - Select OAuth2 authentication, Grant flow: Client Credentials, and Resource access token method: Header.
- Set Token URL to
http://127.0.0.1:<mint-port>/token, using the printed Registry Mint port. Set Client ID toqgis-installation-central. - Open the printed
qgis-client-secretfile in a local editor and copy its value into Client secret. Leave Scope empty and leave Persist between launches off, then save the configuration.
The client secret stays in QGIS’s authentication database. A saved QGIS project refers to the
configuration by its authcfg identifier; the secret and bearer token do not belong in the
layer URL or project file.
Do not paste the secret into shell history, a QGIS connection URL, logs, screenshots, or support messages. The quickstart creates the secret file with owner-only permissions.
Add the protected Point layer
Section titled “Add the protected Point layer”- Open Layer > Data Source Manager > WFS / OGC API - Features, then select New.
- Name the connection
Base Registry Engine spatial quickstart. Set URL to the printed QGIS OAPIF URL and select the saved OAuth2 configuration under Authentication. - Keep GET and feature paging enabled. Set Page size to
25, then save the connection. - Select the connection under Server Connections and select Connect.
- Select
service-site.installation-map-reader, enable Only request features overlapping the view extent, and select Add.
QGIS draws Point features near the map center. Press F6 to open the attribute table. The
table includes id, label, mapLabel, nativeId, serviceKind, siteCode, and zone.
The installation credential carries a service_zones: central claim, so the collection returns
only records whose zone is central. The layer is read-only, requests at most 25 records per
page, and sends the visible extent as a bounding box. Base Registry Engine applies the same scope,
purpose, row, and field rules to the QGIS-compatible route as it applies to native reads.
The bounding box is a filter inside that row boundary, not the boundary itself. If you leave Only request features overlapping the view extent off, QGIS sends no bounding box and pages through every record the row boundary allows, 25 at a time; the server allows at most 100 records per page on this collection.
Pan within the bounding box cap
Section titled “Pan within the bounding box cap”Close the attribute table and use the QGIS pan tool to move a short distance east or west. Keep the status-bar extent within the longitude and latitude spans used in the earlier map setup.
The visible Points move and reload. If QGIS reports query.invalid, reduce the scale value to
1:2500, return to 100.55,13.75, and reload the layer with F5.
The /v1/gis surface supplies the route shape QGIS needs, including collection discovery,
absolute paging links, and GeoJSON features. Its conformance list is empty because Base Registry
Engine does not claim full Open Geospatial Consortium API Features conformance.
Import a Point through Base Registry Engine
Section titled “Import a Point through Base Registry Engine”Keep QGIS open. In the second terminal, validate and import the supplied refresh record:
spatial_run="$PWD/products/breg/quickstart/.run"spatial_input="$PWD/products/breg/acceptance/spatial-service-sites/fixtures/qgis-refresh-service-site.jsonl"bregctl data validate \ --package "$spatial_run/build/package" \ --entity service-site --profile service-site-admin --operation create \ --input "$spatial_input"
spatial_refresh_token="$spatial_run/secrets/refresh-token-$(openssl rand -hex 8)"mint token \ --url "$(cat "$spatial_run/mint-origin")/token" \ --client-id generic-quickstart \ --key "$spatial_run/keys/operator/signing-p256-private-jwk" | python3 products/breg/quickstart/support/quickstart.py \ store-token --out "$spatial_refresh_token"bregctl data import \ --package "$spatial_run/build/package" \ --breg-url "$(cat "$spatial_run/breg-origin")" \ --access-token-file "$spatial_refresh_token" \ --entity service-site --profile service-site-admin --operation create \ --input "$spatial_input" \ --checkpoint "$spatial_run/qgis-refresh-checkpoint.json"The two summaries look like this; the digests depend on the project:
data validate succeededpackage revision: sha256:<package-revision>schema fingerprint: sha256:<schema-fingerprint>entity: service-siteprofile: service-site-adminoperation: createinput bytes: 305items: 1chunks: 1maximum items: 100maximum bytes: 262144data import succeededpackage revision: sha256:<package-revision>schema fingerprint: sha256:<schema-fingerprint>entity: service-siteprofile: service-site-adminoperation: createinput bytes: 305items: 1completed chunks: 1committed items: 1complete: trueRun the block as one unit: every token the spatial quickstart mints, including the operator token
this block requests, expires after 60 seconds. The checkpoint records each committed chunk, so an
interrupted import resumes without sending a completed chunk again. If you run the import a
second time with the same checkpoint, it sends nothing and reports committed items: 0 with
complete: true. The operator token stays in an owner-only file and is never copied into QGIS.
Refresh and confirm credential renewal
Section titled “Refresh and confirm credential renewal”Return to QGIS, select the layer, and press F5. Open the attribute table with F6. Use
Select features using an expression with this expression:
"siteCode" = 'SVC-QGIS-REFRESH'Select the matching feature and move the selection to the top. QGIS shows one record with these values:
label QGIS refresh examplemapLabel SVC-QGIS-REFRESHserviceKind clinicsiteCode SVC-QGIS-REFRESHzone centralWait at least 95 seconds, then pan within the bounded extent and press F5 again. The protected
layer reloads without asking you to paste a token. Spatial quickstart access tokens last 60
seconds; QGIS uses the stored client credential to request a replacement from Registry Mint.
Stop the local services
Section titled “Stop the local services”Close the QGIS project. In the first terminal, press Ctrl+C. The launcher stops Base Registry Engine,
Registry Mint, and the disposable database container. The files under
products/breg/quickstart/.run/ remain until the next quickstart replaces them.
If you do not plan to repeat the tutorial, remove the QGIS server connection and OAuth2 configuration so the disposable client secret does not remain in your QGIS authentication database.
What you built
Section titled “What you built”- A local Base Registry Engine package with synthetic CRS84 Point records and PostGIS-backed bbox reads
- A protected QGIS layer using an OAuth2 client credential stored outside the project file
- A row-bounded map layer whose queries stay inside the profile’s bounding box cap, with page size 25 and flat authorized attributes
- An authenticated API write that appeared after QGIS Refresh
- A protected layer reload after the short-lived access token expired
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Fix |
|---|---|---|
| The first run takes several minutes on Apple Silicon | The pinned PostGIS image uses linux/amd64, so Docker Desktop may run it under emulation | Leave the launcher running; later runs reuse the downloaded image |
The launcher exits before the banner and names breg, bregctl, or mint as required in --installed mode | The installer’s directory is not on your PATH, or you skipped one of the installers in Create and query your first registry | Add ~/.local/bin to PATH in this terminal, rerun the installer you skipped, then start the launcher again |
QGIS reports query.invalid while adding or panning the layer | The visible extent exceeds the profile’s bounding box cap, often after QGIS adjusts the canvas aspect ratio | Return to 100.55,13.75, set scale to 1:2500, confirm the displayed spans are less than 0.24 and 0.19, then press F5 |
| QGIS asks for credentials or reports an OAuth2 error | The token URL, client ID, secret, or authentication selection does not match the current quickstart | Confirm the printed ports, use client ID qgis-installation-central, copy the current owner-only secret, leave Scope empty, and keep the first terminal running |
| The connection opens but no Point appears | The project starts at a world extent or outside the synthetic fixture area | Set project CRS to OGC:CRS84, locate 100.55,13.75, reduce the scale, and reload |
Refresh does not add SVC-QGIS-REFRESH | The import did not complete, QGIS still has an attribute filter, or the layer cache has not reloaded | Confirm complete: true, clear table filters, select the layer, and press F5 |
- Create and query your first registry covers Base Registry Engine records, updates, refusals, and modules without the GIS client.
- Author a registry project explains how to replace the supplied fixture with your own entities, access profiles, and spatial grants.
- Base Registry Engine API reference describes
the
/v1/gisroutes, the bounding box rules, and the GeoJSON encoding. - Deploy a registry covers running Base Registry Engine against your own PostgreSQL with PostGIS.
- QGIS authentication describes the client credential store used by this tutorial.