MapConductor es un SDK de código abierto para manejar SDK de mapas a través de una sola API común. Está disponible para Android (Jetpack Compose), iOS (SwiftUI) y React (TypeScript), y hoy soporta 15 proveedores. La licencia es Apache-2.0.
Como este es el primer artículo, vale la pena volver a escribir qué hace y cuándo sirve.
Los SDK de mapas están todos bien hechos
Google Maps, Mapbox, HERE, ArcGIS, MapLibre, MapTiler, TomTom, Longdo, Mappls: cada uno se fue puliendo durante mucho tiempo y cada uno tiene lo suyo. Detalle en calles y direcciones, navegación, conexión con activos GIS, libertad de diseño, regiones cubiertas. A la pregunta “cuál es el mejor” no hay respuesta general: cambia según la app que se construya y la región a la que se llegue.
Y sin embargo, desde el lado de la implementación, esa elección queda prácticamente sellada en las primeras líneas. El código que dibuja el mapa se enlaza a fondo con los tipos y conceptos de un SDK concreto, así que cuando querés comparar más adelante, lo que ya no te queda es la forma de comparar.
Esto no es un reproche al diseño de nadie. Es más bien el resultado de que cada uno diseñó con cuidado para su propio terreno fuerte: los conceptos y los nombres no coinciden. Emparejar lo que no coincide es tarea de quien escribe encima, no de quien provee el SDK. MapConductor se hace cargo de esa capa.
Qué hace
Tu aplicación depende únicamente de la API unificada de MapConductor. Las diferencias entre proveedores las absorben los controladores, así que al cambiar de proveedor solo se tocan tres cosas: el módulo que incluís, el tipo de la vista de mapa y el tipo del objeto de estado. Cómo escribís marcadores, formas, movimientos de cámara y eventos no cambia.
// Declará los overlays fuera de la bifurcación: al cambiar de proveedor no se reescriben
val overlays: @Composable MapViewScope.() -> Unit = {
Marker(markerState)
Polyline(routeState)
}
if (useMapLibre) {
MapLibreMapView(state = maplibre, content = overlays)
} else {
GoogleMapView(state = googlemaps, content = overlays)
}También podés poner dos mapas lado a lado y cambiar en tiempo de ejecución. Si le pasás al otro la última posición de cámara, ni siquiera salta la imagen.
No solo se empareja la forma de escribir
Lo que más preocupa al oír “API común” es, seguramente, que se empareje la escritura pero no los resultados. Que el zoom 14 se vea distinto según el entorno, que la distancia entre dos puntos no coincida entre Android e iOS: eso pasa de verdad.
MapConductor se hace cargo de esa parte.
| Lo que traemos propio | Lo que gracias a eso coincide |
|---|---|
| Cálculo geográfico | Distancia, rumbo, área e interpolación implementados con la misma fórmula en Kotlin, Swift y TypeScript. Al no depender de las utilidades de cada SDK, los números que se muestran no se desvían entre plataformas |
| Cámara | Convertimos entre zoom y altitud de cámara, calibrado con mediciones. El zoom 14 abarca lo mismo en cualquier proveedor |
| Dibujo de marcadores | Con pocos, marcadores nativos; al pasar los 2.000 cambia internamente a teselas ráster. Con decenas de miles la cámara sigue fluida y el código de la app no cambia ni una línea |
| Formas | Donde el proveedor no tiene la función —polígonos con agujeros, rutas de círculo máximo— lo dibujamos como teselas ráster y llegamos al mismo resultado visual |
| Atribución | La regla que cambia la atribución según el zoom y el área visible es para nosotros parte del diseño del mapa |
Un envoltorio que solo llama a los métodos de cada SDK termina pudiendo lo que puede el SDK con menos funciones. Por eso preferimos dibujar nosotros lo que falta.
Para qué sirve
Se aprende una sola API
Como los conceptos y los nombres cambian según el proveedor, cada cambio de proveedor y cada salto de plataforma obliga a reaprender. Con MapConductor aprendés una API, y en Android, iOS y React tiene el mismo nombre y el mismo significado. Lo que aprendiste en Android sirve tal cual en iOS, y cuando entra alguien al equipo no tiene que leer tantas cosas como proveedores haya.
Se puede escribir código donde no aparece el nombre de ningún SDK de mapas
GeoPoint y MarkerState no pertenecen a ningún SDK de mapas. Armar una ruta, decidir si algo cae dentro de un área, definir qué se muestra: esa lógica se puede escribir separada de los tipos del SDK. Y los componentes de mapa compartidos se pueden sacar como biblioteca en vez de rehacerlos para cada proveedor.
La discusión de la especificación se hace una sola vez
Si en Android, iOS y Web usás SDK de mapas distintos, ni el comportamiento de los marcadores ni el significado de los números de cámara coinciden, y terminás discutiendo la misma funcionalidad tres veces. Con un modelo común, esas tres veces se vuelven una.
Queremos crear un estado en el que se pueda elegir
Hasta acá hablamos del lado de quien integra un mapa. Pero eso no es todo lo que MapConductor busca.
Hoy, la elección del SDK de mapas es el primer commit de la implementación. Así, la selección deja de ser “probar y decidir” para volverse “decidir y después construir”, y la comparación queda en el papel. Para el lado elegido tampoco es un buen estado: un buen SDK queda fuera de la lista no por su calidad, sino porque ya se escribió con otro.
Con una API común, ese orden cambia. Lo hacés andar, comparás la misma pantalla de la misma app y después decidís. Lo que define pasa a ser el precio, las regiones cubiertas, la frescura de los datos, la calidad del dibujado: justo aquello en lo que los proveedores compiten de verdad.
Por eso MapConductor está hecho para no tapar las fortalezas de cada uno. Solo unificamos las funciones básicas que todos los proveedores tienen. Con getMapViewHolder() sobre el objeto de estado obtenés la vista de mapa nativa y la instancia del mapa tal cual, así que lo que existe únicamente en ese proveedor lo escribís directo con su API. Un envoltorio que tapara todo borraría los factores de diferenciación; no hacemos eso. Usar “lo común con MapConductor y lo decisivo con la API del proveedor” es perfectamente normal.
Después de que los navegadores emparejaron su implementación con HTML5, dejaron de competir por la compatibilidad en sí y pasaron a competir por velocidad y funciones. Con los SDK de mapas es igual: una vez fijada la interfaz común, lo que se pregunta es cuán rápido, cuán preciso y en cuántas regiones se puede dibujar. La unificación no detiene la evolución de cada SDK: le alinea la dirección.
Hay algo más, que apunta al futuro. Los datos de mapas y el geocoding venían atados al SDK de mapas de quien los provee. Si se pueden separar la visualización y los datos, aparecen más escenarios para proveedores sin medios propios de visualización: los que solo tienen geocoding, o datos de un área específica. Hoy todavía no hay funciones orientadas a ese uso; es una dirección, no una lista de funcionalidades.
Por lo demás, cumplir los términos de uso de los datos y servicios es responsabilidad de quien los integra. Que algo se pueda combinar técnicamente no significa que la combinación esté autorizada.
Cuándo conviene y cuándo no
Conviene en casos así:
- Querés ofrecer la misma experiencia de mapa en varias plataformas
- Querés dejar abierta la posibilidad de cambiar de proveedor más adelante
- El centro son representaciones de mapa estándar: marcadores, formas, cámara
- Manejás miles o decenas de miles de marcadores
- Se exige coherencia al mostrar distancias y áreas
En cambio, no conviene en estos casos:
- El protagonista es una representación avanzada propia de un proveedor (shaders propios, capas exclusivas del fabricante)
- El objetivo es la función especializada del SDK en sí, como la navegación paso a paso
- Todo se resuelve con una plataforma y un proveedor, y no hay planes de cambiarlo
De todos modos, no es todo o nada. Siempre tenés a mano la instancia nativa del mapa, así que podés escribir solo las partes especiales con código propio del proveedor.
Cómo empezar
Con MapLibre funciona sin clave de API, así que hasta el primer mapa hay unos cinco minutos.
- Empezar — tu primer mapa, con MapLibre
- Por qué MapConductor — las ideas en las que se apoya este artículo
- Arquitectura — cómo se separan la API unificada, el Core y los controladores
- Proveedores compatibles y configuración — los pasos por plataforma
Publicamos el avance del desarrollo y las versiones en Discord. Los comentarios sobre el diseño y los reportes de errores son bienvenidos. El código está en GitHub.
