Highlight route on hover and show start and end timestamps in popup

This commit is contained in:
Eugene Burmakin 2024-05-30 11:50:12 +02:00
parent a90d6f1f39
commit 5e4e686492
5 changed files with 57 additions and 42 deletions

View file

@ -26,26 +26,12 @@ class ExportController < ApplicationController
def start_at def start_at
first_point_timestamp = current_user.tracked_points.order(timestamp: :asc)&.first&.timestamp first_point_timestamp = current_user.tracked_points.order(timestamp: :asc)&.first&.timestamp
@start_at ||= @start_at ||= first_point_timestamp || 1.month.ago.to_i
if params[:start_at].nil? && first_point_timestamp.present?
first_point_timestamp
elsif params[:start_at].nil?
1.month.ago.to_i
else
Time.zone.parse(params[:start_at]).to_i
end
end end
def end_at def end_at
last_point_timestamp = current_user.tracked_points.order(timestamp: :desc)&.last&.timestamp last_point_timestamp = current_user.tracked_points.order(timestamp: :asc)&.last&.timestamp
@end_at ||= @end_at ||= last_point_timestamp || Time.current.to_i
if params[:end_at].nil? && last_point_timestamp.present?
last_point_timestamp
elsif params[:end_at].nil?
Time.zone.now.to_i
else
Time.zone.parse(params[:end_at]).to_i
end
end end
end end

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapController < ApplicationController class MapController < ApplicationController
before_action :authenticate_user! before_action :authenticate_user!

View file

@ -27,22 +27,47 @@ export default class extends Controller {
const dLat = toRad(lat2 - lat1); const dLat = toRad(lat2 - lat1);
const dLon = toRad(lon2 - lon1); const dLon = toRad(lon2 - lon1);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2); Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c * 1000; // Distance in meters return R * c * 1000; // Distance in meters
} }
function addHighlightOnHover(polyline, map, popupContent) {
// Define the original and highlight styles
const originalStyle = { color: 'blue', opacity: 0.6, weight: 3 };
const highlightStyle = { color: 'yellow', opacity: 1, weight: 5 };
// Apply original style to the polyline initially
polyline.setStyle(originalStyle);
// Add mouseover event to highlight the polyline and show the popup
polyline.on('mouseover', function(e) {
polyline.setStyle(highlightStyle);
var popup = L.popup()
.setLatLng(e.latlng)
.setContent(popupContent)
.openOn(map);
});
// Add mouseout event to revert the polyline style and close the popup
polyline.on('mouseout', function(e) {
polyline.setStyle(originalStyle);
map.closePopup();
});
}
var splitPolylines = []; var splitPolylines = [];
var currentPolyline = []; var currentPolyline = [];
// Process markers and split polylines based on the distance // Process markers and split polylines based on the distance
for (let i = 0, len = markers.length; i < len; i++) { for (let i = 0, len = markers.length; i < len; i++) {
if (currentPolyline.length === 0) { if (currentPolyline.length === 0) {
currentPolyline.push(markers[i].slice(0, 2)); currentPolyline.push(markers[i]);
} else { } else {
var lastPoint = currentPolyline[currentPolyline.length - 1]; var lastPoint = currentPolyline[currentPolyline.length - 1];
var currentPoint = markers[i].slice(0, 2); var currentPoint = markers[i];
var distance = haversineDistance(lastPoint[0], lastPoint[1], currentPoint[0], currentPoint[1]); var distance = haversineDistance(lastPoint[0], lastPoint[1], currentPoint[0], currentPoint[1]);
if (distance > 500) { if (distance > 500) {
@ -58,24 +83,39 @@ export default class extends Controller {
splitPolylines.push(currentPolyline); splitPolylines.push(currentPolyline);
} }
// Batch adding polylines to the map // Assuming each polylineCoordinates is an array of objects with lat, lng, and timestamp properties
var polylineLayers = splitPolylines.map(polylineCoordinates => var polylineLayers = splitPolylines.map(polylineCoordinates => {
L.polyline(polylineCoordinates, { color: 'blue', opacity: 0.6, weight: 3 }) // Extract lat-lng pairs for the polyline
); var latLngs = polylineCoordinates.map(point => [point[0], point[1]]);
// Create a polyline with the given coordinates
var polyline = L.polyline(latLngs, { color: 'blue', opacity: 0.6, weight: 3 });
// Get the timestamps of the first and last points
var firstTimestamp = this.formatDate(polylineCoordinates[0][4]);
var lastTimestamp = this.formatDate(polylineCoordinates[polylineCoordinates.length - 1][4])
// Create the popup content
var popupContent = `Route started: ${firstTimestamp}<br>Route ended: ${lastTimestamp}`;
addHighlightOnHover(polyline, map, popupContent);
return polyline;
});
var polylinesLayer = L.layerGroup(polylineLayers).addTo(map); var polylinesLayer = L.layerGroup(polylineLayers).addTo(map);
var heatmapLayer = L.heatLayer(heatmapMarkers, { radius: 20 }).addTo(map); var heatmapLayer = L.heatLayer(heatmapMarkers, { radius: 20 }).addTo(map);
var controlsLayer = { var controlsLayer = {
"Points": markersLayer, "Points": markersLayer,
"Polylines": L.layerGroup(polylinesLayer), "Polylines": L.layerGroup(polylineLayers).addTo(map),
"Heatmap": heatmapLayer "Heatmap": heatmapLayer
}; };
L.control.layers(this.baseMaps(), controlsLayer).addTo(map); L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
this.addTileLayer(map); this.addTileLayer(map);
// markersLayer.addTo(map);
this.addLastMarker(map, markers); this.addLastMarker(map, markers);
} }
@ -153,20 +193,6 @@ export default class extends Controller {
}).addTo(map); }).addTo(map);
} }
addMarkers(map, markers_data) {
var markers = []
for (var i = 0; i < markers_data.length; i++) {
var lat = markers_data[i][0];
var lon = markers_data[i][1];
var popupContent = this.popupContent(markers_data[i]);
var circleMarker = L.circleMarker([lat, lon], {radius: 4})
markers.push(circleMarker.bindPopup(popupContent).openPopup())
}
L.layerGroup(markers).addTo(map);
}
addPolyline(map, markers) { addPolyline(map, markers) {
var coordinates = markers.map(element => element.slice(0, 2)); var coordinates = markers.map(element => element.slice(0, 2));

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'rails_helper' require 'rails_helper'
RSpec.describe Owntracks::PointCreatingJob, type: :job do RSpec.describe Owntracks::PointCreatingJob, type: :job do

View file

@ -180,7 +180,7 @@ paths:
lat: 52.502397 lat: 52.502397
lon: 13.356718 lon: 13.356718
tid: Swagger tid: Swagger
tst: 1717017097 tst: 1717062606
servers: servers:
- url: http://{defaultHost} - url: http://{defaultHost}
variables: variables: