Em um artigo anterior, falei brevemente sobre os recursos do kepler.gl, a nova ferramenta Open Source para visualizar e analisar grandes conjuntos de dados geográficos.

Figura 1. Opções para mapas criados usando kepler.gl (por Uber)
Esse aplicativo da Web permite criar um mapa interativo informativo e, o mais importante, colorido, com base em conjuntos arbitrários de dados geográficos em questão de minutos. No entanto, surge a pergunta: o que fazer com isso a seguir? Como compartilhar os resultados com colegas, amigos ou clientes?
Compare alternativas
Toda a “mágica” do kepler.gl acontece no cliente, então o aplicativo oferece apenas 2 maneiras de compartilhar seus resultados com outras pessoas:
- salve a visualização como uma imagem estática (enquanto perde a capacidade de interagir com o mapa)
- exporte a configuração e os dados criados como arquivos e envie-os a todas as partes interessadas com instruções sobre o download dos dados recebidos para kepler.gl para visualizar o mapa criado
Felizmente, kepler.gl não é apenas uma ferramenta da web, mas também um componente React, com o qual você pode criar rapidamente um site de demonstração com suas visualizações ou integrá-los a um aplicativo da web existente.
Nota Para processar e agregar dados em tempo real, o kepler.gl geralmente exige muitos recursos. Portanto, você deve ter um cuidado especial ao integrá-lo a aplicativos personalizados para dispositivos móveis.
Este caso de uso para kepler.gl permitirá:
- não complique o processo de visualização (basta enviar um link para sua aplicação)
- não forneça acesso aos conjuntos de dados originais de forma explícita (conforme exigido pelo caso base 2)
- restringir formatos acessíveis ao usuário para interagir com visualizações (por exemplo, proibir o autoajuste de filtros ou métodos de exibição de dados)
- salve todos os formatos desejados para interagir com o cartão (dica, zoom, alternar modo de mapa etc.)
A última das opções consideradas exigirá esforços adicionais por parte do criador da visualização geográfica e você não poderá prescindir da programação. No entanto, como você verá em breve, não é difícil implementá-lo da mesma maneira.
Crie um aplicativo de demonstração
É hora de passar da teoria para a prática. Para apresentar as etapas básicas de integração do kepler.gl ao seu código, criei um pequeno aplicativo de demonstração.
Ele permite que o usuário veja informações sobre estacionamentos pagos em Moscou em um dos dois modos - geral ou agregado. Ao mesmo tempo, o aplicativo permite apenas visualizar as visualizações que criamos, alternar entre elas e trabalhar com o mapa no modo somente leitura. Todo o código-fonte e versão ao vivo está disponível no GitHub .

Figura 2. Dois modos de visualização de mapa fornecidos pelo aplicativo demo
Para criar esta demonstração, usei meu próprio modelo de projeto. No entanto, se você decidir brincar com kepler.gl, mas ainda não tiver preferências pessoais, recomendo que você use create-react-app , o que reduzirá significativamente o tempo necessário para criar a base do seu aplicativo futuro.
Adicione kepler.gl ao projeto
Kepler.gl é um componente React que usa o Redux para armazenar e gerenciar seu estado. Para adicioná-lo ao projeto, basta instalar o pacote npm apropriado:
npm install --save kepler.gl
Este pacote npm inclui:
- um conjunto de componentes da interface do usuário e fábricas que permitem que sejam redefinidos com seus próprios componentes
- métodos predefinidos para adicionar / alterar os dados usados e como exibi-los
- Redutor Redux necessário para o seu trabalho
Configurando o armazenamento Redux para kepler.gl
O Kepler.gl usa o Redux para gerenciar seu estado no processo de criação e atualização de mapas. Portanto, antes de usar o componente KeplerGl, precisamos adicionar o redutor apropriado ao redutor do aplicativo.
import { combineReducers } from 'redux'; import keplerGlReducer from 'kepler.gl/reducers'; import appReducer from './appReducer'; const reducers = combineReducers({ keplerGl: mapReducer, app: appReducer, }); export default reducers;
É importante lembrar que, por padrão, o componente KeplerGl fornecerá ao usuário todas as opções disponíveis para auto-edição, download, atualização e filtragem de dados. Para limitar o conjunto de ações permitidas ao usuário, é necessário transferir informações sobre o modo de mapa (para leitura ou edição) e os controles de mapa disponíveis nos parâmetros de estado inicial:
const mapReducer = keplerGlReducer .initialState({ uiState: { readOnly: true, mapControls: { visibleLayers: { show: false }, toggle3d: { show: false }, splitMap: { show: true }, mapLegend: { show: true, active: false } } } });
Também precisaremos instalar o react -palm , que kepler.gl usa para controlar efeitos colaterais e adicionar taskMiddleware deste pacote npm ao repositório Redux de seu aplicativo:
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 Atualmente, a equipe de engenharia da Uber está trabalhando ativamente em uma nova versão do kepler.gl, que não dependerá do react-palm.
Por padrão, kepler.gl espera que seu objeto de estado esteja localizado no nível superior do estado de todo o aplicativo e seja acessível pelo nome keplerGl. Se a configuração do repositório Redux for diferente da esperada, para a operação correta do componente React correspondente, basta especificar a localização de seu estado na hierarquia usando a propriedade getState.
Incorporar o componente KeplerGl React
Para renderização rápida de mapas com um grande número de elementos exibidos (até milhões de pontos geográficos!) O Kepler.gl usa o desk.gl - estrutura WebGL para visualização de dados e o MapBox - plataforma geográfica Open Source, que fornece uma API conveniente e amplas possibilidades para personalizar mapas criados . Portanto, um dos parâmetros necessários passados para o componente KeplerGl é o token da API para acessar o serviço MapBox.
Para receber um token, você precisa se registrar no site www.mapbox.com . O MapBox oferece uma escolha de vários planos tarifários diferentes, mas para pequenas aplicações, uma versão gratuita com 50.000 visualizações por mês será suficiente.
Depois de criar uma conta, você precisa ir para a seção tokens e gerar uma chave pública para acessar o serviço.
Defina o token recebido para a variável de ambiente apropriada:
export MapboxAccessToken=<your_mapBox_token>
Agora você pode criar um componente React para exibir informações sobre estacionamentos pagos. No nosso caso, será apenas um invólucro sobre o componente KeplerGl, que assume as dimensões do 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;
Adicione ParkingMap ao aplicativo. Nesse estágio, em vez de informações de estacionamento, um mapa é simplesmente exibido sem nenhuma informação, porque ainda não transmitimos os dados com base nos quais nossas visualizações são construídas.
Baixe configurações de dados e mapas
Para exibir seus dados no mapa, você precisa transferir para o KeplerGl os dados com base nos quais o mapa será criado e a configuração desejada da visualização final. Isso pode ser feito usando um dos dois métodos - addDataToMap ou updateVisData.
O primeiro método permite não apenas baixar o conjunto de dados necessário e definir / atualizar completamente a configuração da instância correspondente do componente KeplerGl, incluindo as configurações de visualização (visState) e o mapa (mapState), bem como o estilo do mapa usado (mapStyle).
AddDataToMap aceita um objeto que contém as seguintes informações como parâmetro para o método:
Nota Os dados do objeto de configuração sempre têm precedência sobre as configurações passadas no objeto de opções.
O método updateVisData permite atualizar apenas conjuntos de dados usados sem alterar completamente a configuração do componente usado. Como parâmetro, ele, como o primeiro método, pega um objeto que contém informações sobre um novo conjunto ou conjuntos de dados e o parâmetro "options" para atualizar algumas configurações de exibição do mapa.
Inicialização de mapa
Portanto, para o carregamento inicial dos dados, precisamos do método addDataToMap. No aplicativo de demonstração que está sendo criado, o banco de dados de estacionamento pago em Moscou é carregado quando o aplicativo é acessado pela primeira vez por uma solicitação separada. Os dados de origem resultantes devem estar preparados para serem carregados no KeplerGl. Para isso, na maioria dos casos, um dos processadores predefinidos que portam dados csv / json para o formato de dados suportado pelo kepler.gl é suficiente.
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 }) )); }); }; }
Alternar entre modos
Para alternar entre os modos de visualização do mapa, precisamos definir outra função de ação. Como na versão atual do KeplerGl não há uma maneira fácil de alterar apenas a configuração do cartão sem afetar os dados, o método addDataToMap também será o método mais adequado para alternar entre os 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) ); }; }
O parâmetro do conjunto de dados é necessário, portanto, toda vez que alternamos o modo de visualização do mapa, retransmitimos o conjunto de dados original carregado na inicialização do aplicativo. As informações de configuração do cartão serão atualizadas sempre. Neste artigo, não abordarei detalhadamente como os métodos auxiliares getMapConfig e getDatasets são implementados, cujo código-fonte você pode se familiarizar no GitHub.
Nota Atualmente, a API KeplerGl é muito limitada e projetada para os casos mais básicos (adição e atualização de dados). Ao mesmo tempo, os próprios desenvolvedores reconhecem que a versão atual não fornece um método eficaz para atualizar apenas configurações ou atualizações de dados em tempo real. No entanto, não esqueça que o projeto está em desenvolvimento ativo e há esperança de uma expansão antecipada de sua funcionalidade.
Personalizar elementos do mapa
O KeplerGl inclui não apenas um contêiner com visualização geográfica, mas também controles de mapa, uma dica de ferramenta, um painel lateral para gerenciar os dados exibidos, uma caixa de diálogo para carregar dados no formato csv, json ou geojson, etc. Ao mesmo tempo, cada um dos componentes listados pode ser facilmente substituído por sua própria versão usando o sistema de injeção de dependência.
Para substituir o componente base por sua versão customizada, basta:
- importar fábrica de componentes padrão
- definir uma nova fábrica retornando um componente personalizado
- incorporar uma nova fábrica usando o método injectComponents
No aplicativo de demonstração que criamos, não queremos dar ao usuário a oportunidade de configurar independentemente o modo de visualização, filtrar os existentes ou carregar novos dados.
Em teoria, para isso, basta indicar que o componente KeplerGl está no modo somente leitura, que apareceu apenas na versão 0.0.27. No entanto, mesmo nesta versão, todos os controles ainda são exibidos ao usuário nos primeiros momentos antes de carregar o mapa, e somente então ocultam. Para evitar isso, podemos substituir explicitamente componentes indesejados por um componente nulo usando o método injectComponents:
import React from 'react'; import { injectComponents, ModalContainerFactory, SidePanelFactory, } from 'kepler.gl/components';
Convenientemente, o KeplerGl não apenas permite substituir componentes básicos por componentes personalizados, mas o uso do método withState permite adicionar ações adicionais e parâmetros de estado para novos componentes.
Como usar vários cartões de uma só vez
Se você planeja usar vários componentes diferentes do KeplerGL no mesmo aplicativo, cada um deles deve ser definido nos parâmetros com um ID exclusivo necessário para adicionar / atualizar dados e configurações de cada um dos cartões:
const wrapToParking = wrapTo(' parking_map'); dispatch( wrapToParking( addDataToMap({ datasets, config }) ));
Uma alternativa é usar a função connect do Redux e a função forwardTo do kepler.gl. Nesse caso, é simples o suficiente para a função de expedidor correspondente especificar o ID do cartão correspondente:
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) });
Conclusão
O KeplerGl permite adicionar mapas interativos coloridos ao seu aplicativo Web baseado no React. Graças ao uso da estrutura do componente desk.gl, ele pode exibir facilmente milhões de pontos geográficos em um formato conveniente para visualizá-los e analisá-los.
As amplas possibilidades de personalizar não apenas as visualizações criadas, mas também os estilos de mapas, bem como os formatos de interação do usuário, tornam o KeplerGl uma ferramenta muito atraente para a criação de visualizações e painéis cartográficos complexos.
No entanto, limitado apenas pelos cenários básicos da API, o processamento de dados no cliente, bem como o uso do MapBox sem a capacidade de selecionar outra fonte de mapa, reduz o número de projetos para os quais essa ferramenta pode ser usada.
Mas não se esqueça que hoje o projeto ainda é muito jovem e está na fase ativa de desenvolvimento; muitas dessas deficiências podem se tornar irrelevantes no futuro próximo.
Links úteis
- Código de demonstração completo
- Artigo introdutório sobre Kepler.Gl em Habr
- Repositório Kepler.gl no github
- A documentação oficial para kepler.gl
- Kepler.gl Tutorial no Vis.Academy [en]