I'm using the Leaflet mapping API. I would like to determine which point in a polyline has been clicked on. The polyline is one that I have rendered using the Directions services from MapQuest Open.
The relevant code is:
for ( var i = 0; i < latlngs.length; i++ ) {
// the equals method uses a small fudge factor to decide if the two // points are the same.
if ( latlng.equals( latlngs[ i ] )) { return i; } }
.equals() is supposed to compare points with a fudge factor. When I click on the polyline I get an event with lat/lngs like:
'38.83966582989183','-77.0083075761795'
My lat/lngs in the polyline are of less precision as in:
'38.841289','-77.008842'
So as I loop through looking for a match equals() never returns true. Clearly, the click event is firing, so leaflet knows I've clicked the polyline, but there doesn't seem to be a clean way of getting the actual offset of the latlng that was clicked on.
Per this ticket I've tried adjusting the precision to no avail.
Going into the list of lat/lngs I can clearly see that the select lat/lng is between two points in the polyline.
Reducing the precision returned from the mouse click doesn't seem to work either.
Ideally, I'd like to have some method to get the offset into the latlng set of the polyline closest to where the user clicked. I can do a rough job by hand but would, ideally, like a clean solution.
Any help/pointers would be greatly appreciated.
that.historicalTrack.on('click', function(e) {
var point = null;
var angle = null;
var delta = null;
var minDelta = 10;
var numPoints = that.historicalTrackPoints.length;
var pointA = null;
var pointC = null;
var pointB = [e.latlng.lat, e.latlng.lng]
var distanceA = null;
var distanceC = null;
// Compare all points in the set
for(var i=0;i<numPoints-1;i++) {
pointA = [parseFloat(that.historicalTrackPoints[i].latitude), parseFloat(that.historicalTrackPoints[i].longitude)];
pointC = [parseFloat(that.historicalTrackPoints[i+1].latitude), parseFloat(that.historicalTrackPoints[i+1].longitude)];
// Angle between A--B--C
// Delta describes variance from PI radians
angle = vectorAngle(pointA, pointB, pointC);
if (angle < 0) angle = -angle;
delta = Math.PI - angle;
if (delta < 0) delta = -delta;
// A smaller delta should mean a better match... right?
if (delta < minDelta) {
minDelta = delta;
distanceA = e.latlng.distanceTo(L.latLng(pointA));
distanceC = e.latlng.distanceTo(L.latLng(pointC));
// Vote on the two points in the pair
if (distanceA < distanceC) {
point = that.historicalTrackPoints[i];
} else {
point = that.historicalTrackPoints[i+1];
}
}
}
var trackPopup = new L.Popup().setLatLng([point.latitude, point.longitude]).setContent(point.id);
trackPopup.addTo(map);
});