Files
CRM/jscss/GPSControl.js
BACHIR SOULDI 2794e62571 first commit
2025-09-28 08:49:37 +01:00

162 lines
5.0 KiB
JavaScript

// Use UMD pattern : https://github.com/umdjs/umd/blob/master/templates/commonjsStrict.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports', 'leaflet'], factory);
} else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
// CommonJS
factory(exports, require('leaflet'));
} else {
// Browser globals
factory((root.leafletGPSTracker = {}), root.L);
root.GPSControl = root.leafletGPSTracker.GPSControl;
}
}(typeof self !== 'undefined' ? self : this, function (exports, L) {
exports.GPSControl = L.Control.extend({
options: {
position: 'topleft',
class: 'material-icons',
offClass: 'gps_off',
onClass: 'gps_fixed',
noTrackTitle: 'Locate with GPS',
offTitle: 'Activate GPS tracking',
onTitle: 'Deactivate GPS tracking',
active: true,
precision: 5,
track: true,
activeCallback: function(active) {
console.log('GPS tracking is active ? ' + active);
},
successCallback: function(latlng) {
console.log('GPS tracking detected a position change : ' + latlng);
},
errorCallback: function(err) {
console.error('GPS tracking failed : ' + err.message);
}
},
initialize: function(options) {
L.Util.setOptions(this, options);
},
onAdd: function(map) {
var _this = this;
this._div = L.DomUtil.create('div', 'leaflet-bar gps-control');
this._a = L.DomUtil.create('a', '', this._div);
this._i = L.DomUtil.create('i', this.options.class || 'material-icons', this._a);
setTimeout(function() {
if (_this.options.track) {
_this.updateActive(_this.options.active);
} else {
_this._i.innerHTML = _this.options.onClass;
_this._a.title = _this.options.noTrackTitle;
if (_this.options.active) {
_this.locate()
}
}
}, 100);
this._a.addEventListener('click', function(e) {
if (_this.options.track) {
_this.updateActive(!_this.active);
} else {
_this.locate()
}
e.stopPropagation();
});
return this._div;
},
onRemove: function(map) {
this._clearWatch();
},
locate: function() {
// Used when in one time GPS locating mode
var _this = this;
if (this._savedLast && this.options.successCallback) {
this.options.successCallback(this._savedLast);
}
if (window.navigator && window.navigator.geolocation) {
window.navigator.geolocation.getCurrentPosition(
function(pos) { _this._success(pos); },
function(err) { _this._error(err); },
{ enableHighAccuracy: true }
);
} else {
this._error(new Error('No valid window.navigator.geolocation object found (incompatible browser ?)'));
}
},
updateActive: function(value) {
// Used when in active tracking mode
var _this = this;
if (value === this.active) return;
this.active = value;
if (this.options.activeCallback) {
this.options.activeCallback(this.active);
}
if (this.active && !this.options.track) {
return this.locate();
}
this._i.innerHTML = this.active ? this.options.offClass : this.options.onClass;
this._a.title = this.active ? this.options.onTitle : this.options.offTitle;
if (this.active) {
if (this._savedLast && this.options.successCallback) {
this.options.successCallback(this._savedLast);
}
if (window.navigator && window.navigator.geolocation) {
this._clearWatch();
this._watchPosition = window.navigator.geolocation.watchPosition(
function(pos) { _this._success(pos); },
function(err) { _this._error(err); },
{ enableHighAccuracy: true }
);
} else {
this._error(new Error('No valid window.navigator.geolocation object found (incompatible browser ?)'));
}
} else {
this._clearWatch();
}
},
_success: function(pos) {
// should not be possible
if (this.options.track && !this.active) return;
const latlng = new L.LatLng(pos.coords.latitude, pos.coords.longitude);
// Ignore smallest changes
if (this.options.track && this.options.precision > 0 && this._last && latlng.distanceTo(this._last) < this.options.precision) {
return;
}
this._last = latlng;
this._savedLast = latlng;
if (this.options.successCallback) {
this.options.successCallback(latlng);
}
},
_error: function(err) {
if (this.options.errorCallback) {
this.options.errorCallback(err);
}
this._clearWatch()
this.remove()
},
_clearWatch: function() {
this._last = null;
if (this._watchPosition) {
navigator.geolocation.clearWatch(this._watchPosition);
}
}
})
}));