Initial public release
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
GeoIntel release gates / Compile, test, contracts and builds (push) Successful in 1m49s
GeoIntel release gates / Python and npm vulnerability policy (push) Successful in 21s
GeoIntel release gates / Production AI image, SBOM and container scan (push) Successful in 5m39s
GeoIntel release gates / Deploy exact gated revision to Unraid (push) Failing after 58m43s
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
"""Canonical operator scope definitions for GeoIntel.
|
||||
|
||||
These definitions describe administrative/policy scopes only. They do not
|
||||
claim that a policy boundary equals a cultural or physical landscape region.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ScopeMember:
|
||||
name: str
|
||||
nis_code: str
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class GeographicScope:
|
||||
key: str
|
||||
display_name: str
|
||||
project_name: str
|
||||
project_region: str
|
||||
area_name: str
|
||||
authority_name: str
|
||||
authority_url: str
|
||||
scope_type: str
|
||||
limitation_message: str
|
||||
members: tuple[ScopeMember, ...]
|
||||
all_municipalities: bool = False
|
||||
|
||||
@property
|
||||
def nis_codes(self) -> tuple[str, ...]:
|
||||
return tuple(member.nis_code for member in self.members)
|
||||
|
||||
|
||||
MOL_SCOPE = GeographicScope(
|
||||
key="mol",
|
||||
display_name="Mol",
|
||||
project_name="Mol Municipality Workbench",
|
||||
project_region="Mol, Kempen",
|
||||
area_name="Gemeente Mol - officiële grens",
|
||||
authority_name="Digitaal Vlaanderen VRBG",
|
||||
authority_url="https://geo.api.vlaanderen.be/VRBG/ogc/features/v1/collections/Refgem/items",
|
||||
scope_type="municipality",
|
||||
limitation_message="Officiële gemeentegrens; dit is geen perceelsgrens.",
|
||||
members=(ScopeMember("Mol", "13025"),),
|
||||
)
|
||||
|
||||
|
||||
KEMPEN_TRANSPORT_REGION_SCOPE = GeographicScope(
|
||||
key="kempen-transport-region",
|
||||
display_name="Kempen (28 gemeenten)",
|
||||
project_name="Kempen Regional Workbench",
|
||||
project_region="Vervoerregio Kempen, Vlaanderen",
|
||||
area_name="Vervoerregio Kempen - officiële operationele grens",
|
||||
authority_name="Vlaamse overheid - Vervoerregio Kempen",
|
||||
authority_url=(
|
||||
"https://www.vlaanderen.be/mobiliteitsprofessionals/personenvervoer/"
|
||||
"basisbereikbaarheid/mobiliteitsuitdagingen-regionaal-aanpakken/"
|
||||
"vervoerregios/over-de-vervoerregio-kempen"
|
||||
),
|
||||
scope_type="transport_region",
|
||||
limitation_message=(
|
||||
"Operationele beleidsgrens van de Vlaamse vervoerregio Kempen; "
|
||||
"geen claim over de ruimere culturele, landschappelijke of historische Kempen."
|
||||
),
|
||||
members=(
|
||||
ScopeMember("Arendonk", "13001"),
|
||||
ScopeMember("Baarle-Hertog", "13002"),
|
||||
ScopeMember("Balen", "13003"),
|
||||
ScopeMember("Beerse", "13004"),
|
||||
ScopeMember("Dessel", "13006"),
|
||||
ScopeMember("Geel", "13008"),
|
||||
ScopeMember("Grobbendonk", "13010"),
|
||||
ScopeMember("Herentals", "13011"),
|
||||
ScopeMember("Herenthout", "13012"),
|
||||
ScopeMember("Herselt", "13013"),
|
||||
ScopeMember("Hoogstraten", "13014"),
|
||||
ScopeMember("Hulshout", "13016"),
|
||||
ScopeMember("Kasterlee", "13017"),
|
||||
ScopeMember("Laakdal", "13053"),
|
||||
ScopeMember("Lille", "13019"),
|
||||
ScopeMember("Meerhout", "13021"),
|
||||
ScopeMember("Merksplas", "13023"),
|
||||
ScopeMember("Mol", "13025"),
|
||||
ScopeMember("Nijlen", "12026"),
|
||||
ScopeMember("Olen", "13029"),
|
||||
ScopeMember("Oud-Turnhout", "13031"),
|
||||
ScopeMember("Ravels", "13035"),
|
||||
ScopeMember("Retie", "13036"),
|
||||
ScopeMember("Rijkevorsel", "13037"),
|
||||
ScopeMember("Turnhout", "13040"),
|
||||
ScopeMember("Vorselaar", "13044"),
|
||||
ScopeMember("Vosselaar", "13046"),
|
||||
ScopeMember("Westerlo", "13049"),
|
||||
),
|
||||
)
|
||||
|
||||
BELGIUM_SCOPE = GeographicScope(
|
||||
key="belgium",
|
||||
display_name="België",
|
||||
project_name="Belgium and North Sea Workbench",
|
||||
project_region="Belgium and Belgian North Sea",
|
||||
area_name="Belgium land",
|
||||
authority_name="National Geographic Institute (NGI), AdminVector",
|
||||
authority_url="https://www.geo.be/catalog/details/fb1e2993-2020-428c-9188-eb5f75e284b9",
|
||||
scope_type="country",
|
||||
limitation_message=(
|
||||
"De nationale Statbel-sectorlaag dekt het Belgische landgebied. "
|
||||
"Belgische maritieme zones bevatten geen statistische bevolkingssectoren."
|
||||
),
|
||||
members=(),
|
||||
all_municipalities=True,
|
||||
)
|
||||
|
||||
|
||||
GEOGRAPHIC_SCOPES = {
|
||||
scope.key: scope
|
||||
for scope in (MOL_SCOPE, KEMPEN_TRANSPORT_REGION_SCOPE, BELGIUM_SCOPE)
|
||||
}
|
||||
|
||||
|
||||
def validate_scope(scope: GeographicScope) -> None:
|
||||
if not scope.key or not scope.project_name or not scope.area_name:
|
||||
raise ValueError("Geographic scope identity fields must not be empty")
|
||||
if len(scope.members) == 0 and not scope.all_municipalities:
|
||||
raise ValueError(f"Geographic scope {scope.key} has no members")
|
||||
if scope.all_municipalities and scope.scope_type != "country":
|
||||
raise ValueError(f"Geographic scope {scope.key} can include all municipalities only for a country scope")
|
||||
names = [member.name.casefold() for member in scope.members]
|
||||
codes = [member.nis_code for member in scope.members]
|
||||
if len(names) != len(set(names)):
|
||||
raise ValueError(f"Geographic scope {scope.key} contains duplicate municipality names")
|
||||
if len(codes) != len(set(codes)):
|
||||
raise ValueError(f"Geographic scope {scope.key} contains duplicate NIS codes")
|
||||
if any(len(code) != 5 or not code.isdigit() for code in codes):
|
||||
raise ValueError(f"Geographic scope {scope.key} contains an invalid NIS code")
|
||||
|
||||
|
||||
for _scope in GEOGRAPHIC_SCOPES.values():
|
||||
validate_scope(_scope)
|
||||
Reference in New Issue
Block a user