Donnerstag, 4. September 2008

Google Maps und Oracle Maps Mashup mit externem Custom Map Tile Layer (8)

Im letzten Teil dieser Serie zu 'Oracle Maps Mashups mit externen Customer Map Tile Layern' möchte ich schliesslich die Lösung mit Google Maps Tiles vorstellen. Die Parameterdefinition zur Kartenprojektion ist wie beim Virtual Earth Demo vorzunehmen.

Die Google Tiles Url hatte ich bereits im Blog "Google Maps Tile - URL mit PL/SQL bilden" vorgestellt, so dass eigentlich nur die 'getTileURL' - Funktion angepasst werden muss:



Letzendlich erhalten wir das Google Maps / Oracle Maps Mashup:



Natürlich lassen sich auch auf der Google Maps - Base Map statische und dynamische Features of Interest Layers (FOIs) darstellen, insbesondere auf der Basis von topologischen Abfragen direkt aus Oracle Spatial.

Grüße,
Friedhold

OpenStreetMap - FOI, Virtual Earth und Oracle Maps Mashup (7)

Im letzten Teil (6) hatte ich das Virtual Earth / Oracle Maps Mashup vorgestellt. Um Spatial - Daten als Features of Interest Layer (FOI) auf der extern (remote) gerenderten Customer Tile Map darzustellen, müssen wir die verwendeten OpenStreetMap Daten in den Spherical Mercator, sozusagen Map-konform, umrechnen (analog zum Teil (5) ).

Dann können wir diesen FOI- Layer aktivieren:



und erhalten schliesslich das OpenStreetMap / Virtual Earth / Oracle Maps Mashup:



Friedhold

Dienstag, 2. September 2008

Virtual Earth und Oracle Maps Mashup mit externem Custom Map Tile Layer (6)

Nun haben wir uns so langsam dem Spherical Mercator genähert und möchten in Oracle Maps als externe Customer Base Map die Virtual Earth Map von Microsoft darstellen. Im Teil 3 dieser Serie hatte ich bereits auf die Notwendigkeit der Anwendung des Google/Vitual Earth Spherical Mercators hingewiesen! Würde man als Map- Projektion den World Mercator 54004 verwenden, :


var mapConfig=
{
"mapTileLayer":"GX_MERCATOR",
"format":"PNG",
"coordSys":
{
"srid":54004,
"type":"PROJECTED",
"distConvFactor":1.0,
"minX":-2.0037508E7,"minY":-2.0037508E7,
"maxX":2.0037508E7,"maxY":2.0037508E7
},

so wären die Demo- Daten leider nicht Karten - konform:



Mit dem derzeit bekanntem (Im Oracle Forum ist der Spherical Mercator als SRID- Update bereits zugesagt worden!) und im Oracle Spatial Forum veröffentlichtem SRID:


var mapConfig=
{
...
{
"srid:1000002,
...
},

sieht das Mashup aus der Virtual Earth Customer Base Map und dem Oracle Maps Demo - FOI - Layer dann so aus:



Microsoft verwendet zum schnellen Zugriff auf die Virtual Earth - Tiles sogenannte Quad-Keys :

function getVETileQuadKey(tileX, tileY, level)
{
var quadKey = "";
for (var i = level; i > 0; i--)
{
var digit = 0;
var mask = 1 << (i - 1);
if ((tileX & mask) != 0)
{
digit++;
}
if ((tileY & mask) != 0)
{
digit++;
digit++;
}
quadKey += digit;
}
return quadKey;
}

Mit dem Spherical Mercator eröffnen sich neue Mashup - Möglichkeiten !!

Grüße,
Friedhold

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.