Interaktive Karte für eine Webanwendung in wenigen Stunden

In einem früheren Artikel habe ich kurz über die Funktionen von kepler.gl gesprochen, dem neuen Open Source-Tool zur Visualisierung und Analyse großer Geodatensätze.


Optionen für Karten, die mit kepler.gl erstellt wurden
Abbildung 1. Optionen für Karten, die mit kepler.gl (von Uber) erstellt wurden


Mit dieser Webanwendung können Sie in wenigen Minuten eine informative und vor allem farbenfrohe interaktive Karte erstellen, die auf beliebigen Geodatensätzen basiert. Es stellt sich jedoch die Frage, was als nächstes damit zu tun ist. Wie kann ich die Ergebnisse mit Kollegen, Freunden oder Kunden teilen?


Alternativen vergleichen


Die ganze „Magie“ von kepler.gl geschieht auf dem Client, sodass die Anwendung nur zwei Möglichkeiten bietet, Ihre Ergebnisse mit anderen zu teilen:


  • Speichern Sie die Visualisierung als statisches Bild (während Sie nicht mehr mit der Karte interagieren können).
  • Exportieren Sie die erstellte Konfiguration und Daten als Dateien und senden Sie sie an alle Interessenten mit Anweisungen zum Herunterladen der empfangenen Daten auf kepler.gl, um die erstellte Karte anzuzeigen

Glücklicherweise ist kepler.gl nicht nur ein Webtool, sondern auch eine React-Komponente, mit der Sie schnell eine Demo-Site mit Ihren Visualisierungen erstellen oder in eine vorhandene Webanwendung integrieren können.


Hinweis Kepler.gl verarbeitet und aggregiert Daten im laufenden Betrieb und benötigt häufig viele Ressourcen. Daher sollten Sie besonders vorsichtig sein, wenn Sie es in Anwendungen integrieren, die auf Mobilgeräte zugeschnitten sind.


Dieser Anwendungsfall für kepler.gl ermöglicht:


  • das Anzeigen der Visualisierung nicht erschweren (senden Sie einfach einen Link zu Ihrer Anwendung)
  • Geben Sie keinen expliziten Zugriff auf die Originaldatensätze (wie im 2-Basisfall gefordert).
  • Benutzerzugängliche Formate für die Interaktion mit Visualisierungen einschränken (z. B. die Selbstoptimierung von Filtern oder Datenanzeigemethoden verbieten)
  • Speichern Sie alle gewünschten Formate für die Interaktion mit der Karte (Tooltip, Zoom, Kartenmodus wechseln usw.).

Die letzte der in Betracht gezogenen Optionen erfordert zusätzliche Anstrengungen seitens des Erstellers der Geovisualisierung, und Sie können nicht auf die Programmierung verzichten. Wie Sie gleich sehen werden, ist es jedoch nicht schwierig, es auf die gleiche Weise zu implementieren.


Erstellen Sie eine Demo-Anwendung


Es ist Zeit, von der Theorie zur Praxis überzugehen. Um Ihnen die grundlegenden Schritte zur Integration von kepler.gl in Ihren Code vorzustellen, habe ich eine kleine Demo-Anwendung erstellt.


Der Benutzer kann Informationen zu kostenpflichtigen Moskauer Parkplätzen in einem von zwei Modi anzeigen - allgemein oder aggregiert. Gleichzeitig können Sie mit der Anwendung nur die von uns erstellten Visualisierungen anzeigen, zwischen ihnen wechseln und im schreibgeschützten Modus mit der Karte arbeiten. Der gesamte Quellcode und die Live-Version sind auf GitHub verfügbar.


Demo-Antrag für kostenpflichtiges Parken in Moskau
Abbildung 2. Zwei von der Demoanwendung bereitgestellte Kartenansichtsmodi


Um diese Demo zu erstellen, habe ich meine eigene Projektvorlage verwendet. Wenn Sie sich jedoch dazu entschließen, selbst mit kepler.gl zu spielen, aber noch keine persönlichen Vorlieben haben, empfehle ich Ihnen, die App create-react-app zu verwenden , wodurch sich der Zeitaufwand für die Erstellung der Grundlage Ihrer zukünftigen Anwendung erheblich verkürzt.


Fügen Sie kepler.gl zum Projekt hinzu


Kepler.gl ist eine React-Komponente, die Redux zum Speichern und Verwalten ihres Status verwendet. Um es dem Projekt hinzuzufügen, installieren Sie einfach das entsprechende npm-Paket:


npm install --save kepler.gl 

Dieses npm-Paket enthält:


  • Eine Reihe von UI-Komponenten und -Fabriken, mit denen sie mit ihren eigenen Komponenten neu definiert werden können
  • vordefinierte Methoden zum Hinzufügen / Ändern der verwendeten Daten und deren Anzeige
  • Redux Reduzierer für ihre Arbeit notwendig

Redux-Speicher für kepler.gl konfigurieren


Kepler.gl verwendet Redux, um seinen Status beim Erstellen und Aktualisieren von Karten zu verwalten. Bevor wir die KeplerGl-Komponente verwenden, müssen wir dem Anwendungsreduzierer den entsprechenden Reduzierer hinzufügen.


 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 ist wichtig zu beachten, dass die KeplerGl-Komponente dem Benutzer standardmäßig alle verfügbaren Optionen zum Selbstbearbeiten, Herunterladen, Aktualisieren und Filtern von Daten bietet. Um die für den Benutzer zulässigen Aktionen einzuschränken, müssen Sie Informationen zum Kartenmodus (zum Lesen oder Bearbeiten) und verfügbaren Kartensteuerelementen in den Anfangszustandsparametern übertragen:


 const mapReducer = keplerGlReducer .initialState({ uiState: { readOnly: true, mapControls: { visibleLayers: { show: false }, toggle3d: { show: false }, splitMap: { show: true }, mapLegend: { show: true, active: false } } } }); 

Wir müssen auch React -Palm installieren, mit dem kepler.gl Nebenwirkungen kontrolliert und taskMiddleware aus diesem npm-Paket zum Redux-Repository seiner Anwendung hinzufügt:


 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) ); 

Hinweis Derzeit arbeitet das Uber Engineering-Team aktiv an einer neuen Version von kepler.gl, die nicht von React-Palm abhängig sein wird.


Standardmäßig erwartet kepler.gl, dass sich sein Statusobjekt auf der obersten Ebene des Status der gesamten Anwendung befindet und über den Namen keplerGl zugänglich ist. Wenn die Konfiguration des Redux-Repositorys von der erwarteten abweicht, reicht es für den korrekten Betrieb der entsprechenden React-Komponente aus, die Position ihres Status in der Hierarchie mithilfe der getState-Eigenschaft anzugeben.


Betten Sie die KeplerGl-Reaktionskomponente ein


Für das schnelle Rendern von Karten mit einer großen Anzahl angezeigter Elemente (bis zu Millionen von Geopunkten!) Verwendet Kepler.gl das Desk.gl - WebGL-Framework für die Datenvisualisierung und MapBox - Open Source Geo-Plattform, die eine praktische API und umfangreiche Möglichkeiten zum Anpassen erstellter Karten bietet . Daher ist einer der erforderlichen Parameter, die an die KeplerGl-Komponente übergeben werden, das API-Token für den Zugriff auf den MapBox-Dienst.


Um ein Token zu erhalten, müssen Sie sich unter www.mapbox.com registrieren. MapBox bietet eine Auswahl verschiedener Tarifpläne. Für kleine Anwendungen ist jedoch eine kostenlose Version mit 50.000 Ansichten pro Monat ausreichend.


Nach dem Erstellen eines Kontos müssen Sie zum Abschnitt Token gehen und einen öffentlichen Schlüssel generieren, um auf den Dienst zuzugreifen.


Setzen Sie das empfangene Token auf die entsprechende Umgebungsvariable:


 export MapboxAccessToken=<your_mapBox_token> 

Jetzt können Sie eine React-Komponente erstellen, um Informationen zu kostenpflichtigen Parkplätzen anzuzeigen. In unserem Fall handelt es sich lediglich um einen Wrapper über die KeplerGl-Komponente, der die Abmessungen der Karte als Parameter verwendet:


 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; 

Fügen Sie der App ParkingMap hinzu. Zu diesem Zeitpunkt wird anstelle von Parkinformationen einfach eine Karte ohne Informationen angezeigt, da wir die Daten, auf deren Grundlage unsere Visualisierungen erstellt wurden, noch nicht übertragen haben.


Laden Sie Daten und Kartenkonfigurationen herunter


Um Ihre Daten auf der Karte anzuzeigen, müssen Sie den Datensatz, auf dessen Grundlage die Karte erstellt wird, und die gewünschte Konfiguration der endgültigen Visualisierung an KeplerGl übertragen. Dies kann mit einer von zwei Methoden erfolgen - addDataToMap oder updateVisData.


Mit der ersten Methode können Sie nicht nur den erforderlichen Datensatz herunterladen und die Konfiguration der entsprechenden Instanz der KeplerGl-Komponente einschließlich der Visualisierungseinstellungen (visState) und der Karte (mapState) sowie den Stil der verwendeten Karte (mapStyle) vollständig festlegen / aktualisieren.


AddDataToMap akzeptiert ein Objekt mit den folgenden Informationen als Parameter für die Methode:


  • verwendete Datensätze für die Gebäudevisualisierung
  • zusätzliche Konfigurationsparameter (Optionen)
  • Konfigurationsdaten einschließlich mapState, mapStyle, visState
     addDataToMap({ datasets: { … } options: { … } config: { mapState { … }, mapStyle { … }, visState: { … } } }); 

Hinweis Daten aus dem Konfigurationsobjekt haben immer Vorrang vor den im Optionsobjekt übergebenen Einstellungen.


Mit der updateVisData-Methode können nur verwendete Datasets aktualisiert werden, ohne die Konfiguration der verwendeten Komponente vollständig zu ändern. Als Parameter verwendet es wie die erste Methode ein Objekt, das Informationen zu einem neuen Satz oder neuen Datensätzen enthält, sowie den Parameter „options“ zum Aktualisieren einiger Kartenanzeigeeinstellungen.


Karteninitialisierung


Für das anfängliche Laden der Daten benötigen wir daher die Methode addDataToMap. In der erstellten Demo-Anwendung wird die Datenbank für kostenpflichtige Parkplätze in Moskau geladen, wenn auf die Anwendung zum ersten Mal über eine separate Anforderung zugegriffen wird. Die resultierenden Quelldaten müssen für den Upload nach KeplerGl vorbereitet sein. In den meisten Fällen ist hierfür einer der vordefinierten Prozessoren ausreichend, die CSV / JSON-Daten in das von kepler.gl unterstützte Datenformat portieren.


 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 }) )); }); }; } 

Zwischen den Modi wechseln


Um zwischen den Kartenansichtsmodi zu wechseln, müssen wir eine andere Aktionsfunktion definieren. Da es in der aktuellen Version von KeplerGl keine einfache Möglichkeit gibt, nur die Konfiguration der Karte zu ändern, ohne die Daten zu beeinflussen, ist die Methode addDataToMap auch die am besten geeignete Methode zum Umschalten zwischen den Modi:


 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) ); }; } 

Der Datensatzparameter ist erforderlich. Daher übertragen wir jedes Mal, wenn wir den Kartenansichtsmodus wechseln, den beim Start der Anwendung geladenen Originaldatensatz erneut. Die Kartenkonfigurationsinformationen werden jedes Mal aktualisiert. In diesem Artikel werde ich nicht näher darauf eingehen, wie die Hilfsmethoden getMapConfig und getDatasets implementiert sind, deren Quellcode Sie auf GitHub kennenlernen können.


Hinweis Derzeit ist die KeplerGl-API sehr begrenzt und für die grundlegendsten Fälle (Hinzufügen und Aktualisieren von Daten) konzipiert. Gleichzeitig erkennen die Entwickler selbst an, dass die aktuelle Version keine effektive Methode zum Aktualisieren nur von Konfigurationen oder zum Aktualisieren von Daten in Echtzeit bietet. Vergessen Sie jedoch nicht, dass sich das Projekt in der aktiven Entwicklung befindet und Hoffnung auf eine baldige Erweiterung seiner Funktionalität besteht.


Passen Sie Kartenelemente an


KeplerGl enthält nicht nur einen Container mit Geovisualisierung, sondern auch Kartensteuerelemente, einen Tooltip, einen Seitenbereich zum Verwalten der angezeigten Daten, ein Dialogfeld zum Laden von Daten im CSV-, JSON- oder Geojson-Format usw. Gleichzeitig kann jede der aufgelisteten Komponenten mithilfe des Abhängigkeitsinjektionssystems problemlos durch eine eigene Version ersetzt werden.


Um die Basiskomponente durch die angepasste Version zu ersetzen, reicht Folgendes aus:


  • Standardkomponentenfabrik importieren
  • Definieren Sie eine neue Factory, die eine benutzerdefinierte Komponente zurückgibt
  • Betten Sie eine neue Factory mit der Methode insertComponents ein

In der von uns erstellten Demo-Anwendung möchten wir dem Benutzer nicht die Möglichkeit geben, den Anzeigemodus unabhängig zu konfigurieren, vorhandene zu filtern oder neue Daten zu laden.


Theoretisch reicht dies aus, um anzuzeigen, dass sich die KeplerGl-Komponente im schreibgeschützten Modus befindet, der nur in Version 0.0.27 angezeigt wurde. Selbst in dieser Version werden dem Benutzer jedoch in den ersten Augenblicken vor dem Laden der Karte alle Steuerelemente angezeigt und erst dann ausgeblendet. Um dies zu vermeiden, können wir unerwünschte Komponenten mithilfe der injizierenden Komponentenmethode explizit durch eine Nullkomponente ersetzen:


 import React from 'react'; import { injectComponents, ModalContainerFactory, SidePanelFactory, } from 'kepler.gl/components'; // define null factory to don not render any unnecessary components const NullComponent = () => null; const nullComponentFactory = () => NullComponent; const KeplerGl = injectComponents([ [ModalContainerFactory, nullComponentFactory], [SidePanelFactory, nullComponentFactory], ]); export default KeplerGl; 

Mit KeplerGl können Sie nicht nur grundlegende Komponenten durch benutzerdefinierte ersetzen, sondern mit der withState-Methode auch zusätzliche Aktionen und Statusparameter für neue Komponenten hinzufügen.


So verwenden Sie mehrere Karten gleichzeitig


Wenn Sie mehrere verschiedene KeplerGL-Komponenten in derselben Anwendung verwenden möchten, muss jede dieser Komponenten in den Parametern mit einer eindeutigen ID festgelegt werden, die zum Hinzufügen / Aktualisieren von Daten und Konfigurationen der einzelnen Karten erforderlich ist:


 const wrapToParking = wrapTo(' parking_map'); dispatch( wrapToParking( addDataToMap({ datasets, config }) )); 

Eine Alternative besteht darin, die Verbindungsfunktion von Redux und die ForwardTo-Funktion von kepler.gl zu verwenden. In diesem Fall ist es für die entsprechende Dispatcher-Funktion einfach genug, die ID der entsprechenden Karte anzugeben:


 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) }); 

Fazit


Mit KeplerGl können Sie Ihrer reaktionsbasierten Webanwendung farbenfrohe interaktive Karten hinzufügen. Dank der Verwendung des Komponenten-Frameworks desktop.gl können problemlos Millionen von Geopunkten in einem Format angezeigt werden, das für die Anzeige und Analyse geeignet ist.


Die vielfältigen Möglichkeiten, nicht nur erstellte Visualisierungen, sondern auch Kartenstile sowie Benutzerinteraktionsformate anzupassen, machen KeplerGl zu einem sehr attraktiven Werkzeug für die Erstellung komplexer kartografischer Visualisierungen und Dashboards.


Aufgrund der begrenzten API-Szenarien, der Datenverarbeitung auf dem Client sowie der Verwendung von MapBox ohne die Möglichkeit, eine andere Kartenquelle auszuwählen, wird die Anzahl der Projekte reduziert, für die dieses Tool verwendet werden kann.


Vergessen Sie jedoch nicht, dass das Projekt heute noch sehr jung ist und sich in der aktiven Entwicklungsphase befindet, sodass viele dieser Mängel in naher Zukunft möglicherweise irrelevant werden.


Nützliche Links


  1. Vollständiger Demo-Code
  2. Einführungsartikel zu Kepler.Gl zu Habr
  3. Kepler.gl Repository auf Github
  4. Die offizielle Dokumentation zu kepler.gl
  5. Kepler.gl Tutorial zur Vis.Academy [de]

Source: https://habr.com/ru/post/de422759/


All Articles