PHP GD2 im Tile (Kachel) einen Punkt per lat/lon einzeichnen

Hallo OSM Gemeinde,

ich kann mir ja über lat/lon sowie Zoomlevel die x/y-Tilenumber errechnen. Nun möchte ich jedoch im entsprechenden Tile einen Punkt über lat/lon einzeichnen.

Die idee in PHP ist wie folgt :



    $xtile = floor((($lon + 180) / 360) * pow(2, $zoom)); // xTile(Spalte) über Längengrad bestimmen
    // yTile(Zeile) über Breitengrad bestimmen    
    $ytile = floor((1 - log(tan(deg2rad($lat)) + 1 / cos(deg2rad($lat))) / pi()) /2 * pow(2, $zoom));    

// lat und lon aus Tilenumber zurückrechnen
    $n = pow(2, $zoom);
    $lon_deg = $xtile / $n * 360.0 - 180.0;
    $lat_deg = rad2deg(atan(sinh(pi() * (1 - 2 * $ytile / $n))));

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


Aus der Differenz müsste ich jetzt doch über die Tabelle

http://wiki.openstreetmap.org/wiki/Zoom_levels

je nach Zoomlevel den Punkt auf meine 256x256 Pixel einzeichnen können, oder?

Über Erfahrungen oder Denkanstöße wäre ich sehr erfreut :slight_smile:

Das könnte Dir vielleicht helfen … ist zwar C, aber als PHPler solltest Du da schnell durchsteigen können:
http://svn.openstreetmap.org/applications/utils/export/osm2pgsql/expire-tiles.c

Hallo und willkommen im Forum.

Diese Erläuterungen, Formeln und Programmbeispiele in verschiedenen Sprachen könnten hilfreich sein:
Slippy map tilenames.

Hallo und Danke für die Anwtort.

@Willi2006 : Die Formeln verwende ich bereits.

Es geht im wesentlichen darum, dass ich GPS Positionen habe, die ich in die jeweiligen Teils einzeichnen möchte. Ich hatte es mal mit dem zuvor genannten Code und dem hier versucht :


            $x = intval(abs($lat * 6370000) / 2.387);  // Meter in Pixel umrechnen
            $y = intval(abs($lon * 6370000) / 2.387); // Meter in Pixel umrechnen

Dadurch wird Strecke eingezeichnet, jedoch mit versatz :frowning:

Hallo stefant60,

Die Lösung ist einfach den Nachkommaanteil von $xtile bzw. $ytile für die Bestimmung der Position innerhalb der Tile zu verwenden.
Also etwa so:


$xtile = ((($lon + 180) / 360) * pow(2, $zoom)); // genau wie oben, nur _ohne_ "floor"
$ytile = ((1 - log(tan(deg2rad($lat)) + 1 / cos(deg2rad($lat))) / pi()) /2 * pow(2, $zoom)); // genau wie oben, nur _ohne_ "floor"
$xtile_int = floor($xtile);
$ytile_int = floor($ytile);
$pos_x= ($xtile - $xtile_int) * 256;
$pos_y= ($ytile - $ytile_int) * 256;

$pos_x und $pos_y liegen zwischen 0 und 255 unnd geben die Position innerhalb der 256x256 Pixel an. Diese Positionen werden von links ($pos_x) bzw. von oben ($pos_y) gezählt. Falls Dein Koordinatensystem zum Pixeleinzeichnen also z.B. von unten gezählt wird, musst Du “$pos_y= 256- ($ytile - $ytile_int) * 256;” nehmen.

Schöne Grüße

PA94

Vielen vielen Dank es funktioniert! Ich Nase hätte darauf selbst kommen können wenn ich mich nicht so dumm an den Koordinaten fest geklammert hätte.

Eine gute Woche!