from math import radians, cos, sin, asin, sqrt
def distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
# taken from: https://stackoverflow.com/a/4913653/35364
# convert decimal degrees to radians
lon1 = radians(lon1)
lon2 = radians(lon2)
lat1 = radians(lat1)
lat2 = radians(lat2)
# haversine formula
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
r = 6371008 # Average radius of earth in meters
return c * rThe Ruby GIS libaries already have C implementations for haversine but I just wanted to show how easy it is to hook out to a C function for math heavy stuff.
The javascript version runs in 15ms.
> In the real world, things like haversine are implemented as C extensions
Having to write C-extensions is, well a point of friction, and adds complexity.
If you just used a native language to begin with, the simple straight forward code would work just fine.
Btw the source is here, and it also includes the csv file. https://bitbucket.org/hasenj/geodb/src
C extensions are a core part of Ruby. A big chunk of the std lib is implemented in C. You shouldn't be afraid of writing a tiny bit of C. Ruby and Python are scripting languages. They're literally designed for scripting another language.
The JIT for Ruby 3 is well underway, so in a bit it'll be a complete non-issue anyway.