Skip to content

Instantly share code, notes, and snippets.

@joubin
Last active March 4, 2016 17:57
Show Gist options
  • Save joubin/f233ad17a408e7708403 to your computer and use it in GitHub Desktop.
Save joubin/f233ad17a408e7708403 to your computer and use it in GitHub Desktop.
Python method to find the center of a multiple positions
import math
import unittest
class LatLon(object):
def __init__(self, lat, lon, alt):
"""
:param lat: Latitude in radians
:param lon: Longitude in radians
:param alt: Altitude in any unit
"""
self.lat = lat
self.lon = lon
self.alt = alt
def __str__(self):
return "Lat: " + str(self.lat) + " Lon: " + str(self.lon) + " Alt: " + str(self.alt)
@classmethod
def init_with_radians(cls, lat, lon, alt):
"""
:param lat: Latitude in radians
:param lon: Longitude in radians
:param alt: Altitude in any unit
:return: a class
"""
return cls(lat, lon, alt)
@classmethod
def init_with_degrees(cls, lat, lon, alt):
"""
:param lat: Latitude in degrees
:param lon: Longitude in degrees
:param alt: Altitude in any unit
:return: a class
"""
return cls(math.radians(lat), math.radians(lon), alt)
@staticmethod
def find_center(positions):
"""
:return: the center position of a position collection
"""
x = 0
y = 0
z = 0
alt = 0
for pos in positions:
x += math.cos(pos.lat) * math.cos(pos.lon)
y += math.cos(pos.lat) * math.sin(pos.lon)
z += math.sin(pos.lat)
alt += pos.alt
x /= len(positions)
y /= len(positions)
z /= len(positions)
alt /= len(positions)
lon = math.atan2(y, x)
hyp = math.sqrt((x * x) + (y * y))
lat = math.atan2(z, hyp)
return LatLon(lat, lon, alt)
def __eq__(self, *args, **kwargs):
other = args[0]
return self.lat == other.lat and self.lon == other.lon and self.alt == other.alt
class MyTest(unittest.TestCase):
def test_center(self):
for i in [math.radians(x) for x in range(360)]:
positions = [LatLon.init_with_radians(i, i, i), LatLon.init_with_radians(i, -i, i),
LatLon.init_with_radians(-i, i, i), LatLon.init_with_radians(-i, -i, i)]
result = LatLon.find_center(positions)
self.assertEqual(result, LatLon.init_with_radians(0, 0, i))
def test_init(self):
for i in [math.radians(x) for x in range(360)]:
rad = LatLon.init_with_radians(i, i, 0)
deg = LatLon.init_with_degrees(math.degrees(i), math.degrees(i), 0)
self.assertAlmostEqual(rad.lat, deg.lat)
self.assertAlmostEqual(rad.lon, deg.lon)
self.assertAlmostEqual(rad.alt, deg.alt)
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment