Skip to content

Commit

Permalink
Immediately update map when more than one geolocation watch event is …
Browse files Browse the repository at this point in the history
…triggered (mapbox#9092)
  • Loading branch information
Ryan Hamley authored and mike-unearth committed Mar 18, 2020
1 parent 96b2fa2 commit 90f22a8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
11 changes: 11 additions & 0 deletions debug/multiple.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@
style,
hash: false
});

map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true,
showUserLocation: true,
fitBoundsOptions: {
maxZoom: 20
}
}));
}

var containers = document.querySelectorAll('.map');
Expand Down
25 changes: 24 additions & 1 deletion src/ui/control/geolocate_control.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ function checkGeolocationSupport(callback) {
}
}

let numberOfWatches = 0;
let noTimeout = false;

/**
* A `GeolocateControl` control provides a button that uses the browser's geolocation
* API to locate the user on the map.
Expand Down Expand Up @@ -134,6 +137,8 @@ class GeolocateControl extends Evented {

DOM.remove(this._container);
this._map = (undefined: any);
numberOfWatches = 0;
noTimeout = false;
}

_isOutOfMapMaxBounds(position: Position) {
Expand Down Expand Up @@ -270,6 +275,12 @@ class GeolocateControl extends Evented {
if (this._geolocationWatchID !== undefined) {
this._clearWatch();
}
} else if (error.code === 3 && noTimeout) {
// this represents a forced error state
// this was triggered to force immediate geolocation when a watch is already present
// see https://github.com/mapbox/mapbox-gl-js/issues/8214
// and https://w3c.github.io/geolocation-api/#example-5-forcing-the-user-agent-to-return-a-fresh-cached-position
return;
} else {
this._setErrorState();
}
Expand Down Expand Up @@ -366,6 +377,8 @@ class GeolocateControl extends Evented {
case 'ACTIVE_ERROR':
case 'BACKGROUND_ERROR':
// turn off the Geolocate Control
numberOfWatches--;
noTimeout = false;
this._watchState = 'OFF';
this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-waiting');
this._geolocateButton.classList.remove('mapboxgl-ctrl-geolocate-active');
Expand Down Expand Up @@ -423,8 +436,18 @@ class GeolocateControl extends Evented {
this._geolocateButton.classList.add('mapboxgl-ctrl-geolocate-waiting');
this._geolocateButton.setAttribute('aria-pressed', 'true');

numberOfWatches++;
let positionOptions;
if (numberOfWatches > 1) {
positionOptions = {maximumAge:600000, timeout:0};
noTimeout = true;
} else {
positionOptions = this.options.positionOptions;
noTimeout = false;
}

this._geolocationWatchID = window.navigator.geolocation.watchPosition(
this._onSuccess, this._onError, this.options.positionOptions);
this._onSuccess, this._onError, positionOptions);
}
} else {
window.navigator.geolocation.getCurrentPosition(
Expand Down

0 comments on commit 90f22a8

Please sign in to comment.