Geodaten und Application Express: Die Karte wird erweitert ...

Heute wird das in den letzten Ausgaben begonnene Geodaten-Tutorial fortgesetzt. In der ersten Ausgabe haben Sie erfahren, wie Sie die kostenlos erhältlichen Kartendaten von NAVTEQ aus dem OTN herunterladen, in die Datenbank importieren und Berechnungen darauf durchführen können. In der letzten Ausgabe wurden die Daten als Karte dargestellt und in eine Application Express-Anwendung integriert. Der Schwerpunkt der Ausgabe lag dabei auf dem Setup für den Oracle MapViewer, der Software zur Erstellung von Karten. Heute wird die Karte um Elemente zur Navigation und zur dynamischen Anzeige von Kunden- oder anderen Daten erweitert.

Ausgangspunkt für heute ist das Ergebnis der letzten Ausgabe (Abbildung 1)

Ausgangspunkt: Eine Karte in Ihrer Application Express-Anwendung

Abbildung 1: Ausgangspunkt: Eine Karte in Ihrer Application Express-Anwendung

Karte ist eine Region vom Typ Dynamischer PL/SQL-Inhalt und wird mit folgendem Code generiert (Wie das PL/SQL-Paket SDO_MVCLIENT in die Datenbank eingespielt wird, war ebenfalls Thema der letzten Ausgabe).

declare
  v_result    varchar2(1000);
  v_image_url varchar2(1000);
begin
  sdo_mvclient.createMapViewerClient('http://[MapViewer-Host]:8888/mapviewer/omserver');

  sdo_mvclient.setDataSourceName('world');
  sdo_mvclient.setImageFormat('PNG_URL');
  sdo_mvclient.setAntiAliasing('true');
  sdo_mvclient.setBaseMapName('WORLD_SAMPLE');
  sdo_mvclient.setCenterAndSize(10,50,2);
  sdo_mvclient.setDeviceSize(500,400);
  v_result := sdo_mvclient.run();
  v_image_url := sdo_mvclient.getGeneratedMapImageUrl();
  htp.p('<img src="'||v_image_url||'" alt="Karte" title="Karte">');
end;

Fügen Sie der Region Karte zunächst zwei Schaltflächen hinzu und legen Sie gleichzeitig ein Element vom Typ Ausgeblendet mit dem Namen PX_KARTENHOEHE an. Dieses Element nimmt die Höhe der Karte in Grad, welche bislang mit hart kodiert war, auf. Die Schaltflächen sollten als Redirect-Schaltflächen angelegt werden, also zu einer URL umleiten. Achten Sie auf die richtige Belegung des Parameters REQUEST. Abbildung 2 zeigt dies am Beispiel der Schaltfläche ZOOMIN.

URL Redirect für die Schaltfläche ZOOMIN

Abbildung 2: URL-Redirect für die Schaltfläche ZOOMIN

Ihre Anwendungsseite sollte dann wie in Abbildung 3 dargestellt aussehen.

Karte mit Schaltflächen zum Herein- und Herauszoomen

Abbildung 3: Karte mit Schaltflächen zum Herein- und Herauszoomen

Wenn Sie nun auf die Schaltflächen klicken, passiert noch nichts. Damit etwas passiert, benötigen Sie noch einen Seitenprozeß. Er soll beim Laden (onLoad) ausgeführt werden.

Der neue Kartenausschnitt wird mit einem PL/SQL-Prozeß berechnet

Abbildung 4: Der neue Kartenausschnitt wird mit einem PL/SQL-Prozeß berechnet

Hinterlegen Sie folgenden PL/SQL-Code für den Prozeß. Wenn das Element PX_KARTENHOEHE noch keinen Wert hat, soll als Standardwert 2 (wie in der letzten Ausgabe) verwendet werden. Ansonsten wird der Kartenausschnitt bei Klick auf ZOOMIN halbiert und bei Klick auf ZOOMOUT verdoppelt.

begin
  if :PX_KARTENHOEHE is null then 
    :PX_KARTENHOEHE := 2;
  end if;
  if :REQUEST='ZOOMIN' then 
    :PX_KARTENHOEHE := :PX_KARTENHOEHE / 2;
  elsif :REQUEST='ZOOMOUT' then 
    :PX_KARTENHOEHE := :PX_KARTENHOEHE * 2;
  end if;
end;

Ersetzen Sie zum Abschluß die hartkodierte 2 im PL/SQL-Code der Region Karte durch das Element :PX_KARTENHOEHE.

declare
  v_result    varchar2(1000);
  v_image_url varchar2(1000);
begin
  sdo_mvclient.createMapViewerClient('http://[MapViewer-Host]:8888/mapviewer/omserver');

  sdo_mvclient.setDataSourceName('world');
  sdo_mvclient.setImageFormat('PNG_URL');
  sdo_mvclient.setAntiAliasing('true');
  sdo_mvclient.setBaseMapName('WORLD_SAMPLE');
  sdo_mvclient.setCenterAndSize(10,50,:PX_KARTENHOEHE);
  sdo_mvclient.setDeviceSize(500,400);
  v_result := sdo_mvclient.run();
  v_image_url := sdo_mvclient.getGeneratedMapImageUrl();
  htp.p('<img src="'||v_image_url||'" alt="Karte" title="Karte">');
end;

Starten Sie Ihre Seite nun neu und klicken Sie die neuen Schaltflächen an. Der Kartenausschnitt sollte sich dann entsprechend der geklickten Schaltfläche vergrößern oder verkleinern.

Analog dazu können Sie dem Endanwender nun auch die Möglichkeit geben, den Kartenausschnitt zu verschieben. Legen Sie dazu zunächst zwei neue ausgeblendete Elemente PX_KARTENZENTRUM_X und PX_KARTENZENTRUM_Y an. Erzeugen Sie anschließend vier neue Schaltflächen zum Verschieben nach links (SHIFT_LEFT), nach rechts (SHIFT_RIGHT), nach oben (SHIFT_UP) und nach unten (SHIFT_DOWN) analog zu den bereits vorhandenen Schaltflächen ZOOM_IN und ZOOM_OUT.

Nun erweitern Sie den PL/SQL-Code Ihres onLoad-Prozesses wie folgt:

begin
  if :PX_KARTENHOEHE is null then 
    :PX_KARTENHOEHE := 2;
  end if;
  if :PX_KARTENZENTRUM_X is null then
    :PX_KARTENZENTRUM_X := 10;
  end if;
  if :PX_KARTENZENTRUM_Y is null then
    :PX_KARTENZENTRUM_Y := 50;
  end if;
  if :REQUEST='ZOOMIN' then 
    :PX_KARTENHOEHE := :PX_KARTENHOEHE / 2;
  elsif :REQUEST='ZOOMOUT' then 
    :PX_KARTENHOEHE := :PX_KARTENHOEHE * 2;
  elsif :REQUEST = 'SHIFT_LEFT' then
    :PX_KARTENZENTRUM_X :=  :PX_KARTENZENTRUM_X - :PX_KARTENHOEHE;
  elsif :REQUEST = 'SHIFT_RIGHT' then
    :PX_KARTENZENTRUM_X :=  :PX_KARTENZENTRUM_X + :PX_KARTENHOEHE;
  elsif :REQUEST = 'SHIFT_UP' then
    :PX_KARTENZENTRUM_Y :=  :PX_KARTENZENTRUM_Y + :PX_KARTENHOEHE;
  elsif :REQUEST = 'SHIFT_DOWN' then
    :PX_KARTENZENTRUM_Y :=  :PX_KARTENZENTRUM_Y - :PX_KARTENHOEHE;
  end if;
end;

Und zum Abschluß ersetzen Sie (wiederum im PL/SQL-Code der Region Karte) die hartkodierte 10 bzw. 50 durch :PX_KARTENZENTRUM_X bzw. PX_KARTENZENTRUM_Y.

  :
  sdo_mvclient.setCenterAndSize(:PX_KARTENZENTRUM_X, :PX_KARTENZENTRUM_Y, :PX_KARTENHOEHE);
  :

Ihre Seite sollte nun wie in Abbildung 5 aussehen.

Das Ergebnis: Karte mit Schaltflächen zur Navigation

Abbildung 5: Das Ergebnis: Karte mit Schaltflächen zur Navigation

Als nächstes erfahren Sie, wie Sie Ihrer Karte zusätzliche Daten hinzufügen können. Eine erste Idee wäre, die Koordinaten von Kunden in die Karte aufzunehmen.

Für dieses Beispiel werden wir die Koordinaten der Kunden per Zufallsgenerator erzeugen. Grundsätzlich wird das Ermitteln einer Geokoordinate aus einer postalischen Adresse als Geocoding bezeichnet. Auch Geocoding ist mit der Oracle-Datenbank möglich, die Beschreibung würde jedoch den Rahmen dieses Tutorials sprengen. Mehr Informationen zum Thema Geocoding in der Oracle-Datenbank finden Sie in der Oracle-Dokumentation.

Lassen Sie zur Erzeugung einiger Beispieldaten das folgende SQL-Skript laufen. Nehmen Sie dazu jedoch nach Möglichkeit SQL*Plus oder den SQL Developer, nicht jedoch den Application Express SQL Workshop. Loggen Sie sich unter dem Parsing Schema (in welchem auch die anderen Geodaten liegen) ein.

create table kunden (
  id number(10),
  name varchar2(50),
  lokation sdo_geometry,
  constraint pk_kunden primary key (id)
)
/

insert into user_sdo_geom_metadata (table_name, column_name, diminfo, srid)
values (
  'KUNDEN', 
  'LOKATION', 
  SDO_DIM_ARRAY(
    SDO_DIM_ELEMENT('X', -180, 180, 1), 
    SDO_DIM_ELEMENT('Y', -90, 90, 1)
  ), 
  8307
)
/

begin
  for i in 1..250 loop
    insert into kunden (id, name, lokation)
    values (
      i,
      'Kunde #'||i,
      sdo_geometry(
        2001,
        8307,
        sdo_point_type(
          dbms_random.value(8,12),
          dbms_random.value(48,52),
          null
        ),
        null,
        null
      )
    );
  end loop;
end;
/

create index kunden_sx on kunden (lokation)
indextype is mdsys.spatial_index
/

Ändern Sie dann den PL/SQL-Code der Region Karte wie folgt:

declare
  v_result    varchar2(1000);
  v_image_url varchar2(1000);

  v_theme number;
begin
  sdo_mvclient.createMapViewerClient('http://[Mapviewer-Host]:8888/mapviewer/omserver');

  sdo_mvclient.setDataSourceName('world');
  sdo_mvclient.setImageFormat('PNG_URL');
  sdo_mvclient.setAntiAliasing('true');
  sdo_mvclient.setBaseMapName('WORLD_SAMPLE');
  sdo_mvclient.setCenterAndSize(:PX_KARTENZENTRUM_X, :PX_KARTENZENTRUM_Y,:PX_KARTENHOEHE);
  sdo_mvclient.setDeviceSize(500,400);
  v_theme := sdo_mvclient.addJdbcTheme(
    datasource    => 'world',
    name          => 'kunden',
    query         => 'select name, lokation from kunden',
    spatialcolumn => 'LOKATION',
    srid          => '8307',
    labelcolumn   => 'NAME',
    labelstyle    => 'T.S03_CITIES_L2',
    renderstyle   => 'M.CYAN PIN',
    passthrough   => 'FALSE'
  );
  v_result := sdo_mvclient.run();
  v_image_url := sdo_mvclient.getGeneratedMapImageUrl();
  htp.p('<img src="'||v_image_url||'" alt="Karte" title="Karte">');
end;

Bis hierhin haben Sie die vordefinierte Karte WORLD_SAMPLE verwendet. Eine Karte besteht aus mehreren Schichten (Layer), die man sich am besten als übereinandergelegte Klarsichtfolien vorstellen kann. Die "Folien" der Karte WORLD_SAMPLE sind ebenfalls bereits vordefiniert und wurden zusammen mit den NAVTEQ-Geodaten in die Datenbank geladen - bis hierher haben wir also nur mit der bereits vordefinierten Karte gearbeitet.

Mit dem Aufruf von addJdbcTheme werden der Karte nun neue, selbstdefinierte Schichten (oder "Folien") hinzugefügt. Die neue Schicht ist einerseits durch eine SQL-Abfrage, andereseits durch Style-Angaben definiert. Während die SQL-Abfrage die Daten liefert, legen die Style-Angaben fest, wie die Daten in der Karte dargestellt werden sollen.

Zur Darstellung eines Kunden wird der Style "M.CYAN PIN" verwendet; ein Kunde wird in der Karte also durch eine Stecknadel repräsentiert. Für den Namen des Kunden (das " Label" der Stecknadel) wird der Style "T.S03_CITIES_L2" verwendet. Die beiden Styles sind ebenfalls bereits vordefiniert und wurden mit den NAVTEQ-Geodaten in die Datenbank geladen.

Starten Sie die Seite nochmals neu und navigieren Sie in den Bereich der Bundesrepublik Deutschland. Je nach eingestellter Vergrößerung sehen Sie nun mehr oder weniger viele Stecknadeln in Ihrer Karte ...

Kunden in der Karte ...

Abbildung 6: Kunden in der Karte ...

Mit Hilfe eines Kontrollkästchens können die Kunden nun auch dynamisch ein- und ausgeblendet werden. Fügen Sie Ihrer Anwendung ein Kontrollkästchen (Check Box) mit Namen PX_ZEIGE_KUNDEN hinzu. Nehmen Sie eine statische Werteliste und tragen Sie ein: STATIC:;Y. Nun möchten wir noch erreichen, dass die Seite sich automatisch neu aufbaut, wenn die Checkbox geklickt wird. Navigieren Sie also zu den Eigenschaften der Checkbox und tragen Sie als HTML Form Element Attribut den Wert onClick="javaScript:doSubmit();" ein (Abbildung 7).

Automatischen Seiten-Refresh bei Klick auf die Checkbox aktivieren

Abbildung 7: Automatischen Seiten-Refresh bei Klick auf die Checkbox aktivieren

Nun muss der PL/SQL-Code der Region Karte nochmals angepasst werden; der soeben eingefügte Aufruf addJdbcTheme darf nur noch dann ausgeführt werden, wenn die Checkbox PX_ZEIGE_KUNDEN aktiviert ist. Dies erreichen Sie durch eine einfache IF-Bedingung.

  :
  if :PX_ZEIGE_KUNDEN = 'Y' then 
    v_theme := sdo_mvclient.addJdbcTheme(
      datasource    => 'world',
      name          => 'kunden',
      query         => 'select name, lokation from kunden',
      spatialcolumn => 'LOKATION',
      srid          => '8307',
      labelcolumn   => 'NAME',
      labelstyle    => 'T.S03_CITIES_L2',
      renderstyle   => 'M.CYAN PIN',
      passthrough   => 'FALSE'
    );
  end if;
  :

Fügen Sie zum Abschluß noch eine Seitenverzweigung (ohne Bedingung auf die gleiche Seite) ein, Starten Sie die Seite nun nochmals und probieren Sie die neue Checkbox aus. Sie können nun auf einfachem Wege die Darstellung der Kunden aktivieren oder deaktivieren.

Das Ergebnis: Kunden dynamisch ein- und ausblenden

Abbildung 8: Das Ergebnis: Kunden dynamisch ein- und ausblenden

In der nächsten Ausgabe werden wir das Geodaten-Tutorial zumindest vorläufig abschließen. Dann werden Sie erfahren, wie Sie die Karte in Ihrer Application Express-Anwendung so interaktiv machen, wie man es von Google Maps gewohnt ist. Es wird also unter anderem möglich sein, den Kartenausschnitt per Drag & Drop zu verschieben.

Wenn Sie mehr über die Geodaten-Technologie erfahren möchten, finden Sie hier weitere Informationen:

Zurück zur Community-Seite