Skip to content

Instantly share code, notes, and snippets.

@alexalemi
Created August 16, 2011 19:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexalemi/1149902 to your computer and use it in GitHub Desktop.
Save alexalemi/1149902 to your computer and use it in GitHub Desktop.
Scaled Planetary Positions Google Map
<!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>
#! /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"
print
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
@alexalemi
Copy link
Author

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.

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