mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-11 09:41:40 -05:00
Experiment with visits detection
This commit is contained in:
parent
04a2150959
commit
1e207f297c
4 changed files with 86 additions and 1 deletions
|
|
@ -1 +1 @@
|
|||
0.9.8
|
||||
0.9.9
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -9,6 +9,8 @@ gem 'chartkick'
|
|||
gem 'data_migrate'
|
||||
gem 'devise'
|
||||
gem 'geocoder'
|
||||
gem 'geokit'
|
||||
gem 'geokit-rails'
|
||||
gem 'importmap-rails'
|
||||
gem 'kaminari'
|
||||
gem 'lograge'
|
||||
|
|
|
|||
|
|
@ -135,6 +135,10 @@ GEM
|
|||
geocoder (1.8.3)
|
||||
base64 (>= 0.1.0)
|
||||
csv (>= 3.0.0)
|
||||
geokit (1.14.0)
|
||||
geokit-rails (2.5.0)
|
||||
geokit (~> 1.5)
|
||||
rails (>= 3.0)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
hashdiff (1.1.0)
|
||||
|
|
@ -423,6 +427,8 @@ DEPENDENCIES
|
|||
ffaker
|
||||
foreman
|
||||
geocoder
|
||||
geokit
|
||||
geokit-rails
|
||||
importmap-rails
|
||||
kaminari
|
||||
lograge
|
||||
|
|
|
|||
77
app/services/visits/detect.rb
Normal file
77
app/services/visits/detect.rb
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
require 'geokit'
|
||||
|
||||
class Visits::Detect
|
||||
def initialize
|
||||
a = 5.days.ago.beginning_of_month
|
||||
b = 5.days.ago.end_of_month
|
||||
@points = Point.order(timestamp: :asc).where(timestamp: a..b)
|
||||
end
|
||||
|
||||
def call
|
||||
# Group points by day
|
||||
points_by_day = @points.group_by { |point| point_date(point) }
|
||||
|
||||
# Iterate through each day's points
|
||||
points_by_day.each do |day, day_points|
|
||||
# Sort points by timestamp
|
||||
day_points.sort_by! { |point| point.timestamp }
|
||||
|
||||
# Call the method for each day's points
|
||||
grouped_points = group_points_by_radius(day_points)
|
||||
|
||||
# Print the grouped points for the day
|
||||
puts "Day: #{day}"
|
||||
grouped_points.each_with_index do |group, index|
|
||||
puts "Group #{index + 1}:"
|
||||
group.each do |point|
|
||||
puts point
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Method to convert timestamp to date
|
||||
def point_date(point)
|
||||
Time.zone.at(point.timestamp).to_date
|
||||
end
|
||||
|
||||
# Method to check if two points are within a certain radius (in meters)
|
||||
def within_radius?(point1, point2, radius)
|
||||
loc1 = Geokit::LatLng.new(point1.latitude, point1.longitude)
|
||||
loc2 = Geokit::LatLng.new(point2.latitude, point2.longitude)
|
||||
loc1.distance_to(loc2, units: :kms) * 1000 <= radius
|
||||
end
|
||||
|
||||
# Method to group points by increasing radius
|
||||
def group_points_by_radius(day_points, initial_radius = 30, max_radius = 100, step = 10)
|
||||
grouped = []
|
||||
remaining_points = day_points.dup
|
||||
|
||||
while remaining_points.any?
|
||||
point = remaining_points.shift
|
||||
group = [point]
|
||||
radius = initial_radius
|
||||
|
||||
while radius <= max_radius
|
||||
remaining_points.each do |next_point|
|
||||
group << next_point if within_radius?(point, next_point, radius)
|
||||
end
|
||||
|
||||
if group.size > 1
|
||||
remaining_points -= group
|
||||
grouped << group
|
||||
break
|
||||
else
|
||||
radius += step
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
grouped
|
||||
end
|
||||
end
|
||||
|
||||
# Execute the detection
|
||||
# Visits::Detect.new.call
|
||||
Loading…
Reference in a new issue