<?php
$x 
$_GET['x'];
$y $_GET['y'];
$zoom $_GET['zoom'];
$debug $_GET['debug'];
$t $_GET['t'];

// get the rectangle data for the tile and work out the text to display in the middle
if ($t != '') {
    
$rect getLatLongSat($t);
    
$centerText $t "   zoom:" getTileZoom($t);
}
else {
    
$rect getLatLongXYZ($x,$y,$zoom);
    
$centerText "x:" $x ." y:" $y " zoom:" $zoom;
}

// create the image and allocate some colours
$im ImageCreate(256,256);
$grey ImageColorAllocate($im,128,128,128);
$blackImageColorAllocate($im,0,0,0);
$white=ImageColorAllocate($im,255,255,255);

// put a white border on the tile so we can see where it ends.
ImageRectangle($im,0,0,255,255,$white);

// add in the center text
ImageString($im,5,10,120,$centerText,$black);

// add in the bottom left and top right coordinates from the rectangle.
ImageString($im,4,0,240,sprintf("%03.6f,%02.5f"$rect->x$rect->y),$black);
ImageString($im,4,90,0,sprintf("%03.6f,%02.5f"$rect->$rect->width$rect->$rect->height),$black);

// show the image
if ($debug) {
   echo(
"x=$x y=$y z=$zoom");
   
print_r($rect);
}
else {
   
header('Content-Type: image/png');
   
ImagePNG($im);
}


// utility class to hold the rectangle position and size.
class Rectangle {
    var 
$x,$y;
    var 
$width$height;
}

/** returns the Google zoom level for the keyhole string. */
function getTileZoom($keyHoleString) {
  return 
strlen($keyHoleString)-1;
}


/**
 * returns a Rectangle2D with x = lon, y = lat, width=lonSpan, height=latSpan for a keyhole string.
*/
function getLatLongSat($keyholeStr) {
      
$lon      = -180// x
      
$lonWidth 360// width 360

      //double lat = -90;  // y
      //double latHeight = 180; // height 180
      
$lat       = -1;
      
$latHeight 2;

      for (
$i 1$i strlen($keyholeStr); $i++) {
         
$lonWidth /= 2;
         
$latHeight /= 2;

         
$c substr($keyholeStr,$i,1);

         switch (
$c) {
            case 
's':
               
$lon += $lonWidth;

               break;

            case 
'r':
               
$lat += $latHeight;
               
$lon += $lonWidth;

               break;

            case 
'q':
               
$lat += $latHeight;
               break;

            case 
't':
               break;

            default:
               return;
         }
      }

      
// convert lat and latHeight to degrees in a transverse mercator projection
      // note that in fact the coordinates go from about -85 to +85 not -90 to 90!
      
$latHeight += $lat;
      
$latHeight = (atan(exp(PI() * $latHeight))) - (PI() / 2);
      
$latHeight *= (180 PI());

      
$lat = (atan(exp(PI() * $lat))) - (PI() / 2);
      
$lat *= (180 PI());

      
$latHeight -= $lat;

      if (
$lonWidth 0) {
         
$lon      $lon $lonWidth;
         
$lonWidth = -$lonWidth;
      }

      if (
$latHeight 0) {
         
$lat       $lat $latHeight;
         
$latHeight = -$latHeight;
      }

      
//        lat = Math.asin(lat) * 180 / Math.PI();
      
$rect = new Rectangle;
      
$rect->$lon;
      
$rect->$lat;
      
$rect->width $lonWidth;
      
$rect->height $latHeight;
      return 
$rect;
}

   
/**
   * returns a Rectangle2D with x = lon, y = lat, width=lonSpan, height=latSpan
   * for an x,y,zoom as used by google.
   */
function getLatLongXYZ($x$y$zoom) {
$debug $_GET['debug'];
      
$lon      = -180// x
      
$lonWidth 360// width 360

      
$lat       = -1;
      
$latHeight 2;

      
$tilesAtThisZoom << ($zoom);
      
$lonWidth  360.0 $tilesAtThisZoom;
      
$lon       = -180 + ($x $lonWidth);
      
$latHeight 2.0 $tilesAtThisZoom;
      
$lat       = (($tilesAtThisZoom/$y-1) * $latHeight);

if (
$debug) {echo("(uniform) lat:$lat latHt:$latHeight<br>");}
      
// convert lat and latHeight to degrees in a transverse mercator projection
      // note that in fact the coordinates go from about -85 to +85 not -90 to 90!
      
$latHeight += $lat;
      
$latHeight = (atan(exp(PI() * $latHeight))) - (PI() / 2);
      
$latHeight *= (180 PI());

      
$lat = (atan(exp(PI() * $lat))) - (PI() / 2);
      
$lat *= (180 PI());


if (
$debug) {echo("pre subtract lat: $lat latHeight $latHeight<br>");}
      
$latHeight -= $lat;
if (
$debug) {echo("lat: $lat latHeight $latHeight<br>");}

      if (
$lonWidth 0) {
         
$lon      $lon $lonWidth;
         
$lonWidth = -$lonWidth;
      }

      if (
$latHeight 0) {
         
$lat       $lat $latHeight;
         
$latHeight = -$latHeight;
      }


      
$rect = new Rectangle();
      
$rect->$lon;
      
$rect->$lat;
      
$rect->height $latHeight;
      
$rect->width$lonWidth;

      return 
$rect;
   }


?>