61 lines
2.6 KiB
Python
61 lines
2.6 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from pydantic import ValidationError
|
|
|
|
from app.auth.project_dependencies import ProjectContext, get_metadata_repository, get_project_context
|
|
from app.infra.db.metadb.repositories.metadata_repository import MetadataRepository
|
|
from app.domain.schemas.project_map_config import PlaceSearchConfig, ProjectMapConfig
|
|
|
|
from app.domain.schemas.place_search import PlaceSearchItem, PlaceSearchRequest, PlaceSearchResponse, ReverseGeocodingRequest
|
|
from app.services.place_search import PlaceSearchError, search_tianditu_places
|
|
from app.services.reverse_geocoding import reverse_geocode_tianditu
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
async def get_place_search_config(
|
|
ctx: ProjectContext = Depends(get_project_context),
|
|
metadata_repo: MetadataRepository = Depends(get_metadata_repository),
|
|
) -> PlaceSearchConfig:
|
|
project = await metadata_repo.get_project_by_id(ctx.project_id)
|
|
if project is None:
|
|
raise HTTPException(status_code=404, detail="Project not found")
|
|
try:
|
|
config = ProjectMapConfig.model_validate(project.map_config or {}).place_search
|
|
except ValidationError:
|
|
raise HTTPException(status_code=503, detail="当前项目地名搜索配置无效") from None
|
|
if config is None or not config.enabled:
|
|
raise HTTPException(status_code=503, detail="当前项目暂未配置地名搜索")
|
|
return config
|
|
|
|
|
|
@router.post(
|
|
"/place-search-requests",
|
|
response_model=PlaceSearchResponse,
|
|
summary="Search project places",
|
|
description="调用天地图地名搜索,按当前项目 map_config.place_search 的行政区范围,只返回前 10 个可定位候选,不提供分页。",
|
|
)
|
|
async def tianditu_place_search(
|
|
request: PlaceSearchRequest,
|
|
config: PlaceSearchConfig = Depends(get_place_search_config),
|
|
) -> PlaceSearchResponse:
|
|
try:
|
|
return await search_tianditu_places(request, config=config)
|
|
except PlaceSearchError as exc:
|
|
raise HTTPException(status_code=exc.status_code, detail=exc.detail) from exc
|
|
|
|
|
|
@router.post(
|
|
"/reverse-geocoding-requests",
|
|
response_model=PlaceSearchItem,
|
|
summary="Reverse geocode a project map point",
|
|
description="查询 EPSG:4326 地图取点的地名和地址,复用当前项目的地名搜索配置并保留输入坐标。",
|
|
)
|
|
async def tianditu_reverse_geocode(
|
|
request: ReverseGeocodingRequest,
|
|
config: PlaceSearchConfig = Depends(get_place_search_config),
|
|
) -> PlaceSearchItem:
|
|
try:
|
|
return await reverse_geocode_tianditu(request, config=config)
|
|
except PlaceSearchError as exc:
|
|
raise HTTPException(status_code=exc.status_code, detail=exc.detail) from exc
|