Servidor de routing offline usando datos GTFS para aplicaciones Trufi.
Este servidor expone el routing GTFS offline como servicio HTTP, permitiendo que la versión web de trufi-app pueda usar routing sin necesidad de assets locales.
Similar a trufi-server-photon pero para planificación de rutas en lugar de geocoding.
El servidor sirve dos cosas:
- 🌐 Web App: Archivos estáticos de la aplicación Flutter web (trufi-app)
- 🔌 API REST: Endpoints de routing para consultar rutas, paradas, etc.
- 🌐 Web App Incluida: Sirve la aplicación Flutter web como archivos estáticos
- 🚌 Routing Offline: Usa datos GTFS locales sin conexión a internet
- 🔍 Búsqueda de paradas: Encuentra paradas cercanas a coordenadas
- 🗺️ Planificación de rutas: Calcula rutas entre dos puntos
- 📍 Índice espacial: Búsqueda rápida de paradas cercanas (KD-Tree)
- 🐳 Docker: Fácil despliegue con Docker Compose
- 🔌 API REST: Endpoints HTTP simples y documentados
- 📦 Código compartido: Usa
trufi_core_planner(mismo algoritmo que trufi-app)
Este servidor utiliza trufi_core_planner, un paquete compartido que contiene la lógica central de parsing GTFS y routing. Esto garantiza que el algoritmo de routing sea idéntico en:
- 📱 trufi-app (Flutter mobile/web) → usa
trufi_core_routing→ usatrufi_core_planner - 🖥️ trufi-server-planner (servidor Dart) → usa
trufi_core_plannerdirectamente
Ventajas:
- ✅ No hay duplicación de código
- ✅ El mismo GTFS produce las mismas rutas en web y móvil
- ✅ Los bugs se corrigen una vez para todos
- ✅ Más fácil de mantener y probar
Ver MIGRATION.md para más detalles.
- Docker y Docker Compose, O
- Dart SDK 3.10+ (para desarrollo local)
Por defecto, el servidor incluye una página placeholder. Para usar la app real de Flutter:
# Opción A: Script automático
./copy_flutter_build.sh
# Opción B: Manual
cd ../trufi-app
flutter build web --release
cd ../trufi-server-planner
cp -r ../trufi-app/build/web/* web/# Construir e iniciar el servidor
docker-compose up -d --build
# Ver logs
docker-compose logs -f planner
# Acceder a:
# - Web App: http://localhost:8080/
# - API: http://localhost:8080/health# Instalar dependencias
dart pub get
# Ejecutar el servidor
dart run bin/server.dart
# O compilar y ejecutar
dart compile exe bin/server.dart -o build/server
./build/serverGET /health
# Respuesta
{
"status": "healthy",
"service": "trufi-server-planner",
"gtfs": {
"stops": 1234,
"routes": 56,
"trips": 789
}
}GET /stops?limit=100
# Respuesta
{
"stops": [
{
"id": "stop_1",
"name": "Parada Central",
"lat": -17.3935,
"lon": -66.1570,
"code": "001"
}
],
"total": 1234
}GET /stops/nearby?lat=-17.3935&lon=-66.1570&maxDistance=500&maxResults=10
# Parámetros:
# - lat: Latitud (requerido)
# - lon: Longitud (requerido)
# - maxDistance: Distancia máxima en metros (default: 500)
# - maxResults: Número máximo de resultados (default: 10)
# Respuesta
{
"stops": [
{
"stop": {
"id": "stop_1",
"name": "Parada Central",
"lat": -17.3935,
"lon": -66.1570
},
"distance": 123.45
}
],
"count": 5
}GET /routes
# Respuesta
{
"routes": [
{
"id": "route_1",
"shortName": "1",
"longName": "Centro - Norte",
"type": "3",
"color": "FF0000"
}
],
"total": 56
}POST /plan
Content-Type: application/json
{
"from": {
"lat": -17.3935,
"lon": -66.1570
},
"to": {
"lat": -17.4000,
"lon": -66.1600
},
"time": "2024-02-06T10:00:00Z" // opcional
}
# Respuesta
{
"success": true,
"itineraries": [
{
"legs": [
{
"mode": "WALK",
"to": { "id": "stop_1", "name": "Parada A" },
"duration": 120
},
{
"mode": "TRANSIT",
"from": { "id": "stop_1", "name": "Parada A" },
"to": { "id": "stop_2", "name": "Parada B" },
"route": {
"id": "route_1",
"shortName": "1",
"longName": "Centro - Norte"
},
"duration": 600
},
{
"mode": "WALK",
"from": { "id": "stop_2", "name": "Parada B" },
"duration": 90
}
],
"duration": 810
}
]
}PORT: puerto del servidor (default:8080).GTFS_FILE: ruta del archivo GTFS dentro del proceso (default:data/gtfs.zip).
El servidor lee el feed desde data/gtfs.zip (relativo al cwd del proceso, o /app/data/gtfs.zip en docker). El directorio data/ está gitignoreado: cada deploy/dev pone su propio feed allí.
Para cambiar los datos:
# Generá el feed con el builder (una vez):
cd ../trufi-app/tools/gtfs-bolivia-cochabamba
npm install && npm start
# Copialo:
cp ../trufi-app/tools/gtfs-bolivia-cochabamba/out/cochabamba.gtfs.zip data/gtfs.zip
# Reiniciá el contenedor:
docker-compose restart plannerEl repo incluye example.gtfs.zip (3.6MB, Cochabamba) como feed de referencia para tests/dev. CI lo copia a data/gtfs.zip antes de correr los integration tests.
Similar a trufi-server-photon, este servicio se puede integrar con trufi-server:
services:
planner:
build:
context: ./trufi-server-planner
restart: unless-stopped
mem_limit: 2g
networks:
- trufi-server{
"ReverseProxy": {
"Routes": {
"planner": {
"ClusterId": "planner",
"Match": {
"Hosts": ["planner.yourdomain.com"]
}
}
},
"Clusters": {
"planner": {
"Destinations": {
"planner": {
"Address": "http://planner:8080"
}
}
}
}
}
}trufi-server-planner/
├── bin/
│ └── server.dart # Servidor HTTP principal
├── lib/src/
│ ├── models/ # Modelos GTFS
│ │ ├── gtfs_stop.dart
│ │ ├── gtfs_route.dart
│ │ ├── gtfs_trip.dart
│ │ └── gtfs_stop_time.dart
│ ├── parser/ # Parser GTFS
│ │ └── gtfs_parser.dart
│ ├── index/ # Índices para búsqueda
│ │ └── spatial_index.dart
│ └── routing/ # Motor de routing
│ └── simple_planner.dart
├── gtfs_data.zip # Datos GTFS (Cochabamba)
├── Dockerfile # Imagen Docker
├── docker-compose.yml # Orquestación
└── pubspec.yaml # Dependencias Dart
El planner actual es básico. Puedes mejorarlo:
- Algoritmo de routing: Implementar A* o Dijkstra para rutas óptimas
- Horarios: Usar
stop_times.txtpara horarios reales - Transferencias: Soportar múltiples transferencias
- Modos: Agregar caminata, bicicleta, etc.
- Tiempo real: Integrar con GTFS-RT
dart test# Ver logs
docker-compose logs planner
# Verificar que gtfs_data.zip existe
ls -lh gtfs_data.zipSi el GTFS es muy grande, aumenta el límite de memoria en docker-compose.yml:
mem_limit: 4g # En lugar de 2g# Copiar nuevo archivo
cp nuevo_gtfs.zip gtfs_data.zip
# Reiniciar contenedor
docker-compose restart plannerEl servidor actualmente usa datos GTFS de Cochabamba, Bolivia (input/cochabamba.gtfs.zip).
Para usar datos de otra ciudad, simplemente reemplaza gtfs_data.zip con tu archivo GTFS.
- Trufi Association - Open source transit tools for the Global South
- GTFS Specification - General Transit Feed Specification
- OpenTripPlanner - Inspiración para el routing
Part of the Trufi server stack. Open source para mejorar el transporte público en el Sur Global.