Posts mit dem Label Oracle PL/SQL werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Oracle PL/SQL werden angezeigt. Alle Posts anzeigen

Dienstag, 24. Mai 2011

GeoJSON-Beispiel aus PL/SQL in OpenLayers

Oracle Maps und APEX seit der Version 4.0 verwenden das JSON - Format zum direkten Datenzugriff aus der Datenbank und effizienten Verarbeitung in Javascript. Dieses Format hat sich auf Grund seiner Kompaktheit, guten Lesbarkeit und der direkten Ansprechbarkeit in Javascript als implizite JavaScript-Objektnotation in der WebBrowser-Technologie recht gut durchgesetzt.


Somit ist es auch nahe liegend, dass Geo-Daten in dem JSON-Format als Vector-Layer z.B. in OpenLayers direkt dargestellt werden. Hierfür gibt es eine besondere Spezifikation zur Erstellung von Feature-Informationen: Das GeoJSON - Format. Unter anderem bieten der OGC-Konverter GDAL und der FME-Konverter von Safe die direkte Erstellung dieses Geo-Formates an.
In meinem hier vorgestellten Demo wird die Klick-Koordinate zum Suchen des Country-Polygons verwendet und anschließend das gefundene Polygon im GeoJSON-Format erzeugt:


CREATE OR REPLACE PROCEDURE get_simple_geojson_2 (p_x number, p_y number) IS

l_state varchar2(2);

FUNCTION fnc_get_state(p_x NUMBER, p_y NUMBER )
RETURN varchar2 IS
li_state varchar2(2);
BEGIN

SELECT /*+ ORDERD */
s.STATE_ABRV
into li_state
FROM states s
WHERE SDO_RELATE(s.geom,
SDO_GEOMETRY(2001,
8307,
SDO_POINT_TYPE(p_x, p_y, NULL),
NULL,
NULL),
'mask=CONTAINS') = 'TRUE'
AND ROWNUM<2;
RETURN(li_state);
EXCEPTION
WHEN OTHERS then
RETURN('RI');
END fnc_get_state;

FUNCTION get_XY (p_state varchar2) RETURN VARCHAR2 IS
l_coords varchar2(32767);
BEGIN
for l_xy in (SELECT t.X, t.Y
FROM states s,
TABLE(SDO_UTIL.GETVERTICES(s.geom)) t
WHERE s. STATE_ABRV = p_state
) loop
l_coords:= l_coords || '['|| l_xy.X ||','|| l_xy.Y ||'],';
end loop;
RETURN( substr(l_coords, 1, length(l_coords)-1) );
END get_XY;

BEGIN

l_state := fnc_get_state(p_x, p_y);

htp.p('
{
"type": "FeatureCollection",
"features": [
{"type":"Feature", "id":"OpenLayers.Feature.Vector_1489", "properties":{},
"geometry":{ "type":"Polygon",
"coordinates":[['
|| get_XY( l_state ) ||
']] },'||
'"crs":{"type":"OGC", "properties":{"urn":"urn:ogc:def:crs:OGC:1.3:CRS84"}}
}'||
']
}
'
);

end get_simple_geojson_2;
/

Die Verifizierung dieser GeoJSON-Polygone habe ich OpenLayers mit der entsprechenden Darstellung überlassen:
function handleMapClick(e)
{
var lonlat = map.getLonLatFromViewPortPx(e.xy);

var newgeojson = new OpenLayers.Layer.GML("My GeoJSON Layer",
'http://localhost:8089/mvdemo/get_simple_geojson_2?p_x='+lonlat.lon+'&p_y='+lonlat.lat,
{format: OpenLayers.Format.GeoJSON});

map.addLayer(newgeojson);
}

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.

Mittwoch, 2. Januar 2008

Einrichtung eines PL/SQL - DAD für das Schema mvdemo

Seit der Einführung der Oracle HTMLDB u. APEX wird die Web-Konfigurationsseite zum Einrichten anwenderdefinierter PL/SQL-DAD's nicht mehr angeboten, so dass die hier beschriebene, manuelle Einrichtung notwendig ist. Als Datenbankschema verwenden wir das 'mvdemo', da wir uns in Folgebeiträgen hierauf beziehen werden.

Im Verzeichnis %APEX_HOME%\Apache\modplsql\conf wird die DAD-Definition in die dads.conf eingetragen:


Danach wird der Apache neu gestartet und ein kleine Test-Procedure im Schema 'mvdemo' gespeichert:


Entsprechend der 'Location' in der DAD-Definition ist der URL-Path vorgegeben und wir testen den PL/SQL-DAD Zugriff:



Der Konfigurationseintrag und das Testprogramm sind hier zu finden.

Friedhold

Sonntag, 16. September 2007

Logging in Forms und PL/SQL

Derzeit verwende ich in Forms und Stored PL/SQL einen eigenen Logging-Mechanismus in einer Logger-Table:



Soweit so gut : Wenn ich jedoch mit JAVA anfangen möchte, sollte der JAVA-Logger mit dem PL/SQL-Logger der Client- und Serverseite sinnvollerweise identisch sein.
Hier der JAVA-Logger, wonach ich die PL/SQL-Logger angleichen möchte:



Man stelle sich das Szenarion einmal vor: Javascript -> Forms 11g -> PJC -> DB-PL/SQL ..

Friedhold

Dienstag, 14. August 2007

Ein PL/SQL String-Tokenizer mit mehreren Trennzeichen

Häufig sieht man String-Tokenizer, die nur ein Trennzeichen zwischen den Tokens verarbeiten können. Hiermit nun eine Lösung mit beliebig vielen Trennzeichen: download Package.

Anwendung


SQL> declare
separators varchar2(10) :='-;/,. ''';
string varchar2(100):= 'Black;Blue-Green/Yellow''Green-Blue Black Red.Yellow';
token varchar2(100);
begin
token:=parse_string.strtok(string, separators);
while token is not NULL loop
dbms_output.put_line(token);
token:= parse_string.strtok(NULL, separators);
end loop;
end;
/

Black
Blue
Green
Yellow
Green
Blue
Black
Red
Yellow

PL/SQL procedure successfully completed.
SQL>
.

Friedhold