Skip to content

Instantly share code, notes, and snippets.

@LexSong
Last active October 27, 2019 01:03
Show Gist options
  • Select an option

  • Save LexSong/e2830be220542ac637e1ce476e771f79 to your computer and use it in GitHub Desktop.

Select an option

Save LexSong/e2830be220542ac637e1ce476e771f79 to your computer and use it in GitHub Desktop.
Octant to LatLong
import sys
from collections import namedtuple
octant_dict = {
'0': (0, 0, 0),
'1': (1, 0, 0),
'2': (0, 1, 0),
'3': (1, 1, 0),
'4': (0, 0, 1),
'5': (1, 0, 1),
'6': (0, 1, 1),
'7': (1, 1, 1),
}
LatLon = namedtuple('LatLon', ['lat', 'lon'])
class LatLonBox(namedtuple('LatLonBox', ['north', 'south', 'west', 'east'])):
@property
def mid_point(self):
n, s, w, e = tuple(self)
return LatLon((n + s) / 2, (w + e) / 2)
def get_child(self, octant):
try:
oct_x, oct_y, oct_z = octant_dict[octant]
except KeyError:
raise ValueError("invalid octant value")
n, s, w, e = tuple(self)
if oct_y == 0:
n = self.mid_point.lat
elif oct_y == 1:
s = self.mid_point.lat
else:
raise ValueError
if n == 90 or s == -90:
return LatLonBox(n, s, w, e)
if oct_x == 0:
e = self.mid_point.lon
elif oct_x == 1:
w = self.mid_point.lon
else:
raise ValueError
return LatLonBox(n, s, w, e)
first_latlonbox_dict = {
'02': LatLonBox(0, -90, -180, -90),
'03': LatLonBox(0, -90, -90, 0),
'12': LatLonBox(0, -90, 0, 90),
'13': LatLonBox(0, -90, 90, 180),
'20': LatLonBox(90, 0, -180, -90),
'21': LatLonBox(90, 0, -90, 0),
'30': LatLonBox(90, 0, 0, 90),
'31': LatLonBox(90, 0, 90, 180),
}
octant_string = sys.argv[1]
latlonbox = first_latlonbox_dict[octant_string[0:2]]
for octant in octant_string[2:]:
latlonbox = latlonbox.get_child(octant)
print("Midpoint:", tuple(latlonbox.mid_point))
print("Box:", latlonbox)
@rastapasta

Copy link
Copy Markdown

great work! 🍺

replacing line 22 with

        return LatLon((n + s) / 2.0, (w + e) / 2.0)

could improve it by using floats in the calculation - cheers!

@retroplasma

Copy link
Copy Markdown

this is awesome!

@LexSong

LexSong commented Jan 19, 2019

Copy link
Copy Markdown
Author

replacing line 22 with

        return LatLon((n + s) / 2.0, (w + e) / 2.0)

could improve it by using floats in the calculation - cheers!

Unless you're still using Python 2.7, the division in Python 3 will use float division when necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment