From 2c66e59f9054a8c2797bcf287500011bad110fd6 Mon Sep 17 00:00:00 2001 From: Aaron Parecki Date: Sat, 6 Feb 2016 10:52:51 -0800 Subject: [PATCH] adds date range fields to map view --- compass/app/Http/Controllers/Api.php | 3 + compass/app/Http/Controllers/Controller.php | 5 +- compass/public/assets/map-pin-end.png | Bin 0 -> 1455 bytes compass/public/assets/map-pin-start.png | Bin 0 -> 1559 bytes compass/public/assets/map.js | 172 +++++++++++++------- compass/public/assets/styles.css | 14 ++ compass/resources/views/map.blade.php | 9 + 7 files changed, 146 insertions(+), 57 deletions(-) create mode 100644 compass/public/assets/map-pin-end.png create mode 100644 compass/public/assets/map-pin-start.png 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 0000000000000000000000000000000000000000..e164cd89d66700b12d4c02824c8e9fe3383686ab GIT binary patch literal 1455 zcmb7EZA{d57%y7}h(iZqb8}?Y${Z4|Z}--A9B^Fk#yO6ce}O|j7?L$@|1W)h zzvuZq&+~6bY4ID$N$Zm!2ugMrvR*Kzf+syO9=sdR-FXcRFKNyStz4?pBAmiQ_JCB& z!|pH_XxVXr&w-$)j|;vEt-@2p_@yw)={9IIECVzI<>WqGF z#3=+80ybp3*@Jsz2Okm&TNS>%wbuPbut>6dpFCMuQ(G2-spl36t4kA+li-CrAtjx5Yr17_)^Tt?=T7 z0B=g5j`6atMPFcLLqeJ+GZ+?$M9_#4m6RYx&@`=ckfZ@v7}OR~0PbbT?D$Fnjb9A2_k zH81}-_$TtKz80Csyu2zkDSlAJx=qVmt?WoQT-3mLIHiFHRdjKUDnI|h<6%lb@Pf!S zvXZ|k%!`_vwINMSLVzJ%Mv8VgEEGu^ouD>UfyqocaTDpXn~ip>IYzJ?2z;RdfOQoV zPz2?2(zKB#2&b90(+?pUunI6tBi2BABz1V;qh-G<2XyyYhMGC|7d1r(tM1a#2&}%i}RuZ>R zK)Kz*QiRoIG7@$xO915y*ueiz83rQ3^gdhGcd;$d%=&cc6oJLkIpjr9HU*rr8-%(W zg5o}Nvvyzf%HY0JZ=TIhJC7aO0}rifr}`6-{*R_I+8yic!Mk~~tTs<%)!NTZzE{}O z`E}35{_elW3LIS~12VrDF%dT4)1_3ziwpRdghmY#{bJ)ZjF^xe(< zZLiD8zs>ZJhZ3*fUL`;KRl$bJx|jcIyE>GaINJBj)UK424WH&jRv(z#me$OkojT)1 zM&Px#re5i5i;s+bdo!;}PJH3dV_h33FXnu?{fDlDaSgspN!|9n+1tv>a6|X`w2pZ1 zb6wq;MfUr}eV5Z%EF1Z7>>a2W zocf}wt9V8|Ha(DaVd5rh`Tn1Y`l7zN@ub#z^X9VQ!O`k(9&X(E$yTP`Je*%`tcJ|L z+R%eYd}lBE?lr?2^~j?mogc?j-hrc^&z`tX-x{N%vva+de<>P|n}mWjl_OqdE)j>) WhkH)$E=|9x|3cl)Vs@yYru{!>j{vd& literal 0 HcmV?d00001 diff --git a/compass/public/assets/map-pin-start.png b/compass/public/assets/map-pin-start.png new file mode 100644 index 0000000000000000000000000000000000000000..3e927f87b582136438bbfe397dc0d232b69a1e18 GIT binary patch literal 1559 zcmb7EeM}Q)7{7%@91A+JbSe@r^<(Iuch~PbT1n}((n$pi3Uex6+ZVXe-gS3}txV!j zP%8-=I)}~;qfsGBV7g6>io(WZo7=)9ev2{AO)?k3_%WGg?mYzb4`Z^+-Mt_8{C>~# zd!FaLNcOxru`!ck5Cn;JX3%ap#=&Ru=uzV<+Rx_ZOZl!$%F74TjBKM02Z9idAm+4iknxrP3H5*?mb0k(j-F7V ztk0s#)4On2&<2Xxj4}b_l+DZamX&x(pDJxOY7SG7AOIu=4F~+3NQEt`L0$^Z8%!{Kd6A#{}9KxvHV(4~Uj z1YaTLrX54R;L4&ZmZTtsVWCh+9nz|Kp$H>Ll9V|#niOb}BCg;hCY-{FQ->L7AbJHh zD6u?;%8ZPMFO@7R80ixUfuNf$Dwf0%a!wpd7EBu!W`Y=@#xY^gM%Fisa=BiN2n0r~ zMad1G2LD`sF?U4}U~VAtrGgh$v2f}$u3qd&HXPDGxfr1Yz$!WzzX%3DxLi~g44&l} zKh1kf1Avp9v_(}~%K9jcLu(>!HiJo{(b{2cOzAqk$&TwZ4y#^kHR^{6o&`c*Y9GWp z($h_Z$zdf)ElCh|J!vIvkjtjg*=dr*O~Y6xCrS+G1+r5a%Ra@z%Dn(f*#y8yypYTD z{^4%QF6Jd(Earo#EysW+xfn0Y$s04}VncQ)mIea59QYgpA3z85PO;C404GgQuTh5^ zHMqe9m0Jz8i7+~JTEc3i38?%D*7v_thQUZMxzC>IyWuU^%<^>P6v4&FIRqRmn*dK) z-CKu`BgjjSoU}DJeDUKm)(pk`32nD;;B`qm(cagR6Qzji`!R{fGP)S7qJBDG+JD`C zL?X^tFQS)^Zh70;v@firUcP2s{N1+7hBj~I+AsI?-FtkQ?66|_DABAuQsg8`RlVgEf4#Z`tdcNPU;ks8^+fv+++LW^;liQ zh8ZVMFZQPk+IG~vTKllzH_!E^qmgkFvQ|@j zx2!w$)5BYyqyxXq{$~1?56aE$$XW61`p(*~?~loR{pN(Wr2A2K4(;lyimR&pHad5H zXRR?W0xHOY$=9YgdoslnyShFUl^Y8lDau+e*DDrzuig#KR~))MW^9yL;_gjYqr7!P zad@rMyeV%M{y3pvSJx|RCa(N3dHuaVsAh#Ui|?pWY^)wNqpM|8y#MC8nK9(JE8ENW zS}bqgjqYBWw|Qg2iN;Hw(>2pR(OoDwkg@Zf(-+otud0eGZ`wXr`R<+`U#g}oJD@bT z>uMfx=~Zz(`?w`313i^7n=kB}cFA?4ad);Op}S(`-pE43ls}Won|8EPXIuU)pvmYn zL}ApxsDtT$)53=9`5n!no|BnZ{%O3rEUhh}??}Z$I6w9HocZ|82Md0^cs_p0N6}ll gwT%nD>Tf}!kTtPA1Ln_5vgBX2(>{-GPG7eAKmJ8RBme*a literal 0 HcmV?d00001 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') +
+
+
+
+
+ +
+
+