diff --git a/spec/index.html b/spec/index.html index 298e96b..27a7946 100644 --- a/spec/index.html +++ b/spec/index.html @@ -66,6 +66,7 @@ + diff --git a/spec/test.angle.js b/spec/test.angle.js new file mode 100644 index 0000000..b12e987 --- /dev/null +++ b/spec/test.angle.js @@ -0,0 +1,26 @@ +describe('Angle', function() { + + it('It should be 45 degrees', function(done) { + var latlng1 = L.latLng([0.0, 0.0]), + latlng2 = L.latLng([1.0, 1.0]), + result = 45.0; + assert.equal(result, L.GeometryUtil.angle(map, latlng1, latlng2)); + done(); + }); + + it('It should be degrees clockwise from east, 0 degrees', function(done) { + var latlng1 = L.latLng([0.0, 0.0]), + latlng2 = L.latLng([1.0, 0.0]), + result = 0.0; + assert.equal(result, L.GeometryUtil.angle(map, latlng1, latlng2)); + done(); + }); + + it('It should not be a negative value when the angle is greater than 180', function(done) { + var latlng1 = L.latLng([0.0, 0.0]), + latlng2 = L.latLng([-1.0, 1.0]), + result = -135.0; + assert.notEqual(result, L.GeometryUtil.angle(map, latlng1, latlng2)); + done(); + }); +}); diff --git a/spec/test.destination.js b/spec/test.destination.js index 06548b3..682eb13 100644 --- a/spec/test.destination.js +++ b/spec/test.destination.js @@ -26,4 +26,4 @@ describe('Destination', function() { assert.latLngEqual(result, L.GeometryUtil.destination(latlng1, heading, dist)); done(); }); -}); \ No newline at end of file +}); diff --git a/src/leaflet.geometryutil.js b/src/leaflet.geometryutil.js index baf9eba..b4273b6 100644 --- a/src/leaflet.geometryutil.js +++ b/src/leaflet.geometryutil.js @@ -703,8 +703,8 @@ L.GeometryUtil = L.extend(L.GeometryUtil || {}, { 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 + @param {float} heading: heading in degrees, clockwise from 0 degrees north. + @param {float} distance: 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. @@ -728,7 +728,37 @@ L.GeometryUtil = L.extend(L.GeometryUtil || {}, { lon2 = lon2 * radInv; lon2 = lon2 > 180 ? lon2 - 360 : lon2 < -180 ? lon2 + 360 : lon2; return L.latLng([lat2 * radInv, lon2]); - } + }, + + /** + Returns the the angle of the given segment and the Equator in degrees, + clockwise from 0 degrees north. + @param {L.Map} map: Leaflet map to be used for this method + @param {L.LatLng} latlngA: geographical point A of the segment + @param {L.LatLng} latlngB: geographical point B of the segment + @returns {Float} the angle in degrees. + */ + angle: function(map, latlngA, latlngB) { + var pointA = map.latLngToContainerPoint(latlngA), + pointB = map.latLngToContainerPoint(latlngB), + angleDeg = Math.atan2(pointB.y - pointA.y, pointB.x - pointA.x) * 180 / Math.PI + 90; + angleDeg += angleDeg < 0 ? 360 : 0; + return angleDeg; + }, + + /** + Returns a point snaps on the segment and heading away from the given origin point a distance. + @param {L.Map} map: Leaflet map to be used for this method + @param {L.LatLng} latlngA: geographical point A of the segment + @param {L.LatLng} latlngB: geographical point B of the segment + @param {float} distance: distance in meters + @returns {L.latLng} the destination point. + */ + destinationOnSegment: function(map, latlngA, latlngB, distance) { + var angleDeg = L.GeometryUtil.angle(map, latlngA, latlngB), + latlng = L.GeometryUtil.destination(latlngA, angleDeg, distance); + return L.GeometryUtil.closestOnSegment(map, latlng, latlngA, latlngB); + }, }); return L.GeometryUtil;