perf(map): accelerate large spatial metrics
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Codex
2026-07-21 23:22:22 +02:00
parent 61731d9b0f
commit 17d0d85778
+20 -9
View File
@@ -11,7 +11,7 @@ from geoalchemy2.shape import to_shape
from shapely.geometry import box, mapping, shape
from shapely.ops import transform as transform_geometry
from shapely.validation import make_valid
from sqlalchemy import Float, String, cast, func
from sqlalchemy import Float, String, case, cast, func
from app.core.errors import AppError
from app.models import Dataset, VectorFeature
@@ -778,12 +778,18 @@ class VectorFeatureService:
)
if method == "intersection_area":
measured_geometry = (
VectorFeature.geometry
if full_dataset_area
else func.ST_Intersection(VectorFeature.geometry, selection_shape)
)
area_expression = func.ST_Area(func.ST_Transform(measured_geometry, 31370))
source_area = func.ST_Area(func.ST_Transform(VectorFeature.geometry, 31370))
if full_dataset_area:
area_expression = source_area
else:
covered_by_selection = func.ST_CoveredBy(VectorFeature.geometry, selection_shape)
intersection_area = func.ST_Area(
func.ST_Transform(func.ST_Intersection(VectorFeature.geometry, selection_shape), 31370)
)
area_expression = case(
(covered_by_selection, source_area),
else_=intersection_area,
)
area_m2 = db.query(func.coalesce(func.sum(area_expression), 0.0)).filter(*metric_filter).scalar()
divisor = 10_000.0 if unit == "ha" else 1.0
metric_value = float(area_m2 or 0.0) / divisor
@@ -808,12 +814,17 @@ class VectorFeatureService:
)
numeric_value = cast(VectorFeature.properties_json.op("->>")(property_name), Float)
value_expression = numeric_value
covered_by_selection = None
if method == "area_weighted_sum" and not full_dataset_area:
source_area = func.ST_Area(func.ST_Transform(VectorFeature.geometry, 31370))
intersection_area = func.ST_Area(
func.ST_Transform(func.ST_Intersection(VectorFeature.geometry, selection_shape), 31370)
)
coverage_ratio = intersection_area / func.nullif(source_area, 0.0)
covered_by_selection = func.ST_CoveredBy(VectorFeature.geometry, selection_shape)
coverage_ratio = case(
(covered_by_selection, 1.0),
else_=intersection_area / func.nullif(source_area, 0.0),
)
value_expression = numeric_value * coverage_ratio
aggregate_function = {
"mean": func.avg,
@@ -831,7 +842,7 @@ class VectorFeatureService:
partial_feature_count = (
db.query(func.count(VectorFeature.id))
.filter(*metric_filter)
.filter(coverage_ratio < 0.999999)
.filter(~covered_by_selection)
.scalar()
)
is_estimate = bool(config.get("is_estimate", False)) or bool(partial_feature_count)