feat(workbench): add runtime GIS and sample integrations

This commit is contained in:
2026-09-22 10:44:31 +08:00
parent a3b4e75317
commit 7ab9b36a5e
62 changed files with 6685 additions and 51 deletions
+85
View File
@@ -0,0 +1,85 @@
"""Create and publish Fengxian source GIS and water-quality monitoring layers."""
from __future__ import annotations
import argparse
from pathlib import Path
import sys
from psycopg import sql
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from app.infra.db.postgresql.project_spatial import get_project_map_bbox
from app.infra.geoserver.client import GeoServerAdminClient
from app.native.wndb.core.connection import project_connection
SCHEMA_SQL = ROOT / "resources/sql/013_fengxian_map_layers.sql"
SOURCE_MATERIALIZED_LAYERS = (
("fx_20200423_drain_valves", "奉贤排水阀"),
("fx_20200423_service_connections", "奉贤接水点"),
("fx_20200423_flow_meters", "奉贤流量仪"),
("fx_20200423_hydrants", "奉贤消火栓"),
("fx_20200423_customer_meters", "奉贤用户水表"),
("fx_20200423_pipes", "奉贤全网管线"),
("fx_20200423_valves", "奉贤阀门"),
("fx_20200423_non_residential_meters", "奉贤非居民用户水表"),
("fx_20200811_dn100_pipes", "奉贤 DN100 及以上管线"),
)
PUBLISHED_LAYERS = SOURCE_MATERIALIZED_LAYERS + (
("water_quality_monitoring_points", "奉贤水质监测点"),
)
def prepare_layers(database: str) -> dict[str, int]:
with project_connection(database) as conn, conn.transaction():
conn.execute(SCHEMA_SQL.read_text(encoding="utf-8"))
for layer, _title in SOURCE_MATERIALIZED_LAYERS:
conn.execute(
sql.SQL("REFRESH MATERIALIZED VIEW gis.{}").format(
sql.Identifier(layer)
)
)
counts: dict[str, int] = {}
for layer, _title in PUBLISHED_LAYERS:
row = conn.execute(
sql.SQL("SELECT count(*) AS count FROM gis.{}").format(
sql.Identifier(layer)
)
).fetchone()
counts[layer] = int(row["count"])
return counts
def publish_layers(database: str, workspace: str) -> dict[str, int]:
counts = prepare_layers(database)
map_bbox = get_project_map_bbox(database)
with GeoServerAdminClient() as geoserver:
geoserver.check_ready()
for layer, title in PUBLISHED_LAYERS:
geoserver.publish_feature_type(
workspace=workspace,
datastore=workspace,
layer=layer,
title=title,
map_bbox=map_bbox,
)
geoserver.truncate_layer_cache(workspace, layer)
return counts
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--database", default="tjwater_v2")
parser.add_argument("--workspace", default="tjwater_next")
args = parser.parse_args()
counts = publish_layers(args.database, args.workspace)
for layer, count in counts.items():
print(f"{layer}: {count:,}")
if __name__ == "__main__":
main()