For quite a while, I’ve used XPlanet to display a graphic of the earth.

XPlanet is capable of drawing many different views of the earth, as well as projection types such as mercator or orthographic. You can also overlay other information on top of the basic earth image such as clouds, images such as satellites, and labels.

Installing XPlanet

Installing XPlanet is pretty easy with homebrew. (This assumes you already have homebrew and Xcode tools installed. If not, see this post ). Open Termainal.app and type in the following:

brew install xplanet --with-aqua

Lingon X/launchd

I drive the XPlanet image creation from a collection of scripts, fired off by launchd periodically. To make things easy, I use Lingon X to manage my launchd configurations. It looks like this:

Cloud Downloading

The first script is called xplanet_download_clouds.pl. As you might expect, it downloads a cloud file that XPlanet will use to show what the current cloud cover (of the whole planet) looks like.

#!/usr/bin/perl
# 
# Louis Kowolowski © 2009 - 2015
# download table updated 17 JANUARY 2009

use warnings;
use strict;
use LWP::Simple;

# Set options:
#  - where to save the downloaded file (default is current directory)
my $Filename = "/Users/louisk/.xplanet/images/clouds.jpg";

# - how often the image is updated on the server
my $MaxDownloadFrequencyHours = 3;

# - how many times to retry, if the server doesn't respond
my $MaxRetries = 9;

my $Response = "";

# Download the file
print "Downloading...\n";
$Response = getstore("http://xplanetclouds.com/free/local/clouds_2048.jpg", $Filename);

The Lingon/plist screenshot for this is

Marker Downloading

The second script is called xplanet_download_marker.pl. This pulls down information about various places of interest and generates a marker file that will be used by XPlanet to illustrate the places of interest on the image.

#!/usr/bin/perl
#
# Download marker files for xplanet
# Louis Kowolowski © 2009 - 2015

use warnings;
use strict;
use LWP::Simple;

my $uname = `uname`;
my $file_base = "/Users/louisk/.xplanet/";
my @satellite_arr = ('iss.tle', 'iss');
my @marker_arr = ('volcano','storm','quake');
my @arc_arr = ('storm');
my $quake_min = "6.0";

chomp ($uname);
my($me) = "$0";
$me =~ s#^.*/##;

#&getopts('f:Tv');
# f: file to open
# T: if specified, test mode -- don't actually do it
# v: verbose -- chat about progress
#my $file = ${opt_f};

sub get_markers () {
	foreach my $marker ( @marker_arr ) {
		my $get_marker = get "http://www.wizabit.eclipse.co.uk/xplanet/files/local/$marker";
		# check whether we have a successful get or not
			my @get_marker_arr = split ('\n',$get_marker);
			my $marker_file = "$file_base" . "/markers/" . "$marker";
			open(OFILE, "> $marker_file") || die ("Can't open $marker_file: $!");
			my $next_line = "";
			for (my $i = 0; $i < @get_marker_arr; $i+=2) {
				my $curr_line = $get_marker_arr[$i];
				$next_line = $get_marker_arr[$i + 1];
				next unless $curr_line =~ m/\"[5-9]\.\d\"/;
				print OFILE "$curr_line\n" unless $curr_line eq "";
			}
			close OFILE;			
	}
}

sub get_satellites () {
	foreach my $marker ( @satellite_arr ) {
		my $get_marker = get "http://www.wizabit.eclipse.co.uk/xplanet/files/local/$marker";
		my @get_marker_arr = split ('\n', $get_marker);
		my $marker_file = "$file_base" . "/satellites/" . "$marker";
			open(OFILE, "> $marker_file") || die ("Can't open $marker_file: $!");
			foreach my $line ( @get_marker_arr ) {
				print OFILE "$line\n" unless $line eq "";
			}
			close OFILE;
	}
	my $get_visible = get "http://celestrak.com/NORAD/elements/visual.txt";
	my $visible_file = "$file_base" . "satellites/visible-satellites.tle";
	my @get_visible_arr = split ('\n', $get_visible);
	open(OFILE, "> $visible_file") || die ("Can't open $visible_file: $!");
	foreach my $line ( @get_visible_arr ) {
		print OFILE "$line\n" unless $line eq "";
	}
	close OFILE;
}

sub get_arcs () {
	foreach my $marker ( @arc_arr ) {
		my $get_marker = get "http://www.wizabit.eclipse.co.uk/xplanet/files/local/arcs/$marker";
		my @get_marker_arr = split ('\n', $get_marker);
		my $marker_file = "$file_base" . "/arcs/" . "$marker";
		open(OFILE, "> $marker_file") || die ("Can't open $marker_file: $!");
		foreach my $line ( @get_marker_arr ) {
			print OFILE "$line\n" unless $line eq "";
		}
		close OFILE;
	}
}

# Get func-e and call those bad boys!
get_arcs;
get_satellites;
get_markers;

The Lingon/plist screenshot for this is

Satellite Downloading

The third script is called xplanet_download_satellite.pl. This pulls down information about some satellites such as ISS. With this information, XPlanet can draw not only the location but also the trajectory of the satellites.

#!/usr/bin/perl

# Download satellite info for xplanet
#
# Louis Kowolowski © 2009 - 2015
# 

use warnings;
use strict;
use LWP::Simple;

my $uname = `uname`;
my $iss_file = "/Users/louisk/.xplanet/satellites/iss.tle";
my $visible_file = "/Users/louisk/.xplanet/satellites/visible.tle";
chomp ($uname);

sub get_iss () {
	my $get_iss = get 'http://celestrak.com/NORAD/elements/stations.txt';
	open(OFILE, "> $iss_file") || die ("Can't open $iss_file: $!");
	print OFILE "$get_iss" unless $get_iss eq "";
	close OFILE;
}

sub get_visible () {
	my $get_visible = get 'http://celestrak.com/NORAD/elements/visual.txt';
	open(OFILE, "> $visible_file") || die ("Can't open $visible_file: $!");
	print OFILE "$get_visible" unless $get_visible eq "";
	close OFILE;
}

## Get func-e and call those bad boys!
get_iss;
get_visible;

The Lingon/plist screenshot for this is

XPlanet

The last script is called xplanet.sh. This collects all the information and then finally calls the xplanet binary to actually generate the image.

#!/bin/sh

PATH="/bin:/usr/bin:/usr/local/bin"

XPLANET=`which xplanet`
# Generic image directory
XPLANET_IMAGES="/Users/louisk/.xplanet/images"

# figure out the numeric month
MONTH=`/bin/date +%m`
# link day map image to correct month image
cd /Users/louisk/.xplanet/images && ln -f ${MONTH}.jpg day_map.jpg

# Pick the background of the earth depending on which month it is
DAYMAP="/Users/louisk/.xplanet/images/${MONTH}.jpg"
CONF_FILE="/Users/louisk/.xplanet/xplanet.conf"
OUTPUT="/Users/louisk/.xplanet/images/$$.xplanet.jpg"

# Center over where I am (not always accurate, but usually close enough)
source /Users/louisk/.xplanet/location.sh

# keep output the same size as input file
GEOMETRY="4096x2048"

# rectangular fills whole screen
PROJECTION="rectangular"

# set fontsize to 24
FONTSIZE=24

# do it
${XPLANET} --num_times 1 -fontsize ${FONTSIZE} -config ${CONF_FILE} -latitude ${Latitude} -longitude ${Longitude} -projection ${PROJECTION} -geometry ${GEOMETRY} -output ${OUTPUT}

mv ${OUTPUT} /Users/louisk/Pictures/xplanet.jpg

The Lingon/plist screenshot for this is

Once the image has been created, I use Geektool to show the image on the desktop (something akin to a thumbnail, since the original is 4k x 2k). Geektool allows you to choose the size, and location of the ‘geeklet’ that you want to put on your desktop. geeklets can contain text, or images. They can have custom colors and locations.

A screenshot of geektool looks like

A screenshot of my desktop (showing the output from xplanet in the top center) looks like: