From a97e133b35c2ff581300748a431b1e9bd9d522dd Mon Sep 17 00:00:00 2001 From: Eugene Burmakin Date: Thu, 18 Sep 2025 20:15:49 +0200 Subject: [PATCH] Remove unsed class --- app/services/maps/date_parameter_coercer.rb | 9 +- app/services/maps/h3_hexagon_calculator.rb | 85 ------- .../maps/h3_hexagon_calculator_spec.rb | 221 ------------------ 3 files changed, 3 insertions(+), 312 deletions(-) delete mode 100644 app/services/maps/h3_hexagon_calculator.rb delete mode 100644 spec/services/maps/h3_hexagon_calculator_spec.rb diff --git a/app/services/maps/date_parameter_coercer.rb b/app/services/maps/date_parameter_coercer.rb index e85469dd..22473d76 100644 --- a/app/services/maps/date_parameter_coercer.rb +++ b/app/services/maps/date_parameter_coercer.rb @@ -31,12 +31,9 @@ module Maps end def coerce_string_param(param) - # Check if it's a numeric string (timestamp) or date string - if param.match?(/^\d+$/) - param.to_i - else - Time.parse(param).to_i - end + return param.to_i if param.match?(/^\d+$/) + + Time.parse(param).to_i end end end diff --git a/app/services/maps/h3_hexagon_calculator.rb b/app/services/maps/h3_hexagon_calculator.rb deleted file mode 100644 index 84d23435..00000000 --- a/app/services/maps/h3_hexagon_calculator.rb +++ /dev/null @@ -1,85 +0,0 @@ -# frozen_string_literal: true - -module Maps - class H3HexagonCalculator - def initialize(user_id, start_date, end_date, h3_resolution = 8) - @user_id = user_id - @start_date = start_date - @end_date = end_date - @h3_resolution = h3_resolution - end - - def call - user_points = fetch_user_points - return { success: false, error: 'No points found for the given date range' } if user_points.empty? - - h3_indexes = calculate_h3_indexes(user_points) - hexagon_features = build_hexagon_features(h3_indexes) - - { - success: true, - data: { - type: 'FeatureCollection', - features: hexagon_features - } - } - rescue StandardError => e - { success: false, error: e.message } - end - - private - - attr_reader :user_id, :start_date, :end_date, :h3_resolution - - def fetch_user_points - Point.without_raw_data - .where(user_id: user_id) - .where(timestamp: start_date.to_i..end_date.to_i) - .where.not(lonlat: nil) - .select(:id, :lonlat, :timestamp) - end - - def calculate_h3_indexes(points) - h3_counts = Hash.new(0) - - points.find_each do |point| - # Convert PostGIS point to lat/lng array: [lat, lng] - coordinates = [point.lonlat.y, point.lonlat.x] - - # Get H3 index for these coordinates at specified resolution - h3_index = H3.from_geo_coordinates(coordinates, h3_resolution) - - # Count points in each hexagon - h3_counts[h3_index] += 1 - end - - h3_counts - end - - def build_hexagon_features(h3_counts) - h3_counts.map do |h3_index, point_count| - # Get the boundary coordinates for this H3 hexagon - boundary_coordinates = H3.to_boundary(h3_index) - - # Convert to GeoJSON polygon format (lng, lat) - polygon_coordinates = boundary_coordinates.map { |lat, lng| [lng, lat] } - - # Close the polygon by adding the first point at the end - polygon_coordinates << polygon_coordinates.first - - { - type: 'Feature', - geometry: { - type: 'Polygon', - coordinates: [polygon_coordinates] - }, - properties: { - h3_index: h3_index.to_s(16), - point_count: point_count, - center: H3.to_geo_coordinates(h3_index) - } - } - end - end - end -end diff --git a/spec/services/maps/h3_hexagon_calculator_spec.rb b/spec/services/maps/h3_hexagon_calculator_spec.rb deleted file mode 100644 index 10c9ebc4..00000000 --- a/spec/services/maps/h3_hexagon_calculator_spec.rb +++ /dev/null @@ -1,221 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Maps::H3HexagonCalculator, type: :service do - let(:user) { create(:user) } - let(:start_date) { Time.zone.parse('2024-01-01') } - let(:end_date) { Time.zone.parse('2024-01-02') } - let(:service) { described_class.new(user.id, start_date, end_date, 5) } - - describe '#call' do - context 'when user has no points' do - it 'returns error response' do - result = service.call - - expect(result[:success]).to be false - expect(result[:error]).to eq('No points found for the given date range') - end - end - - context 'when user has points outside date range' do - before do - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: end_date.to_i + 1.hour) # Outside range - end - - it 'returns error response' do - result = service.call - - expect(result[:success]).to be false - expect(result[:error]).to eq('No points found for the given date range') - end - end - - context 'when user has valid points' do - before do - # Create points in Berlin area - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: start_date.to_i + 1.hour) - - create(:point, - user: user, - latitude: 52.5190, - longitude: 13.4040, - lonlat: 'POINT(13.4040 52.5190)', - timestamp: start_date.to_i + 2.hours) - - # Point outside date range - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: end_date.to_i + 1.hour) - end - - it 'returns successful response with hexagon features' do - result = service.call - - expect(result[:success]).to be true - expect(result[:data]).to have_key(:type) - expect(result[:data][:type]).to eq('FeatureCollection') - expect(result[:data]).to have_key(:features) - expect(result[:data][:features]).to be_an(Array) - expect(result[:data][:features]).not_to be_empty - end - - it 'creates proper GeoJSON features' do - result = service.call - feature = result[:data][:features].first - - expect(feature).to have_key(:type) - expect(feature[:type]).to eq('Feature') - - expect(feature).to have_key(:geometry) - expect(feature[:geometry][:type]).to eq('Polygon') - expect(feature[:geometry][:coordinates]).to be_an(Array) - expect(feature[:geometry][:coordinates].first).to be_an(Array) - - expect(feature).to have_key(:properties) - expect(feature[:properties]).to have_key(:h3_index) - expect(feature[:properties]).to have_key(:point_count) - expect(feature[:properties]).to have_key(:center) - end - - it 'only includes points within date range' do - result = service.call - - # Should only have features from the 2 points within range - total_points = result[:data][:features].sum { |f| f[:properties][:point_count] } - expect(total_points).to eq(2) - end - - it 'creates closed polygon coordinates' do - result = service.call - feature = result[:data][:features].first - coordinates = feature[:geometry][:coordinates].first - - # First and last coordinates should be the same (closed polygon) - expect(coordinates.first).to eq(coordinates.last) - - # Should have 7 coordinates (6 vertices + 1 to close) - expect(coordinates.length).to eq(7) - end - - it 'counts points correctly per hexagon' do - result = service.call - - # Both points are very close, should likely be in same hexagon - if result[:data][:features].length == 1 - expect(result[:data][:features].first[:properties][:point_count]).to eq(2) - else - # Or they might be in adjacent hexagons - total_points = result[:data][:features].sum { |f| f[:properties][:point_count] } - expect(total_points).to eq(2) - end - end - - it 'includes H3 index as hex string' do - result = service.call - feature = result[:data][:features].first - - h3_index = feature[:properties][:h3_index] - expect(h3_index).to be_a(String) - expect(h3_index).to match(/^[0-9a-f]+$/) # Hex string - end - - it 'includes center coordinates' do - result = service.call - feature = result[:data][:features].first - - center = feature[:properties][:center] - expect(center).to be_an(Array) - expect(center.length).to eq(2) - expect(center[0]).to be_between(52.0, 53.0) # Lat around Berlin - expect(center[1]).to be_between(13.0, 14.0) # Lng around Berlin - end - end - - context 'with different H3 resolution' do - let(:service) { described_class.new(user.id, start_date, end_date, 7) } - - before do - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: start_date.to_i + 1.hour) - end - - it 'uses the specified resolution' do - result = service.call - - expect(result[:success]).to be true - expect(result[:data][:features]).not_to be_empty - - # Higher resolution should create different sized hexagons - feature = result[:data][:features].first - expect(feature[:properties][:h3_index]).to be_present - end - end - - context 'when H3 operations fail' do - before do - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: start_date.to_i + 1.hour) - - allow(H3).to receive(:from_geo_coordinates).and_raise(StandardError, 'H3 error') - end - - it 'returns error response' do - result = service.call - - expect(result[:success]).to be false - expect(result[:error]).to eq('H3 error') - end - end - - context 'with points from different users' do - let(:other_user) { create(:user) } - - before do - # Points for target user - create(:point, - user: user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: start_date.to_i + 1.hour) - - # Points for other user (should be ignored) - create(:point, - user: other_user, - latitude: 52.5200, - longitude: 13.4050, - lonlat: 'POINT(13.4050 52.5200)', - timestamp: start_date.to_i + 1.hour) - end - - it 'only includes points from specified user' do - result = service.call - - total_points = result[:data][:features].sum { |f| f[:properties][:point_count] } - expect(total_points).to eq(1) - end - end - end -end \ No newline at end of file