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