-
Notifications
You must be signed in to change notification settings - Fork 1
/
distances.php
147 lines (111 loc) · 4.27 KB
/
distances.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
/**
* This script uses the Haversine formula to calculate the distance between each point in a .kml file, and adds them up. The total is output to the browser in a spectacularly unexciting manner. It does the job though.
*
* There aren't a lot of comments, because it is fairly self-explanitory. If you struggle or spot * any bugs, get in touch!
*
* This post was very helpful, in fact I took the calculation formula from it and modified it a little. Check it out!
* http://www.nmcmahon.co.uk/getting-the-distance-between-two-locations-using-google-maps-api-and-php/
*
* @author noln (Matt Fenlon)
*/
$file_temp = file_get_contents("location-history.kml");
// Cuts the head and tail off the file.
$split = explode("<gx:Track>",$file_temp);
$split = $split[1];
$split = explode("</gx:Track>",$split);
$gx_track = trim($split[0]);
// Explodes each data point into an array for iterative processing.
$gx_exp = explode("<when>",$gx_track);
/**
* Calculates the "great circle" distance between two points.
* @param array $start is a two-element array of latitude [0] and longitude [1].
* @param array $finish is another two-element array of latitude [0] and longitude [1].
* @return float Distance between the two points in metres.
*/
function Haversine($start, $finish) {
// Reset the value to '0' in case function is called repeatedlt (it will be).
$distance_out_metres = 0;
$theta = $start[1] - $finish[1];
$distance =
(sin(deg2rad($start[0])) *
sin(deg2rad($finish[0]))) +
(cos(deg2rad($start[0])) *
cos(deg2rad($finish[0])) * cos(deg2rad($theta))
);
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
$distance_out = round($distance, 2); // in miles!
if ($distance_out >= 1) {
$distance_out_metres = $distance_out*1609.34;
} else {
$distance_out_metres = 0; // to get around odd issue of 0 = 0.1 in api
}
//}
return $distance_out_metres;
}
/**
* Calculates the great-circle distance between two points, with
* the Haversine formula.
* @param float $latitudeFrom Latitude of start point in [deg decimal]
* @param float $longitudeFrom Longitude of start point in [deg decimal]
* @param float $latitudeTo Latitude of target point in [deg decimal]
* @param float $longitudeTo Longitude of target point in [deg decimal]
* @param float $earthRadius Mean earth radius in [m]
* @return float Distance between points in [m] (same as earthRadius)
*/
function haversineGreatCircleDistance(
$latitudeFrom, $longitudeFrom, $latitudeTo, $longitudeTo, $earthRadius = 6371000)
{
// convert from degrees to radians
$latFrom = deg2rad($latitudeFrom);
$lonFrom = deg2rad($longitudeFrom);
$latTo = deg2rad($latitudeTo);
$lonTo = deg2rad($longitudeTo);
$latDelta = $latTo - $latFrom;
$lonDelta = $lonTo - $lonFrom;
$angle = 2 * asin(sqrt(pow(sin($latDelta / 2), 2) +
cos($latFrom) * cos($latTo) * pow(sin($lonDelta / 2), 2)));
return $angle * $earthRadius;
}
$i = 0;
foreach($gx_exp as $point){
if ($i > 0&&($i%1000)){
//if ($i <= 10){
if(isset($f_geo)){
$f_geo_lat_prev = $f_geo_lat;
$f_geo_lon_prev = $f_geo_lon;
unset($f_geo_prev);
$f_geo_prev = $f_geo;
}
// Get time
$f_tmp = explode("</when>", $point);
$f_time = $f_tmp[0];
// Get geopoint
$f_tmp = explode("<gx:coord>",$point);
$f_tmp = $f_tmp[1];
$f_tmp = explode("</gx:coord>",$f_tmp);
$f_geo_dirty = $f_tmp[0] . "<br/>";
$f_geo_dirty = explode(" ", $f_geo_dirty);
$f_geo_lat = trim($f_geo_dirty[0]);
$f_geo_lon = trim($f_geo_dirty[1]);
unset($f_geo);
$f_geo[]=$f_geo_lat;
$f_geo[]=$f_geo_lon;
//print_r($f_geo);
//print_r($f_geo_prev);
if (isset($f_geo_prev)){
//echo Haversine($f_geo_prev, $f_geo)."\n";
$distance_between_points = haversineGreatCircleDistance($f_geo_prev[1],$f_geo_prev[0],$f_geo[1],$f_geo[0])."\n";
$total_distance_m += $distance_between_points;
$output = <<< HEREDOC
<tr><td>$f_geo_prev[0]</td><td>$f_geo_prev[1]</td><td>$f_geo[0]</td><td>$f_geo[1]</td><td><em>$distance_between_points</em></td></tr>\n
HEREDOC;
}
}
$i++;
}
echo "<div style=\"text-align:center;font-family:Verdana;font-weight:bold;font-size:24px;\"\">" . round(($total_distance_m/1000),0) . " kilometres</div>";
$polyline_points = rtrim(trim($polyline_points), ",");
?>