2015-08-13 18 views
11

ho una mappa opuscolo che viene utilizzato per la localizzazione di condivisione. Quando un utente condivide la propria posizione, viene aggiunto alla mappa un indicatore che mostra la sua posizione per consentire a tutti gli altri utenti di vedere. Si adatta automaticamente alla mappa per visualizzare tutti gli indicatori ogni volta che ne viene aggiunto, spostato o eliminato. Ho anche aggiunto un controllo personalizzato che può attivare e disattivare il comportamento di adattamento automatico. Funziona tutto bene, ma vorrei anche rendere la mappa abbastanza intelligente da disattivare automaticamente il comportamento di adattamento automatico se l'utente apre o ingrandisce la mappa.Rileva le operazioni di pan/zoom avviati dall'utente on Leaflet

questo risulta essere piuttosto difficile, perché non riesco a trovare un buon modo per distinguere se un operazione di pan/zoom viene avviata dall'utente o da un auto-fit. All'inizio stavo ascoltando gli eventi panstart e zoomstart, ma questi sono attivati ​​anche dall'auto-fit. Ho pensato che avrei potuto impostare una bandiera per dire di non disattivare l'adattamento automatico quando lo zoom/pan è causato dall'adattamento automatico. Controllo questo flag prima di disattivare l'adattamento automatico in risposta a panstart e zoomstart, quindi cancellarlo quando vengono ricevuti il ​​panend e lo zoomend.

Questo sembra funzionare bene fino a quando si verifica un auto-adattamento, che non si traduca in una padella o lo zoom. Supponiamo di avere un grande gruppo di marcatori auto-adattati e uno di quelli nel mezzo sia rimosso. Dal momento che la casella limite è invariato, non padella o lo zoom viene attivato, e quindi la bandiera dicendogli di non disattivare l'auto-adattamento non viene mai eliminato. La prossima volta che le pentole utente o ingrandisce la mappa, che non si spegne l'auto-fit come dovrebbe, perché pensa che sia ancora nel mezzo di un'operazione di auto-fit.

Come faccio a fare in modo che possa disattivare in modo affidabile il montaggio automatico quando l'utente esegue il panning o lo zoom direttamente sulla mappa, ma lo lascia acceso quando viene spostato o ingrandito con altri mezzi?

Ecco il codice rilevante:

var markers = [];  // Map markers are stored in this array. 
var autoFit = true;  // Whether auto-fit is turned on 
var lockAutoFit = false; // Temporarily lock auto-fit if true 
var map;     // Leaflet map object 

function initMap() { 
    // Leaflet map initialized here 
    map.on('movestart zoomstart', function() { 
     if (!lockAutoFit) { 
      autoFit = false; 
     } 
    }); 
    map.on('moveend zoomend', function() { 
     lockAutoFit = false; 
    }); 
} 

function toggleAutoFit() { 
    autoFit = !autoFit; 

    if (autoFit) { 
     lockAutoFit = true; 
     fitMap(); 
    } 
} 

function addOrUpdateMarker(marker, coords) { 
    lockAutoFit = true; 
    // do the marker update here 
    fitMap(); 
} 

function removeMarker(marker) { 
    lockAutoFit = true; 
    // remove the marker here 
    fitMap(); 
} 

// Pans and zooms the map so that all markers fit in the map view. 
// Invoked whenever a marker is added, moved or deleted, or when 
// the user turns on auto-fit. 
function fitMap() { 
    if (!autoFit || !markers.length) { 
    return; 
    } 

    map.fitBounds(new L.featureGroup(markers).getBounds()); 
} 

risposta

1

Si potrebbe utilizzare il drag, dragstart, dragend - almeno per la mappa panning. Per lo zoom della mappa non c'è un simile equivalente, penso.

+0

Sì, quelli di trascinamento ero a conoscenza, ma come hai detto tu, non v'è alcuna cosa come per lo zoom, in modo che non, purtroppo, davvero risolvi il mio problema –

0

Il Leaflet reference dichiara di avere zoomstart, zoomend e zoomlevelschange eventi.

+4

Verifica la fonte: in effetti sto utilizzando gli eventi di zoom nel codice. Il problema è che questi eventi vengono attivati ​​sia quando l'utente ingrandisce manualmente sia quando si verifica l'adattamento automatico. Al momento non dispongo di un modo affidabile per determinare se l'evento è stato attivato dall'utente che ha manipolato i controlli o da un'operazione di adattamento automatico. Questo è il problema che sto cercando di risolvere. –

3

ho finito per impostare una bandiera intorno ai miei fitBounds e setView chiamate Es:

isProgramaticZoom = true 
map.fitBounds(new L.featureGroup(markers).getBounds()); 
isProgramaticZoom = false 

Quindi il codice per disattivare l'auto-fit:

map.on('zoomstart', function() { 
    if (!isProgramaticZoom) { 
    //turn off auto-fit 
    } 
}) 

map.on('dragstart', function() { 
    //turn off auto-fit 
}) 

Purtroppo, ancora non è l'ideale, ma dovrebbe fare il trucco

+2

Peccato che questa sia l'unica soluzione ... –

0

Questa è una vecchia domanda, ma come l'ho trovata di recente, penso che sia ancora abbastanza pertinente che valga la pena dare una soluzione .

ho seguito questa soluzione: Leaflet User Triggered Events

che è utilizzare:

map.on('dragstart', function (e) { 
    if (e.hard) { 
     // moved by bounds 
    } else { 
     // moved by drag/keyboard 
    } 
}); 

La parte e.hard irregolare è la soluzione qui; i commenti parlano da soli.

Alternativly, si potrebbe desiderare di utilizzare moveend invece di dragstart