gps_filter.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. <?php
  2. ini_set("display_errors", "1");
  3. error_reporting(E_ALL);
  4. require("connection.php");
  5. $db = new PDO("mysql:host=$dbhost;dbname=$db;charset=utf8mb4", $dbuser, $dbpass);
  6. $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  7. $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
  8. $coords = Array(
  9. Array(123.45, -13.45),//some coodinates to remove from database
  10. );
  11. $distance = 800 / 111139.0; // m / (m/deg)
  12. $json = Array();
  13. foreach($coords as $coord) {
  14. $stmt = $db->prepare("SELECT *, SQRT(POW(ABS(? - lat),2) + POW(ABS(? - lng),2)) AS distance FROM markers WHERE POW(ABS(? - lat),2) + POW(ABS(? - lng),2) < POW(?,2) ORDER BY timestamp");
  15. //$stmt->bindParam(":lat", $coord[0]);
  16. //$stmt->bindParam(":lng", $coord[1]);
  17. //$stmt->bindParam(":dist", $distance);
  18. $stmt->execute(Array($coord[0],$coord[1],$coord[0],$coord[1],$distance));
  19. while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
  20. $row['lat'] = doubleval($row['lat']);
  21. $row['lng'] = doubleval($row['lng']);
  22. $row['alt'] = floatval($row['alt']);
  23. $row['hdop'] = intval($row['hdop']);
  24. $row['timestamp'] = strtotime($row['timestamp']);
  25. $row['format'] = date('d.m.Y H:i:s', $row['timestamp']);
  26. $json[] = $row;
  27. }
  28. $stmt = $db->prepare("DELETE FROM markers WHERE POW(ABS(? - lat),2) + POW(ABS(? - lng),2) < POW(?,2) ORDER BY timestamp");
  29. $stmt->execute(Array($coord[0],$coord[1],$distance));
  30. }
  31. ?>
  32. <!DOCTYPE html >
  33. <head>
  34. <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
  35. <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
  36. <title>Arduino/PHP/MySQL & Google Maps</title>
  37. <script language="javascript" type="text/javascript" src="../flot/jquery.js"></script>
  38. <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0ugZma4Wf5vweeAfy5uulSY_tpPt2bFs"
  39. type="text/javascript"></script>
  40. <style>
  41. .info {
  42. border-radius: 25px;
  43. opacity: .8;
  44. padding: 5px;
  45. margin: 5px;
  46. display: inline-block;
  47. background-color: #8383ff;
  48. text-align: center;
  49. cursor: pointer;
  50. animation: fadein 1.2s;
  51. }
  52. @keyframes fadein {
  53. from { opacity: 0; }
  54. to { opacity: .8; }
  55. }
  56. </style>
  57. <script type="text/javascript">
  58. $(window).resize(function() {
  59. $('#map').height($(window).height());
  60. $('#map').width($(window).width());
  61. });
  62. function load() {
  63. $('#map').height($(window).height());
  64. $('#map').width($(window).width());
  65. var map = new google.maps.Map(document.getElementById("map"), {
  66. center: new google.maps.LatLng(51.9907479, 11.1171459),
  67. zoom: 6,
  68. mapTypeId: 'hybrid'
  69. });
  70. var bikeLayer = new google.maps.BicyclingLayer();
  71. bikeLayer.setMap(map);
  72. var infoWindow = new google.maps.InfoWindow;
  73. var geocoder = new google.maps.Geocoder;
  74. var data = JSON.parse('<?php echo json_encode($json); ?>');
  75. var startIndex = 0, distances = [0], timeDiff = [1], timeMovement = 0, speed = [0], up = 0, down = 0;
  76. var tripDist = 0, tripIndex = 0;
  77. for (var i = 1; i < data.length; i++) {
  78. distances[i] = distance(data[i-1].lat, data[i-1].lng, data[i].lat, data[i].lng);
  79. if(isNaN(distances[i])) distances[i] = 0;
  80. timeDiff[i] = data[i].timestamp - data[i-1].timestamp;
  81. if(data[i].speed != null) {
  82. speed[i] = data[i].speed * 1.852 / 100;
  83. } else {
  84. speed[i] = distances[i] / timeDiff[i] * 3.6;
  85. }
  86. if(timeDiff[i] > 60*30 || i == data.length - 1) {
  87. var color = getRandomColor(i);
  88. var dis = distances.slice(startIndex+1, i).reduce((a, b) => a + b, 0);
  89. var tsp = Math.max.apply(Math, speed.slice(startIndex+1, i)).toFixed(1);
  90. var avg = (dis / timeMovement * 3.6).toFixed(2);
  91. var html = "Start: <b>" + data[startIndex].format +
  92. "</b><br/>Finish: <b>" + data[i-1].format + "</b><br/>" +
  93. "Track time (full): "+ timeFormat(data[i-1].timestamp-data[startIndex].timestamp) + "<br>" +
  94. "Track time (movement): "+ timeFormat(timeMovement) + "<br>" +
  95. "<a target='_blank' href='gps_graph.php?start="+startIndex+"&finish="+i+
  96. "'>Alt:</a> &uarr;" + up.toFixed(1) + "m &darr;" + down.toFixed(1) + "m"+
  97. "<br/>Distance: "+(dis/1000).toFixed(1)+"km<br/>" +
  98. "top speed: "+tsp+
  99. "km/h<br/><a target='_blank' href='gps_graph.php?start="+startIndex+"&finish="+i+
  100. "'>average speed</a>: "+avg+"km/h";
  101. tripDist += dis;
  102. if(timeDiff[i] > 2*24*3600 || i == data.length - 1) {
  103. setTimeout(addInfo, tripIndex * 1200, geocoder, map, tripIndex, data[startIndex], tripDist);
  104. tripIndex++;
  105. tripDist = 0;
  106. }
  107. var path = new google.maps.Polyline({
  108. map: map,
  109. path: data.slice(startIndex, i),
  110. strokeColor: color,
  111. strokeOpacity: 1,
  112. strokeWeight: 4,
  113. zIndex: 1,
  114. icons: [{
  115. icon: {path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW},
  116. offset: '20%',
  117. repeat: '200px'
  118. }],
  119. });
  120. bindInfoWindow(path, map, infoWindow, html);
  121. startIndex = i;
  122. up=0;
  123. down=0;
  124. timeMovement=0;
  125. } else {
  126. if(data[i].alt<250 || data[i].alt>260) {
  127. if(data[i].alt>=data[i-1].alt)
  128. up += data[i].alt - data[i-1].alt;
  129. else
  130. down += data[i-1].alt - data[i].alt;
  131. } else {
  132. if(data[i].hdop>200) {
  133. speed[i] = 0;
  134. }
  135. }
  136. if(speed[i]>60) {
  137. console.log(speed[i].toFixed(2) + " km/h is too fast at " + data[i].format);
  138. } else if(speed[i] > 2) {
  139. timeMovement += timeDiff[i];
  140. }
  141. }
  142. }
  143. }
  144. function bindInfoWindow(path, map, infoWindow, html) {
  145. google.maps.event.addListener(path, 'click', function(e) {
  146. infoWindow.setContent(html);
  147. console.log(e);
  148. infoWindow.setPosition(e.latLng);
  149. infoWindow.open(map);
  150. });
  151. google.maps.event.addListener(path, 'mouseover', function() {
  152. path.setOptions({
  153. zIndex: 2,
  154. strokeWeight: 6
  155. });
  156. });
  157. google.maps.event.addListener(path, 'mouseout', function() {
  158. setTimeout(function() {
  159. path.setOptions({
  160. zIndex: 1,
  161. strokeWeight: 4
  162. });
  163. }, 1000);
  164. });
  165. }
  166. function addInfo(geocoder, map, id, data, dist) {
  167. geocoder.geocode({'location': data}, function(results, status) {
  168. if (status === 'OK') {
  169. if (results[3]) {
  170. $('#info').append("<div class='info' id='info_" + id + "'>" +
  171. data.format.substring(3, 10) + "<br>" +
  172. results[3].formatted_address + "<br><b>" +
  173. (dist/1000).toFixed(1) + " km</b></div>");
  174. $('#info_'+id).click(function() {
  175. map.panTo(data);
  176. map.setZoom(12);
  177. });
  178. } else {
  179. console.log('No results found');
  180. }
  181. } else {
  182. console.log('Geocoder failed due to: ' + status);
  183. }
  184. });
  185. }
  186. function getRandomColor(i) {
  187. /*var letters = '3456789ABCDEF'.split('');
  188. var color = '#';
  189. for (var i = 0; i < 6; i++ ) {
  190. color += letters[Math.floor(Math.random() * 13)];
  191. }
  192. return color;*/
  193. return "hsl(" + ((i*57) % 256) + ", 80%, 50%)";
  194. }
  195. function distance (lat1, lon1, lat2, lon2) {
  196. // Convert degrees to radians
  197. lat1 = lat1 * Math.PI / 180.0;
  198. lon1 = lon1 * Math.PI / 180.0;
  199. lat2 = lat2 * Math.PI / 180.0;
  200. lon2 = lon2 * Math.PI / 180.0;
  201. // radius of earth in metres
  202. var r = 6378100;
  203. // P
  204. var rho1 = r * Math.cos(lat1);
  205. var z1 = r * Math.sin(lat1);
  206. var x1 = rho1 * Math.cos(lon1);
  207. var y1 = rho1 * Math.sin(lon1);
  208. // Q
  209. var rho2 = r * Math.cos(lat2);
  210. var z2 = r * Math.sin(lat2);
  211. var x2 = rho2 * Math.cos(lon2);
  212. var y2 = rho2 * Math.sin(lon2);
  213. // Dot product
  214. var dot = (x1 * x2 + y1 * y2 + z1 * z2);
  215. var cos_theta = dot / (r * r);
  216. var theta = Math.acos(cos_theta);
  217. // Distance in Metres
  218. return r * theta;
  219. }
  220. function timeFormat (sec) {
  221. return new Date(null,null,null,null,null,sec).toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0];
  222. }
  223. //]]>
  224. </script>
  225. </head>
  226. <body onload="load()" style="margin: 0; padding: 0;">
  227. <div id="map" style="width: 800px; height: 800px"></div>
  228. <div id="info" style="position:absolute; bottom:0; left:0;width:100%;overflow-x:auto;white-space: nowrap">
  229. <div class="info">
  230. <form method="post" enctype="multipart/form-data" action='gps_insert.php'>
  231. <input type="file" name="my_file[]" multiple><br>
  232. <input type="submit" value="Upload">
  233. </form>
  234. </div>
  235. </div>
  236. </body>
  237. </html>