leaflet-geometryutil
Advanced tools
Comparing version
@@ -500,2 +500,54 @@ // Packaging/modules magic dance. | ||
return map.unproject(new L.Point(x2,y2), maxzoom); | ||
}, | ||
/** | ||
Returns the bearing in degrees clockwise from north (0 degrees) | ||
from the first L.LatLng to the second, at the first LatLng | ||
@param {L.LatLng} latlng1: origin point of the bearing | ||
@param {L.LatLng} latlng2: destination point of the bearing | ||
@returns {float} degrees clockwise from north. | ||
*/ | ||
bearing: function(latlng1, latlng2) { | ||
var rad = Math.PI / 180, | ||
lat1 = latlng1.lat * rad, | ||
lat2 = latlng2.lat * rad, | ||
lon1 = latlng1.lng * rad, | ||
lon2 = latlng2.lng * rad, | ||
y = Math.sin(lon2 - lon1) * Math.cos(lat2), | ||
x = Math.cos(lat1) * Math.sin(lat2) - | ||
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1); | ||
var bearing = ((Math.atan2(y, x) * 180 / Math.PI) + 360) % 360; | ||
return bearing >= 180 ? bearing-360 : bearing; | ||
}, | ||
/** | ||
Returns the point that is a distance and heading away from | ||
the given origin point. | ||
@param {L.LatLng} latlng: origin point | ||
@param {float}: heading in degrees, clockwise from 0 degrees north. | ||
@param {float}: distance in meters | ||
@returns {L.latLng} the destination point. | ||
Many thanks to Chris Veness at http://www.movable-type.co.uk/scripts/latlong.html | ||
for a great reference and examples. | ||
*/ | ||
destination: function(latlng, heading, distance) { | ||
heading = (heading + 360) % 360; | ||
var rad = Math.PI / 180, | ||
radInv = 180 / Math.PI, | ||
R = 6378137, // approximation of Earth's radius | ||
lon1 = latlng.lng * rad, | ||
lat1 = latlng.lat * rad, | ||
rheading = heading * rad, | ||
sinLat1 = Math.sin(lat1), | ||
cosLat1 = Math.cos(lat1), | ||
cosDistR = Math.cos(distance / R), | ||
sinDistR = Math.sin(distance / R), | ||
lat2 = Math.asin(sinLat1 * cosDistR + cosLat1 * | ||
sinDistR * Math.cos(rheading)), | ||
lon2 = lon1 + Math.atan2(Math.sin(rheading) * sinDistR * | ||
cosLat1, cosDistR - sinLat1 * Math.sin(lat2)); | ||
lon2 = lon2 * radInv; | ||
lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2; | ||
return L.latLng([lat2 * radInv, lon2]); | ||
} | ||
@@ -502,0 +554,0 @@ }); |
{ | ||
"name": "leaflet-geometryutil" | ||
, "version": "0.3.2" | ||
, "version": "0.4.0" | ||
, "description": "Leaflet utility functions on geometries" | ||
@@ -5,0 +5,0 @@ , "keywords": ["Leaflet", "GIS"] |
@@ -37,2 +37,10 @@ Leaflet.GeometryUtil | ||
### 0.4.0 ### | ||
* Same version as v0.3.3, new release as v0.4.0 to keep numbering coherent as a new feature has been added | ||
### 0.3.3 ### | ||
* Add bearing and destination functions (thanks @doublestranded) | ||
### 0.3.2 ### | ||
@@ -39,0 +47,0 @@ |
@@ -481,1 +481,63 @@ var assert = chai.assert; | ||
}); | ||
describe('Compute Bearing', function() { | ||
it('It should be degrees clockwise from north, 0 degrees.', function(done) { | ||
var latlng1 = L.latLng([0.0, 0.0]), | ||
latlng2 = L.latLng([90.0, 0.0]); | ||
assert.equal(0.0, L.GeometryUtil.bearing(latlng1,latlng2)); | ||
done(); | ||
}); | ||
it('Same point, should be zero.', function(done) { | ||
var latlng1 = L.latLng([0.0, 0.0]), | ||
latlng2 = L.latLng([0.0, 0.0]); | ||
assert.equal(0, L.GeometryUtil.bearing(latlng1,latlng2)); | ||
done(); | ||
}); | ||
it('Crossing Prime Meridian.', function(done) { | ||
var latlng1 = L.latLng([10.0, -10.0]), | ||
latlng2 = L.latLng([-10.0, 10.0]); | ||
assert.equal(134.5614514132577, L.GeometryUtil.bearing(latlng1,latlng2)); | ||
done(); | ||
}); | ||
it('Negative value for bearing greater than / equal to 180', function(done) { | ||
var latlng1 = L.latLng([33.0, -120.0]), | ||
latlng2 = L.latLng([34.0, -122.0]); | ||
assert.equal(-58.503883697887375, L.GeometryUtil.bearing(latlng1,latlng2)); | ||
done(); | ||
}); | ||
}); | ||
describe('Destination', function() { | ||
it('It should be [90.0,0.0]', function(done) { | ||
var latlng1 = L.latLng([0.0, 0.0]), | ||
heading = 0.0; | ||
dist = 6378137 * Math.PI / 2.0; // 1/4 Earth's circumference. | ||
result = L.latLng([90.0,0.0]); | ||
assert.latLngEqual(result, L.GeometryUtil.destination(latlng1, heading, dist)); | ||
done(); | ||
}); | ||
it('Crossing the International Date Line', function(done) { | ||
var latlng1 = L.latLng([0.0, -175.0]), | ||
heading = -90.0; | ||
dist = 6378137 * Math.PI / 8.0; | ||
result = L.latLng([0.0, 162.5]); | ||
assert.latLngEqual(result, L.GeometryUtil.destination(latlng1, heading, dist)); | ||
done(); | ||
}); | ||
it('Crossing the Prime Meridian', function(done) { | ||
var latlng1 = L.latLng([10.0, -10.0]), | ||
heading = 134.5614514132577; | ||
dist = 3140555.3283872544; | ||
result = L.latLng([-10, 10.0]); | ||
assert.latLngEqual(result, L.GeometryUtil.destination(latlng1, heading, dist)); | ||
done(); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
253431
91.11%27
50%1988
45.22%95
9.2%