mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
Clean up code a bit
This commit is contained in:
parent
7ea149bd4e
commit
2e46069fcc
2 changed files with 25 additions and 44 deletions
|
|
@ -5,7 +5,6 @@ module Distanceable
|
|||
|
||||
module ClassMethods
|
||||
def total_distance(points = nil, unit = :km)
|
||||
# Handle method being called directly on relation vs with array
|
||||
if points.nil?
|
||||
calculate_distance_for_relation(unit)
|
||||
else
|
||||
|
|
@ -50,20 +49,17 @@ module Distanceable
|
|||
|
||||
return 0 if points.length < 2
|
||||
|
||||
# OPTIMIZED: Single SQL query instead of N individual queries
|
||||
total_meters = calculate_batch_distances(points).sum
|
||||
|
||||
total_meters.to_f / ::DISTANCE_UNITS[unit.to_sym]
|
||||
end
|
||||
|
||||
# Optimized batch distance calculation using single SQL query
|
||||
def calculate_batch_distances(points)
|
||||
return [] if points.length < 2
|
||||
|
||||
point_pairs = points.each_cons(2).to_a
|
||||
return [] if point_pairs.empty?
|
||||
|
||||
# Create a VALUES clause with all point pairs
|
||||
values_clause = point_pairs.map.with_index do |(p1, p2), index|
|
||||
"(#{index}, ST_GeomFromEWKT('#{p1.lonlat}')::geography, ST_GeomFromEWKT('#{p2.lonlat}')::geography)"
|
||||
end.join(', ')
|
||||
|
|
@ -85,7 +81,7 @@ module Distanceable
|
|||
SQL
|
||||
|
||||
# Return array of distances in meters
|
||||
results.map { |row| row['distance_meters'].to_f }
|
||||
results.map { |row| row['distance_meters'].to_i }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -94,7 +90,6 @@ module Distanceable
|
|||
raise ArgumentError, "Invalid unit. Supported units are: #{::DISTANCE_UNITS.keys.join(', ')}"
|
||||
end
|
||||
|
||||
# Extract coordinates based on what type other_point is
|
||||
other_lonlat = extract_point(other_point)
|
||||
return nil if other_lonlat.nil?
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ class Track < ApplicationRecord
|
|||
.first
|
||||
end
|
||||
|
||||
# Optimized SQL segmentation using PostgreSQL window functions
|
||||
def self.segment_points_in_sql(user_id, start_timestamp, end_timestamp, time_threshold_minutes, distance_threshold_meters, untracked_only: false)
|
||||
time_threshold_seconds = time_threshold_minutes * 60
|
||||
|
||||
|
|
@ -104,15 +103,18 @@ class Track < ApplicationRecord
|
|||
|
||||
# Get actual Point objects for each segment with pre-calculated distances
|
||||
def self.get_segments_with_points(user_id, start_timestamp, end_timestamp, time_threshold_minutes, distance_threshold_meters, untracked_only: false)
|
||||
segments_data = segment_points_in_sql(user_id, start_timestamp, end_timestamp, time_threshold_minutes, distance_threshold_meters, untracked_only: untracked_only)
|
||||
segments_data = segment_points_in_sql(
|
||||
user_id,
|
||||
start_timestamp,
|
||||
end_timestamp,
|
||||
time_threshold_minutes,
|
||||
distance_threshold_meters,
|
||||
untracked_only: untracked_only
|
||||
)
|
||||
|
||||
# Get all point IDs we need
|
||||
all_point_ids = segments_data.flat_map { |seg| seg[:point_ids] }
|
||||
point_ids = segments_data.flat_map { |seg| seg[:point_ids] }
|
||||
points_by_id = Point.where(id: point_ids).index_by(&:id)
|
||||
|
||||
# Single query to get all points
|
||||
points_by_id = Point.where(id: all_point_ids).index_by(&:id)
|
||||
|
||||
# Build segments with actual Point objects
|
||||
segments_data.map do |seg_data|
|
||||
{
|
||||
points: seg_data[:point_ids].map { |id| points_by_id[id] }.compact,
|
||||
|
|
@ -151,23 +153,7 @@ class Track < ApplicationRecord
|
|||
def broadcast_track_update(action)
|
||||
TracksChannel.broadcast_to(user, {
|
||||
action: action,
|
||||
track: serialize_track_data
|
||||
track: TrackSerializer.new(self).call
|
||||
})
|
||||
end
|
||||
|
||||
def serialize_track_data
|
||||
{
|
||||
id: id,
|
||||
start_at: start_at.iso8601,
|
||||
end_at: end_at.iso8601,
|
||||
distance: distance.to_i,
|
||||
avg_speed: avg_speed.to_f,
|
||||
duration: duration,
|
||||
elevation_gain: elevation_gain,
|
||||
elevation_loss: elevation_loss,
|
||||
elevation_max: elevation_max,
|
||||
elevation_min: elevation_min,
|
||||
original_path: original_path.to_s
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue