feat: stream municipality vectors by viewport
GeoIntel CI / docs-smoke (push) Canceled after 0s
GeoIntel CI / contract-smoke (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-14 10:47:23 +02:00
parent 4933284890
commit 1ba479b50b
19 changed files with 465 additions and 38 deletions
+22
View File
@@ -167,6 +167,28 @@ REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/geel
bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202
```
Reuse the definitive Mol municipality project for a bounded Mol-Centrum
analysis zone while keeping the municipality-wide reference layer distinct:
```bash
REAL_PROJECT_ID=d74c1f87-29c0-4c67-adfc-560764f2b80e \
REAL_PROJECT_NAME='Mol Municipality Workbench' \
REAL_PROJECT_REGION='Mol, Kempen' \
REAL_AREA_NAME='Mol Centrum - AI analysezone 500m' \
REAL_AREA_BBOX='5.113116,51.189653,5.120284,51.194147' \
REAL_DATASET_NAME_PREFIX='mol_center_ai_500m' \
REAL_RASTER_PATH=/mnt/user/appdata/geointel/storage/operator-data/mol_orthophoto_wms_512.tif \
REAL_REFERENCE_VECTOR_PATH=/mnt/user/appdata/geointel/storage/operator-data/mol_grb_gbg_buildings.geojson \
bash scripts/verify_real_data_detection_qa_workflow.sh http://192.168.10.150:1202
```
`REAL_PROJECT_ID` is validated through the canonical project endpoint; it does
not create a shadow validation project. When `REAL_AREA_BBOX` is present, both
the raster and matching reference upload persist that new Area id. The optional
safe filename prefix prevents the bounded sample from sharing a display name
with the complete Mol GRB dataset. The workflow still performs no data fetch or
model download: the files and configured local model asset must already exist.
Those files are runtime artifacts generated from Digitaal Vlaanderen's
OMWRGBMRVL WMS `Ortho` layer and GRB OGC API Features `GBG` building collection
for a small Geel AOI. They are intentionally not repository fixtures.
@@ -18,8 +18,10 @@ Required inputs:
Optional environment:
REAL_PROJECT_NAME Project name for the validation run.
REAL_PROJECT_REGION Persisted project region, default: Kempen.
REAL_PROJECT_ID Existing project id to reuse instead of creating a validation project.
REAL_AREA_NAME Persisted AOI name when REAL_AREA_BBOX is set.
REAL_AREA_BBOX Optional EPSG:4326 minx,miny,maxx,maxy AOI bounds.
REAL_DATASET_NAME_PREFIX Safe filename prefix for raster/reference uploads in a reused project.
REAL_MODEL_ASSET_ID Specific /api/v1/detection/model-assets id to use.
REAL_TILE_SIZE Raster tile size, default 640.
REAL_TILE_OVERLAP Raster tile overlap, default 64.
@@ -33,8 +35,10 @@ REAL_RASTER_PATH="${2:-${REAL_RASTER_PATH:-}}"
REAL_REFERENCE_VECTOR_PATH="${3:-${REAL_REFERENCE_VECTOR_PATH:-}}"
REAL_PROJECT_NAME="${REAL_PROJECT_NAME:-GeoIntel Real Data Validation}"
REAL_PROJECT_REGION="${REAL_PROJECT_REGION:-Kempen}"
REAL_PROJECT_ID="${REAL_PROJECT_ID:-}"
REAL_AREA_NAME="${REAL_AREA_NAME:-${REAL_PROJECT_NAME} AOI}"
REAL_AREA_BBOX="${REAL_AREA_BBOX:-}"
REAL_DATASET_NAME_PREFIX="${REAL_DATASET_NAME_PREFIX:-}"
REAL_TILE_SIZE="${REAL_TILE_SIZE:-640}"
REAL_TILE_OVERLAP="${REAL_TILE_OVERLAP:-64}"
REAL_CONFIDENCE_THRESHOLD="${REAL_CONFIDENCE_THRESHOLD:-0.5}"
@@ -62,6 +66,13 @@ if [ ! -f "${REAL_REFERENCE_VECTOR_PATH}" ]; then
exit 2
fi
case "${REAL_DATASET_NAME_PREFIX}" in
*[!a-zA-Z0-9._-]*)
echo "REAL_DATASET_NAME_PREFIX may contain letters, numbers, dot, underscore and dash only" >&2
exit 2
;;
esac
case "${REAL_RASTER_PATH,,}" in
*.tif|*.tiff|*.geotiff) ;;
*)
@@ -136,7 +147,16 @@ echo "Base URL: ${BASE_URL}"
echo "Raster: ${REAL_RASTER_PATH}"
echo "Reference vector: ${REAL_REFERENCE_VECTOR_PATH}"
"${PYTHON_BIN}" - "${TMP_DIR}/project_request.json" "${REAL_PROJECT_NAME}" "${REAL_PROJECT_REGION}" <<'PY'
if [ -n "${REAL_PROJECT_ID}" ]; then
curl -fsS "${BASE_URL%/}/api/v1/projects/${REAL_PROJECT_ID}" > "${TMP_DIR}/project.json"
require_json_data "${TMP_DIR}/project.json"
project_id="$(json_field "${TMP_DIR}/project.json" "data.id")"
if [ "${project_id}" != "${REAL_PROJECT_ID}" ]; then
echo "Existing project lookup returned the wrong project id" >&2
exit 1
fi
else
"${PYTHON_BIN}" - "${TMP_DIR}/project_request.json" "${REAL_PROJECT_NAME}" "${REAL_PROJECT_REGION}" <<'PY'
import json
import sys
from datetime import datetime, timezone
@@ -152,14 +172,15 @@ with open(path, "w", encoding="utf-8") as handle:
json.dump(payload, handle)
PY
curl -fsS -X POST "${BASE_URL%/}/api/v1/projects" \
-H "Content-Type: application/json" \
--data-binary "@${TMP_DIR}/project_request.json" > "${TMP_DIR}/project.json"
require_json_data "${TMP_DIR}/project.json"
project_id="$(json_field "${TMP_DIR}/project.json" "data.id")"
if [ -z "${project_id}" ] || [ "${project_id}" = "None" ] || [ "${project_id}" = "null" ]; then
echo "Project creation did not return a project id" >&2
exit 1
curl -fsS -X POST "${BASE_URL%/}/api/v1/projects" \
-H "Content-Type: application/json" \
--data-binary "@${TMP_DIR}/project_request.json" > "${TMP_DIR}/project.json"
require_json_data "${TMP_DIR}/project.json"
project_id="$(json_field "${TMP_DIR}/project.json" "data.id")"
if [ -z "${project_id}" ] || [ "${project_id}" = "None" ] || [ "${project_id}" = "null" ]; then
echo "Project creation did not return a project id" >&2
exit 1
fi
fi
area_id=""
@@ -197,14 +218,29 @@ PY
fi
fi
area_upload_args=()
if [ -n "${area_id}" ]; then
area_upload_args=(-F "area_id=${area_id}")
fi
raster_form_file="file=@${REAL_RASTER_PATH}"
reference_form_file="file=@${REAL_REFERENCE_VECTOR_PATH}"
if [ -n "${REAL_DATASET_NAME_PREFIX}" ]; then
raster_extension="${REAL_RASTER_PATH##*.}"
reference_extension="${REAL_REFERENCE_VECTOR_PATH##*.}"
raster_form_file="${raster_form_file};filename=${REAL_DATASET_NAME_PREFIX}_orthophoto.${raster_extension}"
reference_form_file="${reference_form_file};filename=${REAL_DATASET_NAME_PREFIX}_grb_buildings.${reference_extension}"
fi
curl -fsS -X POST "${BASE_URL%/}/api/v1/projects/${project_id}/datasets/upload" \
-F "file=@${REAL_RASTER_PATH}" \
-F "${raster_form_file}" \
-F "dataset_type=raster" \
-F "source=user_upload" \
-F "dataset_role=source" \
-F "source_name=manual" \
-F 'source_metadata_json={"validation_workflow":"real_data_detection_qa","input_kind":"orthophoto"}' \
-F 'provenance_metadata_json={"operator_supplied":true,"no_external_fetch":true}' \
"${area_upload_args[@]}" \
> "${TMP_DIR}/raster_upload.json"
require_json_data "${TMP_DIR}/raster_upload.json"
raster_dataset_id="$(json_field "${TMP_DIR}/raster_upload.json" "data.id")"
@@ -226,7 +262,7 @@ if not data.get("bounds_json"):
PY
curl -fsS -X POST "${BASE_URL%/}/api/v1/projects/${project_id}/datasets/upload" \
-F "file=@${REAL_REFERENCE_VECTOR_PATH}" \
-F "${reference_form_file}" \
-F "dataset_type=vector" \
-F "source=user_upload" \
-F "dataset_role=reference" \
@@ -234,6 +270,7 @@ curl -fsS -X POST "${BASE_URL%/}/api/v1/projects/${project_id}/datasets/upload"
-F "reference_layer_name=buildings" \
-F 'source_metadata_json={"validation_workflow":"real_data_detection_qa","input_kind":"reference_buildings"}' \
-F 'provenance_metadata_json={"operator_supplied":true,"no_external_fetch":true}' \
"${area_upload_args[@]}" \
> "${TMP_DIR}/reference_upload.json"
require_json_data "${TMP_DIR}/reference_upload.json"
reference_dataset_id="$(json_field "${TMP_DIR}/reference_upload.json" "data.id")"