Cluster di marcatori Mapbox in React

Blog

Cluster di marcatori Mapbox in React

Le prestazioni possono iniziare a peggiorare abbastanza rapidamente quando si tenta di mostrare grandi quantità di dati su una mappa. Anche a centinaia di marcatori utilizzando Mapbox attraverso react-map-gl , potresti sentire che inizia a rallentare. Raggruppando i punti insieme puoi migliorare notevolmente le prestazioni, il tutto presentando i dati in un modo più accessibile.



Superammasso è il pacchetto ideale per raggruppare i punti su una mappa. Per usare il superammasso insieme a React ho creato un useSupercluster gancio per rendere le cose più facili. Questo articolo mostra come integrare il clustering con il superammasso nella tua mappa React Mapbox.

Configurazione di Mapbox in React

Prima di recuperare i dati da visualizzare, prima di raggruppare i dati da visualizzare sulla mappa, è necessario configurare Mapbox. Ho un video introduttivo a Mapbox se non hai lavorato con il reazione-mappa-gl pacchetto prima.



link roku inserisci i codici

Mapbox in React richiede di gestire il viewport di Mapbox nello stato. Qui è dove possiamo impostare i valori iniziali che vengono successivamente aggiornati tramite |_+_| evento.

Creeremo anche un |_+_| variabile per memorizzare un riferimento alla mappa stessa. Questo è necessario per chiamare funzioni sulla mappa, nel nostro caso per ottenere il riquadro di delimitazione della mappa.



Quando lo sviluppo localmente, sto memorizzando il mio token Mapbox in un file chiamato |_+_| e nominandolo con il prefisso |_+_|, verrà caricato automaticamente nell'app creando l'app di reazione.

onViewportChange

Zoom con i cluster

Preparazione dei dati per il superammasso

È molto probabile che i dati provenienti da un'origine esterna/remota debbano essere massaggiati nel formato richiesto dalla libreria del superacluster. L'esempio qui sotto utilizza SWR per recuperare i dati remoti utilizzando gli hook.

Dobbiamo produrre un array di Funzionalità GeoJSON oggetti, con la geometria di ogni oggetto essendo a Punto GeoJSON .

Un esempio dei dati è simile a:

mapRef

Il recupero dei dati utilizzando SWR e la loro conversione nel formato corretto è simile a:

.env.local

Ottenere i limiti della mappa

Affinché il superammasso restituisca i cluster in base all'array di punti che abbiamo creato nella sezione precedente, dobbiamo fornirgli due informazioni aggiuntive:

  • I limiti della mappa: |_+_|
  • Lo zoom della mappa: In Mapbox questo verrà dal nostro |_+_| stato

I limiti possono essere raccolti accedendo al |_+_| proprietà che abbiamo impostato all'inizio. Mettendo insieme alcune chiamate di funzione, possiamo ottenere i dati e inserirli nel formato corretto.

REACT_APP_

Recupero di cluster dal gancio

Con il nostro |_+_| nell'ordine corretto e con |_+_| e |_+_| accessibile, è il momento di recuperare i cluster. Questo utilizzerà |_+_| gancio fornito dal use-supercluster pacchetto.

Ti restituisce attraverso un oggetto destrutturato un array di cluster e, se ne hai bisogno, il |_+_| variabile di istanza.

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

I cluster sono un array di Funzionalità GeoJSON oggetti, ma alcuni di essi rappresentano un gruppo di punti e alcuni rappresentano singoli punti creati sopra. Molto dipende dal tuo livello di zoom e da quanti punti sarebbero all'interno di un raggio specifico. Quando il numero di punti diventa abbastanza piccolo, il superammasso ci fornisce punti individuali piuttosto che ammassi. L'esempio seguente ha un cluster (come indicato dalle proprietà su di esso) e un singolo punto (che nel nostro caso rappresenta un crimine).

come mettere i div uno accanto all'altro
[ { 'type': 'Feature', 'properties': { 'cluster': false, 'crimeId': 78212911, 'category': 'anti-social-behaviour' }, 'geometry': { 'type': 'Point', 'coordinates': [-1.135171, 52.6376] } } ]

Visualizzazione dei cluster come marker

Perché il |_+_| array contiene caratteristiche che rappresentano un cluster o un singolo punto, dobbiamo gestirlo durante la mappatura. In entrambi i casi, entrambi hanno coordinate e possiamo usare |_+_| proprietà per determinare quale è quale.

Lo stile dei cluster dipende da te, ho alcuni stili semplici applicati a ciascuno dei marker:

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 }

Quindi, mentre sto mappando i cluster, cambio la dimensione del cluster con un calcolo basato su quanti punti contiene il cluster: |_+_|.

[westLng, southLat, eastLng, northLat]

Transizione zoom animata in un cluster

Possiamo sempre ingrandire la mappa da soli, ma il superammasso fornisce una funzione chiamata |_+_|, che quando viene passato un ID cluster, ci restituirà il livello di zoom a cui dobbiamo modificare la mappa affinché il cluster venga interrotto in ulteriori cluster più piccoli o in singoli punti.

viewport.zoom

Con il prossimo livello di zoom fornitoci dal superammasso, potremmo semplicemente aggiornare il nostro stato della finestra di Mapbox, ma non sarebbe una transizione graduale. react-map-gl fornisce una classe chiamata |_+_| che anima la mappa al nuovo zoom e lat/lon piuttosto che il cambiamento è istantaneo.

mapRef.current

Dove risiedono i frammenti di codice di cui sopra? Li ho messi all'interno di un |_+_| evento sul div del marker per ogni cluster di cui viene eseguito il rendering.

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 }

Conclusione

Usando |_+_|, abbiamo la possibilità di usare Mapbox all'interno della nostra app React. Usando |_+_| siamo in grado di usare il superammasso come un gancio per rendere grappoli di punti sulla nostra mappa.

Poiché abbiamo accesso all'istanza di superammasso, siamo anche in grado di afferrare le foglie (i singoli punti che compongono un ammasso) tramite |_+_| funzione. Con questo possiamo mostrare i dettagli sul numero x di punti contenuti all'interno di un cluster.

Il codice sorgente completo di questo progetto può essere trovato qui .

#React #JavaScript #WebDev #reactjs #react-js