dawarich/app/controllers/api/v1/maps/hexagons_controller.rb
2025-09-18 18:29:46 +02:00

105 lines
3.3 KiB
Ruby

# frozen_string_literal: true
class Api::V1::Maps::HexagonsController < ApiController
skip_before_action :authenticate_api_key, if: :public_sharing_request?
def index
return unless public_sharing_request? || validate_required_parameters
result = Maps::HexagonRequestHandler.call(
params: params,
current_api_user: current_api_user
)
render json: result
rescue Maps::HexagonContextResolver::SharedStatsNotFoundError => e
render json: { error: e.message }, status: :not_found
rescue Maps::DateParameterCoercer::InvalidDateFormatError => e
render json: { error: e.message }, status: :bad_request
rescue Maps::H3HexagonCenters::TooManyHexagonsError,
Maps::H3HexagonCenters::InvalidCoordinatesError,
Maps::H3HexagonCenters::PostGISError => e
render json: { error: e.message }, status: :bad_request
rescue StandardError => _e
handle_service_error
end
def bounds
context = Maps::HexagonContextResolver.call(
params: params,
current_api_user: current_api_user
)
result = Maps::BoundsCalculator.new(
target_user: context[:target_user],
start_date: context[:start_date],
end_date: context[:end_date]
).call
if result[:success]
render json: result[:data]
else
render json: {
error: result[:error],
point_count: result[:point_count]
}, status: :not_found
end
rescue Maps::HexagonContextResolver::SharedStatsNotFoundError => e
render json: { error: e.message }, status: :not_found
rescue Maps::BoundsCalculator::NoUserFoundError => e
render json: { error: e.message }, status: :not_found
rescue Maps::BoundsCalculator::NoDateRangeError => e
render json: { error: e.message }, status: :bad_request
rescue Maps::DateParameterCoercer::InvalidDateFormatError => e
render json: { error: e.message }, status: :bad_request
end
private
def hexagon_params
params.permit(:h3_resolution, :uuid, :start_date, :end_date)
end
def handle_service_error
render json: { error: 'Failed to generate hexagon grid' }, status: :internal_server_error
end
def public_sharing_request?
params[:uuid].present?
end
def validate_required_parameters
required_params = %i[min_lon max_lon min_lat max_lat start_date end_date]
missing_params = required_params.select { |param| params[param].blank? }
unless missing_params.empty?
error_message = "Missing required parameters: #{missing_params.join(', ')}"
render json: { error: error_message }, status: :bad_request
return false
end
# Validate coordinate ranges
if !valid_coordinate_ranges?
render json: { error: 'Invalid coordinate ranges' }, status: :bad_request
return false
end
true
end
def valid_coordinate_ranges?
min_lon = params[:min_lon].to_f
max_lon = params[:max_lon].to_f
min_lat = params[:min_lat].to_f
max_lat = params[:max_lat].to_f
# Check longitude range (-180 to 180)
return false unless (-180..180).cover?(min_lon) && (-180..180).cover?(max_lon)
# Check latitude range (-90 to 90)
return false unless (-90..90).cover?(min_lat) && (-90..90).cover?(max_lat)
# Check that min values are less than max values
return false unless min_lon < max_lon && min_lat < max_lat
true
end
end