|
@@ -1,270 +0,0 @@
|
|
|
-<?php
|
|
|
-ini_set("display_errors", "1");
|
|
|
-error_reporting(E_ALL);
|
|
|
-require("connection.php");
|
|
|
-
|
|
|
-$db = new PDO("mysql:host=$dbhost;dbname=$db;charset=utf8mb4", $dbuser, $dbpass);
|
|
|
-$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
-$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
|
|
-
|
|
|
-$coords = Array(
|
|
|
- Array(123.45, -13.45),
|
|
|
-);
|
|
|
-$distance = 800 / 111139.0;
|
|
|
-
|
|
|
-$json = Array();
|
|
|
-
|
|
|
-foreach($coords as $coord) {
|
|
|
- $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");
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- $stmt->execute(Array($coord[0],$coord[1],$coord[0],$coord[1],$distance));
|
|
|
-
|
|
|
- while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
|
|
- $row['lat'] = doubleval($row['lat']);
|
|
|
- $row['lng'] = doubleval($row['lng']);
|
|
|
- $row['alt'] = floatval($row['alt']);
|
|
|
- $row['hdop'] = intval($row['hdop']);
|
|
|
- $row['timestamp'] = strtotime($row['timestamp']);
|
|
|
- $row['format'] = date('d.m.Y H:i:s', $row['timestamp']);
|
|
|
- $json[] = $row;
|
|
|
- }
|
|
|
- $stmt = $db->prepare("DELETE FROM markers WHERE POW(ABS(? - lat),2) + POW(ABS(? - lng),2) < POW(?,2) ORDER BY timestamp");
|
|
|
- $stmt->execute(Array($coord[0],$coord[1],$distance));
|
|
|
-}
|
|
|
-
|
|
|
-?>
|
|
|
-
|
|
|
-<!DOCTYPE html >
|
|
|
- <head>
|
|
|
- <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
|
|
|
- <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
|
|
|
- <title>Arduino/PHP/MySQL & Google Maps</title>
|
|
|
- <script language="javascript" type="text/javascript" src="../flot/jquery.js"></script>
|
|
|
- <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA0ugZma4Wf5vweeAfy5uulSY_tpPt2bFs"
|
|
|
- type="text/javascript"></script>
|
|
|
- <style>
|
|
|
- .info {
|
|
|
- border-radius: 25px;
|
|
|
- opacity: .8;
|
|
|
- padding: 5px;
|
|
|
- margin: 5px;
|
|
|
- display: inline-block;
|
|
|
- background-color:
|
|
|
- text-align: center;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- animation: fadein 1.2s;
|
|
|
- }
|
|
|
- @keyframes fadein {
|
|
|
- from { opacity: 0; }
|
|
|
- to { opacity: .8; }
|
|
|
- }
|
|
|
- </style>
|
|
|
-<script type="text/javascript">
|
|
|
- $(window).resize(function() {
|
|
|
- $('#map').height($(window).height());
|
|
|
- $('#map').width($(window).width());
|
|
|
- });
|
|
|
-function load() {
|
|
|
- $('#map').height($(window).height());
|
|
|
- $('#map').width($(window).width());
|
|
|
- var map = new google.maps.Map(document.getElementById("map"), {
|
|
|
- center: new google.maps.LatLng(51.9907479, 11.1171459),
|
|
|
- zoom: 6,
|
|
|
- mapTypeId: 'hybrid'
|
|
|
- });
|
|
|
- var bikeLayer = new google.maps.BicyclingLayer();
|
|
|
- bikeLayer.setMap(map);
|
|
|
- var infoWindow = new google.maps.InfoWindow;
|
|
|
- var geocoder = new google.maps.Geocoder;
|
|
|
-
|
|
|
- var data = JSON.parse('<?php echo json_encode($json); ?>');
|
|
|
- var startIndex = 0, distances = [0], timeDiff = [1], timeMovement = 0, speed = [0], up = 0, down = 0;
|
|
|
- var tripDist = 0, tripIndex = 0;
|
|
|
-
|
|
|
- for (var i = 1; i < data.length; i++) {
|
|
|
-
|
|
|
- distances[i] = distance(data[i-1].lat, data[i-1].lng, data[i].lat, data[i].lng);
|
|
|
- if(isNaN(distances[i])) distances[i] = 0;
|
|
|
- timeDiff[i] = data[i].timestamp - data[i-1].timestamp;
|
|
|
-
|
|
|
- if(data[i].speed != null) {
|
|
|
- speed[i] = data[i].speed * 1.852 / 100;
|
|
|
- } else {
|
|
|
- speed[i] = distances[i] / timeDiff[i] * 3.6;
|
|
|
- }
|
|
|
-
|
|
|
- if(timeDiff[i] > 60*30 || i == data.length - 1) {
|
|
|
-
|
|
|
- var color = getRandomColor(i);
|
|
|
- var dis = distances.slice(startIndex+1, i).reduce((a, b) => a + b, 0);
|
|
|
- var tsp = Math.max.apply(Math, speed.slice(startIndex+1, i)).toFixed(1);
|
|
|
- var avg = (dis / timeMovement * 3.6).toFixed(2);
|
|
|
- var html = "Start: <b>" + data[startIndex].format +
|
|
|
- "</b><br/>Finish: <b>" + data[i-1].format + "</b><br/>" +
|
|
|
- "Track time (full): "+ timeFormat(data[i-1].timestamp-data[startIndex].timestamp) + "<br>" +
|
|
|
- "Track time (movement): "+ timeFormat(timeMovement) + "<br>" +
|
|
|
- "<a target='_blank' href='gps_graph.php?start="+startIndex+"&finish="+i+
|
|
|
- "'>Alt:</a> ↑" + up.toFixed(1) + "m ↓" + down.toFixed(1) + "m"+
|
|
|
- "<br/>Distance: "+(dis/1000).toFixed(1)+"km<br/>" +
|
|
|
- "top speed: "+tsp+
|
|
|
- "km/h<br/><a target='_blank' href='gps_graph.php?start="+startIndex+"&finish="+i+
|
|
|
- "'>average speed</a>: "+avg+"km/h";
|
|
|
-
|
|
|
-
|
|
|
- tripDist += dis;
|
|
|
- if(timeDiff[i] > 2*24*3600 || i == data.length - 1) {
|
|
|
- setTimeout(addInfo, tripIndex * 1200, geocoder, map, tripIndex, data[startIndex], tripDist);
|
|
|
- tripIndex++;
|
|
|
- tripDist = 0;
|
|
|
- }
|
|
|
-
|
|
|
- var path = new google.maps.Polyline({
|
|
|
- map: map,
|
|
|
- path: data.slice(startIndex, i),
|
|
|
- strokeColor: color,
|
|
|
- strokeOpacity: 1,
|
|
|
- strokeWeight: 4,
|
|
|
- zIndex: 1,
|
|
|
- icons: [{
|
|
|
- icon: {path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW},
|
|
|
- offset: '20%',
|
|
|
- repeat: '200px'
|
|
|
- }],
|
|
|
- });
|
|
|
- bindInfoWindow(path, map, infoWindow, html);
|
|
|
- startIndex = i;
|
|
|
- up=0;
|
|
|
- down=0;
|
|
|
- timeMovement=0;
|
|
|
- } else {
|
|
|
- if(data[i].alt<250 || data[i].alt>260) {
|
|
|
- if(data[i].alt>=data[i-1].alt)
|
|
|
- up += data[i].alt - data[i-1].alt;
|
|
|
- else
|
|
|
- down += data[i-1].alt - data[i].alt;
|
|
|
- } else {
|
|
|
- if(data[i].hdop>200) {
|
|
|
- speed[i] = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- if(speed[i]>60) {
|
|
|
- console.log(speed[i].toFixed(2) + " km/h is too fast at " + data[i].format);
|
|
|
- } else if(speed[i] > 2) {
|
|
|
- timeMovement += timeDiff[i];
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- function bindInfoWindow(path, map, infoWindow, html) {
|
|
|
- google.maps.event.addListener(path, 'click', function(e) {
|
|
|
- infoWindow.setContent(html);
|
|
|
- console.log(e);
|
|
|
- infoWindow.setPosition(e.latLng);
|
|
|
- infoWindow.open(map);
|
|
|
- });
|
|
|
- google.maps.event.addListener(path, 'mouseover', function() {
|
|
|
- path.setOptions({
|
|
|
- zIndex: 2,
|
|
|
- strokeWeight: 6
|
|
|
- });
|
|
|
- });
|
|
|
- google.maps.event.addListener(path, 'mouseout', function() {
|
|
|
- setTimeout(function() {
|
|
|
- path.setOptions({
|
|
|
- zIndex: 1,
|
|
|
- strokeWeight: 4
|
|
|
- });
|
|
|
- }, 1000);
|
|
|
- });
|
|
|
- }
|
|
|
- function addInfo(geocoder, map, id, data, dist) {
|
|
|
- geocoder.geocode({'location': data}, function(results, status) {
|
|
|
- if (status === 'OK') {
|
|
|
- if (results[3]) {
|
|
|
-
|
|
|
- $('#info').append("<div class='info' id='info_" + id + "'>" +
|
|
|
- data.format.substring(3, 10) + "<br>" +
|
|
|
- results[3].formatted_address + "<br><b>" +
|
|
|
- (dist/1000).toFixed(1) + " km</b></div>");
|
|
|
-
|
|
|
- $('#info_'+id).click(function() {
|
|
|
- map.panTo(data);
|
|
|
- map.setZoom(12);
|
|
|
- });
|
|
|
- } else {
|
|
|
- console.log('No results found');
|
|
|
- }
|
|
|
- } else {
|
|
|
- console.log('Geocoder failed due to: ' + status);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- function getRandomColor(i) {
|
|
|
-
|
|
|
- var color = '#';
|
|
|
- for (var i = 0; i < 6; i++ ) {
|
|
|
- color += letters[Math.floor(Math.random() * 13)];
|
|
|
- }
|
|
|
- return color;*/
|
|
|
- return "hsl(" + ((i*57) % 256) + ", 80%, 50%)";
|
|
|
- }
|
|
|
- function distance (lat1, lon1, lat2, lon2) {
|
|
|
-
|
|
|
-
|
|
|
- lat1 = lat1 * Math.PI / 180.0;
|
|
|
- lon1 = lon1 * Math.PI / 180.0;
|
|
|
-
|
|
|
- lat2 = lat2 * Math.PI / 180.0;
|
|
|
- lon2 = lon2 * Math.PI / 180.0;
|
|
|
-
|
|
|
-
|
|
|
- var r = 6378100;
|
|
|
-
|
|
|
-
|
|
|
- var rho1 = r * Math.cos(lat1);
|
|
|
- var z1 = r * Math.sin(lat1);
|
|
|
- var x1 = rho1 * Math.cos(lon1);
|
|
|
- var y1 = rho1 * Math.sin(lon1);
|
|
|
-
|
|
|
-
|
|
|
- var rho2 = r * Math.cos(lat2);
|
|
|
- var z2 = r * Math.sin(lat2);
|
|
|
- var x2 = rho2 * Math.cos(lon2);
|
|
|
- var y2 = rho2 * Math.sin(lon2);
|
|
|
-
|
|
|
-
|
|
|
- var dot = (x1 * x2 + y1 * y2 + z1 * z2);
|
|
|
- var cos_theta = dot / (r * r);
|
|
|
-
|
|
|
- var theta = Math.acos(cos_theta);
|
|
|
-
|
|
|
-
|
|
|
- return r * theta;
|
|
|
- }
|
|
|
-
|
|
|
- function timeFormat (sec) {
|
|
|
- return new Date(null,null,null,null,null,sec).toTimeString().match(/\d{2}:\d{2}:\d{2}/)[0];
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- </script>
|
|
|
- </head>
|
|
|
-
|
|
|
- <body onload="load()" style="margin: 0; padding: 0;">
|
|
|
- <div id="map" style="width: 800px; height: 800px"></div>
|
|
|
- <div id="info" style="position:absolute; bottom:0; left:0;width:100%;overflow-x:auto;white-space: nowrap">
|
|
|
- <div class="info">
|
|
|
- <form method="post" enctype="multipart/form-data" action='gps_insert.php'>
|
|
|
- <input type="file" name="my_file[]" multiple><br>
|
|
|
- <input type="submit" value="Upload">
|
|
|
- </form>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </body>
|
|
|
-
|
|
|
-</html>
|