Welcome, guest | Sign In | My Account | Store | Cart
```#coding:UTF-8
"""
Python implementation of Haversine formula
Copyright (C) <2009>  Bartek Górny <bartek@gorny.edu.pl>

This program is free software: you can redistribute it and/or modify
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
"""

import math

def recalculate_coordinate(val,  _as=None):
"""
Accepts a coordinate as a tuple (degree, minutes, seconds)
You can give only one of them (e.g. only minutes as a floating point number)
and it will be duly recalculated into degrees, minutes and seconds.
Return value can be specified as 'deg', 'min' or 'sec'; default return value is
a proper coordinate tuple.
"""
deg,  min,  sec = val
# pass outstanding values from right to left
min = (min or 0) + int(sec) / 60
sec = sec % 60
deg = (deg or 0) + int(min) / 60
min = min % 60
# pass decimal part from left to right
dfrac,  dint = math.modf(deg)
min = min + dfrac * 60
deg = dint
mfrac,  mint = math.modf(min)
sec = sec + mfrac * 60
min = mint
if _as:
sec = sec + min * 60 + deg * 3600
if _as == 'sec': return sec
if _as == 'min': return sec / 60
if _as == 'deg': return sec / 3600
return deg,  min,  sec

def points2distance(start,  end):
"""
Calculate distance (in kilometers) between two points given as (long, latt) pairs
based on Haversine formula (http://en.wikipedia.org/wiki/Haversine_formula).
Implementation inspired by JavaScript implementation from
http://www.movable-type.co.uk/scripts/latlong.html
Accepts coordinates as tuples (deg, min, sec), but coordinates can be given
in any form - e.g. can specify only minutes:
(0, 3133.9333, 0)
is interpreted as
(52.0, 13.0, 55.998000000008687)
which, not accidentally, is the lattitude of Warsaw, Poland.
"""
d_latt = end_latt - start_latt
d_long = end_long - start_long
a = math.sin(d_latt/2)**2 + math.cos(start_latt) * math.cos(end_latt) * math.sin(d_long/2)**2
c = 2 * math.atan2(math.sqrt(a),  math.sqrt(1-a))
return 6371 * c

if __name__ == '__main__':
warsaw = ((21,  0,  30),  (52, 13, 56))
cracow = ((19, 56, 18),  (50, 3, 41))
print points2distance(warsaw,  cracow)
```