index.php
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Geohashing KML Calculator</title>
<link href="testForm.css" rel="stylesheet" type="text/css">
</head>
<body>
<h1> Geohashing KML Calculator</h1>
<p><img src="Sourcerer%20KML.jpg" alt="KML Calculator" width="615" height="451" /></p>
<ul>
<li>This tool works in conjunction with KML aware applications like <a href="https://www.google.com/earth/versions/#earth-pro">Google Earth Pro Desktop</a> and <a href="https://marble.kde.org/">Marble</a>.</li>
<li>When you submit the form, if your PC is correctly set up, Google Earth Desktop will launch and show the calculated hashpoints.</li>
<li>This seems to work on Android mobile phones and perhaps others too.</li>
<li>UK geohashers might find the link to the Ordnance Survey maps particularly useful. Outside the UK you just get the normal Bing maps.</li>
<li>Use this form or make a bookmark or shortcut - like this<br>
<b>https://nbest.co.uk/kmlGeohash/index.php?date=2016-01-31&lat=52&lon=-1&clat=52.5&clon=1.5&skins=3</b>
</li>
<li>For the <strong>Globalhash</strong>, zoom out until it comes into view.</li>
</ul>
<form action="calculator.php" id="kmlForm">
<table>
<tr>
<td style="text-align:center;"><strong>date</strong></td>
<td><input name="date" type="text" id="f_date" size="12" maxlength="10" onKeyUp="urlGen()"></td>
<td><strong>Date: yyyy-mm-dd</strong> - if blank, the date defaults to today - alternatively use -7 to 7, 1 means tomorrow, -2 is the day before yesterday.</td>
</tr>
<tr>
<td style="text-align:center;"><strong>lat</strong></td>
<td><input name="lat" type="text" id="f_lat" size="12" maxlength="4" onKeyUp="urlGen()"></td>
<td><strong>Latitude: -89 to 89</strong> - if blank, the latitude defaults to 51 (Grenwich). Whole numbers please.</td>
</tr>
<tr>
<td style="text-align:center;"><strong>lon</strong></td>
<td><input name="lon" type="text" id="f_lon" size="12" maxlength="4" onKeyUp="urlGen()"></td>
<td><strong>Longitude: -179 to 179</strong> - if blank, the longitude defaults to 0 (Grenwich meridian). Whole numbers please.</td>
</tr>
<tr>
<td style="text-align:center;"><strong>clat</strong></td>
<td><input name="clat" type="text" id="f_clat" size="12" maxlength="4" onKeyUp="urlGen()"></td>
<td><strong>Centre Latitude: -89.9999 to 89.9999</strong> - optional view centre. It's OK to leave this blank. </tr>
<tr>
<td style="text-align:center;"><strong>clon</strong></td>
<td><input name="clon" type="text" id="f_clon" size="12" maxlength="4" onKeyUp="urlGen()"></td>
<td><strong>Centre Longitude: -179.9999 to 179.9999</strong> - - optional view centre. It's OK to leave this blank. </tr>
<tr>
<td style="text-align:center;"><strong>skins</strong></td>
<td><input name="skins" type="text" id="f_skins" size="12" maxlength="1" onKeyUp="urlGen()"></td>
<td><strong>Skins: 0 to 6.</strong> The default is 1. This gives 9 hashpoints. 6 skins will give you 169 hashpoints.</td>
</tr>
<tr>
<td style="text-align:center;"><strong>debug</strong></td>
<td style="text-align:center;"><input name="debug" type="checkbox" id="f_debug" value="debug" onClick="urlGen()"></td>
<td><strong>Debug:</strong> Check this to get debuging information. The KML data will be shown as text.</td>
</tr>
<tr>
<td> </td>
<td style="text-align:center;"><p><input type="submit" name="Submit" id="Submit" value="Submit"></p></td>
<td><span id="f_url"></span></td>
</tr>
</table>
</form>
<p><strong>Disclaimer:</strong> Do no damage. Don't disturb people, animals or the environment. Stay safe!</p>
<p><a href="https://wiki.xkcd.com/geohashing/User:Sourcerer/KML_tool">Geohashing Wiki</a> - <a href="https://github.com/nbauers/Geohashing-KML-Calculator">Code on GitHub</a> - <a href="source.php">Calculator Live Source</a></p>
<script>
// -------------------------------------------------------------
// https://nbest.co.uk/kmlGeohash/calculator.php?date=2016-01-01&lat=52&lon=0&skins=1
function urlGen() {
var f_date = document.forms["kmlForm"]["f_date"].value;
var f_lat = document.forms["kmlForm"]["f_lat"].value;
var f_lon = document.forms["kmlForm"]["f_lon"].value;
var f_clat = document.forms["kmlForm"]["f_clat"].value;
var f_clon = document.forms["kmlForm"]["f_clon"].value;
var f_skins = document.forms["kmlForm"]["f_skins"].value;
var f_debug = "";
if (document.forms["kmlForm"]["f_debug"].checked){
f_debug = "debug";
}else{
f_debug = "";
}
var f_url = "<pre><a href=\"https://nbest.co.uk/kmlGeohash/calculator.php?date=" + f_date;
f_url = f_url + "&lat=" + f_lat;
f_url = f_url + "&lon=" + f_lon;
f_url = f_url + "&clat=" + f_clat;
f_url = f_url + "&clon=" + f_clon;
f_url = f_url + "&skins=" + f_skins;
f_url = f_url + "&debug=" + f_debug;
f_url = f_url + "\">https://nbest.co.uk/kmlGeohash/calculator.php?date=" + f_date;
f_url = f_url + "&lat=" + f_lat;
f_url = f_url + "&lon=" + f_lon ;
f_url = f_url + "&clat=" + f_clat;
f_url = f_url + "&clon=" + f_clon;
f_url = f_url + "&skins=" + f_skins;
f_url = f_url + "&debug=" + f_debug;
f_url = f_url + "</a></pre>";
// console.log(f_url);
document.getElementById("f_url").innerHTML = f_url;
}
// -------------------------------------------------------------
</script>
</body>
</html>
calculator.php
<?php
// -----------------------------------------------------------------------------------------
// This code should be run from a PHP enabled web server.
// Call up the page with your choice of date, latitude, longitude, skins and debug mode
//
// There is an input form ...
// https://nbest.co.uk/kmlGeohash/testForm.php
//
// Or call the calculator page directly - all the parameters have default values if omitted
// https://nbest.co.uk/kmlGeohash/index.php?date=2015-12-12&lat=52&lon=-0&skins=2&debug=debug
// -----------------------------------------------------------------------------------------
require_once("hash_up.php"); // Geohashing functions
require_once("html_gen.php"); // html functions
require_once("kml_gen.php"); // KML functions
// -----------------------------------------------------------------------------------------
$djia_e = false;
$djia_w = false;
$msg = "";
// -----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Validate $_GET
// ---------------------------------------------------------------------------------------
$clean_get = clean_up_get_params($_GET);
extract($clean_get);
// ---------------------------------------------------------------------------------------
// ==== FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL FAIL ====
//html_head();
//echo "<p>This Geohashing KML Calculator is on the blink. I'm working on a fix. 2018-02-02</p>";
//echo "<p>http://carabiner.peeron.com/xkcd/map/data/yyyy-mm-dd seems to be refusung connections.</p>";
//html_tail();
//exit;
// ==========================================================================
// ---------------------------------------------------------------------------------------
if ($get_debug)
{
html_head();
echo "<h2>Debug Mode</h2>\n";
echo "<hr>\n";
echo "<pre>\$_GET\n" . print_r($_GET, true) . "</pre>\n";
echo "<pre>\$clean_get\n" . print_r($clean_get, true) . "</pre>\n";
echo "<p>\$get_date $get_date<br>\$get_lat $get_lat<br>\$get_lon $get_lon<br>\$get_skins $get_skins<br>\$get_debug $get_debug</p>\n";
}
// ---------------------------------------------------------------------------------------
// Get djia values for date and day before - could be null
// ---------------------------------------------------------------------------------------
list($djia_e, $djia_w, $msg) = get_djias($get_date, $get_debug);
// ---------------------------------------------------------------------------------------
if ($get_debug)
{
echo "<p>";
if ($djia_e) echo "\$djia_e = $djia_e<br>\n";
if ($djia_w) echo "\$djia_w = $djia_w<br>\n";
echo "\$msg: $msg";
echo "</p>\n";
}
if (($djia_w === false) && ($djia_e === false)) // If both djia values are missing ...
{
if ($get_debug)
{
echo "<h3>$msg</h3>";
}
else
{
html_head();
echo "<h3>$msg</h3>\n\n";
html_tail();
exit;
}
}
// ---------------------------------------------------------------------------------------
// Get coordinates for east and west of 30W
// ---------------------------------------------------------------------------------------
if ($djia_e) list($lat_e, $lon_e) = get_coords($get_date, $djia_e, $get_debug);
if ($djia_e) list($lat_g, $lon_g) = get_global($get_date, $djia_e, $get_debug);
if ($djia_w) list($lat_w, $lon_w) = get_coords($get_date, $djia_w, $get_debug);
// ---------------------------------------------------------------------------------------
if ($get_debug)
{
echo "<p>";
if ($djia_e) echo "\$lat_e = $lat_e \$lon_e = $lon_e";
if ($djia_w) echo "<br>\$lat_w = $lat_w \$lon_w = $lon_w<br><br>\$lat_g = $lat_g \$lon_g = $lon_g";
echo "</p>\n\n";
}
$day = date('D', strtotime($get_date)); // Get "Mon" or something similar from 2016-01-25
$day_nn = $day . " " . substr ($get_date, 8 ); // Get "Mon 25" or something similar from 2016-01-25
$kml = "";
$countPins = 0;
if ($djia_e || $djia_w) // Do the nested for loops ...
{
if ($get_debug)
{
echo "<table style=\"border-collapse: collapse; border:solid 1px #bbb;\">\n";
echo " <tr>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">\$grat_lat</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">\$grat_lon</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">\$lat</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">\$lon</td>\n";
echo " <tr>\n";
}
$kml_head = ""; // $kml_head = kml_begin($get_date . "_$day.kml", $lat, $lon); // It's more convenient to get this inside the nested loop below
$kml .= kml_style(); // push pin and styles
$min_lat = 90;
$min_lon = 180;
$max_lat = -90;
$max_lon = -180;
// -------------------------------------------------------------------------------------
// GLOBAL HASH PUSH PIN
// -------------------------------------------------------------------------------------
if ($djia_e)
{
$kml .= kml_folder_start("Global Points");
$kml .= kml_globalmark($get_date, $lat_g, $lon_g, $day_nn); // kml global placemark
$kml .= kml_folder_end();
}
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// Generate the local push pins
// -------------------------------------------------------------------------------------
$count = 0;
$kml .= kml_folder_start("Graticule Points");
for ($yy_lat = -$get_skins; $yy_lat < ($get_skins + 1); $yy_lat++) { // Iterate through latitudes (vertical)
for ($xx_lon = -$get_skins; $xx_lon < ($get_skins + 1); $xx_lon++) { // Iterate through longitudes (horizontal)
if ((($get_lon + $xx_lon < -30) && ($djia_w)) || ($get_lon + $xx_lon >= -30))
{
// -------------------------------------------------------------------------
// $yy_lat -3, -2, -1, 0, 1, 2, 3 Iterator Index
// -2, -1, -0, 0, 1, 2, 3 Graticule name
// -------------------------------------------------------------------------
if ($get_lon + $xx_lon >= -30) // Use $lat_e and $lon_e
{
if ($get_lat + $yy_lat >= 0) // North of the equator
{
$lat = $get_lat + $yy_lat + $lat_e;
}
else
{
$lat = 1 + $get_lat + $yy_lat - $lat_e;
}
if ($get_lon + $xx_lon >= 0) // East of the meridian
{
$lon = $get_lon + $xx_lon + $lon_e;
}
else
{
$lon = 1 + $get_lon + $xx_lon - $lon_e;
}
}
else // Use $lat_w and $lon_w
{
if ($get_lat + $yy_lat >= 0) // North of the equator
{
$lat = $get_lat + $yy_lat + $lat_w;
}
else
{
$lat = 1 + $get_lat + $yy_lat - $lat_w;
}
if ($get_lon + $xx_lon >= 0) // East of the meridian
{
$lon = $get_lon + $xx_lon + $lon_w;
}
else
{
$lon = 1 + $get_lon + $xx_lon - $lon_w;
}
}
// -------------------------------------------------------------------------
if ($get_lat + $yy_lat >= 0) { $grat_lat = $get_lat + $yy_lat; } else { $grat_lat = 1 + $get_lat + $yy_lat; }
if ($get_lat + $yy_lat == -1) { $grat_lat = "-" . $grat_lat; }
if ($get_lon + $xx_lon >= 0) { $grat_lon = $get_lon + $xx_lon; } else { $grat_lon = 1 + $get_lon + $xx_lon; }
if ($get_lon + $xx_lon == -1) { $grat_lon = "-" . $grat_lon; }
// -------------------------------------------------------------------------
if ($get_debug)
{
echo " <tr>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">$grat_lat</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">$grat_lon</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">$lat</td>\n";
echo " <td style=\"border-style:solid; border:solid 1px #bbb; padding:2px;\">$lon</td>\n";
echo " <tr>\n";
}
if (($yy_lat == 0) && ($xx_lon == 0))
{
if (($get_clat != "") && ($get_clon != ""))
{
$kml_head = kml_begin($get_date . "_" . $day . "_" . round($lat_g) . "_" . round($lon_g) . ".kml", $get_clat, $get_clon, 150000); // kml head section
}
else
{
$kml_head = kml_begin($get_date . "_" . $day . "_" . round($lat_g) . "_" . round($lon_g) . ".kml", $lat, $lon, 1000); // kml head section
}
}
if ($kml_head == "") $kml_head = kml_begin($get_date . "_" . $day . "_" . round($lat_g) . "_" . round($lon_g) . ".kml", $lat, $lon, 1000);
$kml .= kml_placemark($get_date, $grat_lat, $grat_lon, $lat, $lon, $day_nn); // kml placemark
$countPins++;
// -------------------------------------------------------------------------------
// mnn: Convert -0 notation to useable coordinates
// 1 => 1 0 => 0 -0 => -1 -1 => -2 etc.
// -------------------------------------------------------------------------------
if (mnn($grat_lat) <= $min_lat) $min_lat = mnn($grat_lat); // -2 -1 -0 0 1 2 3
if (mnn($grat_lon) <= $min_lon) $min_lon = mnn($grat_lon); // -3 -2 -1 0 1 2 3
if (mnn($grat_lat) >= $max_lat) $max_lat = mnn($grat_lat);
if (mnn($grat_lon) >= $max_lon) $max_lon = mnn($grat_lon);
if ($get_debug) echo "! " . mnn($grat_lat) . " " . mnn($grat_lon) . "<br>";
// -------------------------------------------------------------------------------
if ($count++ > 200) break; // Discourage infinite loops!
} // if ((($get_lon + $xx_lon < -30) && ($dija_w_found)) || ($get_lon + $xx_lon >= -30))
} // for ($xx_lon = -$get_skins; $xx_lon < ($get_skins + 1); $xx_lon++) { // Iterate through longitudes (horizontal)
} // for ($yy_lat = -$get_skins; $yy_lat < ($get_skins + 1); $yy_lat++) { // Iterate through latitudes (vertical)
// -------------------------------------------------------------------------------------
$kml .= kml_folder_end();
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// Draw the grid lines
// -------------------------------------------------------------------------------------
if ($get_debug) echo "<p>\$min_lat $min_lat<br>" .
"\$min_lon $min_lon<br>" .
"\$max_lat $max_lat<br>" .
"\$max_lon $max_lon</p>";
$count = 0;
$kml .= kml_folder_start("Grid Lines");
for ($yy = $min_lat; $yy < $max_lat + 2; $yy++) // Iterate through latitudes (vertical)
{
for ($xx = $min_lon; $xx < $max_lon + 2; $xx++) // Iterate through longitudes (horizontal)
{
if ($xx < $max_lon + 1)
{
$kml .= kml_grid($xx, $yy, $xx + 1, $yy, $count); // kml horizontal grid line (lon1,lat1,lon2,lat2)
$count++;
}
if ($yy < $max_lat + 1)
{
$kml .= kml_grid($xx, $yy, $xx, $yy + 1, $count); // kml vertical grid line (lon1,lat1,lon2,lat2)
$count++;
}
if ($get_debug) echo "<p>\$xx $xx, \$yy $yy</p>";
if ($count > 400) break; // Discourage infinite loops!
}
}
// -------------------------------------------------------------------------------------
$kml .= kml_folder_end();
$kml .= kml_end(); // kml tail section
$kml = $kml_head . $kml; // prepend the head section
if ($get_debug) echo "</table>\n\n";
}
// ---------------------------------------------------------------------------------------
if ($get_debug)
{
echo "<pre>KML Data:\n\n" . str_replace("<", "<", $kml) . "</pre>\n\n";
html_tail();
} else {
if ($countPins > 0) {
header('Content-type: application/vnd.google-earth.kml+xml');
header("Content-Disposition: attachment; filename=\"" . $get_date . "_" . $day . "_" . round($lat_g) . "_" . round($lon_g) . ".kml");
echo $kml;
} else {
html_head();
echo "<h3>30W zone - DJIA not available yet.</h3>\n\n";
html_tail();
}
}
// ---------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
hash_up.php
<?php
// -----------------------------------------------------------------------------------------
// Geohashing support functions
// -----------------------------------------------------------------------------------------
$crox = "http://www.geo.crox.net/djia/"; // try www, www1, www2 INCLUDE TRAILING /
//$crox = "http://carabiner.peeron.com/xkcd/map/data/"; // yyyy/mm/dd
// ---------------------------------------------------------------------------------------
function mnn($latlon) // Convert -0 notation to useable coordinates 1 => 1 0 => 0 -0 => -1 -1 => -2 etc.
{
if ($latlon === "-0") return -1;
else if ($latlon >= 0) return $latlon;
else if ($latlon < 0) return $latlon - 1;
}
function validateDate($date) // Returns true if $date is a valid date formatted as 'yyyy-mm-dd'
{
$d = DateTime::createFromFormat('Y-m-d', $date);
return $d && $d->format('Y-m-d') == $date;
}
function tweekDate($ISO_8601_Date, $days, $debug = false) // Adds $days to the input date formatted as yyyy-mm-dd The returned date format is also yyyy-mm-dd
{
$date_array = explode("-", $ISO_8601_Date);
if ($debug) { echo "<pre>\$date_array "; print_r($date_array); echo "</pre>\n"; }
$newDate = mktime(0, 0, 0, $date_array[1], $date_array[2] + $days, $date_array[0]);
return date('Y-m-d', $newDate);
}
function clean_up_get_params($_get) // Clean up $_GET and return an array of validated inputs or provide default values
{
if (isset($_get['lat'])) $get_lat = $_get['lat']; else $get_lat = 51;
if (isset($_get['lon'])) $get_lon = $_get['lon']; else $get_lon = 0;
if (isset($_get['clat'])) $get_clat = $_get['clat']; else $get_clat = "";
if (isset($_get['clon'])) $get_clon = $_get['clon']; else $get_clon = "";
if (isset($_get['date'])) $get_date = $_get['date']; else $get_date = date("Y-m-d");
if (isset($_get['skins'])) $get_skins = $_get['skins']; else $get_skins = 1;
if (isset($_get['debug'])) { if ($_get['debug'] =="debug") { $get_debug = true; } else { $get_debug = false; } } else { $get_debug = false; }
// -------------------------------------------------------------------------------------
// $get_skins default and range check
// -------------------------------------------------------------------------------------
if ($get_skins == "") $get_skins = 1;
if (! is_int($get_skins + 0)) $get_skins = 1;
if ($get_skins > 6) $get_skins = 6;
if ($get_skins < 0) $get_skins = 0;
// -------------------------------------------------------------------------------------
// LATITUDE and LONGITUDE INTEGERS
// -------------------------------------------------------------------------------------
// $get_lat default and range check
// -------------------------------------------------------------------------------------
if ($get_lat == "") $get_lat = 51;
if (! is_int($get_lat + 0)) $get_lat = 51;
if ($get_lat < 0) $get_lat = $get_lat - 1;
if ($get_lat === "-0") $get_lat = -1; // ##
if ($get_lat + $get_skins > 89) $get_lat = 89 - $get_skins; // 89 88 87 86 85 84 83 82 81 80 79 78 77
if ($get_lat - $get_skins < -89) $get_lat = -90 + $get_skins; // 89 88 87 86 85 84 83 82 81 80 79 78 77
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// $get_lon default and range check
// -------------------------------------------------------------------------------------
if ($get_lon == "") $get_lon = 0;
if (! is_int($get_lon + 0)) $get_lon = 0;
if ($get_lon < 0) $get_lon = $get_lon - 1;
if ($get_lon === "-0") $get_lon = -1; // ###
if ($get_lon + $get_skins > 179) $get_lon = 179 - $get_skins; // 179 178 177 176 175 174 173 172 171 170 169 168 167
if ($get_lon - $get_skins < -179) $get_lon = -180 + $get_skins; // 179 178 177 176 175 174 173 172 171 170 169 168 167
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// VIEW CENTERING LATITUDE and LONGITUDE REAL NUMBERS
// -------------------------------------------------------------------------------------
// $get_clat default and range check
// -------------------------------------------------------------------------------------
if (! is_numeric(floatval($get_clat) + 0)) $get_clat = "";
if (floatval($get_clat) < 0) $get_clat = $get_clat - 1;
if (floatval($get_clat) === "-0") $get_clat = -1;
if (floatval($get_clat) > 89.9999) $get_clat = 89.9999;
if (floatval($get_clat) < -89.9999) $get_clat = -89.9999;
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// $get_clon default and range check
// -------------------------------------------------------------------------------------
if (! is_numeric(floatval($get_clon) + 0)) $get_clon = "";
if (floatval($get_clon) < 0) $get_clon = $get_clon - 1;
if (floatval($get_clon) === "-0") $get_clon = -1;
if (floatval($get_clon) > 179.9999) $get_clon = 179.9999;
if (floatval($get_clon) < -179.9999) $get_clon = -179.9999;
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// $get_date default and validate
// -------------------------------------------------------------------------------------
if ($get_date == "") $get_date = date("Y-m-d"); // Today is the default
if (! validateDate($get_date))
{
if ((is_int($get_date + 0)) && ($get_date >= -7) && ($get_date <= 7)) $get_date = tweekDate(date("Y-m-d"), $get_date); else $get_date = date("Y-m-d");
}
$return_array = array("get_date" => $get_date, "get_lat" => $get_lat, "get_lon" => $get_lon, "get_clat" => $get_clat, "get_clon" => $get_clon, "get_skins" => $get_skins, "get_debug" => $get_debug);
return $return_array;
}
function get_http_response_code($url, $debug = false) // See if the input URL returns a page successfully - codes 404 or 200 etc.
{
$headers = get_headers($url);
if ($debug) echo "<pre>\n\n" . print_r($headers, 1) . "\n\n</pre>\n";
return substr($headers[0], 9, 3);
}
function get_djias($date, $debug = false) // Attempt to get the DJIAs for west and east of -30
{ // DJIA from and thank you to - http://wiki.xkcd.com/geohashing/User:Crox
global $crox;
$djia_e = false;
$djia_w = false;
$msg = "";
if ($date >= "2008-05-27") // The day of the algorithm change
{
$dow_date_e = tweekDate($date, -1); // Use yesterday's opening price
$dow_date_w = $date; // Use today's opening price
$yye = substr($dow_date_e, 0, 4) . "/"; // yyyy-mm-dd
$mme = substr($dow_date_e, 5, 2) . "/"; // 0123456789
$dde = substr($dow_date_e, 8, 2);
$yyw = substr($dow_date_w, 0, 4) . "/"; // yyyy-mm-dd
$mmw = substr($dow_date_w, 5, 2) . "/"; // 0123456789
$ddw = substr($dow_date_w, 8, 2);
}
else
{
$dow_date_e = $date; // Use today's opening price
$dow_date_w = $date; // Use today's opening price
$yye = substr($dow_date_e, 0, 4) . "/"; // yyyy-mm-dd
$mme = substr($dow_date_e, 5, 2) . "/"; // 0123456789
$dde = substr($dow_date_e, 8, 2);
$yyw = substr($dow_date_w, 0, 4) . "/"; // yyyy-mm-dd
$mmw = substr($dow_date_w, 5, 2) . "/"; // 0123456789
$ddw = substr($dow_date_w, 8, 2);
}
if ($debug) echo "<p>\$dow_date_e: $dow_date_e<br>\$dow_date_w: $dow_date_w</p>\n";
$urle = $crox . $yye . $mme . $dde;
// -------------------------------------------------------------------------------------
// Get data east of -30
// -------------------------------------------------------------------------------------
if(get_http_response_code("$crox$yye$mme$dde", $debug) != "200")
{
$msg .= "$dow_date_e: DJIA not found. Sorry!<br>";
}
else
{
$djia_e = file_get_contents("$crox$yye$mme$dde");
if ($debug) echo "<p>\$djia_e = file_get_contents(\"$crox$yye$mme$dde\")<br>" . $djia_e . "</p>\n";
if (! is_numeric($djia_e))
{
$msg .= "DJIA \"$djia_e\" seems to be invalid - Sorry!<br>";
}
}
// -------------------------------------------------------------------------------------
// Get data west of -30
// -------------------------------------------------------------------------------------
if(get_http_response_code("$crox$yyw$mmw$ddw", $debug) != "200")
{
$msg .= "$dow_date_w: DJIA not found. Sorry!<br>";
}
else
{
$djia_w = file_get_contents("$crox$yyw$mmw$ddw");
if ($debug) echo "<p>\$djia_w = file_get_contents(\"$crox$yyw$mmw$ddw\")<br>" . $djia_w . "</p>\n";
if (! is_numeric($djia_w))
{
$msg .= "DJIA \"$djia_w\" seems to be invalid - Sorry!<br>";
}
}
// -------------------------------------------------------------------------------------
return array($djia_e, $djia_w, $msg);
}
function hex2dec($var) // Return the input number converted into hexadecimal
{ // This code is based on - http://wiki.xkcd.com/geohashing/User:Eupeodes - Thanks!
$o = 0;
for($i = 0; $i < 16; $i++)
{
$o += hexdec($var[$i]) * pow(16, -$i -1);
}
return $o;
}
function get_coords($date, $djia, $debug = false) // Input a date and return an array containing the fractional lat and lon values
{ // This code is based on - http://wiki.xkcd.com/geohashing/User:Eupeodes - Thanks!
$md5 = md5($date."-".$djia);
list($lat, $lon) = str_split($md5, 16);
$latlon = array(hex2dec($lat), hex2dec($lon));
if ($debug) echo "<pre>local:\n" . print_r($latlon, true) . "</pre>\n";
return $latlon;
}
function get_global($date, $djia, $debug = false) // return the global hashpoint
{
// To generate this point take W30 decimals for a date (to make it global).
// Multiply the latitude by 180 and subtract 90
// Multiply the longitude by 360 subtracting 180.
// This will return a single point on the globe which is today's only globalhash.
// ---------------------------------------------------------------------------------------
$md5 = md5($date."-".$djia);
list($lat, $lon) = str_split($md5, 16);
$latlon = array(hex2dec($lat), hex2dec($lon));
if ($debug) echo "<pre>local:\n" . print_r($latlon, true) . "</pre>\n";
$latlon[0] = $latlon[0] * 180 - 90;
$latlon[1] = $latlon[1] * 360 - 180;
if ($debug) echo "<pre>global:\n" . print_r($latlon, true) . "</pre>\n";
return $latlon;
}
?>
html_gen.php
<?php
// -----------------------------------------------------------------------------------------
// html support functions
// -----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// html head
// ---------------------------------------------------------------------------------------
function html_head()
{
?><!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>KML Geohash</title>
</head>
<body>
<?php
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// html tail section if debugging
// ---------------------------------------------------------------------------------------
function html_tail()
{
?></body>
</html><?php
}
// -----------------------------------------------------------------------------------------
?>
kml_gen.php
<?php
// -----------------------------------------------------------------------------------------
// KML file support functions
// -----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build the KML file beginning text
// ---------------------------------------------------------------------------------------
function kml_begin($file_name, $lat, $lon, $range = 1000)
{
$kml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
$kml .= "<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:atom=\"http://www.w3.org/2005/Atom\">\n";
$kml .= "<Document>\n";
$kml .= " <name>$file_name</name>\n";
$kml .= " <description><![CDATA[This data is designed to work with KML aware applications like <a href=\"http://www.google.com/earth/\">Google Earth</a> or <a href=\"https://marble.kde.org/\">Marble</a>.]]></description>\n";
$kml .= " <LookAt>\n";
$kml .= " <longitude>$lon</longitude>\n";
$kml .= " <latitude>$lat</latitude>\n";
$kml .= " <altitude>0</altitude>\n";
$kml .= " <heading>0</heading>\n";
$kml .= " <tilt>0</tilt>\n";
$kml .= " <range>" . $range . "</range>\n";
$kml .= " </LookAt>\n";
return $kml;
}
//----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build the KML for a push pin and its style
// ---------------------------------------------------------------------------------------
function kml_style()
{
$kml = " <Style id=\"s_ylw-pushpin_hl\">\n";
$kml .= " <IconStyle>\n";
$kml .= " <scale>1.3</scale>\n";
$kml .= " <Icon>\n";
$kml .= " <href>http://maps.google.com/mapfiles/kml/paddle/grn-blank.png</href>\n";
$kml .= " </Icon>\n";
$kml .= " <hotSpot x=\"32\" y=\"1\" xunits=\"pixels\" yunits=\"pixels\"/>\n";
$kml .= " </IconStyle>\n";
$kml .= " <ListStyle>\n";
$kml .= " <ItemIcon>\n";
$kml .= " <href>http://maps.google.com/mapfiles/kml/paddle/grn-blank-lv.png</href>\n";
$kml .= " </ItemIcon>\n";
$kml .= " </ListStyle>\n";
$kml .= " </Style>\n";
$kml .= " <Style id=\"s_ylw-pushpin\">\n";
$kml .= " <IconStyle>\n";
$kml .= " <scale>1.1</scale>\n";
$kml .= " <Icon>\n";
$kml .= " <href>http://maps.google.com/mapfiles/kml/paddle/grn-blank.png</href>\n";
$kml .= " </Icon>\n";
$kml .= " <hotSpot x=\"32\" y=\"1\" xunits=\"pixels\" yunits=\"pixels\"/>\n";
$kml .= " </IconStyle>\n";
$kml .= " <ListStyle>\n";
$kml .= " <ItemIcon>\n";
$kml .= " <href>http://maps.google.com/mapfiles/kml/paddle/grn-blank-lv.png</href>\n";
$kml .= " </ItemIcon>\n";
$kml .= " </ListStyle>\n";
$kml .= " </Style>\n";
$kml .= " <StyleMap id=\"m_ylw-pushpin\">\n";
$kml .= " <Pair>\n";
$kml .= " <key>normal</key>\n";
$kml .= " <styleUrl>#s_ylw-pushpin</styleUrl>\n";
$kml .= " </Pair>\n";
$kml .= " <Pair>\n";
$kml .= " <key>highlight</key>\n";
$kml .= " <styleUrl>#s_ylw-pushpin_hl</styleUrl>\n";
$kml .= " </Pair>\n";
$kml .= " </StyleMap>\n";
return $kml;
}
//----------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Start the folder
// ---------------------------------------------------------------------------------------
function kml_folder_start($folderName)
{
$kml = " <Folder>\n";
$kml .= " <name>$folderName</name>\n";
return $kml;
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// End the folder
// ---------------------------------------------------------------------------------------
function kml_folder_end()
{
$kml = " </Folder>\n";
return $kml;
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build a KML placemark
// ---------------------------------------------------------------------------------------
function kml_placemark($get_date, $grat_lat, $grat_lon, $lat, $lon, $day)
{
$kml = " <Placemark>\n";
$kml .= " <name>" . $grat_lat . " " . $grat_lon . " " . $day . "</name>\n";
$kml .= " <description><![CDATA[" .
number_format($lat, 6) . " " . number_format($lon, 6) . "<br>" .
"<a href=\"http://wiki.xkcd.com/geohashing/" . $get_date . "_" . $grat_lat . "_" . $grat_lon . "\">" . $get_date . " " . $grat_lat . " " . $grat_lon . "</a><br>" .
"<a href=\"http://geo.crox.net/poster/" . $get_date . " " . $grat_lat . " " . $grat_lon . "\">Poster</a> " .
"<a href=\"http://wiki.xkcd.com/geohashing/" . $grat_lat . "," . $grat_lon . "\">Graticule</a><br>" .
"<a href=\"http://carabiner.peeron.com/xkcd/map/map.html?date=" . $get_date . "&lat=" . $grat_lat . "&long=" . $grat_lon . "&zoom=8\">Peeron</a> " .
"<a href=\"http://geohashing.info/" . $get_date . "/s/z:8/" . $grat_lat . "," . $grat_lon . "\">Geohashing</a><br>" .
"<a href=\"https://www.google.com/maps/dir/?api=1&destination=$lat,$lon\">Google Nav</a> " .
"<a href=\"http://www.openstreetmap.org/?mlat=" . $lat . "&mlon=" . $lon . "&zoom=16\">OSM</a><br>" .
"<a href=\"http://www.bing.com/maps/?cp=" . $lat . "~" . $lon . "&lvl=15&style=s&sp=point." . $lat . "_" . $lon . "_" . $get_date . " " . $grat_lat . " " . $grat_lon . "\">Bing for UK OS</a>" .
"]]></description>\n";
//
// "<a href=\"http://maps.google.com/?ie=UTF8&ll=" . $lat . "," . $lon . "&z=8&q=loc:" . $lat . "," . $lon . "\">Google Map</a><br>" .
$kml .= " <LookAt>\n";
$kml .= " <longitude>" . number_format($lon, 6) . "</longitude>\n";
$kml .= " <latitude>" . number_format($lat, 6) . "</latitude>\n";
$kml .= " <altitude>0</altitude>\n";
$kml .= " <heading>0</heading>\n";
$kml .= " <tilt>0</tilt>\n";
$kml .= " <range>1000</range>\n";
//$kml .= " <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>\n";
$kml .= " </LookAt>\n";
$kml .= " <styleUrl>#m_ylw-pushpin</styleUrl>\n";
$kml .= " <Point>\n";
$kml .= " <gx:drawOrder>1</gx:drawOrder>\n";
$kml .= " <coordinates>" . number_format($lon, 6) . "," . number_format($lat, 6) . ",0</coordinates>\n";
$kml .= " </Point>\n";
$kml .= " </Placemark>\n";
return $kml;
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build a KML global placemark
// ---------------------------------------------------------------------------------------
function kml_globalmark($get_date, $lat_g, $lon_g, $day)
{
$kml = " <Placemark>\n";
$kml .= " <name>Global - " . $day . "</name>\n";
$kml .= " <description><![CDATA[" .
number_format($lat_g, 6) . " " . number_format($lon_g, 6) . "<br>" .
"<a href=\"http://wiki.xkcd.com/geohashing/" . $get_date . "_global\">" . $get_date . " global</a><br>" .
"<a href=\"http://wiki.xkcd.com/geohashing/Global\">Globalhash</a> " .
"<a href=\"http://geo.crox.net/poster/" . $get_date . "_global\">Poster</a><br>" .
"<a href=\"http://www.openstreetmap.org/?mlat=" . $lat_g . "&mlon=" . $lon_g . "&zoom=16\">OSM</a> " .
"<a href=\"http://maps.google.com/?ie=UTF8&ll=" . $lat_g . "," . $lon_g . "&z=8&q=loc:" . $lat_g . "," . $lon_g . "\">Google</a> " .
"<a href=\"http://www.bing.com/maps/?cp=" . $lat_g . "~" . $lon_g . "&lvl=15&style=s&sp=point." . $lat_g . "_" . $lon_g . "_" . $get_date . " global\">Bing</a>" .
"]]></description>\n";
$kml .= " <LookAt>\n";
$kml .= " <longitude>" . number_format($lon_g, 6) . "</longitude>\n";
$kml .= " <latitude>" . number_format($lat_g, 6) . "</latitude>\n";
$kml .= " <altitude>0</altitude>\n";
$kml .= " <heading>0</heading>\n";
$kml .= " <tilt>0</tilt>\n";
$kml .= " <range>4000000</range>\n";
//$kml .= " <gx:altitudeMode>relativeToSeaFloor</gx:altitudeMode>\n";
$kml .= " </LookAt>\n";
$kml .= " <styleUrl>#m_ylw-pushpin</styleUrl>\n";
$kml .= " <Point>\n";
$kml .= " <gx:drawOrder>1</gx:drawOrder>\n";
$kml .= " <coordinates>" . number_format($lon_g, 6) . "," . number_format($lat_g, 6) . ",0</coordinates>\n";
$kml .= " </Point>\n";
$kml .= " </Placemark>\n";
return $kml;
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build a KML gridline
// ---------------------------------------------------------------------------------------
function kml_grid($lon1, $lat1, $lon2, $lat2, $count)
{
$kml = " <Placemark>\n";
$kml .= " <name>Path_$count</name>\n";
$kml .= " <LineString>\n";
$kml .= " <tessellate>1</tessellate>\n";
$kml .= " <coordinates>\n";
$kml .= " $lon1,$lat1,0 $lon2,$lat2,0\n";
$kml .= " </coordinates>\n";
$kml .= " </LineString>\n";
$kml .= " </Placemark>\n";
return $kml;
}
// ---------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------
// Build the KML file ending text
// ---------------------------------------------------------------------------------------
function kml_end()
{
$kml = "</Document>\n";
$kml .= "</kml>";
return $kml;
}
// ---------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------
?>
testForm.css
/* CSS Document */
a {
text-decoration:none;
}
a:hover {
color:#ff0000;
}
table {
border-collapse: collapse;
}
td {
border-style:solid;
border-width: 1px;
padding: 4px;
border-color: gray;
vertical-align:top;
}