En un artículo anterior, hablé brevemente sobre las capacidades de kepler.gl, la nueva herramienta de código abierto para visualizar y analizar grandes conjuntos de datos geográficos.

Figura 1. Opciones para mapas creados usando kepler.gl (por Uber)
Esta aplicación web le permite crear un mapa interactivo informativo y, lo más importante, colorido basado en conjuntos arbitrarios de datos geográficos en cuestión de minutos. Sin embargo, surge la pregunta de qué hacer con él a continuación. ¿Cómo compartir los resultados con colegas, amigos o clientes?
Compara alternativas
Toda la "magia" de kepler.gl ocurre en el cliente, por lo que la aplicación ofrece solo 2 formas de compartir sus resultados con otros:
- guardar la visualización como una imagen estática (mientras se pierde la capacidad de interactuar con el mapa)
- exporte la configuración y los datos creados como archivos y envíelos a todas las partes interesadas con instrucciones sobre cómo descargar los datos recibidos a kepler.gl para ver el mapa creado
Afortunadamente, kepler.gl no es solo una herramienta web, sino también un componente React, con el que puede crear rápidamente un sitio de demostración con sus visualizaciones o integrarlas en una aplicación web existente.
Nota Al procesar y agregar datos sobre la marcha, kepler.gl a menudo requiere muchos recursos. Por lo tanto, debe ser especialmente cuidadoso al integrarlo en aplicaciones personalizadas para dispositivos móviles.
Este caso de uso para kepler.gl permitirá:
- no complique el proceso de visualización de visualización (solo envíe un enlace a su aplicación)
- no dé acceso a los conjuntos de datos originales de forma explícita (como lo requiere el caso base 2)
- restringir formatos accesibles para el usuario para interactuar con visualizaciones (por ejemplo, prohibir el autoajuste de filtros o métodos de visualización de datos)
- guarde todos los formatos deseados para interactuar con la tarjeta (información sobre herramientas, zoom, cambiar el modo de mapa, etc.)
La última de las opciones consideradas requerirá esfuerzos adicionales por parte del creador de la geo-visualización y no podrá prescindir de la programación. Sin embargo, como verá pronto, no es difícil implementarlo de la misma manera.
Crea una aplicación de demostración
Es hora de pasar de la teoría a la práctica. Para presentarle los pasos básicos para integrar kepler.gl en su código, hice una pequeña aplicación de demostración.
Permite al usuario ver información sobre los estacionamientos pagados de Moscú en uno de los dos modos: general o agregado. Al mismo tiempo, la aplicación solo permite ver las visualizaciones que creamos, cambiar entre ellas y trabajar con el mapa en modo de solo lectura. Todo el código fuente y la versión en vivo están disponibles en GitHub .

Figura 2. Dos modos de vista de mapa proporcionados por la aplicación de demostración
Para crear esta demostración, utilicé mi propia plantilla de proyecto. Sin embargo, si decide jugar con kepler.gl usted mismo, pero aún no tiene preferencias personales, le recomiendo que use create-react-app , lo que reducirá significativamente el tiempo necesario para crear la base de su futura aplicación.
Agregue kepler.gl al proyecto
Kepler.gl es un componente React que usa Redux para almacenar y administrar su estado. Para agregarlo al proyecto, simplemente instale el paquete npm apropiado:
npm install --save kepler.gl
Este paquete npm incluye:
- Un conjunto de componentes y fábricas de interfaz de usuario que les permite redefinirse con sus propios componentes
- métodos predefinidos para agregar / cambiar los datos utilizados y cómo mostrarlos
- Redux reductor necesario para su trabajo
Configurar el almacenamiento de Redux para kepler.gl
Kepler.gl usa Redux para administrar su estado en el proceso de creación y actualización de mapas. Por lo tanto, antes de usar el componente KeplerGl, necesitamos agregar el reductor apropiado al reductor de la aplicación.
import { combineReducers } from 'redux'; import keplerGlReducer from 'kepler.gl/reducers'; import appReducer from './appReducer'; const reducers = combineReducers({ keplerGl: mapReducer, app: appReducer, }); export default reducers;
Es importante recordar que, de manera predeterminada, el componente KeplerGl proporcionará al usuario todas las opciones disponibles para autoedición, descarga, actualización y filtrado de datos. Para limitar el conjunto de acciones permitidas al usuario, debe transferir información sobre el modo de mapa (para leer o editar) y los controles de mapa disponibles en los parámetros de estado iniciales:
const mapReducer = keplerGlReducer .initialState({ uiState: { readOnly: true, mapControls: { visibleLayers: { show: false }, toggle3d: { show: false }, splitMap: { show: true }, mapLegend: { show: true, active: false } } } });
También necesitaremos instalar react-palm , que kepler.gl usa para controlar los efectos secundarios y agregar taskMiddleware desde este paquete npm al repositorio de Redux de su aplicación:
import {createStore, applyMiddleware, compose} from 'redux'; import {taskMiddleware} from 'react-palm'; import reducers from './reducers'; const initialState = { }; const middlewares = [ taskMiddleware ]; const enhancers = [applyMiddleware(...middlewares)]; export default createStore( reducers, initialState, compose(...enhancers) );
Nota Actualmente, el equipo de Ingeniería de Uber está trabajando activamente en una nueva versión de kepler.gl que no dependerá de react-palm.
De forma predeterminada, kepler.gl espera que su objeto de estado se ubique en el nivel superior del estado de toda la aplicación y sea accesible con el nombre keplerGl. Si la configuración del repositorio de Redux difiere de la esperada, entonces, para el correcto funcionamiento del componente React correspondiente, es suficiente especificar la ubicación de su estado en la jerarquía utilizando la propiedad getState.
Incrustar el componente de reacción KeplerGl
Para la representación rápida de mapas con una gran cantidad de elementos visualizados (¡hasta millones de puntos geográficos!) Kepler.gl utiliza desk.gl - marco WebGL para visualización de datos, y MapBox - geo-plataforma de código abierto, que proporciona una API conveniente y amplias posibilidades para personalizar mapas creados . Por lo tanto, uno de los parámetros obligatorios pasados al componente KeplerGl es el token API para acceder al servicio MapBox.
Para recibir un token, debe registrarse en el sitio www.mapbox.com . MapBox ofrece una selección de varios planes de tarifas diferentes, pero para pequeñas aplicaciones, una versión gratuita con 50,000 vistas por mes será suficiente.
Después de crear una cuenta, debe ir a la sección de tokens y generar una clave pública para acceder al servicio.
Establezca el token recibido en la variable de entorno adecuada:
export MapboxAccessToken=<your_mapBox_token>
Ahora puede pasar a crear un componente Reaccionar para mostrar información sobre los estacionamientos pagados. En nuestro caso, será solo un contenedor sobre el componente KeplerGl, que toma las dimensiones del mapa como parámetros:
import React from 'react'; import KeplerGl from 'kepler.gl'; const mapboxAccessToken = process.env.MapboxAccessToken; const ParkingMap = (props) => ( <KeplerGl id="parking_map" mapboxApiAccessToken={mapboxAccessToken} width={ props.width } height={ props.height } /> ); export default ParkingMap;
Agrega ParkingMap a la aplicación. En esta etapa, en lugar de la información de estacionamiento, simplemente se muestra un mapa sin ninguna información, porque todavía no hemos transmitido los datos en función de los cuales se construyen nuestras visualizaciones.
Descargar datos y configuraciones de mapas
Para mostrar sus datos en el mapa, debe transferir a KeplerGl el conjunto de datos en función del cual se creará el mapa y la configuración deseada de la visualización final. Esto se puede hacer usando uno de dos métodos: addDataToMap o updateVisData.
El primer método le permite no solo descargar el conjunto de datos necesarios y establecer / actualizar completamente la configuración de la instancia correspondiente del componente KeplerGl, incluida la configuración de visualización (visState) y el mapa (mapState), así como el estilo del mapa utilizado (mapStyle).
AddDataToMap acepta un objeto que contiene la siguiente información como parámetro del método:
Nota Los datos del objeto de configuración siempre tienen prioridad sobre la configuración pasada en el objeto de opciones.
El método updateVisData permite actualizar solo los conjuntos de datos usados sin cambiar completamente la configuración del componente utilizado. Como parámetro, como el primer método, toma un objeto que contiene información sobre un nuevo conjunto o conjuntos de datos y el parámetro "opciones" para actualizar algunas configuraciones de visualización del mapa.
Inicialización del mapa
Por lo tanto, para la carga de datos inicial, necesitamos el método addDataToMap. En la aplicación de demostración que se está creando, la base de datos de estacionamiento pagado en Moscú se carga cuando se accede por primera vez a la aplicación mediante una solicitud por separado. Los datos de origen resultantes deben estar preparados para cargarlos en KeplerGl. Para esto, en la mayoría de los casos, es suficiente uno de los procesadores predefinidos que transfieren datos csv / json al formato de datos compatible con kepler.gl.
export function loadParkingData(mapMode) { return (dispatch) => { dispatch( requestParkingData() ); fetch(demoDataUrl) .then(response => response.text()) .then(source => { dispatch( getParkingData() ); const data = Processors.processCsvData(source); const config = getMapConfig(mapMode); const datasets = [{ info, data }]; dispatch( wrapTo('parking_map', addDataToMap({ datasets, config }) )); }); }; }
Cambiar entre modos
Para cambiar entre los modos de vista del mapa, necesitamos definir otra función de acción. Dado que en la versión actual de KeplerGl no hay una manera fácil de cambiar solo la configuración del mapa sin afectar los datos, el método addDataToMap también será el método más adecuado para cambiar entre modos:
export function toggleMapMode(mode) { return (dispatch, getState) => { const config = getMapConfig( mode ); const datasets = getDatasets(getState()); dispatch( wrapTo('parking_map', addDataToMap({ datasets, config }) )); dispatch( setMapMode(mode) ); }; }
El parámetro del conjunto de datos es obligatorio, por lo tanto, cada vez que cambiemos el modo de vista del mapa, retransmitiremos el conjunto de datos original cargado al inicio de la aplicación. La información de configuración de la tarjeta se actualizará cada vez. En este artículo no me detendré en cómo se implementan los métodos de ayuda getMapConfig y getDatasets, cuyo código fuente puede familiarizarse con usted en GitHub.
Nota Actualmente, la API KeplerGl es muy limitada y está diseñada para los casos más básicos (agregar y actualizar datos). Al mismo tiempo, los propios desarrolladores reconocen que la versión actual no proporciona un método efectivo para actualizar solo configuraciones o para actualizaciones de datos en tiempo real. Sin embargo, no olvide que el proyecto se encuentra en desarrollo activo y existe la esperanza de una pronta expansión de su funcionalidad.
Personalizar elementos del mapa
KeplerGl incluye no solo un contenedor con geo-visualización, sino también controles de mapas, información sobre herramientas, un panel lateral para administrar los datos mostrados, un cuadro de diálogo para cargar datos en formato csv, json o geojson, etc. Al mismo tiempo, cada uno de los componentes enumerados se puede reemplazar fácilmente con su propia versión utilizando el sistema de inyección de dependencia.
Para reemplazar el componente base con su versión personalizada, es suficiente:
- importar fábrica de componentes por defecto
- definir una nueva fábrica que devuelva un componente personalizado
- incrustar una nueva fábrica utilizando el método injectComponents
En la aplicación de demostración que creamos, no queremos darle al usuario la oportunidad de configurar de forma independiente el modo de visualización, filtrar los datos existentes o cargar nuevos datos.
En teoría, para esto es suficiente indicar que el componente KeplerGl está en modo de solo lectura, que apareció solo en la versión 0.0.27. Sin embargo, incluso en esta versión, todos los controles todavía se muestran al usuario durante los primeros momentos antes de cargar el mapa, y solo luego se ocultan. Para evitar esto, podemos reemplazar explícitamente componentes no deseados con un componente nulo utilizando el método injectComponents:
import React from 'react'; import { injectComponents, ModalContainerFactory, SidePanelFactory, } from 'kepler.gl/components';
Convenientemente, KeplerGl no solo le permite reemplazar componentes básicos por otros personalizados, sino que el uso del método withState le permite agregar acciones adicionales y parámetros de estado para nuevos componentes.
Cómo usar varias tarjetas a la vez
Si planea usar varios componentes KeplerGL diferentes dentro de la misma aplicación, cada uno de ellos debe establecerse en los parámetros con una identificación única, necesaria para agregar / actualizar datos y configuraciones de cada una de las tarjetas:
const wrapToParking = wrapTo(' parking_map'); dispatch( wrapToParking( addDataToMap({ datasets, config }) ));
Una alternativa es utilizar la función de conexión de Redux y la función forwardTo de kepler.gl. En este caso, es lo suficientemente simple como para que la función del despachador correspondiente especifique la identificación de la tarjeta correspondiente:
import KeplerGl from 'kepler.gl'; import { forwardTo, toggleFullScreen } from 'kepler.gl/actions'; import {connect} from 'react-redux'; const MapContainer = props => ( <div> <button onClick=() => props.keplerGlDispatch(toggleFullScreen())/> <KeplerGl id="foo" /> </div> ) const mapStateToProps = state => state const mapDispatchToProps = (dispatch, props) => ({ dispatch, keplerGlDispatch: forwardTo('foo', dispatch) });
Conclusión
KeplerGl le permite agregar coloridos mapas interactivos a su aplicación web basada en React. Gracias al uso del marco del componente desk.gl, puede mostrar fácilmente millones de puntos geográficos en un formato conveniente para verlos y analizarlos.
Las amplias posibilidades para personalizar no solo las visualizaciones creadas, sino también los estilos de mapas, así como los formatos de interacción del usuario, hacen de KeplerGl una herramienta muy atractiva para crear complejas visualizaciones cartográficas y paneles.
Sin embargo, limitado solo por escenarios API básicos, el procesamiento de datos en el cliente, así como el uso de MapBox sin la capacidad de seleccionar otra fuente de mapa, reducen el número de proyectos para los que se puede utilizar esta herramienta.
Pero no olvide que hoy el proyecto aún es muy joven y se encuentra en la fase activa de desarrollo, por lo que muchas de estas deficiencias pueden volverse irrelevantes en el futuro cercano.
Enlaces utiles
- Código demo completo
- Artículo introductorio sobre Kepler.Gl sobre Habr
- Repositorio Kepler.gl en github
- La documentación oficial de kepler.gl
- Kepler.gl Tutorial sobre Academia de Vis. [En]