leaflet-routing-machine
Version:
132 lines (110 loc) • 3.06 kB
JavaScript
(function() {
'use strict';
var L = require('leaflet');
module.exports = 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;
}
});
})();