You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
5.8 KiB

  1. var map = L.map('map', { zoomControl: false }).setView([45.516, -122.660], 14, null, null, 24);
  2. var layer = L.esri.basemapLayer("Topographic");
  3. layer.maxZoom = 24;
  4. layer.maxNativeZoom = 24;
  5. layer.addTo(map);
  6. new L.Control.Zoom({ position: 'topleft' }).addTo(map);
  7. var geojsonLineOptions = {
  8. color: "#0033ff",
  9. weight: 4,
  10. opacity: 0.5
  11. };
  12. var startIcon = L.icon({
  13. iconUrl: '/assets/map-pin-start.png',
  14. iconSize: [18,28],
  15. iconAnchor: [9,28]
  16. });
  17. var endIcon = L.icon({
  18. iconUrl: '/assets/map-pin-end.png',
  19. iconSize: [18,28],
  20. iconAnchor: [9,28]
  21. });
  22. var visible_layers = [];
  23. var visible_data = [];
  24. var highlightedMarker;
  25. var animatedMarker;
  26. var startMarker;
  27. var endMarker;
  28. var timers = [];
  29. function pointFromGeoJSON(geo) {
  30. return L.latLng(geo[1], geo[0])
  31. }
  32. function resetAnimation() {
  33. if(animatedMarker) {
  34. map.removeLayer(animatedMarker);
  35. }
  36. if(timers.length > 0) {
  37. for(var i in timers) {
  38. clearTimeout(timers[i]);
  39. }
  40. }
  41. }
  42. function displayLineOnMap(response, options) {
  43. var data = response.linestring;
  44. if(data.coordinates && data.coordinates.length > 0) {
  45. // For any null coordinates, fill it in with the previous location
  46. var lastCoord = null;
  47. for(var i in data.coordinates) {
  48. if(data.coordinates[i] == null) {
  49. data.coordinates[i] = lastCoord;
  50. } else {
  51. lastCoord = data.coordinates[i];
  52. }
  53. }
  54. visible_data.push(data);
  55. visible_layers.push(L.geoJson(data, {
  56. style: geojsonLineOptions
  57. }).addTo(map));
  58. // Show the start/end pins if necessary
  59. if(options.pins) {
  60. startMarker = L.marker(pointFromGeoJSON(visible_data[0].coordinates[0]), {icon: startIcon});
  61. startMarker.addTo(map);
  62. endMarker = L.marker(pointFromGeoJSON(visible_data[0].coordinates[ visible_data[0].coordinates.length-1 ]), {icon: endIcon});
  63. endMarker.addTo(map);
  64. }
  65. // If the new layer is completely outside the current view, zoom the map to fit all layers
  66. var vlayer = visible_layers[visible_layers.length - 1];
  67. var is_outside = false;
  68. if(!map.getBounds().intersects(vlayer.getBounds())) {
  69. is_outside = true;
  70. }
  71. if(is_outside) {
  72. console.log('is outside');
  73. console.log(vlayer);
  74. var full_bounds;
  75. for(var i in visible_layers) {
  76. if(visible_layers[i].getBounds) {
  77. if(full_bounds) {
  78. full_bounds.extend(visible_layers[i].getBounds());
  79. } else {
  80. full_bounds = visible_layers[i].getBounds();
  81. }
  82. }
  83. }
  84. map.fitBounds(full_bounds);
  85. }
  86. showBatteryGraph(response);
  87. }
  88. }
  89. jQuery(function($){
  90. $('.calendar a').click(function(evt){
  91. var append = evt.altKey;
  92. if(!append) {
  93. removeVisibleLayers();
  94. }
  95. $(this).addClass('selected');
  96. resetAnimation();
  97. var db_name = $("#database").data("name");
  98. var db_token = $("#database").data("token");
  99. $.get("/api/query?format=linestring&date="+$(this).data('date')+"&tz="+$("#timezone").val()+"&token="+db_token, function(data){
  100. displayLineOnMap(data, {pins: false});
  101. });
  102. $("#range-from").val($(this).data('date')+' 00:00:00');
  103. $("#range-to").val($(this).data('date')+' 23:59:59');
  104. return false;
  105. });
  106. $('#range-go').click(function(evt) {
  107. var stateObj = {from: $('#range-from').val(), to: $('#range-to').val(), tz: $('#timezone').val()};
  108. var baseURL = "/map/" + $("#database").data('name');
  109. var historyURL = baseURL + "?from="+stateObj.from+"&to="+stateObj.to+"&tz="+stateObj.tz;
  110. window.history.pushState(stateObj, "GPS Log", historyURL)
  111. resetAnimation();
  112. removeVisibleLayers();
  113. $("#range-go").addClass("loading");
  114. var db_token = $("#database").data("token");
  115. $.get("/api/query?format=linestring&start="+$('#range-from').val()+"&end="+$('#range-to').val()+"&tz="+$("#timezone").val()+"&token="+db_token, function(data){
  116. $("#range-go").removeClass("loading");
  117. $("#trip-create-form").removeClass("hidden");
  118. displayLineOnMap(data, {pins: true});
  119. });
  120. return false;
  121. })
  122. $('#btn-play').click(function(){
  123. console.log(visible_data[0].coordinates[0]);
  124. var point = pointFromGeoJSON(visible_data[0].coordinates[0]);
  125. resetAnimation();
  126. animatedMarker = L.marker(point);
  127. animatedMarker.addTo(map);
  128. timers = [];
  129. var interval = 3;
  130. for(var i in visible_data[0].coordinates) {
  131. (function(i){
  132. timers.push(setTimeout(function(){
  133. point = pointFromGeoJSON(visible_data[0].coordinates[i]);
  134. animatedMarker.setLatLng(point);
  135. }, interval*i));
  136. })(i);
  137. }
  138. });
  139. $("#trip-create").click(function(){
  140. $("#trip-create").addClass("loading");
  141. $.post('/api/trip-complete', {
  142. start: $("#range-from").val(),
  143. end: $("#range-to").val(),
  144. tz: $("#timezone").val(),
  145. mode: $("#trip-mode").val(),
  146. token: $("#database").data("write-token")
  147. }, function(response) {
  148. $("#trip-create").removeClass("loading");
  149. });
  150. });
  151. if($("#range-from").val() == "") {
  152. console.log("Autoselecting calendar day");
  153. $(".calendar a[data-date="+((new Date()).toISOString().slice(0,10))+"]").focus().click();
  154. } else {
  155. console.log("Loading range");
  156. $("#range-go").click();
  157. }
  158. });
  159. function removeVisibleLayers() {
  160. $('.calendar a').removeClass('selected');
  161. if(visible_layers.length) {
  162. for(var i in visible_layers) {
  163. map.removeLayer(visible_layers[i]);
  164. }
  165. }
  166. visible_layers = [];
  167. visible_data = [];
  168. if(startMarker) {
  169. map.removeLayer(startMarker);
  170. map.removeLayer(endMarker);
  171. }
  172. }
  173. function moveMarkerToPosition(point) {
  174. if(point.location) {
  175. var coord = pointFromGeoJSON(point.location);
  176. if(coord) {
  177. if(!highlightedMarker) {
  178. highlightedMarker = L.marker(coord).addTo(map);
  179. } else {
  180. highlightedMarker.setLatLng(coord);
  181. }
  182. }
  183. }
  184. }
  185. function pointFromGeoJSON(geo) {
  186. return L.latLng(geo[1], geo[0])
  187. }