On the 2020/06/06 I finally made my first Python module.
The reason for the creation of this module is that I needed to perform certain calculations regarding distances.
I wanted to write an article that would cover the most well known ways transmitting data.
Namely, via streaming protocols.
I ended up logically talking about RabbitMQ and Kafka.
Although it was clear for me what I wanted to write about, I wasn't sure what should I base my article about.
An idea was to calculate distances in Km in different planets.
Of course, for this, we need pretty good knowledge of how coordinates work.
I ended up hastily implementing python code to give me those calculations.
At some point I did think I was going too far in my article and ended up settling to planet 🌎 Earth 🌍 and make something with trains and trucks.
The old Geo Library can be found there on path )
, we can find very interesting references about the Haversine Theory.
It also contains the complete description of it.
For us, what's important is to understand its origins and what it is about.
The beginnings of this theory take us back to 1801.
At this time, .
Finally, the actual term haversine was invented by James Inman(1776–1859).
He was an English mathematician an professor at the .
This college has been closed, and it was active between 1733 and 1837
As we can see through this very vey quick introduction to its history, the haversine formula exists for a long time.
It is a centuries old technology, but it's important to realize that although old, its is the basis of what we are about to see.
Not only that, but is part of the theory that makes today GPS (Global Positioning System) possible and with that, we can nowadays know how long the train will take to get to us.
We now know when the buses are coming.
We know how long it will take from A to B.
We even now can have an estimate so precise, that we don't even think about it and take it most of the times for granted.
Even when we have to go from A to B going through C to D and all the way to Z.
Almost everything is calculated wth extreme precision.
We are going to see that although we will consider Earth to be a big globe, all the calculations will still match.
Earth can also be described as a big potato that is almost round.
That small difference for all our distance calculations are negligible.
Unless of coure we need even more extremely precise data for scientific studies.
But that is another issue.
2. Theory
Let's first have a look at the meaning of the word Haversine.
I didn't mention this in the introduction, just because this term involves quite a lot of mathematical explanation.
This is way it doesn't seem to belong to a historical backgroundf section.
However, it is precisely the end of that section where we will start this one.
From the studies of James Inman, we can finally understand what a Haversine is.
From this image we can see that vers is basically a versed sine.
We can now make the correct formula:
vers 𝜭 = 1 - cos 𝜭 = 2 sin ² (𝜭/2)
Half of that is
hav 𝜭 = (1 - cos 𝜭)/2 = sin ² (𝜭/2)
And this is what a haversine formula is about.
haversine just means Half versed sine.
That small distance become something very attractive for people at sea.
The main reason was that it would always result in a positive number.
Plus, a haversine is very easily invertible and works well with small numbers.
Rounding numbers isn't really a problem using haversines.
For our implementation we will use this base to develop different formulas.
In line with a good understanding of this problem, it is important that we become very much aware of what latitude and longitude actually mean.
2.1. Latitude (ɸ)
One line parallel to the equator has the same latitude on every of its points and its called a parallel
Latitude is a measurement in degrees of the angle formed from the equator line of the earth to the location we are determining.
The equator line seems like an obvious point to set the latitude at 0°.
This is because it cuts Earth in two halves, and it was already responsible for the separation between the Northen and Southern hemisphere.
The symbol for Latitude is ɸ.
2.2. Longitude (λ)
One line drawn from pole to pole has the same longitude and its called a meridian
Longitude is a measurement in degrees from the
This formula is derivated from the formula we saw in our introduction.
In code terms this translates to:
def __distance_to(self, coord, planet_radius_km):
lon1 = self.lon
lat1 = self.lat
lon2 = coord.lon
lat2 = coord.lat
phi_1 = radians(lat1)
phi_2 = radians(lat2)
delta_phi = radians(lat2 - lat1)
delta_lambda = radians(lon2 - lon1)
h = sin(delta_phi / 2.0) ** 2 + cos(phi_1) * cos(phi_2) * sin(delta_lambda / 2.0) ** 2
arc_sin = atan2(sqrt(h), sqrt(1 - h))
d = 2 * arc_sin * planet_radius_km
return d
In our code we still find these utility methods
def create_west_random_point(center, radius):
degree = random.randint(-90, 90)
d_lat_km = cos(radians(degree)) * radius
d_lon_km = sin(radians(degree)) * radius
origin = Coord(center.lat, center.lon)
origin = add_delta_in_km_to_coord(origin, -d_lat_km, d_lon_km)
return origin
def create_east_random_point(center, radius):
degree = random.randint(-90, 90)
d_lat_km = cos(radians(degree)) * radius
d_lon_km = sin(radians(degree)) * radius
origin = Coord(center.lat, center.lon)
origin = add_delta_in_km_to_coord(origin, +d_lat_km, d_lon_km)
return origin
What these do is to create a random point in a limited square delimiting a circumference of a determined radius and a certain ceter Coord.
4. Publishing a library
In order to publish a library I followed the rules determined by the example given in:
The important file for this is the setup.py file:
# -*- coding: utf-8 -*-
from distutils.core import setup
with open("README.txt", "r") as fh:
long_description = fh.read()
setup(
long_description=long_description,
long_description_content_type="text/markdown",
name='geo_calculator',
package_dir={'': 'src'},
py_modules=["geo_calculator"],
version='1.0.0-SNAPSHOT',
description='Multi function Geo Location calculator',
author='João Esperancinha',
author_email='[email protected]',
url='http://joaofilipesabinoesperancinha.nl/main',
download_url='https://github.com/user/reponame/archive/v_01.tar.gz',
keywords=['geo', 'location', 'latitude', 'longitude'],
install_requires=[
# 'math',
# 'random',
],
classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'Topic :: Software Development :: Build Tools',
'License :: OSI Approved :: Apache Software License',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
)
The first line # -*- coding: utf-8 -*- is important if we are using uncommon characters.
In my own name, I do have one of these uncommon characters and that is the Ãẫ of my name João.
To configure descriptions we need:
long_description=long_description,
long_description_content_type="text/markdown",
Note, that although markdown descriptions are supported, I couldn't get themm to work in a way that I like to see.
This is why I just ended up reading a simple Readme.txt file instead:
with open("README.txt", "r") as fh:
long_description = fh.read()
We then need to give some self-explanatory paramter:
name='geo_calculator',
package_dir={'': 'src'},
py_modules=["geo_calculator"],
version='1.0.0-SNAPSHOT',
description='Multi function Geo Location calculator',
author='João Esperancinha',
For the rest of the parameters for our module, it is important to consult the
7. Resources
7.1. Books & Papers
7.2. Websites
If you like algorithms, you'll probably find interesting to know a bit more about tail recursivity, how that led to tail call optimization and the current state of thing. I tell all about that in this video over here:
SOCIAL SHARE CARD GENERATOR