mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
Fix api point serializer to return correct latitude and longitude values
This commit is contained in:
parent
2af1aab787
commit
f8a05e68e3
5 changed files with 49 additions and 14 deletions
|
|
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Hexagons for the stats page are now being calculated a lot faster.
|
||||
- Prometheus exporter is now not being started when console is being run.
|
||||
- Stats will now properly reflect countries and cities visited after importing new points.
|
||||
- `GET /api/v1/points will now return correct latitude and longitude values. #1502
|
||||
|
||||
## Changed
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::PointSerializer < PointSerializer
|
||||
EXCLUDED_ATTRIBUTES = %w[created_at updated_at visit_id import_id user_id raw_data country_id].freeze
|
||||
class Api::PointSerializer
|
||||
EXCLUDED_ATTRIBUTES = %w[
|
||||
created_at updated_at visit_id import_id user_id raw_data
|
||||
country_id
|
||||
].freeze
|
||||
|
||||
def initialize(point)
|
||||
@point = point
|
||||
end
|
||||
|
||||
def call
|
||||
point.attributes.except(*EXCLUDED_ATTRIBUTES)
|
||||
point.attributes.except(*EXCLUDED_ATTRIBUTES).tap do |attributes|
|
||||
lat = point.lat
|
||||
lon = point.lon
|
||||
|
||||
attributes['latitude'] = lat.nil? ? nil : lat.to_s
|
||||
attributes['longitude'] = lon.nil? ? nil : lon.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :point
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,15 +48,16 @@ module LocationSearch
|
|||
last_point = sorted_points.last
|
||||
|
||||
# Calculate visit duration
|
||||
duration_minutes = if sorted_points.length > 1
|
||||
((last_point[:timestamp] - first_point[:timestamp]) / 60.0).round
|
||||
else
|
||||
# Single point visit - estimate based on typical stay time
|
||||
15 # minutes
|
||||
end
|
||||
duration_minutes =
|
||||
if sorted_points.any?
|
||||
((last_point[:timestamp] - first_point[:timestamp]) / 60.0).round
|
||||
else
|
||||
# Single point visit - estimate based on typical stay time
|
||||
15 # minutes
|
||||
end
|
||||
|
||||
# Find the most accurate point (lowest accuracy value means higher precision)
|
||||
most_accurate_point = points.min_by { |p| p[:accuracy] || 999999 }
|
||||
most_accurate_point = points.min_by { |p| p[:accuracy] || 999_999 }
|
||||
|
||||
# Calculate average distance from search center
|
||||
average_distance = (points.sum { |p| p[:distance_meters] } / points.length).round(2)
|
||||
|
|
@ -86,7 +87,7 @@ module LocationSearch
|
|||
hours = minutes / 60
|
||||
remaining_minutes = minutes % 60
|
||||
|
||||
if remaining_minutes == 0
|
||||
if remaining_minutes.zero?
|
||||
"~#{pluralize(hours, 'hour')}"
|
||||
else
|
||||
"~#{pluralize(hours, 'hour')} #{pluralize(remaining_minutes, 'minute')}"
|
||||
|
|
|
|||
|
|
@ -76,7 +76,11 @@
|
|||
<div class="join">
|
||||
<%= link_to "#{MANAGER_URL}/auth/dawarich?token=#{current_user.generate_subscription_token}" do %>
|
||||
<span class="join-item btn btn-sm <%= trial_button_class(current_user) %>">
|
||||
<span class="tooltip tooltip-bottom" data-tip="Your trial will end in <%= distance_of_time_in_words(current_user.active_until, Time.current) %>"><%= (current_user.active_until.to_date - Time.current.to_date).to_i %> days remaining</span>
|
||||
<% if current_user.active_until.past? %>
|
||||
<span class="tooltip tooltip-bottom">Trial expired 🥺</span>
|
||||
<% else %>
|
||||
<span class="tooltip tooltip-bottom" data-tip="Your trial will end in <%= distance_of_time_in_words(current_user.active_until, Time.current) %>"><%= (current_user.active_until.to_date - Time.current.to_date).to_i %> days remaining</span>
|
||||
<% end %>
|
||||
</span><span class="join-item btn btn-sm btn-success">
|
||||
Subscribe
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -7,14 +7,26 @@ RSpec.describe Api::PointSerializer do
|
|||
subject(:serializer) { described_class.new(point).call }
|
||||
|
||||
let(:point) { create(:point) }
|
||||
let(:expected_json) { point.attributes.except(*Api::PointSerializer::EXCLUDED_ATTRIBUTES) }
|
||||
let(:all_excluded) { PointSerializer::EXCLUDED_ATTRIBUTES + Api::PointSerializer::ADDITIONAL_EXCLUDED_ATTRIBUTES }
|
||||
let(:expected_json) do
|
||||
point.attributes.except(*all_excluded).tap do |attributes|
|
||||
# API serializer extracts coordinates from PostGIS geometry
|
||||
attributes['latitude'] = point.lat.to_s
|
||||
attributes['longitude'] = point.lon.to_s
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns JSON with correct attributes' do
|
||||
expect(serializer.to_json).to eq(expected_json.to_json)
|
||||
end
|
||||
|
||||
it 'does not include excluded attributes' do
|
||||
expect(serializer).not_to include(*Api::PointSerializer::EXCLUDED_ATTRIBUTES)
|
||||
expect(serializer).not_to include(*all_excluded)
|
||||
end
|
||||
|
||||
it 'extracts coordinates from PostGIS geometry' do
|
||||
expect(serializer['latitude']).to eq(point.lat.to_s)
|
||||
expect(serializer['longitude']).to eq(point.lon.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue