mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
69 lines
2 KiB
Ruby
69 lines
2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Tracks::CreateFromPoints
|
|
include Tracks::Segmentation
|
|
include Tracks::TrackBuilder
|
|
|
|
attr_reader :user, :distance_threshold_meters, :time_threshold_minutes, :start_at, :end_at
|
|
|
|
def initialize(user, start_at: nil, end_at: nil)
|
|
@user = user
|
|
@start_at = start_at
|
|
@end_at = end_at
|
|
@distance_threshold_meters = user.safe_settings.meters_between_routes.to_i || 500
|
|
@time_threshold_minutes = user.safe_settings.minutes_between_routes.to_i || 60
|
|
end
|
|
|
|
def call
|
|
time_range_info = start_at || end_at ? " for time range #{start_at} - #{end_at}" : ""
|
|
Rails.logger.info "Creating tracks for user #{user.id} with thresholds: #{distance_threshold_meters}m, #{time_threshold_minutes}min#{time_range_info}"
|
|
|
|
tracks_created = 0
|
|
|
|
Track.transaction do
|
|
# Clear existing tracks for this user (optionally scoped to time range)
|
|
tracks_to_delete = start_at || end_at ? scoped_tracks_for_deletion : user.tracks
|
|
tracks_to_delete.destroy_all
|
|
|
|
track_segments = split_points_into_segments(user_points)
|
|
|
|
track_segments.each do |segment_points|
|
|
next if segment_points.size < 2
|
|
|
|
track = create_track_from_points(segment_points)
|
|
tracks_created += 1 if track&.persisted?
|
|
end
|
|
end
|
|
|
|
Rails.logger.info "Created #{tracks_created} tracks for user #{user.id}#{time_range_info}"
|
|
tracks_created
|
|
end
|
|
|
|
private
|
|
|
|
def user_points
|
|
@user_points ||= begin
|
|
points = Point.where(user: user)
|
|
.where.not(lonlat: nil)
|
|
.where.not(timestamp: nil)
|
|
|
|
# Apply timestamp filtering if provided
|
|
if start_at.present?
|
|
points = points.where('timestamp >= ?', start_at)
|
|
end
|
|
|
|
if end_at.present?
|
|
points = points.where('timestamp <= ?', end_at)
|
|
end
|
|
|
|
points.order(:timestamp)
|
|
end
|
|
end
|
|
|
|
def scoped_tracks_for_deletion
|
|
user.tracks.where(
|
|
'start_at <= ? AND end_at >= ?',
|
|
Time.zone.at(end_at), Time.zone.at(start_at)
|
|
)
|
|
end
|
|
end
|