1 | var haversine = (function () {
|
2 | var RADII = {
|
3 | km: 6371,
|
4 | mile: 3960,
|
5 | meter: 6371000,
|
6 | nmi: 3440
|
7 | }
|
8 |
|
9 |
|
10 | var toRad = function (num) {
|
11 | return num * Math.PI / 180
|
12 | }
|
13 |
|
14 |
|
15 | var convertCoordinates = function (format, coordinates) {
|
16 | switch (format) {
|
17 | case '[lat,lon]':
|
18 | return { latitude: coordinates[0], longitude: coordinates[1] }
|
19 | case '[lon,lat]':
|
20 | return { latitude: coordinates[1], longitude: coordinates[0] }
|
21 | case '{lon,lat}':
|
22 | return { latitude: coordinates.lat, longitude: coordinates.lon }
|
23 | case 'geojson':
|
24 | return { latitude: coordinates.geometry.coordinates[1], longitude: coordinates.geometry.coordinates[0] }
|
25 | default:
|
26 | return coordinates
|
27 | }
|
28 | }
|
29 |
|
30 | return function haversine (startCoordinates, endCoordinates, options) {
|
31 | options = options || {}
|
32 |
|
33 | var R = options.unit in RADII
|
34 | ? RADII[options.unit]
|
35 | : RADII.km
|
36 |
|
37 | var start = convertCoordinates(options.format, startCoordinates)
|
38 | var end = convertCoordinates(options.format, endCoordinates)
|
39 |
|
40 | var dLat = toRad(end.latitude - start.latitude)
|
41 | var dLon = toRad(end.longitude - start.longitude)
|
42 | var lat1 = toRad(start.latitude)
|
43 | var lat2 = toRad(end.latitude)
|
44 |
|
45 | var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
|
46 | Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2)
|
47 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
|
48 |
|
49 | if (options.threshold) {
|
50 | return options.threshold > (R * c)
|
51 | }
|
52 |
|
53 | return R * c
|
54 | }
|
55 |
|
56 | })()
|
57 |
|
58 | if (typeof module !== 'undefined' && module.exports) {
|
59 | module.exports = haversine
|
60 | }
|