Fix minor issues

This commit is contained in:
Eugene Burmakin 2026-01-11 19:50:21 +01:00
parent 4a9a87350c
commit 301c14d3b4
3 changed files with 37 additions and 7 deletions

View file

@ -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

View file

@ -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

View file

@ -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
}
}