APEX und Geodaten: Positionen, Koordinaten und mehr - Teil 1
Erscheinungsmonat |
APEX-Version |
Datenbankversion |
Oktober 2013 |
alle |
ab 10.2 |
Die Arbeit mit Positionen und Koordinaten, also Geodaten, spielt in mehr und mehr
Anwendungsgebieten eine Rolle. Diese Tipp-Reihe der deutschsprachigen APEX Community
stellt am Beispiel einer Image Geotagging Application
vor, wie man in einer APEX-Anwendung
mit Geodaten arbeiten, die Möglichkeiten
der Datenbank ausnutzen und schließlich eine Karte in die APEX-Anwendung integrieren kann.
Die Anwendung wird es ermöglichen ...
- ... mit dem Smartphone aufgenommene Bilder per APEX-Anwendung hochzuladen
- ... die Position zu extrahieren und als Koordinate zu speichern
- ... die Bilder auf einer Karte darzustellen
- ... räumliche Abfragen bzw. Auswertungen mit den Positionen durchzuführen
Abbildung 1: APEX Anwendung: "Image Geotagging"
Da dies den Rahmen eines einzelnen Community-Tipps sprengen würde, werden die
Themengebiete auf mehrere Community-Tipps verteilt.
- Teil 1: Geodaten mit SDO_GEOMETRY in einer APEX-Anwendung nutzen
- Teil 2: Eine Karte einbinden mit dem Oracle Maps APEX Plugin
- Teil 3: Aufbau eines eigenen Kartenservers: Oracle MapViewer und Oracle Maps
- Teil 4: Oracle Maps intensiver nutzen: Programmieren mit der JavaScript API
Arbeiten mit Geodaten in der Datenbank: SDO_GEOMETRY
Die Oracle-Datenbank bietet seit langer Zeit eine umfassende Unterstützung für
die Arbeit mit Geodaten an. Kern der Funktionalität ist der Datentyp SDO_GEOMETRY,
welcher "geometrische Primitive" wie Punkte, Linienzüge oder Polygone repräsentiert.
SDO_GEOMETRY kann in Tabellen und PL/SQL-Logik so verwendet werden, wie jeder
andere Datentyp auch. Der erste Schritt zur Nutzung von Geodaten in APEX ist also
das Erzeugen einer Tabelle mit einer Spalte vom Typ SDO_GEOMETRY.
Die Bilder werden in der Spalte IMAGE vom Typ BLOB abgelegt. Zur Darstellung ist
es hilfreich, eine im Vorfeld "kleingerechnete" Version des Bildes vorzuhalten; dieses
wird in der Spalte THUMBNAIL hinterlegt. Die Spalte GEOMETRY ist vom Typ SDO_GEOMETRY
und wird die Koordinate aufnehmen - weitere Metadaten des Bildes werden in METADATA
im XML-Format gespeichert. Wie für jede andere Tabelle empfiehlt es sich auch hier,
zur Befüllung der Primärschlüsselspalte ID eine Sequence und einen Trigger zu erzeugen.
Spalten vom Typ SDO_GEOMETRY erfordern allerdings noch einen weiteren Schritt: Sie
müssen nochmals separat im Data Dictionary registriert werden. Dies geschieht, indem in
die View USER_SDO_GEOM_METADATA eine Zeile eingefügt wird. Beachten Sie, dass dieser
Schritt nicht im APEX SQL Workshop gemacht werden kann - Sie müssen den SQL Developer
oder SQL*Plus oder ein anderes Werkzeug dafür verwenden. Wichtig dabei ist, dass Sie die physikalische
Datenbankverbindung als Eigentümer der Tabellen aufgebaut haben - das ist bei
APEX nicht der Fall. Alle anderen Schritte können auch im APEX SQL Workshop gemacht werden.
Neben dem Tabellen- und Spaltennamen sind hier vor allem die mögliche räumliche Ausdehnung
der Koordinaten (Spalte DIMINFO) und das verwendete
Koordinatensystem (SRID) wichtig.
Im Beispiel werden Längen- und
Breitengrade ("WGS84" mit der ID 8307) als Koordinatensystem verwendet - als Koordinaten
kommt "die ganze Welt" in Frage (Längengrade: -180 bis +180; Breitengrade: -90 bis +90).
Der räumliche Index ist ebenfalls wichtig, wenn es um Tabellen mit SDO_GEOMETRY-Spalten geht. Dieser
ist zwar nicht zwingend erforderlich - die meisten Operationen sind jedoch nur mit Spatial-Index
möglich; es ist also sinnvoll, ihn gleich anzulegen.
SDO_GEOMETRY: Einige Beispiele
Wie schon gesagt, repräsentiert SDO_GEOMETRY geometrische Primitive wie Punkte, Linienzüge
oder Polygone. Abbildung 2 zeigt die möglichen Geometrieformen.
Abbildung 2: Mögliche Geometrieformen mit SDO_GEOMETRY
Der genaue Aufbau des Datentypen SDO_GEOMETRY ist in der
Dokumentation (Oracle Spatial and Graph Developers Guide
ausführlich beschrieben - im folgenden seien daher nur einige Beispiele
gezeigt.
- Am häufigsten benötigt man sicherlich den Punkt. Der Punkt besteht normalerweise
aus einem Koordinatenpaar (Längen- und Breitengrad). Das folgende Beispiel
erzeugt einen (zweidimensionalen) Punkt als SDO_GEOMETRY:
Das erste Attribut des SDO_GEOMETRY (2001) besagt, dass es sich hier um einen
zweidimensionalen Punkt handelt, der zweite Parameter bestimmt das verwendete
Koordinatensystem (8307 = WGS84 = Längen- und Breitengrade). Der dritte
Parameter wird nur bei Punten verwendet und enthält die konkreten Koordinaten; der
vierte und fünfte Parameter bleiben leer - diese sind komplexeren Geometrieformen
vorbehalten.
- Ein Linienzug wird wie folgt gebildet:
Wiederum bestimmt das erste Attribut die Art der Geometrie (2002 = zweidimensionaler Linienzug);
das zweite Attribut bestimmt (wiederum) das Koordinatensystem; das dritte Attribut bleibt
leer (kein Punkt). Die Koordinaten selbst befinden sich im fünften Attribut; das vierte
Attribut legt genau fest, wie die Koordinaten zu interpretieren sind (hier als Linienzug
mit geraden Linien). Mit einem solchen Linienzug lässt sich schon etwas anfangen; so kann
man mit der Funktion SDO_GEOM.SDO_LENGTH die Länge bestimmen ...
- Eine Fläche wird als Polygon formuliert. Wir beginnen mit dem "Normalfall":
Der grundsätzliche Aufbau ist analog zum Linienzug. Der Geometrietyp 2003 bedeutet,
dass hier ein zweidimensionales Polygon vorliegt. Die Koordinaten sind
wiederum im fünften Attribut; das vierte Attribut bedeutet, dass das Polygon
durch einen geschlossenen Linienzug entgegen dem Uhrzeigersinn definiert ist; folgerichtig
ist das letzte Koordinatenpaar gleich dem ersten. Die gleiche Geometrie kann auch
einfacher (als "optimiertes Rechteck") formuliert werden. In diesem Fall werden
nur die linke untere und die rechte obere Ecke angegeben.
Ein Polygon eignet sich gut zur Flächenberechnung (SDO_GEOM.SDO_AREA).
Anhand dieser Informationen könnte man nun schon damit beginnen, die Tabelle
mit Koordinaten zu befüllen. Allerdings möchten wir das nicht manuell tun, vielmehr
sollen die Koordinaten aus den hochgeladenen Bildern extrahiert werden.
Koordinaten aus einem Smartphone-Bild extrahieren
Die Oracle-Datenbank bietet mit dem Paket ORDIMAGE einige Methoden zum Umgang
mit Bildern an - dazu gibt es einen eigenen
Community-Tipp. Zur Extraktion der GPS-Position, an
der das Bild aufgenommen wurde, ist vor allem die Möglichkeit interessant, die EXIF-Metadaten
auszulesen - dazu bietet die Datenbank die Funktion ORDIMAGE.GETMETADATA an. Voraussetzung
ist natürlich, dass das Bild mit einem GPS-Fähigen Smartphone aufgenommen wurde.
Hat man also ein Bild in Form eines BLOB vorliegen, so kann man mit dieser
Funktion die Metadaten abrufen. Diese werden dann als XML aufbereitet. Vor dem
Aufruf von GETMETADATA sollte man sicherstellen,
dass NLS_TERRITORY auf AMERICA
eingestellt ist, sonst werden Fehlermeldungen wegen des Datumsformats ausgelöst.
Mit den XML-Funktionen der Datenbank lassen sich die Koordinaten recht einfach
aus dem Bild ausschneiden. Spielen Sie dazu das PL/SQL-Paket PKG_ORDIMAGE in Ihr Datenbankschema ein. Darin enthalten ist die Funktion GET_LOCATION, welche
diese Arbeit erledigt und darüber hinaus die Funktion THUMBNAIL, welche eine kleinere
Vorschauversion generiert.
Mit Hilfe von PKG_ORDIMAGE lässt sich nun eine PL/SQL-Prozedur (PROC_STOREIMAGE) erstellen, welche
ein Bild entgegennimmt und in die anfangs erstellt Tabelle TAB_GEOTAG_IMAGES
speichert. Zusätzlich werden die Metadaten und die Position ausgelesen, der
Thumbnail generiert und alles zusammen in die Tabelle abgelegt.
Mit Hilfe dieser Prozedur können Sie nun beginnen, Bilder in Ihre Tabelle abzulegen.
- Erstellen Sie eine neue APEX-Anwendung mit einer Anwendungsseite und einer Region vom Typ
HTML.
- Fügen Sie der Region ein neues Seitenelement vom Typ Datei durchsuchen namens P{X}_BILD hinzu.
Legen Sie fest, dass die Datei in die Tabelle WWV_FLOW_FILES (und nicht in eine eigene Tabelle)
gespeichert wird.
Abbildung 3: Bild in Tabelle "WWV_FLOW_FILES" ablegen
- Fügen Sie eine Schaltfläche zum Absenden hinzu (Page Submit).
- Hinterlegen Sie einen Prozess zum Speichern des Bildes in die eigentliche Tabelle. Er soll
bei Klick auf die Schaltfläche gestartet werden und folgenden PL/SQL Code ausführen.
Starten Sie die Anwendung anschließend und speichern Sie einige Bilder ab. Wenn Sie
die Tabelle danach nochmals ansehen, sollte die Spalte GEOMETRY gefüllt sein.
Referenzdaten (Kartendaten) hinzufügen
Um richtig mit Geodaten arbeiten zu können, braucht man neben den Anwendungsdaten
meist zusätzlich noch Kartendaten. Kartendaten müssen typischerweise käuflich erworden
werden; dafür kommen die verschiedensten Anbieter in Betracht. In diesem Tipp möchten
wir speziell auf das Beispieldatenset von HERE (ehemals NAVTEQ) eingehen, welches
aus dem Oracle OTN kostenlos heruntergeladen werden kann. Das World Sample wird als DataPump-Exportdatei
bereitgestellt und kann entsprechend mit dem impdp-Werkzeug in die Datenbank importiert werden. Enthalten sind vor allem Ländergrenzen, Administrative Einheiten und Major Roads, also
die wichtigen Straßen eines Landes. Detailliertere Informationen wir Ortsstraßen sind nicht enthalten. Spielen Sie das Beispieldatenset also entsprechend der beigefügten Installationsanleitung ein - typischerweise wird dafür das Datenbankschema WORLD_SAMPLE erzeugt. Nach dem Einspielen enthält es einige neue Tabellen mit den
Kartendaten.
Die Tabelle WOM_AREA enthält alle Flächen - da das WORLD_SAMPLE hauptsächlich zur
Kartendarstellung gedacht ist, sind alle Flächen aller administrativen Ebenen in einer
Tabelle zusammengefasst - der Inhalt der Spalte FEATURE_TYPE legt fest, ob die Fläche
ein Staat, ein Bundesland oder eine Gemeindefläche ist.
Mit diesen Tabellen kann nun auf SQL-Ebene gearbeitet werden. So zeigt die folgende
SQL-Abfrage, in welchen Staaten die Bilder gemacht wurden.
Schränkt man FEATURE_TYPE auf einen anderen Wert ein, so erhält man die Bundesländer bzw.
Provinzen (in Staaten, die keine Bundesrepubliken sind).
Mit diesen Informationen lässt sich nun ein APEX-Bericht in die Anwendung
einbauen - dieser soll eine Übersicht über die gespeicherten Bilder zeigen. Legen
Sie also einen klassischen Bericht an und verwenden
Sie dazu die folgende SQL-Abfrage.
Der erste Wurf kann noch nicht ganz überzeugen (Abbildung 4) ...
Abbildung 4: Erster Wurf: Klassischer Bericht mit SQL-Abfrage
Sowohl die Spalten THUMBNAIL als auch GEOMETRY werden von APEX nicht dargestellt. Zur Darstellung
des Vorschaubildes kann allerdings APEX-Standardfunktionalität verwendet werden. Ändern Sie dazu zunächst
die SQL-Abfrage wie folgt um:
Navigieren Sie dann zu den Spaltenattributen der Spalte THUMBNAIL. Tragen Sie
dort im Bereich Column Attributes den Text IMAGE:TAB_GEOTAG_IMAGES:THUMBNAIL:ID::::::Inline:Download als Number / Date Format ein (Abbildung 5).
Abbildung 5: Spaltenformat zur Anzeige eines Bildes im klassischen Bericht
Nun sollte der Bericht wie in Abbildung 6 aussehen.
Abbildung 6: Nun werden die Bilder angezeigt
Es bleibt die Spalte GEOMETRY übrig. APEX ist aus dem Stand nicht in der Lage, die
Inhalte eines SDO_GEOMETRY anzuzeigen. Da es in diesem Fall aber nur um Punkte geht,
kann man sich einfach helfen. Es braucht eine PL/SQL-Funktion, welche einen SDO_GEOMETRY
in eine Zeichenkette umwandelt. Die Dezimalzahl wandeln wir dann auch gleich in eine
Angabe in Grad, Minuten und Sekunden um. Spielen Sie also die folgende Funktion
FUNC_GEOMTOSTRING in Ihr Datenbankschem ein.
In der SQL-Abfrage wird diese nun einfach eingesetzt ...
Danach sieht der Bericht wie in Abbildung 7 aus.
Abbildung 7: Nun werden die Bilder und die Position angezeigt
Ändert man das Berichtstemplate, lässt sich Layout noch weiter optimieren:
- Erzeugen Sie ein neues Berichtstemplate
- Wählen Sie from Scratch
- Nehmen Sie ein Named Column Template
- Vergeben Sie einen Namen und speichern Sie ab.
- Navigieren Sie dann zu den Berichtsattributen, wählen Sie das neue Template aus und
schalten Sie dabei auch gleich die Pagination ab.
- Navigieren Sie zum soeben erstellten Berichtstemplate, wählen Sie Bearbeiten und
hinterlegen Sie bei Row Template 1 den folgenden HTML-Code.
Abbildung 8: HTML-Code des neuen Berichts-Templates
Nun sieht die Bildübersicht etwas eleganter aus (Abbildung 9).
Abbildung 9: Bildübersicht mit neuem Berichts-Template
Fazit
In diesem Community-Tipp haben Sie erfahren, wie Sie eine Tabelle mit einer
SDO_GEOMETRY-Spalte zur Verwaltung von Geoinformationen erzeugen. Neben einigen
Beispielen zum Umgang mit SDO_GEOMETRY wurde eine APEX-Anwendung erzeugt, mit
der Bilder in die Tabelle gespeichert werden - dabei werden die Metadaten und
damit die GPS-Position des Bildes extrahiert und in der Tabelle gespeichert. Mit
Hilfe des HERE (ehemals NAVTEQ)-Beispieldatensets "World Sample" können räumliche Abfragen durchgeführt
und so bspw. das Land, in dem das Bild aufgenommen wurde, festgestellt werden. Mit Hilfe
von APEX-Standardkomponenten wie dem klassichen Bericht lässt sich schließlich eine
einfache Übersicht über die vorhandenen Bilder generieren.
Der nun folgende, nächste logische Schritt ist das Aufnehmen einer Karte in die
Anwendung. Dies wird in Teil 2 der Tipp-Reihe behandelt.
Zurück zur Community-Seite
|