Created
August 16, 2011 19:17
-
-
Save alexalemi/1149902 to your computer and use it in GitHub Desktop.
Scaled Planetary Positions Google Map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="viewport" content="initial-scale=0.5, user-scalable=no" /> | |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> | |
<title>Planet Locations</title> | |
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" /> | |
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script> | |
<script type="text/javascript"> | |
function initialize() [ | |
var myLatlng = new google.maps.LatLng({0.lat},{0.lon}); | |
var myOptions = [ | |
zoom: 15, | |
center: myLatlng, | |
mapTypeId: google.maps.MapTypeId.ROADMAP | |
] | |
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); | |
var image = 'http://i.imgur.com/54DiG.png'; | |
var myLatLng = new google.maps.LatLng({0.lat},{0.lon}); | |
var sunmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Sun" | |
]); | |
var image = 'http://i.imgur.com/y0bGr.png'; | |
var myLatLng = new google.maps.LatLng({1.lat}, {1.lon}); | |
var mercurymarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Mercury" | |
]); | |
var image = 'http://i.imgur.com/Q4kA1.png'; | |
var myLatLng = new google.maps.LatLng({2.lat},{2.lon}); | |
var venusmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Venus" | |
]); | |
var image = 'http://i.imgur.com/CB6Tc.png'; | |
var myLatLng = new google.maps.LatLng({3.lat},{3.lon}); | |
var earthmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Earth" | |
]); | |
var image = 'http://i.imgur.com/8LOQv.png'; | |
var myLatLng = new google.maps.LatLng({4.lat}, {4.lon}); | |
var marsmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Mars" | |
]); | |
var image = 'http://i.imgur.com/fgt9I.png'; | |
var myLatLng = new google.maps.LatLng({5.lat},{5.lon}); | |
var jupitermarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Jupiter" | |
]); | |
var image = 'http://i.imgur.com/YlItl.png'; | |
var myLatLng = new google.maps.LatLng({6.lat}, {6.lon}); | |
var saturnmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Saturn" | |
]); | |
var image = 'http://i.imgur.com/ZjFFz.png'; | |
var myLatLng = new google.maps.LatLng({7.lat}, {8.lon}); | |
var uranusmarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Uranus" | |
]); | |
var image = 'http://i.imgur.com/0jqrc.png'; | |
var myLatLng = new google.maps.LatLng({8.lat},{8.lon}); | |
var neptunemarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Neptune" | |
]); | |
var image = 'http://i.imgur.com/axDH0.png'; | |
var myLatLng = new google.maps.LatLng({9.lat}, {9.lon}); | |
var plutomarker = new google.maps.Marker([ | |
position: myLatLng, | |
map: map, | |
icon: image, | |
title: "Pluto" | |
]); | |
] | |
</script> | |
</head> | |
<p> This page shows the real-time locations of the planets in the solar system, to scale | |
In order to change the location the planets are rendered from, change the arguments in the page's address. lat and lon should be the latitude and longitude of the sun's location, and sun is the scaled radius of the sun, in meters. | |
E.g. to have the planets centered on the physical science building at cornell university, and corresponding to a sun radius of 0.1 m, set the address to the following: | |
<pre> | |
.../planets.py?lat=42.449741&lon=-76.48165&sun=0.1 | |
</pre> | |
</p> | |
<p> | |
The current settings are: Latitude: {0.lat}, Longitude: {0.lon}, Sun-radius: {sun} meters | |
</p> | |
<p> Planetary positions are calculated according to <a href="http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf">this NASA brief</a> | |
</p> | |
<center> | |
<table border=1> | |
<tr><td> Body <td> Latitude <td> Longitude | |
<tr><td> Sun <td> {0.lat} <td> {0.lon} | |
<tr><td> Mercury <td> {1.lat} <td> {1.lon} | |
<tr><td> Earth <td> {2.lat} <td> {2.lon} | |
<tr><td> Mars <td> {3.lat} <td> {3.lon} | |
<tr><td> Jupiter <td> {4.lat} <td> {4.lon} | |
<tr><td> Saturn <td> {5.lat} <td> {5.lon} | |
<tr><td> Uranus <td> {6.lat} <td> {6.lon} | |
<tr><td> Neptune <td> {7.lat} <td> {7.lon} | |
<tr><td> Pluto <td> {8.lat} <td> {8.lon} | |
</table> | |
</center> | |
<p> | |
Brought to you by <a href="http://thevirtuosi.blogspot.com">TheVirtuosi</a>. Code available at <a href="https://gist.github.com/1149902">this gist</a>. | |
<body onload="initialize()"> | |
<div id="map_canvas"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python | |
""" Calculation of planetary positions, | |
according to http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf """ | |
#IMPORTS | |
import cgi | |
form = cgi.FieldStorage() | |
import time | |
import datetime | |
import calendar | |
from math import sin, cos, sqrt, atan2, asin | |
#Define some useful constants | |
J2000 = calendar.timegm( datetime.datetime(2000,1,1,12,0).timetuple() ) | |
PI = 3.141592653589793 | |
DEG = 180./PI | |
TOL = 10.**(-6) | |
EP = 23.43928/DEG | |
R = 6378100. #radius of earth in meters | |
#START COORD | |
#grab the lat and long from the form request | |
from collections import namedtuple | |
gps = namedtuple('gps','lat lon') | |
if 'lat' in form: | |
lat = float(form['lat'].value) | |
else: | |
lat = 42.449741 | |
if 'lon' in form: | |
lon = float(form['lon'].value) | |
else: | |
lon = -76.48165 | |
#internally, use a named tuple for gps coords | |
START = gps(lat=lat,lon=lon) | |
#grab the sun's radius from form | |
if 'sun' in form: | |
sun = float(form['sun'].value) | |
else: | |
sun = 0.1 | |
# worked out the units | |
SCALE = 215.1 * sun # radius of sun in meters | |
#convert unix time to Jtime | |
def current_Jtime(ttime=None): | |
""" Convert a time in unix seconds since epoch to Jtime, | |
which is centuries past J2000 """ | |
if ttime is None: | |
ttime = time.time() | |
Jtime = (ttime - J2000)/(60.*60.*24.*36525) | |
return Jtime | |
class Planet(object): | |
""" A planet, given its orbital data, can compute its position at any time | |
follows the instructions at: http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf """ | |
def __init__(self, name, | |
a0, adot, | |
e0, edot, | |
I0, Idot, | |
L0, Ldot, | |
pomega0, pomegadot, | |
Omega0, Omegadot): | |
self.name = name | |
self.a0 = a0 | |
self.adot = adot | |
self.e0 = e0 | |
self.edot = edot | |
self.I0 = I0 | |
self.Idot = Idot | |
self.L0 = L0 | |
self.Ldot = Ldot | |
self.pomega0 = pomega0 | |
self.pomegadot = pomegadot | |
self.Omega0 = Omega0 | |
self.Omegadot = Omegadot | |
def __repr__(self): | |
return "<Planet: {0.name}, lat={0.gps.lat}, lon={0.gps.lon}>".format(self) | |
def _anomoly(self,M, e): | |
""" Compute the eccentric anomoly stepwise """ | |
estar = DEG * e | |
E0 = M + estar * sin( M / DEG) | |
E = E0 | |
DeltaE = 1. | |
while DeltaE > TOL: | |
DeltaM = M - ( E - estar * sin( E/DEG ) ) | |
DeltaE = DeltaM / ( 1. - e* cos( E/DEG) ) | |
E += DeltaE | |
return E | |
@property | |
def position(self,ttime = None): | |
""" Compute the position of a planet given a time """ | |
##STEP 1 | |
Jtime = current_Jtime( ttime ) | |
a = self.a0 + self.adot * Jtime | |
e = self.e0 + self.edot * Jtime | |
I = self.I0 + self.Idot * Jtime | |
L = self.L0 + self.Ldot * Jtime | |
pomega = self.pomega0 + self.pomegadot * Jtime | |
Omega = self.Omega0 + self.Omega0 * Jtime | |
##STEP 2 | |
#compute perihelion | |
omega = pomega - Omega | |
#compute mean anomoly | |
M = L - pomega | |
##STEP 3 | |
#modulus M to -180 to 180 | |
M = ( ( M + 180. ) % 360. ) - 180. | |
E = self._anomoly( M, e ) | |
##STEP 4 | |
x_prime = a * ( cos( E/DEG ) - e ) | |
y_prime = a * sqrt( 1. - e**2 ) * sin( E / DEG ) | |
z_prime = 0. | |
##STEP 5 | |
x_ecl = (cos(omega/DEG)*cos(Omega/DEG) - sin(omega/DEG)*sin(Omega/DEG)*cos(I/DEG) ) * x_prime + (-sin(omega/DEG)*cos(Omega/DEG) - cos(omega/DEG)*sin(Omega/DEG)*cos(I/DEG) ) * y_prime | |
y_ecl = (cos(omega/DEG)*sin(Omega/DEG) + sin(omega/DEG)*cos(Omega/DEG)*cos(I/DEG) )*x_prime + (-sin(omega/DEG)*sin(Omega/DEG) + cos(omega/DEG)*cos(Omega/DEG)*cos(I/DEG) )*y_prime | |
z_ecl = (sin(omega/DEG)*sin(I/DEG) )*x_prime + (cos(omega/DEG)*sin(I/DEG) )*y_prime | |
##STEP 6 (THOUGH WE WON'T USE IT) | |
x_eq = x_ecl | |
y_eq = cos(EP)*y_ecl - sin(EP)*z_ecl | |
z_eq = sin(EP)*y_ecl + cos(EP)*z_ecl | |
return (x_ecl,y_ecl,z_ecl) | |
@property | |
def polar(self): | |
""" Returns polar coordinates, with theta from north """ | |
x,y,z = self.position | |
r = sqrt( x**2 + y**2 ) | |
theta = atan2(x,y) | |
return r,theta | |
@property | |
def gps(self): | |
""" Get the gps coordinates of the planets """ | |
r,theta = self.polar | |
rscaled = r * SCALE | |
lat = DEG * asin( sin( START.lat / DEG) * cos( rscaled/R) + cos(START.lat/DEG)*sin(rscaled/R)*cos(theta)) | |
lon = START.lon + DEG * atan2( sin(theta) * sin(rscaled/R) * cos(START.lat/DEG) , cos(rscaled/R) - sin(START.lat / DEG) * sin( lat/DEG) ) | |
return gps(lat,lon) | |
#Create planets, from data in NASA table at: | |
# http://ssd.jpl.nasa.gov/txt/aprx_pos_planets.pdf | |
mercury = Planet("Mercury", 0.38709927,0.00000037, | |
0.20563593,0.00001906, | |
7.00497902,-0.00594749, | |
252.25032350,149472.67411175, | |
77.45779628,0.16047689, | |
48.33076593,-0.12534081) | |
venus = Planet("Venus", 0.7233566,0.00000390, | |
0.00677672,-0.00004107, | |
3.39467605,-0.00078890, | |
181.97909950,58517.81538729, | |
131.60246718,0.00268329, | |
76.67984255,-0.27769418) | |
earth = Planet("Earth", 1.00000261,0.00000562, | |
0.01671123,-0.00004392, | |
-0.00001531,-0.01294668, | |
100.46457166,35999.37244981, | |
102.93768193,0.32327364, | |
0.0,0.0) | |
mars = Planet("Mars", 1.52371034,0.00001847, | |
0.09339410,0.00007882, | |
1.84969142,-0.00813131, | |
-4.55343205,19140.30268499, | |
-23.94362959,0.44441088, | |
49.55953891,-0.29257343) | |
jupiter = Planet("Jupiter", 5.20288700,-0.00011607, | |
0.04838624,-0.00013253, | |
1.30439695,-0.00183714, | |
34.39644051,3034.74912775, | |
14.72847983,0.21252668, | |
100.47390909,0.20469106) | |
saturn = Planet("Saturn", 9.53667594,-0.00125060, | |
0.05386179,-0.00050991, | |
2.48599187,0.00193609, | |
49.95424423,1222.49362201, | |
92.59887831,-0.41897216, | |
113.66242448,-0.28867794) | |
uranus = Planet("Uranus", 19.18916464,-0.00196176, | |
0.04725744, -0.00004397, | |
0.77263783,-0.00242939, | |
313.23810451,428.48202785, | |
170.95427630,0.40805281, | |
74.01692503,0.04240589) | |
neptune = Planet("Neptune", 30.06992276,0.0026291, | |
0.00859048,0.00005105, | |
1.77004347,0.00035372, | |
-55.12002969,218.45945325, | |
44.96476227,-0.32242464, | |
131.78422574,-0.00508664) | |
pluto = Planet("Pluto", 39.48211675,-0.00031596, | |
0.24882730,0.00005170, | |
17.14001206,0.00004818, | |
238.92903833,145.20780515, | |
224.06891629,-0.04062942, | |
110.30393684,-0.01183482) | |
#create a list of planets | |
planets = [mercury,venus,earth,mars,jupiter,saturn,uranus,neptune,pluto] | |
#ensure that we can make a nice page | |
print "Content-Type: text/html" | |
coords = [START] + [ p.gps for p in planets ] | |
#compute the positions and place into the maps.html format | |
output = open('maps.html','r').read() | |
output = output.format(*coords,sun=sun) | |
# a trick to allow python string formatting | |
output = output.replace('[','{') | |
output = output.replace(']','}') | |
print output |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a python cgi script and html template that creates a google maps map with the planets current positions put on it, scaled to size according to the chosen sun radius.