diff --git a/compass/app/Http/Controllers/Api.php b/compass/app/Http/Controllers/Api.php index b921beb..b23e1c6 100644 --- a/compass/app/Http/Controllers/Api.php +++ b/compass/app/Http/Controllers/Api.php @@ -45,6 +45,9 @@ class Api extends BaseController if($date=$request->input('date')) { $start = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 00:00:00', new DateTimeZone($tz)); $end = DateTime::createFromFormat('Y-m-d H:i:s', $date.' 23:59:59', new DateTimeZone($tz)); + } elseif(($start=$request->input('start')) && ($end=$request->input('end'))) { + $start = new DateTime($start, new DateTimeZone($tz)); + $end = new DateTime($end, new DateTimeZone($tz)); } else { return response(json_encode(['error' => 'no date provided']))->header('Content-Type', 'application/json'); } diff --git a/compass/app/Http/Controllers/Controller.php b/compass/app/Http/Controllers/Controller.php index 14f9612..9f87c29 100644 --- a/compass/app/Http/Controllers/Controller.php +++ b/compass/app/Http/Controllers/Controller.php @@ -93,7 +93,10 @@ class Controller extends BaseController 'database' => $db, 'menu' => [ '/settings/'.$name => 'Settings' - ] + ], + 'range_from' => $request->input('from') ?: '', + 'range_to' => $request->input('to') ?: '', + 'range_tz' => $request->input('tz') ?: 'America/Los_Angeles' ]); } diff --git a/compass/public/assets/map-pin-end.png b/compass/public/assets/map-pin-end.png new file mode 100644 index 0000000..e164cd8 Binary files /dev/null and b/compass/public/assets/map-pin-end.png differ diff --git a/compass/public/assets/map-pin-start.png b/compass/public/assets/map-pin-start.png new file mode 100644 index 0000000..3e927f8 Binary files /dev/null and b/compass/public/assets/map-pin-start.png differ diff --git a/compass/public/assets/map.js b/compass/public/assets/map.js index ea210f3..e956997 100644 --- a/compass/public/assets/map.js +++ b/compass/public/assets/map.js @@ -13,12 +13,29 @@ var geojsonLineOptions = { opacity: 0.5 }; +var startIcon = L.icon({ + iconUrl: '/assets/map-pin-start.png', + iconSize: [18,28], + iconAnchor: [9,28] +}); +var endIcon = L.icon({ + iconUrl: '/assets/map-pin-end.png', + iconSize: [18,28], + iconAnchor: [9,28] +}); + var visible_layers = []; var visible_data = []; var highlightedMarker; var animatedMarker; +var startMarker; +var endMarker; var timers = []; +function pointFromGeoJSON(geo) { + return L.latLng(geo[1], geo[0]) +} + function resetAnimation() { if(animatedMarker) { map.removeLayer(animatedMarker); @@ -30,20 +47,67 @@ function resetAnimation() { } } +function displayLineOnMap(response, options) { + var data = response.linestring; + + if(data.coordinates && data.coordinates.length > 0) { + // For any null coordinates, fill it in with the previous location + var lastCoord = null; + for(var i in data.coordinates) { + if(data.coordinates[i] == null) { + data.coordinates[i] = lastCoord; + } else { + lastCoord = data.coordinates[i]; + } + } + + visible_data.push(data); + visible_layers.push(L.geoJson(data, { + style: geojsonLineOptions + }).addTo(map)); + + // Show the start/end pins if necessary + if(options.pins) { + startMarker = L.marker(pointFromGeoJSON(visible_data[0].coordinates[0]), {icon: startIcon}); + startMarker.addTo(map); + endMarker = L.marker(pointFromGeoJSON(visible_data[0].coordinates[ visible_data[0].coordinates.length-1 ]), {icon: endIcon}); + endMarker.addTo(map); + } + + // If the new layer is completely outside the current view, zoom the map to fit all layers + var vlayer = visible_layers[visible_layers.length - 1]; + var is_outside = false; + if(!map.getBounds().intersects(vlayer.getBounds())) { + is_outside = true; + } + + if(is_outside) { + console.log('is outside'); + console.log(vlayer); + var full_bounds; + for(var i in visible_layers) { + if(visible_layers[i].getBounds) { + if(full_bounds) { + full_bounds.extend(visible_layers[i].getBounds()); + } else { + full_bounds = visible_layers[i].getBounds(); + } + } + } + map.fitBounds(full_bounds); + } + + showBatteryGraph(response); + } +} + jQuery(function($){ $('.calendar a').click(function(evt){ var append = evt.altKey; if(!append) { - $('.calendar a').removeClass('selected'); - if(visible_layers.length) { - for(var i in visible_layers) { - map.removeLayer(visible_layers[i]); - } - } - visible_layers = []; - visible_data = []; + removeVisibleLayers(); } $(this).addClass('selected'); @@ -52,55 +116,32 @@ jQuery(function($){ var db_name = $("#database").data("name"); var db_token = $("#database").data("token"); - $.get("/api/query?format=linestring&date="+$(this).data('date')+"&tz=America/Los_Angeles&token="+db_token, function(response){ - var data = response.linestring; - - if(data.coordinates && data.coordinates.length > 0) { - // For any null coordinates, fill it in with the previous location - var lastCoord = null; - for(var i in data.coordinates) { - if(data.coordinates[i] == null) { - data.coordinates[i] = lastCoord; - } else { - lastCoord = data.coordinates[i]; - } - } - - visible_data.push(data); - visible_layers.push(L.geoJson(data, { - style: geojsonLineOptions - }).addTo(map)); - - // If the new layer is completely outside the current view, zoom the map to fit all layers - var vlayer = visible_layers[visible_layers.length - 1]; - var is_outside = false; - if(!map.getBounds().intersects(vlayer.getBounds())) { - is_outside = true; - } - - if(is_outside) { - console.log('is outside'); - console.log(vlayer); - var full_bounds; - for(var i in visible_layers) { - if(visible_layers[i].getBounds) { - if(full_bounds) { - full_bounds.extend(visible_layers[i].getBounds()); - } else { - full_bounds = visible_layers[i].getBounds(); - } - } - } - map.fitBounds(full_bounds); - } - - showBatteryGraph(response); - } + $.get("/api/query?format=linestring&date="+$(this).data('date')+"&tz="+$("#timezone").val()+"&token="+db_token, function(data){ + displayLineOnMap(data, {pins: false}); }); + $("#range-from").val($(this).data('date')+' 00:00:00'); + $("#range-to").val($(this).data('date')+' 23:59:59'); return false; }); - + + $('#range-go').click(function(evt) { + var stateObj = {from: $('#range-from').val(), to: $('#range-to').val(), tz: $('#timezone').val()}; + var baseURL = "/map/" + $("#database").data('name'); + var historyURL = baseURL + "?from="+stateObj.from+"&to="+stateObj.to+"&tz="+stateObj.tz; + window.history.pushState(stateObj, "GPS Log", historyURL) + resetAnimation(); + removeVisibleLayers(); + + $("#range-go").addClass("loading"); + var db_token = $("#database").data("token"); + $.get("/api/query?format=linestring&start="+$('#range-from').val()+"&end="+$('#range-to').val()+"&tz="+$("#timezone").val()+"&token="+db_token, function(data){ + $("#range-go").removeClass("loading"); + displayLineOnMap(data, {pins: true}); + }); + return false; + }) + $('#btn-play').click(function(){ console.log(visible_data[0].coordinates[0]); var point = pointFromGeoJSON(visible_data[0].coordinates[0]); @@ -121,13 +162,33 @@ jQuery(function($){ }, interval*i)); })(i); } - }); - $(".calendar a[data-date='"+((new Date()).toISOString().slice(0,10))+"']").focus().click(); + if($("#range-from").val() == "") { + console.log("Autoselecting calendar day"); + $(".calendar a[data-date="+((new Date()).toISOString().slice(0,10))+"]").focus().click(); + } else { + console.log("Loading range"); + $("#range-go").click(); + } }); +function removeVisibleLayers() { + $('.calendar a').removeClass('selected'); + if(visible_layers.length) { + for(var i in visible_layers) { + map.removeLayer(visible_layers[i]); + } + } + visible_layers = []; + visible_data = []; + if(startMarker) { + map.removeLayer(startMarker); + map.removeLayer(endMarker); + } +} + function moveMarkerToPosition(point) { if(point.location) { var coord = pointFromGeoJSON(point.location); @@ -144,4 +205,3 @@ function moveMarkerToPosition(point) { function pointFromGeoJSON(geo) { return L.latLng(geo[1], geo[0]) } - diff --git a/compass/public/assets/styles.css b/compass/public/assets/styles.css index 2912b7a..12a6376 100644 --- a/compass/public/assets/styles.css +++ b/compass/public/assets/styles.css @@ -77,3 +77,17 @@ .hidden { display: none; } + +#daterange { + z-index: 100; + width: 40vw; + position: absolute; + top: 60px; + left: 60px; + border: 3px #aaa solid; + border-radius: 4px; + background: white; +} +#daterange .in { + margin: 4px; +} diff --git a/compass/resources/views/map.blade.php b/compass/resources/views/map.blade.php index cc66af4..fcdd7cd 100644 --- a/compass/resources/views/map.blade.php +++ b/compass/resources/views/map.blade.php @@ -4,6 +4,15 @@ @include('partials/logged-in') +
+
+
+
+
+ +
+
+