Mapbox-Marker-Clustering in React

Blog

Mapbox-Marker-Clustering in React

Die Leistung kann ziemlich schnell nachlassen, wenn Sie versuchen, große Datenmengen auf einer Karte anzuzeigen. Selbst bei Hunderten von Markern mit Mapbox über reagieren-map-gl , können Sie spüren, dass es langsamer wird. Durch das Zusammenfassen der Punkte können Sie die Leistung erheblich verbessern und gleichzeitig die Daten zugänglicher darstellen.



Supercluster ist das Go-to-Paket, um Punkte auf einer Karte zu gruppieren. Für die Verwendung von Supercluster zusammen mit React habe ich a . erstellt Supercluster verwenden Haken, um die Dinge zu erleichtern. Dieser Artikel zeigt, wie Sie Clustering mit Supercluster in Ihre React Mapbox-Karte integrieren.

Mapbox-Setup in React

Vor dem Abrufen der anzuzeigenden Daten und vor dem Clustern dieser Daten zur Anzeige auf der Karte müssen wir Mapbox einrichten. Ich habe eine Einführung in das Mapbox-Video, falls Sie noch nicht mit dem gearbeitet haben reagieren-map-gl Paket vor.



PHP-Array-Suche mehrdimensional

Mapbox in React erfordert, dass Sie das Ansichtsfenster von Mapbox im Status verwalten. Hier können wir Anfangswerte setzen, die später über die |_+_| . aktualisiert werden Veranstaltung.

Wir werden auch ein |_+_| . erstellen Variable, um einen Verweis auf die Karte selbst zu speichern. Dies ist erforderlich, um Funktionen auf der Karte aufzurufen, in unserem Fall um die Bounding Box der Karte zu erhalten.



Wenn ich dies lokal entwickle, speichere ich mein Mapbox-Token in einer Datei namens |_+_|, und indem ich es mit dem Präfix |_+_| benenne, wird es automatisch von create response app in die App geladen.

onViewportChange

Zoomen mit Clustern

Daten für Supercluster vorbereiten

Daten von einer externen/entfernten Quelle müssen höchstwahrscheinlich in das von der Supercluster-Bibliothek benötigte Format übertragen werden. Das Beispiel unten verwendet SWR um entfernte Daten mit Hooks abzurufen.

Wir müssen eine Reihe von GeoJSON-Funktion Objekte, wobei die Geometrie jedes Objekts a GeoJSON-Punkt .

Ein Beispiel für die Daten sieht so aus:

mapRef

Das Abrufen der Daten mit SWR und das Konvertieren in das richtige Format sieht so aus:

.env.local

Kartengrenzen abrufen

Damit der Supercluster die Cluster basierend auf dem im vorherigen Abschnitt erstellten Array von Punkten zurückgibt, müssen wir ihm zwei zusätzliche Informationen bereitstellen:

  • Die Kartengrenzen: |_+_|
  • Der Kartenzoom: In Mapbox kommt dieser von unserem |_+_| Zustand

Die Grenzen können durch Zugriff auf die |_+_| . erfasst werden Eigenschaft, die wir zu Beginn eingerichtet haben. Indem wir einige Funktionsaufrufe aneinanderreihen, können wir die Daten abrufen und in das richtige Format bringen.

REACT_APP_

Cluster vom Haken holen

Mit unserem |_+_| in der richtigen Reihenfolge und mit dem |_+_| und |_+_| zugänglich ist, ist es an der Zeit, die Cluster abzurufen. Dies verwendet die |_+_| Haken zur Verfügung gestellt von der Nutzungs-Supercluster Paket.

Es gibt Ihnen durch ein destrukturiertes Objekt ein Array von Clustern und bei Bedarf die |_+_| . zurück Instanzvariable.

export default function App() { // setup map const [viewport, setViewport] = useState({ latitude: 52.6376, longitude: -1.135171, width: '100vw', height: '100vh', zoom: 12 }); const mapRef = useRef(); // load and prepare data // get map bounds // get clusters // return map return ( { setViewport({ ...newViewport }); }} ref={mapRef} > {/* markers here */} ); }

Cluster sind ein Array von GeoJSON-Funktion Objekte, aber einige von ihnen stellen eine Ansammlung von Punkten dar und einige stellen einzelne Punkte dar, die Sie oben erstellt haben. Vieles hängt von Ihrer Zoomstufe ab und davon, wie viele Punkte sich in einem bestimmten Radius befinden würden. Wenn die Anzahl der Punkte klein genug wird, gibt uns Supercluster einzelne Punkte statt Cluster. Das folgende Beispiel hat einen Cluster (wie durch die Eigenschaften darauf angegeben) und einen einzelnen Punkt (der in unserem Fall eine Straftat darstellt).

Quickbooks Druck- und PDF-Reparaturwerkzeug Windows 10
[ { 'type': 'Feature', 'properties': { 'cluster': false, 'crimeId': 78212911, 'category': 'anti-social-behaviour' }, 'geometry': { 'type': 'Point', 'coordinates': [-1.135171, 52.6376] } } ]

Cluster als Marker anzeigen

Weil die |_+_| Array enthält Features, die entweder einen Cluster oder einen einzelnen Punkt darstellen, das müssen wir beim Mapping behandeln. In jedem Fall haben beide Koordinaten, und wir können die |_+_| . verwenden Eigenschaft zu bestimmen, was was ist.

Das Styling der Cluster liegt bei Ihnen, ich habe einige einfache Stile auf jeden der Marker angewendet:

const fetcher = (...args) => fetch(...args).then(response => response.json()); export default function App() { // setup map // load and prepare data const url = 'https://data.police.uk/api/crimes-street/all-crime?lat=52.629729&lng=-1.131592&date=2019-10'; const { data, error } = useSwr(url, { fetcher }); const crimes = data && !error ? data : []; const points = crimes.map(crime => ({ type: 'Feature', properties: { cluster: false, crimeId: crime.id, category: crime.category }, geometry: { type: 'Point', coordinates: [ parseFloat(crime.location.longitude), parseFloat(crime.location.latitude) ] } })); // get map bounds // get clusters // return map }

Dann, während ich die Cluster abbilde, ändere ich die Größe des Clusters mit einer Berechnung, die darauf basiert, wie viele Punkte der Cluster enthält: |_+_|.

[westLng, southLat, eastLng, northLat]

Animierter Zoomübergang in einen Cluster

Wir können jederzeit selbst in die Karte hineinzoomen, aber Supercluster bietet eine Funktion namens |_+_|, die uns bei Übergabe einer Cluster-ID zurückgibt, auf welche Zoomstufe wir die Karte ändern müssen, damit der Cluster aufgelöst wird in weitere kleinere Cluster oder einzelne Punkte herunter.

viewport.zoom

Mit der nächsten Zoomstufe, die uns vom Supercluster bereitgestellt wird, könnten wir unseren Mapbox-Ansichtsfensterstatus einfach aktualisieren, aber es wäre kein reibungsloser Übergang. React-map-gl bietet eine Klasse namens |_+_| was die Karte zum neuen Zoom und Lat/Lon animiert, anstatt dass die Änderung sofort erfolgt.

mapRef.current

Wo leben die obigen Codeschnipsel? Ich habe sie in ein |_+_| . gesteckt Ereignis auf dem Div des Markers für jeden gerenderten Cluster.

export default function App() { // setup map // load and prepare data // get map bounds const bounds = mapRef.current ? mapRef.current .getMap() .getBounds() .toArray() .flat() : null; // get clusters // return map }

Abschluss

Mit |_+_| haben wir die Möglichkeit, Mapbox in unserer React-App zu verwenden. Verwenden von |_+_| Wir können Supercluster als Hook verwenden, um Punktcluster auf unserer Karte zu rendern.

Da wir Zugriff auf die Supercluster-Instanz haben, können wir sogar die Blätter (die einzelnen Punkte, die einen Cluster bilden) über das |_+_| . greifen Funktion. Damit können wir Details über die x Anzahl der Punkte anzeigen, die in einem Cluster enthalten sind.

Der vollständige Quellcode dieses Projekts kann sein hier gefunden .

#Reagieren #JavaScript #WebDev #reactjs #react-js