User:AeroIllini/GeoHistory
From Geo Hashing
[edit] GeoHistory
GeoHistory is a perl script that outputs a kml file containing every historical geohash point in a specific graticule since a specified date. This can be used to get a retroactive Couch Potato Award, apply for a Curse of Unawareness Award, or simply study past geohash points.
[edit] Requirements
Runs under Linux with Perl 5.12.
The script outputs to stdout, so you should really pipe the output to a file to work with it.
This script requires the following CPAN Modules:
- Geo::Hashing
- Date::Calc
- Time::Local
[edit] Source Code
#! /usr/bin/perl
#
# GeoHistory - (C) 2012 AeroIllini <aeroillini@gmail.com>
#
# This script generates a kml file containing placemarks for every
# geohash point in a certain graticule since a certain date. The
# default start date is May 21, 2008, which is the date the comic
# first appeared and Geohashing was born.
#
# The output should be piped to a file, and then either loaded in
# Google Earth or hosted on a public server and loaded in Google
# Maps.
#
# The script can be used to explore the random distribution of points,
# or to check for retroactive Couch Potato Awards (or Curse of
# Unawareness Awards).
#
# More information on Geohashing:
# <http://wiki.xkcd.com/geohashing/Main_Page>
#
# ---------------------------------------------------------------------
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# ---------------------------------------------------------------------
# Import some useful stuff.
use Date::Calc qw(Add_Delta_Days Delta_Days);
use Time::Local;
use Geo::Hashing;
# This is the start date. Modify as you see fit.
($startyear, $startmonth, $startday) = ("2008", "5", "21");
# This is the graticule we're calculating for.
($lat, $lon) = ("47", "-122");
# Grab the current date.
($a,$a,$a,$todayday,$todaymonth,$todayyear,$a,$a,$a) = localtime(time);
# Translate months for placemark titles.
@months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
# Do some interim math.
$todayyear = $todayyear+1900;
$todaymonth = $todaymonth+1;
($year, $month, $day) = ($startyear, $startmonth, $startday);
$delta = Delta_Days(($startyear, $startmonth, $startday),($todayyear,$todaymonth,$todayday));
# Output file header xml stuff
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<kml xmlns=\"http://www.google.com/earth/kml/2\">
<Document>
<name>Historical Geohash Points for ",$lat,",",$lon,"</name>
";
# Main loop
for ($i = 0; $i <= $delta; $i++) {
# format date for Geo::Hashing
my $date = sprintf("%04d-%02d-%02d", $year, $month, $day);
# magic happens!
my $geo = new Geo::Hashing(lat => $lat, lon => $lon, date => $date);
# output placemark xml
print "<Placemark>";
print "<name>";
print $months[$month-1]," ",$day,", ",$year;
print "</name>";
print "<description>",$geo->lat,", ",$geo->lon,"</description>";
print "<Point><coordinates>",$geo->lon,",",$geo->lat,"</coordinates></Point>";
print "</Placemark>","\n";
# increment day and loop again!
($year, $month, $day) = Add_Delta_Days($startyear, $startmonth, $startday, $i);
}
# finish up xml file
print "</Document>
</kml>";
[edit] Global Hash Version
This version spits out all historical global hashes in a kml. Note that you have to set the use_30w_rule in the Geo::Hashing object.
#! /usr/bin/perl
use Date::Calc qw(Add_Delta_Days Delta_Days);
use Time::Local;
use Geo::Hashing;
@months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
($startyear, $startmonth, $startday) = ("2008", "5", "21");
($year, $month, $day) = ($startyear, $startmonth, $startday);
($lat, $lon) = ("47", "-122");
($a,$a,$a,$todayday,$todaymonth,$todayyear,$a,$a,$a) = localtime(time);
$todayyear = $todayyear+1900;
$todaymonth = $todaymonth+1;
$delta = Delta_Days(($startyear, $startmonth, $startday),($todayyear,$todaymonth,$todayday));
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<kml xmlns=\"http://www.google.com/earth/kml/2\">
<Document>
<name>Historical Global Geohash Points</name>
";
for ($i = 0; $i <= $delta; $i++) {
my $date = sprintf("%04d-%02d-%02d", $year, $month, $day);
my $geo = new Geo::Hashing(date => $date, use_30w_rule => "1");
$globallat = ($geo->lat * 180) - 90;
$globallon = ($geo->lon * 360) - 180;
print "<Placemark>";
print "<name>";
print $months[$month-1]," ",$day,", ",$year;
print "</name>";
print "<description>Global: ",$globallat,", ",$globallon,"</description>";
print "<Point><coordinates>",$globallon,",",$globallat,"</coordinates></Point>";
print "</Placemark>","\n";
($year, $month, $day) = Add_Delta_Days($startyear, $startmonth, $startday, $i);
}
print "</Document>
</kml>";