mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 01:31:39 -05:00
Update hovering over route to show time and distance to next and previous routes
This commit is contained in:
parent
4962d48910
commit
fe73b5040a
4 changed files with 75 additions and 21 deletions
|
|
@ -5,13 +5,15 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [0.4.3] — 2024-05-30
|
||||
## [0.4.3] — 2024-05-31
|
||||
|
||||
### Added
|
||||
|
||||
- Now user can hover on route and see when it started, when it ended and how much time it took to travel
|
||||
- New buttons to quickly move to today's, yesterday's and 7 days data on the map
|
||||
- "Download JSON" button to points page
|
||||
- For debugging purposes, now user can use `?meters_between_routes=500` and `?minutes_between_routes=60` query parameters to set the distance and time between routes to split them on the map. This is useful to understand why routes might not be connected on the map.
|
||||
- Added scale indicator to the map
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
@ -21,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
### Changed
|
||||
|
||||
- Removed "Your data" page as its function was replaced by "Download JSON" button on the points page
|
||||
- Hovering over a route now also shows time and distance to next route as well as time and distance to previous route. This allows user to understand why routes might not be connected on the map.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -13,3 +13,9 @@
|
|||
*= require_tree .
|
||||
*= require_self
|
||||
*/
|
||||
|
||||
.emoji-icon {
|
||||
font-size: 36px; /* Adjust size as needed */
|
||||
text-align: center;
|
||||
line-height: 36px; /* Same as font-size for perfect centering */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export default class extends Controller {
|
|||
var markers = JSON.parse(this.element.dataset.coordinates)
|
||||
var center = markers[markers.length - 1] || JSON.parse(this.element.dataset.center)
|
||||
var center = (center === undefined) ? [52.516667, 13.383333] : center;
|
||||
var timezone = this.element.dataset.timezone;
|
||||
|
||||
var map = L.map(this.containerTarget, {
|
||||
layers: [this.osmMapLayer(), this.osmHotMapLayer()]
|
||||
|
|
@ -33,7 +34,11 @@ export default class extends Controller {
|
|||
return R * c * 1000; // Distance in meters
|
||||
}
|
||||
|
||||
function addHighlightOnHover(polyline, map, popupContent) {
|
||||
function getURLParameter(name) {
|
||||
return new URLSearchParams(window.location.search).get(name);
|
||||
}
|
||||
|
||||
function addHighlightOnHover(polyline, map, startPoint, endPoint, prevPoint, nextPoint, timezone) {
|
||||
// Define the original and highlight styles
|
||||
const originalStyle = { color: 'blue', opacity: 0.6, weight: 3 };
|
||||
const highlightStyle = { color: 'yellow', opacity: 1, weight: 5 };
|
||||
|
|
@ -41,24 +46,57 @@ export default class extends Controller {
|
|||
// Apply original style to the polyline initially
|
||||
polyline.setStyle(originalStyle);
|
||||
|
||||
// Add mouseover event to highlight the polyline and show the popup
|
||||
// Create the popup content for the route
|
||||
var firstTimestamp = new Date(startPoint[4] * 1000).toLocaleString('en-GB', { timeZone: timezone });
|
||||
var lastTimestamp = new Date(endPoint[4] * 1000).toLocaleString('en-GB', { timeZone: timezone });
|
||||
var timeOnRoute = Math.round((endPoint[4] - startPoint[4]) / 60); // Time in minutes
|
||||
|
||||
// Calculate distances to previous and next points
|
||||
var distanceToPrev = prevPoint ? haversineDistance(prevPoint[0], prevPoint[1], startPoint[0], startPoint[1]) : 'N/A';
|
||||
var distanceToNext = nextPoint ? haversineDistance(endPoint[0], endPoint[1], nextPoint[0], nextPoint[1]) : 'N/A';
|
||||
|
||||
// Calculate time between routes
|
||||
var timeBetweenPrev = prevPoint ? Math.round((startPoint[4] - prevPoint[4]) / 60) : 'N/A';
|
||||
var timeBetweenNext = nextPoint ? Math.round((nextPoint[4] - endPoint[4]) / 60) : 'N/A';
|
||||
|
||||
// Create custom emoji icons
|
||||
const startIcon = L.divIcon({ html: '🚥', className: 'emoji-icon' });
|
||||
const finishIcon = L.divIcon({ html: '🏁', className: 'emoji-icon' });
|
||||
|
||||
// Create markers for the start and end points
|
||||
const startMarker = L.marker([startPoint[0], startPoint[1]], { icon: startIcon }).bindPopup(`Start: ${firstTimestamp}`);
|
||||
|
||||
const endMarker = L.marker([endPoint[0], endPoint[1]], { icon: finishIcon }).bindPopup(`
|
||||
Start: ${firstTimestamp}<br>
|
||||
End: ${lastTimestamp}<br>
|
||||
Time on route: ${timeOnRoute} minutes<br>
|
||||
Distance to previous route: ${Math.round(distanceToPrev)} meters<br>
|
||||
Distance to next route: ${Math.round(distanceToNext)} meters<br>
|
||||
Time from previous route: ${timeBetweenPrev} minutes<br>
|
||||
Time to next route: ${timeBetweenNext} minutes
|
||||
`);
|
||||
|
||||
// Add mouseover event to highlight the polyline and show the start and end markers
|
||||
polyline.on('mouseover', function(e) {
|
||||
polyline.setStyle(highlightStyle);
|
||||
var popup = L.popup()
|
||||
.setLatLng(e.latlng)
|
||||
.setContent(popupContent)
|
||||
.openOn(map);
|
||||
startMarker.addTo(map);
|
||||
endMarker.addTo(map).openPopup();
|
||||
});
|
||||
|
||||
// Add mouseout event to revert the polyline style and close the popup
|
||||
// Add mouseout event to revert the polyline style and remove the start and end markers
|
||||
polyline.on('mouseout', function(e) {
|
||||
polyline.setStyle(originalStyle);
|
||||
map.closePopup();
|
||||
polyline.setStyle(originalStyle);
|
||||
map.closePopup();
|
||||
map.removeLayer(startMarker);
|
||||
map.removeLayer(endMarker);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var splitPolylines = [];
|
||||
var currentPolyline = [];
|
||||
var distanceThresholdMeters = parseInt(getURLParameter('meters_between_routes')) || 500;
|
||||
var timeThresholdMinutes = parseInt(getURLParameter('minutes_between_routes')) || 60;
|
||||
|
||||
// Process markers and split polylines based on the distance and time
|
||||
for (let i = 0, len = markers.length; i < len; i++) {
|
||||
|
|
@ -70,7 +108,7 @@ export default class extends Controller {
|
|||
var distance = haversineDistance(lastPoint[0], lastPoint[1], currentPoint[0], currentPoint[1]);
|
||||
var timeDifference = (currentPoint[4] - lastPoint[4]) / 60; // Time difference in minutes
|
||||
|
||||
if (distance > 500 || timeDifference > 60) {
|
||||
if (distance > distanceThresholdMeters || timeDifference > timeThresholdMinutes) {
|
||||
splitPolylines.push([...currentPolyline]); // Use spread operator to clone the array
|
||||
currentPolyline = [currentPoint];
|
||||
} else {
|
||||
|
|
@ -84,22 +122,23 @@ export default class extends Controller {
|
|||
}
|
||||
|
||||
// Assuming each polylineCoordinates is an array of objects with lat, lng, and timestamp properties
|
||||
var polylineLayers = splitPolylines.map(polylineCoordinates => {
|
||||
var polylineLayers = splitPolylines.map((polylineCoordinates, index) => {
|
||||
// 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])
|
||||
var timeEnRoute = Math.round((polylineCoordinates[polylineCoordinates.length - 1][4] - polylineCoordinates[0][4]) / 60); // Time in minutes
|
||||
// Get the start and end points
|
||||
var startPoint = polylineCoordinates[0];
|
||||
var endPoint = polylineCoordinates[polylineCoordinates.length - 1];
|
||||
|
||||
// Create the popup content
|
||||
var popupContent = `Route started: ${firstTimestamp}<br>Route ended: ${lastTimestamp}<br>Time en route: ${timeEnRoute} minutes`;
|
||||
// Get the previous and next points
|
||||
var prevPoint = index > 0 ? splitPolylines[index - 1][splitPolylines[index - 1].length - 1] : null;
|
||||
var nextPoint = index < splitPolylines.length - 1 ? splitPolylines[index + 1][0] : null;
|
||||
|
||||
addHighlightOnHover(polyline, map, popupContent);
|
||||
// Add highlighting and popups on hover
|
||||
addHighlightOnHover(polyline, map, startPoint, endPoint, prevPoint, nextPoint, timezone);
|
||||
|
||||
return polyline;
|
||||
});
|
||||
|
|
@ -113,6 +152,13 @@ export default class extends Controller {
|
|||
"Heatmap": heatmapLayer
|
||||
};
|
||||
|
||||
L.control.scale({
|
||||
position: 'bottomright', // The default position is 'bottomleft'
|
||||
metric: true, // Display metric scale
|
||||
imperial: false, // Display imperial scale
|
||||
maxWidth: 120 // Maximum width of the scale control in pixels
|
||||
}).addTo(map);
|
||||
|
||||
L.control.layers(this.baseMaps(), controlsLayer).addTo(map);
|
||||
|
||||
this.addTileLayer(map);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
</summary>
|
||||
<ul class="p-2 bg-base-100 rounded-t-none z-10">
|
||||
<li><%= link_to 'Settings', edit_user_registration_path %></li>
|
||||
<li><%= link_to 'Your data', export_path %></li>
|
||||
<li><%= link_to 'Logout', destroy_user_session_path, method: :delete, data: { turbo_method: :delete } %></li>
|
||||
</ul>
|
||||
</details>
|
||||
|
|
|
|||
Loading…
Reference in a new issue