Dienstag, 2. September 2008

Google Maps Tile - URL mit PL/SQL bilden

Zum Verständnis von Googles / Virtual Earth's Sperical Mercator möchte ich zunächst die dabei verwendete Mercator-Formel vorstellen :



Möchte man nun auf die einzelnen Google-Tiles zugreifen, so muss die Umrechnung der Latitude - und Longitude - Werte mit der Mercator - Formel zunächst in die World-Pixel Koordinaten erfolgen, um letztendlich die Tiles Koordinaten zu bestimmen.

Hier ein Beispiel zur Verifizierung der von mir erstellten PL/SQL- Prozeduren:



Mit der PL/SQL - Package erstellen wir die Google Tile - URL (angewendet wird die sinus-Gleichung):


CREATE OR REPLACE PACKAGE BODY PKG_GET_GMAPS_URL AS

PI CONSTANT NUMBER := 3.141592653589793 ;
DTOR CONSTANT NUMBER := PI / 180;
RTOD CONSTANT NUMBER := 180 / PI;
TILE_SIZE CONSTANT NUMBER := 256;
MERC_BORDER CONSTANT NUMBER := 85.0511287798066;

FUNCTION fnc_get_TileCoord (p_lat IN number, p_lon IN number, p_zoom IN number,
p_x OUT NUMBER, p_y OUT NUMBER, p_z OUT NUMBER) RETURN varchar2 IS

l_sin_pi NUMBER;
l_norm_x NUMBER;
l_norm_y NUMBER;
l_col NUMBER;
l_row NUMBER;

BEGIN
IF abs(p_lat) > MERC_BORDER THEN
RETURN('Invalide Latitude');
ELSE
l_sin_pi := SIN((p_lat) * DTOR);
l_norm_x := p_lon / 180;
l_norm_y := (0.5 * LN ( (( 1 + l_sin_pi) / (1 - l_sin_pi)) ) ) / PI;
-- column
p_x := POWER(2, p_zoom) * (( l_norm_x + 1 ) / 2);
-- row
p_y := POWER(2, p_zoom) * (( 1 - l_norm_y ) / 2);
p_z:= p_zoom;

RETURN('OK');
END IF;
END fnc_get_TileCoord;

PROCEDURE prc_get_TileCoord (p_lat IN number, p_lon IN number, p_zoom IN number) IS

l_x NUMBER;
l_y NUMBER;
l_z NUMBER;
l_xpos NUMBER;
l_ypos NUMBER;
l_res VARCHAR2(2000);
l_paras VARCHAR2(500);

BEGIN

l_res:= fnc_get_TileCoord(p_lat, p_lon, p_zoom, l_x, l_y, l_z);

dbms_output.put_line(l_res);

l_xpos:= trunc((l_x - trunc(l_x) ) * TILE_SIZE);
l_ypos:= trunc((l_y - trunc(l_y) ) * TILE_SIZE);

dbms_output.put_line('x-Pos. in World: '||to_char(trunc(l_x * 256) ) || ' / ' ||
'y-Pos. in World: '||to_char(trunc(l_y * 256) ));

dbms_output.put_line('x-Pos. in Tile: '||to_char(l_xpos)|| ' / ' ||
'y-Pos. in Tile: '||to_char(l_ypos));
dbms_output.put_line(' --- ');

l_paras := 'x=' ||to_char( trunc( l_x ) )||
'&y='||to_char( trunc( l_y ) )||
'&zoom='||to_char(17-p_zoom);

dbms_output.put_line('http://mt0.google.com/mt?'||l_paras);

END prc_get_TileCoord;

END PKG_GET_GMAPS_URL;

Nachfolgend angewendet, erhalten wir die World- und Tile - Pixel Koordinaten und natürlich die Google- Tile URL:


SQL> set serverout on
SQL> exec pkg_get_gmaps_URL.prc_get_TileCoord (52.514653902014715, 13.350105285644531, 13)
OK
x-Pos. in World: 1126345 / y-Pos. in World: 687822
x-Pos. in Tile: 201 / y-Pos. in Tile: 206
---
http://mt0.google.com/mt?x=4399&y=2686&zoom=4

Eine Differenz von einem World-Pixel zur obigen Tile - Map kann man gelten lassen !

Dank Oracle's PL/SQL !

Friedhold

PS: Googles Mercator wird übrigens 900913 genannt und kommt eigentlich von 600613 - in der SMS-Schrift : Google.

Keine Kommentare: