feat(sensor): 返回候选节点最大管径
This commit is contained in:
@@ -2,7 +2,7 @@ import logging
|
||||
from typing import Any
|
||||
from urllib.parse import quote
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, Path, Query, status
|
||||
from fastapi.responses import StreamingResponse
|
||||
from starlette.concurrency import run_in_threadpool
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.algorithms.sensor import (
|
||||
from app.auth.metadata_dependencies import get_current_metadata_user
|
||||
from app.auth.project_dependencies import ProjectContext, get_project_context
|
||||
from app.domain.schemas.sensor_placement import (
|
||||
SensorPointResponse,
|
||||
SensorPlacementExportRequest,
|
||||
SensorPlacementOptimizeRequest,
|
||||
SensorPlacementSchemeResponse,
|
||||
@@ -24,6 +25,7 @@ from app.services.sensor_placement import (
|
||||
SensorPlacementValidationError,
|
||||
build_sensor_placement_workbook,
|
||||
can_edit_sensor_placement,
|
||||
get_sensor_placement_candidate,
|
||||
get_sensor_placement_scheme,
|
||||
update_sensor_placement_scheme,
|
||||
)
|
||||
@@ -94,6 +96,25 @@ def _get_scheme_response(
|
||||
raise _service_http_error(exc) from exc
|
||||
|
||||
|
||||
@router.get(
|
||||
"/sensor-placement-candidates/{node_id}",
|
||||
response_model=SensorPointResponse,
|
||||
summary="获取监测点候选节点详情",
|
||||
)
|
||||
async def get_sensor_placement_candidate_detail(
|
||||
node_id: str = Path(..., min_length=1, max_length=32),
|
||||
project_context: ProjectContext = Depends(get_project_context),
|
||||
) -> dict[str, Any]:
|
||||
try:
|
||||
return await run_in_threadpool(
|
||||
get_sensor_placement_candidate,
|
||||
project_context.project_code,
|
||||
node_id,
|
||||
)
|
||||
except SensorPlacementValidationError as exc:
|
||||
raise _service_http_error(exc) from exc
|
||||
|
||||
|
||||
@router.post(
|
||||
"/sensor-placement-optimization-runs",
|
||||
response_model=SensorPlacementSchemeResponse,
|
||||
|
||||
@@ -67,6 +67,10 @@ class SensorPlacementExportRequest(BaseModel):
|
||||
|
||||
class SensorPointResponse(BaseModel):
|
||||
node_id: str
|
||||
max_pipe_diameter: float | None = Field(
|
||||
...,
|
||||
description="节点关联管道的最大管径,单位:毫米",
|
||||
)
|
||||
project_x: float
|
||||
project_y: float
|
||||
map_x: float
|
||||
|
||||
@@ -66,8 +66,22 @@ def get_sensor_placement_nodes(
|
||||
with conn.cursor(row_factory=dict_row) as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
WITH incident_pipe_diameters AS (
|
||||
SELECT node_id, MAX(diameter) AS max_pipe_diameter
|
||||
FROM (
|
||||
SELECT node1 AS node_id, diameter
|
||||
FROM pipes
|
||||
WHERE node1 = ANY(%s)
|
||||
UNION ALL
|
||||
SELECT node2 AS node_id, diameter
|
||||
FROM pipes
|
||||
WHERE node2 = ANY(%s)
|
||||
) AS incident_pipes
|
||||
GROUP BY node_id
|
||||
)
|
||||
SELECT DISTINCT ON (gj.id)
|
||||
gj.id AS node_id,
|
||||
ipd.max_pipe_diameter,
|
||||
gj.elevation,
|
||||
ST_X(c.coord) AS project_x,
|
||||
ST_Y(c.coord) AS project_y,
|
||||
@@ -75,10 +89,11 @@ def get_sensor_placement_nodes(
|
||||
ST_Y(gj.geom) AS map_y
|
||||
FROM geo_junctions_mat AS gj
|
||||
JOIN coordinates AS c ON c.node = gj.id
|
||||
LEFT JOIN incident_pipe_diameters AS ipd ON ipd.node_id = gj.id
|
||||
WHERE gj.id = ANY(%s)
|
||||
ORDER BY gj.id
|
||||
""",
|
||||
(node_ids,),
|
||||
(node_ids, node_ids, node_ids),
|
||||
)
|
||||
return list(cur.fetchall())
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@ def _sensor_points(
|
||||
points.append(
|
||||
{
|
||||
"node_id": node_id,
|
||||
"max_pipe_diameter": (
|
||||
float(node["max_pipe_diameter"])
|
||||
if node["max_pipe_diameter"] is not None
|
||||
else None
|
||||
),
|
||||
"project_x": project_x,
|
||||
"project_y": project_y,
|
||||
"map_x": map_x,
|
||||
@@ -92,6 +97,15 @@ def _sensor_points(
|
||||
return points
|
||||
|
||||
|
||||
def get_sensor_placement_candidate(
|
||||
network: str,
|
||||
node_id: str,
|
||||
) -> dict[str, Any]:
|
||||
"""Return the authoritative editable point data for one junction."""
|
||||
|
||||
return _sensor_points(network, _normalize_locations([node_id]))[0]
|
||||
|
||||
|
||||
def validate_sensor_placement_nodes(
|
||||
network: str,
|
||||
sensor_location: list[str],
|
||||
|
||||
Reference in New Issue
Block a user