Highlight routes again

This commit is contained in:
Eugene Burmakin 2025-01-19 17:49:11 +01:00
parent 94e08d56e1
commit 64b141fa24
2 changed files with 130 additions and 52 deletions

View file

@ -170,51 +170,54 @@ export function addHighlightOnHover(polylineGroup, map, polylineCoordinates, use
let hoverPopup = null; let hoverPopup = null;
polylineGroup.on("mouseover", function (e) { // Add events to both group and individual polylines
let closestSegment = null; polylineGroup.eachLayer((layer) => {
let minDistance = Infinity; if (layer instanceof L.Polyline) {
let currentSpeed = 0; layer.on("mouseover", function (e) {
console.log("Individual polyline mouseover", e);
handleMouseOver(e);
});
polylineGroup.eachLayer((layer) => { layer.on("mouseout", function (e) {
if (layer instanceof L.Polyline) { console.log("Individual polyline mouseout", e);
const layerLatLngs = layer.getLatLngs(); handleMouseOut(e);
const distance = pointToLineDistance(e.latlng, layerLatLngs[0], layerLatLngs[1]); });
}
});
if (distance < minDistance) { function handleMouseOver(e) {
minDistance = distance; console.log('Individual polyline mouseover', e);
closestSegment = layer;
const startIdx = polylineCoordinates.findIndex(p => { // Handle both direct layer events and group propagated events
const latMatch = Math.abs(p[0] - layerLatLngs[0].lat) < 0.0000001; const layer = e.layer || e.target;
const lngMatch = Math.abs(p[1] - layerLatLngs[0].lng) < 0.0000001; let speed = 0;
return latMatch && lngMatch;
});
if (startIdx !== -1 && startIdx < polylineCoordinates.length - 1) { if (layer instanceof L.Polyline) {
currentSpeed = calculateSpeed( // Get the coordinates array from the layer
polylineCoordinates[startIdx], const coords = layer.getLatLngs();
polylineCoordinates[startIdx + 1] if (coords && coords.length >= 2) {
); const startPoint = coords[0];
} const endPoint = coords[coords.length - 1];
// Find the corresponding markers for these coordinates
const startMarkerData = polylineCoordinates.find(m =>
m[0] === startPoint.lat && m[1] === startPoint.lng
);
const endMarkerData = polylineCoordinates.find(m =>
m[0] === endPoint.lat && m[1] === endPoint.lng
);
// Calculate speed if we have both markers
if (startMarkerData && endMarkerData) {
speed = startMarkerData[5] || endMarkerData[5] || 0;
} }
} }
}); }
// Apply highlight style to all segments layer.setStyle({
polylineGroup.eachLayer((layer) => { weight: 8,
if (layer instanceof L.Polyline) { opacity: 0.8,
const highlightStyle = { color: '#FFD700'
weight: 5,
opacity: 1
};
// Only change color to yellow if speed colors are disabled
if (!userSettings.speed_colored_routes) {
highlightStyle.color = '#ffff00';
}
layer.setStyle(highlightStyle);
}
}); });
startMarker.addTo(map); startMarker.addTo(map);
@ -225,7 +228,7 @@ export function addHighlightOnHover(polylineGroup, map, polylineCoordinates, use
<strong>End:</strong> ${lastTimestamp}<br> <strong>End:</strong> ${lastTimestamp}<br>
<strong>Duration:</strong> ${timeOnRoute}<br> <strong>Duration:</strong> ${timeOnRoute}<br>
<strong>Total Distance:</strong> ${formatDistance(totalDistance, distanceUnit)}<br> <strong>Total Distance:</strong> ${formatDistance(totalDistance, distanceUnit)}<br>
<strong>Current Speed:</strong> ${Math.round(currentSpeed)} km/h <strong>Current Speed:</strong> ${Math.round(speed)} km/h
`; `;
if (hoverPopup) { if (hoverPopup) {
@ -236,16 +239,15 @@ export function addHighlightOnHover(polylineGroup, map, polylineCoordinates, use
.setLatLng(e.latlng) .setLatLng(e.latlng)
.setContent(popupContent) .setContent(popupContent)
.openOn(map); .openOn(map);
}); }
polylineGroup.on("mouseout", function () { function handleMouseOut(e) {
// Restore original style
polylineGroup.eachLayer((layer) => { polylineGroup.eachLayer((layer) => {
if (layer instanceof L.Polyline) { if (layer instanceof L.Polyline) {
const originalStyle = { const originalStyle = {
weight: 3, weight: 3,
opacity: userSettings.route_opacity, opacity: userSettings.route_opacity,
color: layer.options.originalColor // Use the stored original color color: layer.options.originalColor
}; };
layer.setStyle(originalStyle); layer.setStyle(originalStyle);
@ -257,16 +259,31 @@ export function addHighlightOnHover(polylineGroup, map, polylineCoordinates, use
} }
map.removeLayer(startMarker); map.removeLayer(startMarker);
map.removeLayer(endMarker); map.removeLayer(endMarker);
}); }
// Keep the original group events as a fallback
polylineGroup.on("mouseover", handleMouseOver);
polylineGroup.on("mouseout", handleMouseOut);
// Keep the click event
polylineGroup.on("click", function () { polylineGroup.on("click", function () {
map.fitBounds(polylineGroup.getBounds()); map.fitBounds(polylineGroup.getBounds());
}); });
} }
export function createPolylinesLayer(markers, map, timezone, routeOpacity, userSettings, distanceUnit) { export function createPolylinesLayer(markers, map, timezone, routeOpacity, userSettings, distanceUnit) {
// Create a canvas renderer // Create a custom pane for our polylines with higher z-index
const renderer = L.canvas({ padding: 0.5 }); if (!map.getPane('polylinesPane')) {
map.createPane('polylinesPane');
map.getPane('polylinesPane').style.zIndex = 450; // Above the default overlay pane (400)
}
const renderer = L.canvas({
padding: 0.5,
pane: 'polylinesPane'
});
console.log("Creating polylines layer with markers:", markers.length);
const splitPolylines = []; const splitPolylines = [];
let currentPolyline = []; let currentPolyline = [];
@ -295,9 +312,15 @@ export function createPolylinesLayer(markers, map, timezone, routeOpacity, userS
splitPolylines.push(currentPolyline); splitPolylines.push(currentPolyline);
} }
return L.layerGroup( console.log("Split into polyline groups:", splitPolylines.length);
splitPolylines.map((polylineCoordinates) => {
// Create the layer group with the polylines
const layerGroup = L.layerGroup(
splitPolylines.map((polylineCoordinates, groupIndex) => {
console.log(`Creating group ${groupIndex} with coordinates:`, polylineCoordinates.length);
const segmentGroup = L.featureGroup(); const segmentGroup = L.featureGroup();
const segments = [];
for (let i = 0; i < polylineCoordinates.length - 1; i++) { for (let i = 0; i < polylineCoordinates.length - 1; i++) {
const speed = calculateSpeed(polylineCoordinates[i], polylineCoordinates[i + 1]); const speed = calculateSpeed(polylineCoordinates[i], polylineCoordinates[i + 1]);
@ -309,25 +332,77 @@ export function createPolylinesLayer(markers, map, timezone, routeOpacity, userS
[polylineCoordinates[i + 1][0], polylineCoordinates[i + 1][1]] [polylineCoordinates[i + 1][0], polylineCoordinates[i + 1][1]]
], ],
{ {
renderer: renderer, // Use canvas renderer renderer: renderer,
color: color, color: color,
originalColor: color, originalColor: color,
opacity: routeOpacity, opacity: routeOpacity,
weight: 3, weight: 3,
speed: speed, speed: speed,
startTime: polylineCoordinates[i][4], interactive: true,
endTime: polylineCoordinates[i + 1][4] pane: 'polylinesPane',
bubblingMouseEvents: false
} }
); );
segments.push(segment);
segmentGroup.addLayer(segment); segmentGroup.addLayer(segment);
} }
// Add mouseover/mouseout to the entire group
segmentGroup.on('mouseover', function(e) {
console.log("Group mouseover", groupIndex);
L.DomEvent.stopPropagation(e);
segments.forEach(segment => {
segment.setStyle({
weight: 8,
opacity: 1
});
if (map.hasLayer(segment)) {
segment.bringToFront();
}
});
});
segmentGroup.on('mouseout', function(e) {
console.log("Group mouseout", groupIndex);
L.DomEvent.stopPropagation(e);
segments.forEach(segment => {
segment.setStyle({
weight: 3,
opacity: routeOpacity,
color: segment.options.originalColor
});
});
});
// Make the group interactive
segmentGroup.options.interactive = true;
segmentGroup.options.bubblingMouseEvents = false;
// Add the hover functionality to the group
addHighlightOnHover(segmentGroup, map, polylineCoordinates, userSettings, distanceUnit); addHighlightOnHover(segmentGroup, map, polylineCoordinates, userSettings, distanceUnit);
return segmentGroup; return segmentGroup;
}) })
).addTo(map); );
// Add CSS to ensure our pane receives mouse events
const style = document.createElement('style');
style.textContent = `
.leaflet-polylinesPane-pane {
pointer-events: auto !important;
}
.leaflet-polylinesPane-pane canvas {
pointer-events: auto !important;
}
`;
document.head.appendChild(style);
// Add to map and return
layerGroup.addTo(map);
console.log("Layer group added to map");
return layerGroup;
} }
export function updatePolylinesColors(polylinesLayer, useSpeedColors) { export function updatePolylinesColors(polylinesLayer, useSpeedColors) {

View file

@ -8,6 +8,9 @@ export function createPopupContent(marker, timezone, distanceUnit) {
marker[3] = marker[3] * 3.28084; marker[3] = marker[3] * 3.28084;
} }
// convert marker[5] from m/s to km/h and round to nearest integer
marker[5] = Math.round(marker[5] * 3.6);
return ` return `
<strong>Timestamp:</strong> ${formatDate(marker[4], timezone)}<br> <strong>Timestamp:</strong> ${formatDate(marker[4], timezone)}<br>
<strong>Latitude:</strong> ${marker[0]}<br> <strong>Latitude:</strong> ${marker[0]}<br>