[ka-Map-users] tile.php hack for googlemap

Joe Franklin traderboy at yahoo.com
Thu Dec 22 10:14:38 EST 2005


Here's a hack to tile.php to serve up tiles that can
be displayed in GoogleMap.  It assumes you know how to
set up GoogleMap.  It also expects your data in your
.map file to be in Mercator projection (epsg:54004 I
think).  The scales in config.php should match the
equivalent zoom levels GM uses.  It's not pretty or
well written but it seems to work ok.

In config.php:

$tileWidth = 256;
$tileHeight = 256;
$metaWidth = 5;
$metaHeight = 5;
$metaBuffer = 0;

//add element to $aszMapFiles
"google" => array("Google",
"c:/ms4w/Apache/htdocs/ka-map/google.map",
array(222340438.6,111170219.3,55585109.65,27792554.82,13896277.41,6948138.706,3474069.353,1737034.676,868517.3382,434258.6691,217129.3346,108564.6673,54282.33364,27141.16682,13570.58341,6785.291705,3392.645852,1696.322926),"PNG"),

In your HTML/Javascript:

map = new GMap(mymapdiv);
// Copy Object Function
function copy_obj(o) {
var c = new Object(); for (var e in o) { c[e] = o[e];
} return c;
}
//Copy mapType
myMapType = copy_obj(map.mapTypes[0]);
myMapType.hasOverlay = function () {return true;};
myMapType.getOverlayURL= function (x, y, zoom){
return
"http://localhost/ka-map/gtile.php?x="+x+"&y="+y+"&zoom="+zoom+"&g=__base__&i=PNG";
}
// Map Display name in the auto-generated maplink in
the top right corner.
myMapType.getLinkText = function() { return 'My Data';
}
//Add the map spec to the list 
map.mapTypes.push(myMapType);
map.setMapType(myMapType);

In tile.php:

//change to these lines below (original code commented
out)
$top = isset( $_REQUEST['y'] ) ?
intval($_REQUEST['y']) : 0;
$left = isset( $_REQUEST['x'] ) ?
intval($_REQUEST['x']) : 0;
$scale = isset( $_REQUEST['zoom'] ) ?
intval($_REQUEST['zoom']) : 16;
$rect = getBoundsXYZ($left, $top, $scale, $metaWidth,
$metaHeight ); 
//$top = isset( $_REQUEST['t'] ) ?
intval($_REQUEST['t']) : 0;
//$left = isset( $_REQUEST['l'] ) ?
intval($_REQUEST['l']) : 0;
//$scale = isset( $_REQUEST['s'] ) ?
intval($_REQUEST['s']) : $anScales[0];

//and these
$metaLeft = $left;
$metaTop = $top;
//$metaLeft = floor( ($left)/($tileWidth*$metaWidth) )
* $tileWidth * $metaWidth;
//$metaTop = floor( ($top)/($tileHeight*$metaHeight) )
* $tileHeight *$metaHeight;

//here too
$minx = $rect->minx;
$miny = $rect->miny;
$maxx = $rect->maxx;
$maxy = $rect->maxy;
//$minx = $metaLeft * $geoWidth;
//$maxx = $minx + $geoWidth * $oMap->width;
//$maxy = -1 * $metaTop * $geoHeight;
//$miny = $maxy - $geoHeight * $oMap->height;

//add these functions to tile.php
//swiped from http://www.ponies.me.uk/maps/dbgmap.html
function getLatLongXYZ($x, $y, $zoom) { 
$debug = $_GET['debug']; 
      $lon      = -180; // x 
      $lonWidth = 360; // width 360 

      $lat       = -1; 
      $latHeight = 2; 

      $tilesAtThisZoom = 1 << (17 - $zoom); 
      $lonWidth  = 360.0 / $tilesAtThisZoom; 
      $lon       = -180 + ($x * $lonWidth); 
      $latHeight = 2.0 / $tilesAtThisZoom; 
      $lat       = (($tilesAtThisZoom/2 - $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 = (2 * atan(exp(PI() * $latHeight)))
- (PI() / 2); 
      $latHeight *= (180 / PI()); 

      $lat = (2 * 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; 
      } 

      $point = new Point(); 
      $point->x = $lon; // + $lonWidth;
      $point->y = $lat + $latHeight;
      return $point;
}

function getBoundsXYZ($x, $y,
$zoom,$metaWidth,$metaHeight) { 
  $point1 = getLatLongXYZ($x, $y, $zoom);
  $point2 = getLatLongXYZ($x+$metaWidth,
$y+$metaHeight, $zoom);

	//reverse the y values
  $rect =
project($point1->x,$point2->y,$point2->x,$point1->y);
  return $rect; 
}

function project($minx,$miny,$maxx,$maxy){
	$newRect = new Rectangle();
	$newRect->minx = degrees_to_mercator_metersX($minx);
	$newRect->maxx = degrees_to_mercator_metersX($maxx);
	$newRect->miny = degrees_to_mercator_metersY($miny);
	$newRect->maxy = degrees_to_mercator_metersY($maxy);
	return $newRect;	
}

//swiped from some perl code somewhere on the Internet
function degrees_to_mercator_metersX($lon) {
	$DEG_TO_RAD = 0.017453292519943296;
	$RAD_TO_DEG = 57.295779513082322;
	$PI         = 3.14159267;
	//meters->var MAGIC_NUM  = 6356752.3142;
	//feet
	$MAGIC_NUM  = 6371000.0;
  //assert( ($lat>=-90) && ($lat<=90) ), if DEBUG;
  //assert( ($lon>=-90) && ($lon<=90) ), if DEBUG;

  $lon_m = $MAGIC_NUM * ($lon *$DEG_TO_RAD);
  return $lon_m;
}

function degrees_to_mercator_metersY( $lat) {
	$DEG_TO_RAD = 0.017453292519943296;
	$RAD_TO_DEG = 57.295779513082322;
	$PI         = 3.14159267;
	//meters->var MAGIC_NUM  = 6356752.3142;
	//feet
	$MAGIC_NUM  = 6371000.0;

  //assert( ($lat>=-90) && ($lat<=90) ), if DEBUG;
  //assert( ($lon>=-90) && ($lon<=90) ), if DEBUG;
	if ($lat >= 85) $lat=85;
	if ($lat <= -85) $lat=-85;

  $lat_m = $MAGIC_NUM * log( tan( (($lat *
$DEG_TO_RAD) + (PI()/2)) / 2 ) );

  return $lat_m;
}

class Point { 
    var $x,$y; 
} 

// utility class to hold the rectangle position and
size. 
class Rectangle { 
    var $minx,$miny; 
    var $maxx, $maxy; 
} 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 


More information about the ka-Map-users mailing list