---
name: valhalla_route
kind: function
lang: py
domain: geo
version: "1.0.0"
purity: impure
signature: "def valhalla_route(locations: list[dict], base_url: str = 'http://localhost:8002', costing: str = 'auto', units: str = 'metric', timeout_s: float = 60.0) -> dict | None"
description: "Calcula una ruta punto a punto usando el motor de enrutamiento Valhalla. POST a /route, retorna la respuesta JSON con trip.summary (length, time) o None si error."
tags: [valhalla, routing, geo, http, isochrone]
uses_functions: []
uses_types: []
returns: []
returns_optional: true
error_type: "error_go_core"
imports: [httpx]
params:
  - name: locations
    desc: "Lista de dicts con 'lat' y 'lon'. Minimo 2 puntos (origen y destino)."
  - name: base_url
    desc: "URL base del servidor Valhalla. Por defecto http://localhost:8002."
  - name: costing
    desc: "Modelo de coste de enrutamiento: 'auto', 'bicycle', 'pedestrian', etc."
  - name: units
    desc: "Unidades de distancia: 'metric' (km) o 'imperial' (millas)."
  - name: timeout_s
    desc: "Timeout en segundos para la request HTTP. Por defecto 60."
output: "Dict con la respuesta JSON de Valhalla (campo 'trip' con summary.length en km y summary.time en segundos), o None si el servidor no responde o retorna error."
tested: true
tests: ["ruta Madrid-Barcelona supera 500 km"]
test_file_path: "python/functions/geo/tests/test_valhalla_route.py"
file_path: "python/functions/geo/valhalla_route.py"
source_repo: "internal:footprint_aurgi"
source_license: "internal-aurgi"
source_file: "better_maps/scripts/test_valhalla_route.py"
---

## Ejemplo

```python
result = valhalla_route(
    locations=[
        {"lat": 40.4168, "lon": -3.7038},  # Madrid
        {"lat": 41.3874, "lon": 2.1686},   # Barcelona
    ]
)
if result:
    summary = result["trip"]["summary"]
    print(f"{summary['length']} km, {summary['time'] / 3600:.2f} h")
```

## Notas

Retorna None ante cualquier excepcion (timeout, HTTP error, JSON invalido). Si necesitas el error concreto, usa httpx directamente. Requiere Valhalla activo en base_url.
