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
TobWen
September 14, 2010, 8:19pm
#2
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
PA94
September 19, 2010, 8:06am
#5
Hallo stefant60,
stefant60:
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
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!