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