RutaFácil
PWA para repartidores: captura ubicaciones desde WhatsApp y genera la ruta de entregas más corta en el dispositivo.
Cronología
2 Semanas
Rol
Frontend & PWA Developer

El Problema
Los repartidores urbanos independientes reciben decenas de pedidos diarios por WhatsApp u otras mensajerías. Coordinar el orden de visita manualmente causa pérdidas considerables de tiempo y combustible, mientras que las soluciones comerciales de ruteo implican suscripciones costosas o complejas apps con dependencias de APIs de pago.
- ✕Pérdida de tiempo y combustible ordenando paradas de forma intuitiva o desordenada.
- ✕Fricción al copiar y pegar direcciones individuales entre WhatsApp y aplicaciones de mapas.
- ✕Costosas suscripciones y APIs de ruteo que no son viables para trabajadores independientes o pequeños negocios.
- ✕Falta de funcionamiento sin conexión o consumo excesivo de datos móviles en la calle.
La Solución
Diseñé y desarrollé RutaFácil, una PWA mobile-first ultra rápida y de coste operativo $0. Permite a los repartidores compartir ubicaciones directamente desde WhatsApp al menú Compartir de su dispositivo, optimizando la ruta con algoritmos heurísticos en local.
Optimización Heurística TSP
Algoritmo de vecino más cercano con mejora 2-opt que corre en milisegundos en el navegador, minimizando la distancia total sin costes de servidor.
Integración con Menú Compartir
Uso de la Web Share Target API para recibir ubicaciones desde WhatsApp, Google Maps o Waze en un par de toques.
PWA Offline-First
Instalable como app nativa en Android/iOS con persistencia local mediante Zustand, funcionando sin interrupciones incluso sin conexión.
Mapas Vectoriales $0
Integración con MapLibre GL y teselas Esri World Street Map, ofreciendo renderizado de mapas fluido sin requerir API keys comerciales.
Navegación Turn-by-Turn
Modo guiado parada a parada con apertura directa en Google Maps/Waze y marcado de entregas con feedback auditivo y háptico.
Gestión de Despachos y Cobros
Control de montos a cobrar en efectivo por parada, generación de mensajes para clientes y exportación de rutas en formato GPX.
Stack Tecnológico
React 18
Frontend
Vite 6
Build Tool
TypeScript
Language
PWA
Mobile & Offline
MapLibre GL
Mapping / GIS
Zustand
State Management
Framer Motion
Animations
Vitest
Testing
Retos Técnicos
Algoritmo TSP On-Device a Coste Cero
Resolver el problema del viajante de comercio (TSP) sin depender de servidores o APIs de pago como Google Directions requirió implementar una solución en el cliente combinando la heurística del vecino más cercano con optimización 2-opt sobre distancias Haversine. Esta solución calcula la ruta óptima para hasta 30 paradas en menos de 5ms directamente en el smartphone del repartidor.
// Heurística de Vecino Más Cercano + Mejora 2-Opt (Cálculo On-Device $0)
export function optimizeOrder(
origin: LatLng,
stops: LatLng[],
fixedEnd?: LatLng,
): number[] {
const n = stops.length;
if (n <= 1) return stops.map((_, i) => i);
const points = fixedEnd ? [origin, ...stops, fixedEnd] : [origin, ...stops];
const dist: number[][] = points.map((a) =>
points.map((b) => haversineKm(a, b)),
);
const endIdx = fixedEnd ? n + 1 : null;
// 1. Vecino más cercano desde el origen
const visited = new Array<boolean>(n + 1).fill(false);
visited[0] = true;
const path: number[] = [0];
let current = 0;
for (let step = 0; step < n; step++) {
let best = -1;
let bestDist = Infinity;
for (let j = 1; j <= n; j++) {
if (!visited[j] && dist[current][j] < bestDist) {
bestDist = dist[current][j];
best = j;
}
}
visited[best] = true;
path.push(best);
current = best;
}
if (endIdx !== null) path.push(endIdx);
// 2. Optimización 2-opt: invierte segmentos mientras acorte el camino
let improved = true;
while (improved) {
improved = false;
for (let i = 1; i < n; i++) {
for (let k = i + 1; k <= n; k++) {
const a = path[i - 1];
const b = path[i];
const c = path[k];
const d = k + 1 <= n ? path[k + 1] : endIdx;
const before = dist[a][b] + (d !== null ? dist[c][d] : 0);
const after = dist[a][c] + (d !== null ? dist[b][d] : 0);
if (after < before - 1e-9) {
let lo = i;
let hi = k;
while (lo < hi) {
[path[lo], path[hi]] = [path[hi], path[lo]];
lo++;
hi--;
}
improved = true;
}
}
}
}
return path.slice(1, n + 1).map((p) => p - 1);
}Parser Multiformato y Web Share Target
Los repartidores reciben ubicaciones en formatos dispares: enlaces cortos de Google Maps, coordenadas en texto plano, enlaces de Waze o cadenas de texto complejas. Se diseñó un parser regex resiliente capaz de procesar conversaciones completas pegadas de una sola vez y extraer todas las paradas automáticamente.