Calculate and mark position in tiles of a slippy map

Hi Community,

while playing with the osm i start to code an php script that loads all necessary tiles of an slippymap. Now i got a Problem to draw Locationspoints (mark own Position). I get the the Position from my Android Smartphone that uses GPS. A own Logger app writes lat and lon Data in a CSV File.

For Example:

Step 1:
I load the tile in Zoomlevel 16 of lat=50.31142830848694 and lon=7.553218603134155. I get the Tilenumber with


$xtile = floor((($lon + 180) / 360) * pow(2, $zoom));
$ytile = floor((1 - log(tan(deg2rad($lat)) + 1 / cos(deg2rad($lat))) / pi()) /2 * pow(2, $zoom));

Step 2: (Here i got my Problem)
Now a want to mark the Point of lat=50.31142830848694 and lon=7.553218603134155 in the loaded Tile of the Slippymap.
I do it like this:


$n = pow(2, $zoom);
$lon_deg = $xtile / $n * 360.0 - 180.0;
$lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));

$lat_diff = ($lat-$lat_deg);    
$lon_diff = ($lon-$lon_deg);

// 1Pixel = 2.387 Metre in Zoomlevel 16
$scaleToPixel = 2.387;
$x = intval(abs($lat * 6378137) / $scaleToPixel);
$y = intval(abs($lon * 6378137) / $scaleToPixel);                
            
imagefilledellipse($image, $y, $x, 2, 2, $color);


But the drawed Points arent exactly on the Position lat=50.31142830848694 and lon=7.553218603134155.

Here you can see it:
http://www.create-your-site.de/versatz.png

I think that happens because my calculation is bad…

If anyone can help me it can save the Day :wink:

Hi,

did you solve your problem already?

I am working on a different problem too. But I just started.

I found at least some bugs:


$x = intval(abs($lon_diff * 6378137) / $scaleToPixel);
$y = intval(abs($lat_diff * 6378137) / $scaleToPixel);

My debug-Output for your special lon and lat is:


lon_diff = 0.00011801719665527
lat_diff = -0.0024721025860543
x = intval(abs(0.00011801719665527 * 6378137) / 2.387);
y = intval(abs(-0.0024721025860543 * 6378137) / 2.387);

x = 315
y = 6605

but the tile byself is only 256x256.

I am not sure but I think your lat_diff should be positive? Excelpt the 0,0 of the tile is not top,left but bottom,left?

Good for testing:
http://www.openstreetmap.org/?lat=50.31142830848694&lon=7.553218603134155&zoom=16&layers=M&mlat=50.31142830848694&mlon=7.553218603134155

Even if you took the PHP-code from here: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#PHP
the xtile is wrong.

http://tile.openstreetmap.org/16/34142/22137.png instead of http://tile.openstreetmap.org/16/34143/22137.png.

Check it here: http://tools.geofabrik.de/map/?type=Geofabrik&lon=7.5532186031342&lat=50.311428308487&zoom=16&grid=1

Coach

Hi,

here is my idea / solution


$n = pow(2, $zoom);

// Tile Top Left
$lon_deg_top_left = $xtile / $n * 360.0 - 180.0;
$lat_deg_top_left = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));

// Tile Bottom Right
$lon_deg_bottom_right = ($xtile+1) / $n * 360.0 - 180.0;
$lat_deg_bottom_right = rad2deg(atan(sinh(pi() * (1 - 2 * ($ytile+1) / $n))));

// Tile Size
$lon_diff_tile = abs($lon_deg_bottom_right-$lon_deg_top_left);
$lat_diff_tile = abs($lat_deg_bottom_right-$lat_deg_top_left);

// Difference to Top Left
$lon_diff = abs($lon-$lon_deg_top_left);
$lat_diff = abs($lat-$lat_deg_top_left);

// Difference / x = TileSize / 256
$x = floor($lon_diff / $lon_diff_tile * 256);
$y = floor($lat_diff / $lat_diff_tile * 256);

Coach