@fleetbase/leaflet-routing-machine
Version:
ESM module Routing for Leaflet
120 lines (100 loc) • 3.52 kB
JavaScript
export default L.LayerGroup.extend({
includes: (typeof L.Evented !== 'undefined' && L.Evented.prototype) || L.Mixin.Events,
options: {
styles: [
{ color: 'black', opacity: 0.15, weight: 9 },
{ color: 'white', opacity: 0.8, weight: 6 },
{ color: 'red', opacity: 1, weight: 2 },
],
missingRouteStyles: [
{ color: 'black', opacity: 0.15, weight: 7 },
{ color: 'white', opacity: 0.6, weight: 4 },
{ color: 'gray', opacity: 0.8, weight: 2, dashArray: '7,12' },
],
addWaypoints: true,
extendToWaypoints: true,
missingRouteTolerance: 10,
},
initialize: function (route, options) {
L.setOptions(this, options);
L.LayerGroup.prototype.initialize.call(this, options);
this._route = route;
if (this.options.extendToWaypoints) {
this._extendToWaypoints();
}
this._addSegment(route.coordinates, this.options.styles, this.options.addWaypoints);
},
getBounds: function () {
return L.latLngBounds(this._route.coordinates);
},
_findWaypointIndices: function () {
var wps = this._route.inputWaypoints,
indices = [],
i;
for (i = 0; i < wps.length; i++) {
indices.push(this._findClosestRoutePoint(wps[i].latLng));
}
return indices;
},
_findClosestRoutePoint: function (latlng) {
var minDist = Number.MAX_VALUE,
minIndex,
i,
d;
for (i = this._route.coordinates.length - 1; i >= 0; i--) {
// TODO: maybe do this in pixel space instead?
d = latlng.distanceTo(this._route.coordinates[i]);
if (d < minDist) {
minIndex = i;
minDist = d;
}
}
return minIndex;
},
_extendToWaypoints: function () {
var wps = this._route.inputWaypoints,
wpIndices = this._getWaypointIndices(),
i,
wpLatLng,
routeCoord;
for (i = 0; i < wps.length; i++) {
wpLatLng = wps[i].latLng;
routeCoord = L.latLng(this._route.coordinates[wpIndices[i]]);
if (wpLatLng.distanceTo(routeCoord) > this.options.missingRouteTolerance) {
this._addSegment([wpLatLng, routeCoord], this.options.missingRouteStyles);
}
}
},
_addSegment: function (coords, styles, mouselistener) {
var i, pl;
for (i = 0; i < styles.length; i++) {
pl = L.polyline(coords, styles[i]);
this.addLayer(pl);
if (mouselistener) {
pl.on('mousedown', this._onLineTouched, this);
}
}
},
_findNearestWpBefore: function (i) {
var wpIndices = this._getWaypointIndices(),
j = wpIndices.length - 1;
while (j >= 0 && wpIndices[j] > i) {
j--;
}
return j;
},
_onLineTouched: function (e) {
var afterIndex = this._findNearestWpBefore(this._findClosestRoutePoint(e.latlng));
this.fire('linetouched', {
afterIndex: afterIndex,
latlng: e.latlng,
});
L.DomEvent.stop(e);
},
_getWaypointIndices: function () {
if (!this._wpIndices) {
this._wpIndices = this._route.waypointIndices || this._findWaypointIndices();
}
return this._wpIndices;
},
});