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
first_point_timestamp = current_user.tracked_points.order(timestamp: :asc)&.first&.timestamp
@start_at ||=
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
@start_at ||= first_point_timestamp || 1.month.ago.to_i
end
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 ||=
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_at ||= last_point_timestamp || Time.current.to_i
end
end

View file

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

View file

@ -27,22 +27,47 @@ export default class extends Controller {
const dLat = toRad(lat2 - lat1);
const dLon = toRad(lon2 - lon1);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLon / 2) * Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
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 currentPolyline = [];
// Process markers and split polylines based on the distance
for (let i = 0, len = markers.length; i < len; i++) {
if (currentPolyline.length === 0) {
currentPolyline.push(markers[i].slice(0, 2));
currentPolyline.push(markers[i]);
} else {
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]);
if (distance > 500) {
@ -58,24 +83,39 @@ export default class extends Controller {
splitPolylines.push(currentPolyline);
}
// Batch adding polylines to the map
var polylineLayers = splitPolylines.map(polylineCoordinates =>
L.polyline(polylineCoordinates, { color: 'blue', opacity: 0.6, weight: 3 })
);
// Assuming each polylineCoordinates is an array of objects with lat, lng, and timestamp properties
var polylineLayers = splitPolylines.map(polylineCoordinates => {
// 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 heatmapLayer = L.heatLayer(heatmapMarkers, { radius: 20 }).addTo(map);
var controlsLayer = {
"Points": markersLayer,
"Polylines": L.layerGroup(polylinesLayer),
"Polylines": L.layerGroup(polylineLayers).addTo(map),
"Heatmap": heatmapLayer
};
L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
this.addTileLayer(map);
// markersLayer.addTo(map);
this.addLastMarker(map, markers);
}
@ -153,20 +193,6 @@ export default class extends Controller {
}).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) {
var coordinates = markers.map(element => element.slice(0, 2));

View file

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

View file

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