"""Geocode endpoints — debug + frontend Suggest proxy.""" from __future__ import annotations import logging from typing import Annotated from fastapi import APIRouter, Depends, HTTPException, Query from pydantic import BaseModel from sqlalchemy.orm import Session from app.core.db import get_db from app.services.geocoder import GeocodeResult, geocode, reverse_geocode, suggest logger = logging.getLogger(__name__) router = APIRouter() @router.get("/lookup", response_model=GeocodeResult) async def lookup( address: Annotated[str, Query(min_length=3, max_length=500)], db: Annotated[Session, Depends(get_db)], ) -> GeocodeResult: """Геокодинг адреса → lat/lon. Примеры: /api/v1/geocode/lookup?address=ул.+Малышева+30+Екатеринбург /api/v1/geocode/lookup?address=Куйбышева+50+Екатеринбург """ result = await geocode(address, db) if result is None: raise HTTPException(status_code=404, detail=f"Address not found: {address}") return result class SuggestItem(BaseModel): label: str full_address: str lat: float lon: float kind: str class SuggestResponse(BaseModel): items: list[SuggestItem] @router.get("/suggest", response_model=SuggestResponse) async def suggest_addresses( q: Annotated[str, Query(min_length=2, max_length=200, description="Запрос для автокомплита")], limit: Annotated[int, Query(ge=1, le=15)] = 8, ) -> SuggestResponse: """Автокомплит адресов в пределах ЕКБ. Используется в EstimateForm для подсказок пока пользователь печатает. Bounded viewbox = ЕКБ (lon 60.40-60.85, lat 56.65-56.95). Пример: /api/v1/geocode/suggest?q=Малышева /api/v1/geocode/suggest?q=Цвиллинга # → пусто, такой улицы в ЕКБ нет """ items = await suggest(q, limit=limit) return SuggestResponse(items=[ SuggestItem( label=s.label, full_address=s.full_address, lat=s.lat, lon=s.lon, kind=s.kind, ) for s in items ]) @router.get("/reverse") async def reverse( lat: Annotated[float, Query(ge=-90, le=90)], lon: Annotated[float, Query(ge=-180, le=180)], ) -> dict[str, object]: """Обратный геокодинг — координаты с карты → адрес (map-picker). Пример: /api/v1/geocode/reverse?lat=56.8389&lon=60.6057 """ address = await reverse_geocode(lat, lon) if address is None: raise HTTPException(status_code=404, detail="address not found for coordinates") return {"address": address, "lat": lat, "lon": lon}