diff --git a/shard.yml b/shard.yml index 95aa0fc..c5032f3 100644 --- a/shard.yml +++ b/shard.yml @@ -11,6 +11,8 @@ dependencies: version: ">= 0.6.0" geohash: github: geocrystal/geohash + geo_bearing: + github: geocrystal/geo_bearing development_dependencies: ameba: diff --git a/src/geo.cr b/src/geo.cr index abf09f0..0506838 100644 --- a/src/geo.cr +++ b/src/geo.cr @@ -1,5 +1,6 @@ require "convex_hull" require "geohash" +require "geo_bearing" require "./geo/utils" require "./geo/coord" require "./geo/polygon" diff --git a/src/geo/bearing.cr b/src/geo/bearing.cr index 3798e5c..239958b 100644 --- a/src/geo/bearing.cr +++ b/src/geo/bearing.cr @@ -1,35 +1,8 @@ module Geo struct Coord - # The formula used for calculating the initial bearing between two points on the Earth's surfaceis - # is derived from the broader concepts of great-circle distance and navigation on a spherical Earth model. - # https://en.wikipedia.org/wiki/Great-circle_distance - # - # https://github.com/Turfjs/turf/blob/master/packages/turf-bearing/index.ts + # Calculates initial and final bearings between two points using great-circle distance formulas def bearing(to : Geo::Coord, final = false) : Float64 - if final - # Calculate the bearing from the destination point back to the original point - reverse_bearing = calculate_bearing(to.lat, to.lng, lat, lng) - - # Adjust by 180 degrees to get the final bearing in the correct direction - (reverse_bearing + 180) % 360 - else - calculate_bearing(lat, lng, to.lat, to.lng) - end - end - - private def calculate_bearing(lat1, lng1, lat2, lng2) : Float64 - rad_lat1 = Geo::Utils.degrees_to_radians(lat1) - rad_lng1 = Geo::Utils.degrees_to_radians(lng1) - rad_lat2 = Geo::Utils.degrees_to_radians(lat2) - rad_lng2 = Geo::Utils.degrees_to_radians(lng2) - - delta_lng = rad_lng2 - rad_lng1 - - a = Math.sin(delta_lng) * Math.cos(rad_lat2) - b = Math.cos(rad_lat1) * Math.sin(rad_lat2) - - Math.sin(rad_lat1) * Math.cos(rad_lat2) * Math.cos(delta_lng) - - Geo::Utils.radians_to_degrees(Math.atan2(a, b)) % 360 + Geo::Bearing.bearing(lat, lng, to.lat, to.lng, final) end end end diff --git a/src/geo/utils.cr b/src/geo/utils.cr index 2d7b5be..0f27a57 100644 --- a/src/geo/utils.cr +++ b/src/geo/utils.cr @@ -21,13 +21,5 @@ module Geo return 0 if val == 0 # colinear val > 0 ? 1 : 2 # clockwise or counterclockwise end - - def degrees_to_radians(degrees : Number) : Float64 - degrees * Math::PI / 180.0 - end - - def radians_to_degrees(radians : Number) : Float64 - radians * 180.0 / Math::PI - end end end