2026-09-18 — Ruta Maya: navegación smooth con stack abierto
Contexto
Recetario del diseño confirma que la sensación “smooth” de Google Maps no depende de la API de Google, sino de coreografía de cámara + sincronía lista↔mapa + panel deslizante. Podemos replicarlo con stack 100% abierto.
Stack técnico decidido
Mapa vectorial
- MapLibre GL JS (BSD, fork de Mapbox GL v1)
- Tiene todas las primitivas:
flyTo,easeTo,fitBounds,pitch,bearing - Extrusión 3D de edificios + terreno
setFeatureStatesobre GeoJSON → resaltado GPU (no DOM)
- Tiene todas las primitivas:
Teselas vectoriales
- OpenFreeMap (gratis, sin API key, OSM)
- Alternativa soberana: PMTiles de Protomaps en Cloudflare R2
- Archivo estático, sin servidor de teselas
- Autoalojado en R2 → costos mínimos
POIs (puntos de interés)
- Overture Maps Places (CDLA-Permissive-2.0)
- Cobertura buena en México
- Datos abiertos, sin restricciones de Google ToS
- Photon / Nominatim: geocodificación y búsqueda
- Wikimedia Commons / Panoramax: fotos abiertas
- Valhalla / OSRM: rutas opcionales
Móvil (si SPAB requiere app)
- @maplibre/maplibre-react-native + Expo (development build)
- Misma lógica de cámara web → móvil
Primitivas de navegación smooth
// Vuelo con easing cúbico, pitch, padding para panel
map.flyTo({
center: place.coords,
zoom: 16.5,
pitch: 55, // inclinación 3D
bearing: -20, // rotación
padding: { left: panelWidth }, // lugar visible junto al panel
speed: 0.9,
curve: 1.6, // qué tanto "sale" antes de entrar
easing: t => 1 - Math.pow(1 - t, 3)
});
// Sincronía lista ↔ mapa con setFeatureState
map.setFeatureState(
{ source: 'places', id: placeId },
{ hover: true }
);Arquitectura de la Ruta Maya
1. Narrativa geográfica
Concepto: Ruta continua por destinos mayas (Tulum → Cobá → Bacalar → Chetumal → Calakmul) con 5 lugares top por parada.
Datos:
{
"slug": "ruta-maya-qroo",
"nombre": "Ruta Maya - Quintana Roo",
"paradas": [
{
"destino": "tulum",
"orden": 1,
"lugares": [ /* top 5 por rating */ ]
},
{
"destino": "coba",
"orden": 2,
"lugares": [ /* top 5 */ ]
}
]
}2. UX de navegación
- Vista inicial: Mapa con todas las paradas numeradas (1→2→3)
- Clic en parada:
flyTo+ panel lateral muestra los 5 lugares - Clic en lugar: zoom a nivel street, panel de detalle completo
- Botón “Siguiente parada”: transición smooth a la siguiente coordenada
3. Panel de detalle austero pero intencional
Brecha real: Google tiene fotos/reseñas/horarios que OSM no iguala.
Solución de diseño:
- Fotos: Wikimedia Commons + placeholders con colores dominantes (ya en
places-explorer) - Reseñas: Solo mostrar rating agregado de Google Places (no texto de reseñas)
- Horarios: OSM
opening_hourstag + fallback manual - Descripción: Wikipedia extract (ya en
spab-retrieval/src/lib/connectors/wikipedia.ts)
Austero → intencional:
- Tipografía editorial (Bricolage Grotesque + Atkinson Hyperlegible)
- Paleta limitada (terracota, jade, arena)
- Skeletons animados mientras carga
- “Datos abiertos” como badge de orgullo
Datos ya disponibles
✅ Destinos con coordenadas: spab-retrieval/data/destinos.json
✅ Lugares con rating: googleplaces.ts → base/lugares.csv
✅ Descripciones Wikipedia: wikipedia.ts
✅ Navegación smooth: places-explorer/src/maplibre-adapter.js
Próximo paso: prototipo Ruta Maya
Alcance del prototipo
- Mapa base: OpenFreeMap con estilo Positron
- GeoJSON de paradas: línea conectando Tulum → Cobá → Bacalar
- Panel lateral: al clic en parada, muestra top 5 lugares
- Transición smooth:
flyTocon pitch + bearing entre paradas - Detalle de lugar: mismo panel de
places-exploreradaptado
Estructura de archivos
ruta-maya/
├── index.html
├── data/
│ └── ruta-maya-qroo.json # paradas + lugares
├── src/
│ ├── ruta-store.js # estado de la ruta (parada actual, progreso)
│ ├── ruta-panel.js # panel de paradas + lugares
│ ├── maplibre-adapter.js # extendido de places-explorer
│ └── ruta-api.js # carga ruta + top 5 por parada
└── README.md
Comando para arrancar
# Generar ruta-maya-qroo.json desde base/lugares.csv
node scripts/build-ruta.js
# Servir
cd ruta-maya && python3 -m http.server 8000Referencias
- MapLibre GL JS: https://maplibre.org/maplibre-gl-js/docs/
- OpenFreeMap: https://openfreemap.org
- Overture Places: https://docs.overturemaps.org/guides/places/
- PMTiles spec: https://protomaps.com/docs/pmtiles
Decisión final
SÍ, armamos el prototipo. La infraestructura de places-explorer ya tiene el 70% del camino hecho — solo falta:
- Cargar GeoJSON de ruta (línea + paradas)
- Extender
maplibre-adapter.jspara transiciones entre paradas - Adaptar
places-panel.jspara modo “ruta” (parada actual + siguiente)
✅ Completado: Quintana Roo + Corredor Tren Maya
Datos agregados
Destinos nuevos en spab-retrieval/data/destinos.json:
- Puerto Morelos (lat: 20.8485, lon: -86.8728) - Estación Tren Maya
- Felipe Carrillo Puerto (lat: 19.5783, lon: -88.0456) - Estación Tren Maya
- Chetumal (lat: 18.5001, lon: -88.2960) - Aeropuerto CTM
- Isla Mujeres (lat: 21.2311, lon: -86.7310) - Pueblo Mágico
Total Quintana Roo: 9 destinos (Cancún, Puerto Morelos, Playa del Carmen, Cozumel, Tulum, Felipe Carrillo Puerto, Bacalar, Chetumal, Isla Mujeres)
GeoJSON: ruta-maya/tren-maya-quintana-roo.geojson
- 8 estaciones principales del Tren Maya en Q. Roo
- LineString del corredor completo (456 km)
- Metadata por estación: municipio, aeropuerto, POIs cercanos, sección/tramo, fecha de inauguración
- Puntos de interés vinculados: 151 sitios arqueológicos, 67 reservas naturales, 23 templos, 21 museos, 13 pueblos mágicos
API: ruta-maya/src/tren-maya-api.js
- 35 lugares distribuidos en 7 estaciones (top 5 por estación)
- Categorías extendidas: cenote, playa, patrimonio, comida, estancia, arqueología, naturaleza
- Datos simulados con estructura real de Google Places (rating, reviewCount)
- Método
placesByStation(estacion)para filtrar por parada
Estaciones mapeadas
| Estación | Destino | Aeropuerto | Pueblo Mágico | Inauguración |
|---|---|---|---|---|
| Cancún Aeropuerto | Cancún | CUN | - | 2023-12-15 |
| Puerto Morelos | Puerto Morelos | - | - | 2024-02-29 |
| Playa del Carmen | Playa del Carmen | - | - | 2024-02-29 |
| Tulum | Tulum | - | ✓ | 2024-09-20 |
| Tulum Aeropuerto | Tulum | TQO | - | 2024-09-20 |
| Felipe Carrillo Puerto | Felipe Carrillo Puerto | - | - | 2024-09-20 |
| Bacalar | Bacalar | - | ✓ | 2024-12-15 |
| Chetumal Aeropuerto | Chetumal | CTM | - | 2024-12-15 |
Próximos pasos
- HTML de visualización (
ruta-maya/index.html) - adaptarplaces-explorer/index.html - Selector de estación en el panel lateral
- Transición smooth estación→estación con
flyTo - Capa de línea del corredor en MapLibre
- Conectar con datos reales de
base/lugares.csv
Ramas creadas
places-turismo (base de datos + componentes)
0f8bf46: adaptar places-explorer para turismo (top 5 por rating)c6f7b68: completar destinos Quintana Roo (4 nuevos)
Contenido:
places-explorer/- componente reutilizable de navegación smoothspab-retrieval/data/destinos.json- 9 destinos de Q. Roo
campana-ruta-maya (prototipo navegable)
7bc1f62: GeoJSON y API del corredor Tren Maya Q.Roo1a6373c: prototipo navegable Ruta Maya con smooth nav
Contenido:
ruta-maya/tren-maya-quintana-roo.geojson- 8 estaciones + corredorruta-maya/src/tren-maya-api.js- 35 lugares (top 5 × 7 estaciones)ruta-maya/index.html- navegación smooth entre estacionesruta-maya/README.md- documentación completa
Cómo probar
cd ~//nef/estado_turismo
# Cambiar a la rama de la campaña
git checkout campana-ruta-maya
# Servir el prototipo
cd ruta-maya && python3 -m http.server 8000
# Abrir http://localhost:8000Navegación:
- Selector de estaciones en panel izquierdo
- Clic en estación → vuelo smooth con pitch 45°
- Marcadores en mapa con popups
- Panel de lugares con detalle (rating, reseñas, fotos)
Stack: MapLibre GL JS + OpenFreeMap + Vanilla JS + Web Components