From 301c14d3b4108d0b511e6840abab20beb33ffb7e Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Sun, 11 Jan 2026 19:50:21 +0100 Subject: [PATCH] Fix minor issues --- app/controllers/map/leaflet_controller.rb | 11 ++++++---- .../maps/maplibre/event_handlers.js | 21 ++++++++++++++++++- .../maps_maplibre/utils/route_segmenter.js | 12 +++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/app/controllers/map/leaflet_controller.rb b/app/controllers/map/leaflet_controller.rb index 0c425a57..fe8282b1 100644 --- a/app/controllers/map/leaflet_controller.rb +++ b/app/controllers/map/leaflet_controller.rb @@ -45,6 +45,8 @@ class Map::LeafletController < ApplicationController # Use PostGIS window function for efficient distance calculation # This is O(1) database operation vs O(n) Ruby iteration + import_filter = params[:import_id].present? ? 'AND import_id = :import_id' : '' + sql = <<~SQL.squish SELECT COALESCE(SUM(distance_m) / 1000.0, 0) as total_km FROM ( SELECT ST_Distance( @@ -55,14 +57,15 @@ class Map::LeafletController < ApplicationController WHERE user_id = :user_id AND timestamp >= :start_at AND timestamp <= :end_at + #{import_filter} ) distances SQL + query_params = { user_id: current_user.id, start_at: start_at, end_at: end_at } + query_params[:import_id] = params[:import_id] if params[:import_id].present? + result = Point.connection.select_value( - ActiveRecord::Base.sanitize_sql_array([ - sql, - { user_id: current_user.id, start_at: start_at, end_at: end_at } - ]) + ActiveRecord::Base.sanitize_sql_array([sql, query_params]) ) result&.to_f&.round || 0 diff --git a/app/javascript/controllers/maps/maplibre/event_handlers.js b/app/javascript/controllers/maps/maplibre/event_handlers.js index 4c450822..59a60f26 100644 --- a/app/javascript/controllers/maps/maplibre/event_handlers.js +++ b/app/javascript/controllers/maps/maplibre/event_handlers.js @@ -220,6 +220,17 @@ export class EventHandlers { if (!sourceData || !sourceData.features) return null // Find the matching feature by properties + // First try to match by unique ID (most reliable) + if (properties.id) { + const featureById = sourceData.features.find(f => f.properties.id === properties.id) + if (featureById) return featureById + } + if (properties.routeId) { + const featureByRouteId = sourceData.features.find(f => f.properties.routeId === properties.routeId) + if (featureByRouteId) return featureByRouteId + } + + // Fall back to matching by start/end times and point count return sourceData.features.find(feature => { const props = feature.properties return props.startTime === properties.startTime && @@ -234,10 +245,18 @@ export class EventHandlers { _areFeaturesSame(feature1, feature2) { if (!feature1 || !feature2) return false - // Compare by start/end times and point count (unique enough for routes) const props1 = feature1.properties const props2 = feature2.properties + // First check for unique route identifier (most reliable) + if (props1.id && props2.id) { + return props1.id === props2.id + } + if (props1.routeId && props2.routeId) { + return props1.routeId === props2.routeId + } + + // Fall back to comparing start/end times and point count return props1.startTime === props2.startTime && props1.endTime === props2.endTime && props1.pointCount === props2.pointCount diff --git a/app/javascript/maps_maplibre/utils/route_segmenter.js b/app/javascript/maps_maplibre/utils/route_segmenter.js index 168f6c15..127c82da 100644 --- a/app/javascript/maps_maplibre/utils/route_segmenter.js +++ b/app/javascript/maps_maplibre/utils/route_segmenter.js @@ -131,6 +131,13 @@ export class RouteSegmenter { const coordinates = this.unwrapCoordinates(segment) const totalDistance = this.calculateSegmentDistance(segment) + const startTime = segment[0].timestamp + const endTime = segment[segment.length - 1].timestamp + + // Generate a stable, unique route ID based on start/end times + // This ensures the same route always has the same ID across re-renders + const routeId = `route-${startTime}-${endTime}` + return { type: 'Feature', geometry: { @@ -138,9 +145,10 @@ export class RouteSegmenter { coordinates }, properties: { + id: routeId, pointCount: segment.length, - startTime: segment[0].timestamp, - endTime: segment[segment.length - 1].timestamp, + startTime: startTime, + endTime: endTime, distance: totalDistance } }