1 | 1 | 'use strict'; |
2 | | |
3 | 1 | var haversine = module.exports = {}; |
4 | | |
5 | | |
6 | | // ----- configurable earthRadius |
7 | | // --------------------------------------- |
8 | 1 | haversine.earthRadius = 6371000; |
9 | | |
10 | | |
11 | | // ----- convert degrees to radians |
12 | | // --------------------------------------- |
13 | 1 | haversine.degreesToRadians = function(deg) { |
14 | 24 | return deg * (Math.PI / 180); |
15 | | }; |
16 | | |
17 | | |
18 | | // ----- distance between two points |
19 | | // --------------------------------------- |
20 | 1 | haversine.distance = function(coords1, coords2) { |
21 | | |
22 | 5 | var lat1 = coords1[0]; |
23 | 5 | var lon1 = coords1[1]; |
24 | 5 | var lat2 = coords2[0]; |
25 | 5 | var lon2 = coords2[1]; |
26 | | |
27 | 5 | var latitudeDifference = this.degreesToRadians(lat2 - lat1); |
28 | 5 | var logitudeDifference = this.degreesToRadians(lon2 - lon1); |
29 | | |
30 | 5 | var haversine = |
31 | | Math.sin(latitudeDifference/2) * Math.sin(latitudeDifference/2) + |
32 | | Math.cos(this.degreesToRadians(lat1)) * Math.cos(this.degreesToRadians(lat2)) * |
33 | | Math.sin(logitudeDifference/2) * Math.sin(logitudeDifference/2); |
34 | | |
35 | 5 | var distance = 2 * Math.atan2(Math.sqrt(haversine), Math.sqrt(1 - haversine)); |
36 | | |
37 | 5 | return this.earthRadius * distance; |
38 | | |
39 | | }; |
40 | | |
41 | | |
42 | | // ----- convert degrees/minutes/seconds to decimal degrees |
43 | | // --------------------------------------- |
44 | 1 | haversine.toDecimal = function(str) { |
45 | | |
46 | 8 | str = str.toLowerCase(); // throws if input is not a string |
47 | 8 | var lastChar = str.slice(-1); |
48 | 8 | var negative = false; |
49 | | |
50 | 8 | if (lastChar === 'w' || lastChar === 's') { |
51 | 2 | negative = true; // south and west => negative |
52 | | } |
53 | | |
54 | 8 | var values = str.split(/[^0-9.]/); |
55 | 8 | var i; |
56 | | // convert strings to numbers |
57 | 8 | for (i = 0; i < values.length; i++) { |
58 | | |
59 | | // remove empty values |
60 | 27 | if (!values[i]) { |
61 | 8 | values.splice(i, 1); |
62 | 8 | continue; |
63 | | } |
64 | | |
65 | 19 | values[i] = parseFloat(values[i]); |
66 | | |
67 | | } |
68 | | |
69 | | // make sure array has length 3 |
70 | 8 | for (i = 0; i < 3; i++) { |
71 | 24 | values[i] = values[i] || 0; |
72 | | } |
73 | | |
74 | 8 | var result = values[0] + (values[1] / 60) + (values[2] / 3600); |
75 | | |
76 | 8 | if (negative) { |
77 | 2 | return result * -1; |
78 | | } |
79 | | |
80 | 6 | return result; |
81 | | |
82 | | }; |