Folien

Werbung
7 Anwendungsprogrammierung
7.1 Kopplung von SQL mit Programmiersprachen
7.2 Postgres und JDBC
7.3 Oracle Spatial und JDBC
7.4 Verarbeitung von GMLbasierten Daten
7.5 Funktionales Programmieren mit Polygonen
7.6 Zusammenfassung
aus: [KGB04]
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
577
Anwendungsprogrammierung
→“Kern-SQL” ist auch mit räumlichen Erweiterungen
nicht berechnungsuniversell
→zahlreiche Anwendungen (z.B. Formvereinfachungen) sind jedoch ohne Berechnungsuniversalität
nicht oder nur sehr umständlich lösbar
→für geometrische/räumliche Anwendungen ist
Kopplung zwischen SQL und Programmiersprachen
nötig
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
578
7.1 Kopplung von SQL mit
Programmiersprachen
→aktuelle SQL-Programmschnittstellen sind
Einbettung
Call-Schnittstelle
→beide Schnittstellen
müssen den
“Impedance Mismatch”
überbrücken (satzorien‐
tierte Programmiersprache vs. mengenorientierte Datenbanksprache)
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
579
Kopplung von SQL mit Programmiersprachen
→Einbettung (Embedded SQL)
beide Sprachen (SQL und Programmiersprache) bleiben
weitgehend unverändert
SQL-Anweisungen werden durch Präfix gekennzeichnet
(EXEC SQL)
Bearbeitung durch
Precompiler
Variablen der Program‐
miersprache in SQL
werden durch “:”
gekennzeichnet
SQL Communication Area enthält Statusinformationen
über Ergebnis
von SQL-Anweisung
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
580
Kopplung von SQL mit Programmiersprachen
→alle SQL-DML-Anweisungen können eingebettet
werden, außerdem noch
Deklarations-Anweisungen
Kursor-Anweisungen
weitere Anweisungen, die es nur in Embedded SQL und
nicht im interaktiven SQL gibt
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
581
Kopplung von SQL mit Programmiersprachen
→Beispiel (Embedded SQL und C)
/* C-Includes zur Ein-/Ausgabe */
/* und Stringverarbeitung
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Include zur Interaktion mit der Datenbank */
#include <sqlenv.h>
/* Deklaration der SQL Communication Area */
EXEC SQL INCLUDE SQLCA;
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
582
Kopplung von SQL mit Programmiersprachen
main()
{
/* Deklaration der C-Variablen, die in */
/* SQL-Anweisungen verwendet werden */
EXEC SQL BEGIN DECLARE SECTION;
char name[20];
char fachgebiet[20];
EXEC SQL END DECLARE SECTION;
/* Cursor-Deklaration fuer Anfrage */
EXEC SQL DECLARE C1 CURSOR FOR
SELECT name, fachgebiet
FROM professoren
ORDER BY name;
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
583
Kopplung von SQL mit Programmiersprachen
/* Verbindungsaufbau zur benutzten Datenbank */
/* und oeffnen des Cursors */
EXEC SQL CONNECT TO unidb;
EXEC SQL OPEN C1;
/* solange noch Tupel vorhanden ... */
while(strncmp(sqlca.sqlstate, "02000", 5))
{
/* Tupelattribute in C-Variablen schreiben */
/* und Werte der Variablen ausgeben */
EXEC SQL FETCH C1 INTO :name, :fachgebiet;
printf("%s %s\n", name, fachgebiet);
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
584
Kopplung von SQL mit Programmiersprachen
/* Cursor schliessen und */
/* Datenbankverbindung abbauen */
EXEC SQL CLOSE C1;
EXEC SQL DISCONNECT CURRENT;
return;
}
Beigl Informatik
Bender Mathematik
Eick Mathematik
Fekete Informatik
Kemnitz Mathematik
Kreiss Mathematik
Wolf Informatik
Zimmermann Mathematik
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
585
Kopplung von SQL mit Programmiersprachen
→Embedded SQL erlaubt auch Konstruktion von
Anfragen zur Laufzeit (Dynamic SQL)
Anfrage wird dazu als Wert einer Textvariable im
Anwendungsprogramm konstruiert
Anweisung PREPARE übersetzt Anfrage in ausführbaren
Objektcode und schreibt sie in SQL-Variable vom Typ
STATEMENT
EXECUTE führt übersetzte Anfrage aus
Schemainformationen
werden zur Laufzeit
mit DESCRIBE ermittelt
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
586
Kopplung von SQL mit Programmiersprachen
→Struktur der SQL Description Area (SQLDA) relativ
kompliziert
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
587
Kopplung von SQL mit Programmiersprachen
→SQLJ ist ein “eingebettetes SQL für Java”
direkte Einbettung von
(statischen) SQL-Anweisungen in Java-Code
ANSI-Standard, entstanden
in Zusammenarbeit mehrerer Firmen
eingebettete SQL-Anweisungen können zur Übersetzungszeit syntaktisch
und semantisch überprüft
werden (auch gegen das
Schema einer Datenbank)
aus: http://www.oracle.com/
SQL-Anweisungen
werden durch Präfix
“#sql” gekennzeichnet
Benutzung von Variablen wie beim statischen Embedded SQL
als Ergebnis einer
Anfrage wird ein SQLJIterator erzeugt
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
588
Kopplung von SQL mit Programmiersprachen
→SQLJ-Systemkomponenten
aus: [SaS03]
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
589
Kopplung von SQL mit Programmiersprachen
→SQLJ-Beispiel
#sql public iterator BookIter(String titel, double preis);
try{
// Verbindungsaufbau
Connection con = DriverManager.getConnection(url, user, passwd);
DefaultContext ctx = newDefaultContext(con);
DefaultContext.setDefaultContext(ctx);
// Anfrageausfuehrung
BookIter iter;
#sql iter= SELECT titel, preis FROM buch;
while(iter.next())
System.out.println(iter.titel() + ", " + iter.preis());
} catch (SQLException exc)
{System.out.println(exc);}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
590
Kopplung von SQL mit Programmiersprachen
→Call-Schnittstelle (Call Level Interface, CLI)
Datenbankfunktionen werden aus Anwendungsprogramm durch externe Prozeduren (Methoden) realisiert
grobe Unterscheidung in
6 Gruppen
• An/Abmelden,
Passwort/Identifikation
• Bekanntgabe von Programmvariablen
• Übersetzen/Ausführen
von SQL-Anweisungen
• Ergebnisverarbeitung
• Fehlerbehandlung
• Transaktionsverwaltung
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
aus: http://publib.boulder.ibm.com/
591
Kopplung von SQL mit Programmiersprachen
→aktuelle Call-Schnittstelle für Java:
JDBC (Java Database Connectivity)
→setzt auf Java-Basisklassen
auf
→bietet Methoden für
Zugriff aus JavaApplikationen auf
beliebige
(relationale)
Datenbanksysteme
aus: http://www.developersbook.com
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
592
Kopplung von SQL mit Programmiersprachen
→Java-Package java.sql mit Klassen
DriverManager: Einstiegspunkt, Laden von Treibern
Connection: Datenbankverbindung
Statement: Ausführung von Anweisungen über eine
Verbindung
ResultSet: verwaltet Ergebnisse einer Anfrage, Zugriff
auf einzelne Tupel und Attribute
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
593
Kopplung von SQL mit Programmiersprachen
→Treiberkonzept
Treibermanager
abstrakte Klassen für Datenbankzugriff
dynamisches Laden von Treibern
Auswahl des geeigneten Treibers über Verbindungsdaten
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
594
Kopplung von SQL mit Programmiersprachen
→typischer Ablauf
Aufbau einer Verbindung zur Datenbank
• Angabe der Verbindungsinformationen
• Auswahl und Laden des
DriverManager
Treibers
senden einer SQL-Anweisung
• Definition der Anweisung
• Belegung von Parametern
verarbeiten der
Anfrageergebnisse
Statement
• Navigation in
Ergebnistupeln
• Zugriff auf Attribute
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
getConnection()
Connection
createStatement()
Statement
Statement
executeQuery()
ResultSet
595
Kopplung von SQL mit Programmiersprachen
→JDBC-Beispiel
import java.sql.*;
public class Sample {
static final String pad="
";
public static void main(String args[]) {
ResultSet rs=null;
Statement stmt=null;
Connection con=null;
try {
// Treiber fuer postgresql laden:
Class.forName("org.postgresql.Driver");
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
596
Kopplung von SQL mit Programmiersprachen
// Verbindung zur Datenbank ’sample’ auf Postgres
// auf dem Rechner it177.idb.cs.tm-cu.de und dem
// Port 4742 aufbauen
con=DriverManager.getConnection(
"jdbc:postgresql://it177.idb.cs.tm-cu.de:4742/sample",
"mueller", // Benutzername
"pwmller"); // Passwort
// Ein neues Statement erzeugen
stmt=con.createStatement();
// Namen, Plz und Staedte aller Personen nach Name
// sortiert abfragen
rs=stmt.executeQuery("SELECT name, plz, stadt "+
"FROM personen "+
"ORDER BY name");
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
597
Kopplung von SQL mit Programmiersprachen
// Ergebnis auf Bildschirm bringen
if (!rs.next()) { // keine Ergebniszeilen // wer hat die Daten geloescht???
System.out.println(
"\nWer hat die Daten aus der DB geloescht?\n"+
"Bitte wieder welche eintragen!!!\n\n(Attribute: \n"+
"name text not null\nplz int not null\nstadt "+
"text not null)");
} else { // Normalfall...
// Ein kleiner Header...
System.out.println("\nName |"+
|"+
" PLZ Stadt");
System.out.println("--------------------------+"+
"-----------------------------------------");
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
598
Kopplung von SQL mit Programmiersprachen
// Alle Datensaetze ausgeben - da rs.next()
// schon aufgerufen wurde,
// koennen wir direkt erst einmal Datensaetze ausgeben
do {
String name=rs.getString("name")+pad;
System.out.println(name.substring(0,25)+" | "+
rs.getInt("plz")+" "+ rs.getString(3));
} while (rs.next());
// noch eine Leerzeile ...
System.out.println();
}
} catch (ClassNotFoundException c) {
System.err.println(
"\nEine Klasse konnte nicht gefunden werden "+
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
599
Kopplung von SQL mit Programmiersprachen
"(Fehlermeldung:\n\n\t"+c.getMessage()+"\n\n)\n\n"+
"Ist das Java Archiv ’/usr/dblocal/java/classes/"+
"pg815.jdbc3.jar’ mit\nim CLASSPATH (\"echo "+
"$CLASSPATH\")?\n");
} catch (SQLException se) {
System.err.println(
"\nAchtung: Es gab einen (unerwarteten?) SQL-Fehler!"+
"\n\nFehlermeldung:\n\n\t"+se.getMessage()+"\n");
}
// schliessen von ResultSet, Statement, Connection
try { rs.close(); } catch (Exception ex) { }
try { stmt.close(); } catch (Exception ex) { }
try { con.close(); } catch (Exception ex) { }
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
}
600
7.2 Postgres und JDBC
→Postgres ist relationales Datenbanksystem mit
räumlichen Datentypen und entsprechenden
SQL-Erweiterungen (vgl. Abschnitt 4.5)
→es bietet u.a. die Datentypen
point (float, float)
box (point, point)
lseg (point, point)
line (point1, point2, ..., pointn)
polygon (point1, point2, ..., pointn)
circle (point, float)
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
601
Postgres und JDBC
→dazu zahlreiche geometrische Prädikate und
Funktionen
→räumliche Datentypen können wie gewohnt für
Attribute genutzt CREATE TABLE Gebäude
(Id CHAR(25), Nutzung CHAR(25),
werden
Grundriss POLYGON(50), PRIMARY KEY(Id));
→Werte räumlicher Datentypen werden als
entsprechende Zeichenketten angegeben
INSERT INTO Gebäude VALUES (
’G4211’,’Polizei’,
’((12125,1333),(13430,1560),(13260,2497),
(14111,2695),(14111,2638),(16040,3092),
(15303,6468),(13345,5958),(13771,3943),
(12948,3773),(12948,3887),(11671,3631))’);
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
602
Postgres und JDBC
→zur Verarbeitung geometrischer Attribute werden
spezielle Java-Klassen und Methoden angeboten
→sind Unterklassen der Klasse “PGobject”
public class Pgobject extends java.lang.Object
implements java.io.Serializable, java.lang.Cloneable
→Unterklassen sind PGpoint, PGbox, PGlseg,
PGline, PGpolygon, PGcircle
→jede Unterklasse enthält u.a. Methoden
Konstruktor
equals vergleicht zwei Objekte gleichen Typs
getValue liefert Objekt als Zeichenkette
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
603
Postgres und JDBC
→Beispiel: Konstruktor für Circle
/**
* @param c PGpoint describing
*
the circle’s center
* @param r radius of circle
*/
public PGcircle(PGpoint c, double r)
{
this();
this.center = c;
this.radius = r;
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
604
Postgres und JDBC
→Beispiel: equals für Polygon
/**
* @param obj Object to compare with
* @return true if the two polygons are identical
*/
public boolean equals(Object obj)
{
if (obj instanceof PGpolygon)
{
PGpolygon p = (PGpolygon)obj;
if (p.points.length != points.length)
return false;
for (int i = 0;i < points.length;i++)
if (!points[i].equals(p.points[i]))
return false;
return true;
}
return false;
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
605
Postgres und JDBC
→Beispiel: getValue für Polygon
/**
* @return the PGpolygon in the syntax expected
* by org.postgresql
*/
public String getValue()
{
StringBuffer b = new StringBuffer();
b.append("(");
for (int p = 0;p < points.length;p++)
{
if (p > 0)
b.append(",");
b.append(points[p].toString());
}
b.append(")");
return b.toString();
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
606
Postgres und JDBC
→zum Transferieren von nichträumlichen Tupelattributen in Java-Variable gibt es spezielle
Methoden (der Klasse ResultSet), u.a.:
getBoolean, getByte, getDate, getDouble, getFloat,
getInt, getObject, getString, getTime
→allerdings gibt es kein
getPoint, getBox, getLseg, getLine, getPolygon,
getCircle
→zum Transferieren von räumlichen Tupelattributen wird daher Methode “getObject” mit dem
entsprechenden Casting auf die passende Unterklasse von “PGobject” benutzt
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
607
Postgres und JDBC
→Beispiel eines Anwendungsprogrammes mit
räumlichen Datentypen, Postgres und JDBC
import java.sql.*;
// es werden die raeumlichen Datentypen
// point und circle benutzt
import org.postgresql.geometric.PGpoint;
import org.postgresql.geometric.PGcircle;
public class GeometricTest {
// in der main-Methode wird
// - Treiber fuer postgresql geladen
// - Verbindung zur Datenbank ’test’ auf Postgres
// auf Server localhost und Port 5432 aufgebaut
// - Relation geomtest eingerichtet
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
608
Postgres und JDBC
// - Methoden insertCircle und retrieveCircle aufgerufen
// - Verbindung zur Datenbank geschlossen
public static void main(String args[]) throws Exception {
Class.forName("org.postgresql.Driver");
String url = "jdbc:postgresql://localhost:5432/test";
Connection conn = DriverManager.getConnection(url,"test","");
Statement stmt = conn.createStatement();
// Relation geomtest hat nur das Attribut mycirc
// mit dem Datentyp circle
stmt.execute("CREATE TEMP TABLE geomtest(mycirc circle)");
stmt.close();
insertCircle(conn);
retrieveCircle(conn);
conn.close();
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
609
Postgres und JDBC
// die Methode insertCircle fuegt einen Kreis
// in die Relation mycirc ein (ein Tupel mit einem Attributwert)
private static void insertCircle(Connection conn)
throws SQLException {
// Konstruktion des Kreises aus center und radius
PGpoint center = new PGpoint(1, 2.5);
double radius = 4;
PGcircle circle = new PGcircle(center, radius);
// vorbereiten des Einfuegens mit "?" als Parameter
PreparedStatement ps = conn.prepareStatement(
"INSERT INTO geomtest(mycirc) VALUES (?)");
// setzen des Parameters und ausfuehren der Anweisung
ps.setObject(1, circle);
ps.executeUpdate();
ps.close();
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
610
}
Postgres und JDBC
// die Methode retrieveCircle holt einen Kreis
// mit dessen berechneter Flaeche aus der Relation mycirc
// und gibt diese Daten aus
private static void retrieveCircle(Connection conn)
throws SQLException {
Statement stmt = conn.createStatement();
// Anfrage fuer Kreis und Kreisflaeche
ResultSet rs = stmt.executeQuery(
"SELECT mycirc, area(mycirc) FROM geomtest");
rs.next();
// Kreisdaten holen per getObject und casten auf PGcircle
PGcircle circle = (PGcircle)rs.getObject(1);
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
611
Postgres und JDBC
// berechnete Kreisflaeche holen per getDouble
double area = rs.getDouble(2);
// center und radius extrahieren
PGpoint center = circle.center;
double radius = circle.radius;
// alle Daten ausgeben
System.out.println("Center (X, Y) = (" +
center.x + ", " + center.y + ")");
System.out.println("Radius = " + radius);
System.out.println("Area = " + area);
}
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
612
7.3 Oracle Spatial und JDBC
→Erweiterung des Oracle-Datenbanksystems
→zentraler, sehr spezieller geometrischer Datentyp
(vgl. Abschnitt 4.5)
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO MDSYS.SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES MDSYS.SDO_ORDINATE_ARRAY);
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
613
Oracle Spatial und JDBC
→Übersicht über die
Komponenten von
Oracle Spatial
aus: [KGB04]
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
614
Oracle Spatial und JDBC
→räumlicher Datentyp kann wie gewohnt für Attribute genutzt
CREATE TABLE Gebäude
(Id CHAR(25), Nutzung CHAR(25),
werden
Grundriss SDO_GEOMETRY, PRIMARY KEY(Id));
→Werte des räumlichen Datentypen werden als
entsprechende Zeichenketten angegeben
INSERT INTO Gebäude VALUES (’G4211’,’Polizei’,
SDO_GEOMETRY(SDO_GTYPE = 1003,
SDO_SRID = NULL, SDO_POINT = NULL,
SDO_ELEM INFO = (1,1003,1),
SDO_ORDINATES = (12125,1333,13430,1560,13260,
2497,14111,2695,14111,2638,16040,3092,15303,6468,
13345,5958,13771,3943,12948,3773,12948,3887,11671,3631)));
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
615
Oracle Spatial und JDBC
→zur Verarbeitung geometrischer Attribute wird
spezielle Java-Klasse “JGeometry” angeboten
→JGeometry bildet den Datentyp SDO_GEOMETRY
als Struktur (STRUCT) ab
→bietet zahlreiche Basismethoden zum Zugriff auf
räumliche Informationen, u.a.
createCircle, createPoint, createLinearPolygon, equals,
getDimensions, getElemInfo, getFirstPoint,
getJavaPoint, getJavaPoints, getLastPoint,
getNumPoints, getOrdinatesArray, getSize, getType,
isCircle, isPoint, isRectangle, load, setType, store,
toString
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
616
Oracle Spatial und JDBC
→Rahmen-Beispiel
// Geometrie von Datenbank lesen
ResultSet rs = statement.executeQuery(
"SELECT geometry FROM states where name = ’Florida’");
STRUCT st = (oracle.sql.STRUCT) rs.getObject(1);
// STRUCT in JGeometry kovertieren
JGeometry j_geom = JGeometry.load(st);
// ... Geometrie handhaben oder neue Geometrie erzeugen ...
// Geometrie zurueck in Datenbank schreiben
PreparedStatement ps = connection.prepareStatement(
"UPDATE states set geometry=? where name=’Florida’");
//JGeometry in STRUCT kovertieren
STRUCT obj = JGeometry.store(j_geom, connection);
ps.setObject(1, obj);
ps.execute();
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
617
Oracle Spatial und JDBC
→Zugriff auf geometrische Attribute über STRUCT
und JGeometry ist ziemlich kompliziert
→einfacher und klarer ist die Benutzung der Klasse
“oracle.sdoapi”
→bietet ähnliche Geometrie-Klassen wie Simple
Features (OGC) bzw.
SQL/MM
Spatial
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
aus: http://www.geodbs.de/
618
Oracle Spatial und JDBC
→Umwandlung zwischen Datenbankrepräsentation
(STRUCT) und passender Geometrieklasse durch
Schnittstelle “GeometryAdapter”
→Methoden “importGeometry” und
“exportGeometry”
→vordefinierte
Adapter in der
Klasse
“OraSpatialManager”
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
aus: http://www.geo.unizh.ch/
619
Oracle Spatial und JDBC
→Einlesen von Geoobjekten mit oracle.sdoapi
(Quelle: http://www.geodbs.de/)
import java.sql.*; // Import der JDBC-Klassen
import oracle.sql.STRUCT; // Import von STRUCT
// Import der Klassen des SDO-API:
import oracle.sdoapi.OraSpatialManager;
import oracle.sdoapi.adapter.GeometryAdapter;
import oracle.sdoapi.geom.*;
public class SdoapiReadExample {
public static void main (String[] args) {
try {
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
620
Oracle Spatial und JDBC
// Verbindung zur Datenbank aufbauen
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@"+DBHOST+":"+
DBPORT+":"+DBNAME;
Connection db = DriverManager.getConnection(
url, DBUSER, DBPASSWORD);
// GeometryAdapter holen
GeometryAdapter adapter =
OraSpatialManager.getGeometryAdapter
("SDO", "8.1.6", STRUCT.class, null, null, db);
if (adapter == null) {
db.close();
throw new ClassNotFoundException("Kein GeometryAdapter!");
}
// Anfrage ausfuehren,
// es wird ein Tupel der Relation "Gemeinden" geholt,
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
621
Oracle Spatial und JDBC
// Definition der Relation:
// CREATE TABLE Gemeinden (
// gkz DECIMAL(8),
-- Gemeindeschluessel
// name VARCHAR(30) NOT NULL, -- Gemeindename
// einw DECIMAL(7) DEFAULT 0, -- Einwohnerzahl
// centrum SDO_GEOMETRY,
-- Zentrumspunkt
// gebiet SDO_GEOMETRY,
-- Gebietspolygon
// CONSTRAINT pk_gem PRIMARY KEY (gkz));
Statement statement = db.createStatement();
String sql = "SELECT * FROM Gemeinden WHERE gkz = 3403000";
ResultSet result = statement.executeQuery(sql);
if (result.next()) {
System.out.print(result.getString("name") + " - ");
Point centrum =
(Point)adapter.importGeometry(result.getObject("centrum"));
System.out.println(centrum.getX() + " / " + centrum.getY());
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
622
Oracle Spatial und JDBC
Polygon pol =
(Polygon)adapter.importGeometry(result.getObject("gebiet"));
CurveString outerRing = pol.getExteriorRing();
System.out.println("#Eckpunkte: " + outerRing.getNumPoints());
}
result.close();
statement.close();
// Verbindung schliessen
db.close();
} // try
// Fehlerbehandlung
catch (Exception ex) {
System.err.println("SdoapiReadExample.main: " + ex);
}
} // main
} // class
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
623
7.4 Verarbeitung von GML-basierten Daten
→GML ist wichtiger XML-basierter
Standard zum Austausch von
Geodaten (vgl. Abschnitt 6.3)
→einlesen, verarbeiten und
ausgeben von GML-Daten kann
typische Sequenz im GISKontext sein
→Beispiel: Platzierung von
Symbolsignaturen in GMLkodierten Gebäude-Polygonen
(vgl. Abschnitt 3.4)
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
624
Verarbeitung von GML-basierten Daten
→Verarbeitung von XML-Dokumenten mit Java
meist per SAX oder DOM
SAX (Simple API for XML)
• ereignisbasierte Programmierschnittstelle
• stellt über Eventhandler
Methoden zum Erkennen
von “Dokument-Ereignissen” bereit
(z.B. startDocument, startElement, characters)
aus: http://www.xml.com/
DOM (Document Object Model)
• objektbasierte Programmierschnittstelle
• stellt Klassen zur Handhabung von Dokumenten bereit
(u.a. Node, NodeList, Element, Text)
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
625
Verarbeitung von GML-basierten Daten
→Benutzung des Document Object Models
bietet sich an bei
wahlfreiem, direkten Zugriff auf Dokument
Transformationen des Dokumentes
Navigation im Dokumentenbaum
genügend Hauptspeicher
aus: http://www.xml.com/
→Verarbeitung in zwei Schritten
parsen des Dokumentes und Aufbau eines
entsprechend strukturierten Objektes
navigieren, bearbeiten, ändern des Objektes
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
626
Verarbeitung von GML-basierten Daten
→Methoden des DOM-API erlauben
Navigation zwischen den einzelnen Knoten eines
Dokuments
erzeugen, verschieben,
löschen von Knoten
auslesen, ändern, löschen
von Textinhalten
→wichtige Methoden zum Navigieren
boolean node.hasChildNodes
gibt an, ob Knoten Kinder besitzt
Node node.getFirstChild
gibt Knoten am Anfang der Kinderliste
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
627
Verarbeitung von GML-basierten Daten
String node.getNodeName
gibt Namen des Knoten
short node.getNodeType
gibt den Typ des Knoten
→wichtige Methoden zum Erweitern von
Dokumenten
node.appendChild(Node newChild)
hängt neue Knoten an
node.removeChild(Node oldChild)
entfernt Knoten
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
628
Verarbeitung von GML-basierten Daten
node.replaceChild(Node newChild, Node oldChild)
ersetzt Knoten
node.insertBefore(Node newChild, Node refChild)
fügt neuen Knoten ein
node.setNodeValue(String nodeValue)
setzt Wert des Knoten
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
629
Verarbeitung von GML-basierten Daten
→typisches System zum Parsen von XML-Dokumenten und zum Aufbau einer DOM-Repräsentation
ist “Xerces”
zum Arbeiten mit Xerces notwendige Pakete
• import org.w3c.dom.*;
• import org.xml.sax.SAXException;
• import org.apache.xerces.parsers.DOMParser;
nächste Schritte sind bilden einer Instanz des DOMParsers, parsen des Dokumentes der Eingabedatei,
erzeugen eines geparsten DOM-Objektes
• DOMParser parser = new DOMParser();
• parser.parse(Name der XML-Quelldatei);
• Document doc = parser.getDocument();
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
630
Verarbeitung von GML-basierten Daten
→als (stark vereinfachtes) Beispiel
im Folgenden ein (stark gekürzter)
Ausschnitt zum Verarbeiten von
GML-basierten Gebäudedaten
ALKIS-Bestandsdatenauszüge liegen
als GML-Daten vor
enthalten typischerweise jeweils ca.
10.000 Objekte (Gebäude,
Flurstücke, Grenzpunkte usw.)
bei Ableitung von Liegenschaftskarte
bei manchen Gebäuden zusätzliche
Platzierung von Symbolsignaturen
nötig Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
631
Verarbeitung von GML-basierten Daten
→zum Platzieren von Signaturen u.a. folgende
Schritte nötig
<gml:featureMember>
<AP_PPO gml:id="DEBWL00100000fAW">
parsen von
<lebenszeitintervall> ... </lebenszeitintervall>
Gebäuden
<anlass>000000</anlass>
<position>
feststellen, dass
<gml:Point>
kein Präsenta<gml:pos>3540847.175 5805897.864</gml:pos>
tionsobjekt zuge- </gml:Point>
</position>
ordnet ist (vgl.
<signaturnummer>3316</signaturnummer>
<dientZurDarstellungVon
Abschnitt 3.4)
xlink:href="urn:adv:oid:DEBWL00100000jwR"/>
berechnen der
<drehwinkel>67.000</drehwinkel>
</AP_PPO>
optimalen
</gml:featureMember>
Position
erzeugen eines neuen Präsentationsobjektes
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
632
Verarbeitung von GML-basierten Daten
→im Folgenden Ausschnitt aus der Methode zum
Parsen von Gebäuden, die bereits in einer DOMStruktur vorliegen
ein Exemplar der Objektklasse “AX_Gebaeude”
<AX_Gebaeude gml:id="DEHHSERV00001FN1">
(vereinfacht)
...
<position>
<gml:Polygon>
<gml:exterior>
<gml:Ring>
...
<gml:pos>3567807.047 5930017.550</gml:pos>
<gml:pos>3567810.850 5930024.755</gml:pos>
...
<gml:pos>3567807.047 5930017.550</gml:pos>
...
</gml:Ring>
</gml:exterior>
</gml:Polygon>
</position>
<gebaeudefunktion>2000 </gebaeudefunktion>
<weitereGebaeudefunktion>
1170
</weitereGebaeudefunktion>
<bauweise>2100</bauweise>
<anzahlDerOberirdischenGeschosse>
1
</anzahlDerOberirdischenGeschosse>
<anzahlDerUnterirdischenGeschosse>
1
</anzahlDerUnterirdischenGeschosse>
<dachform>3100</dachform>
</AX_Gebaeude>
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
633
Verarbeitung von GML-basierten Daten
static public void parseGebaeude()throws
SAXException, IOException, ParserConfigurationException {
// alle Gebaeude in eine Liste;
// ein Bestandsdateauszug liegt schon als Wurzel vor
NodeList GebaeudeListe =
Wurzel.getElementsByTagName("AX_Gebaeude");
// alle Gebaeude einzeln bearbeiten
for(int k=0; k< GebaeudeListe.getLength();k++){
Element Gebaeude = (Element)GebaeudeListe.item(k);
// Gebaudefunktion initialisieren
int gebfkt = 0;
// Weiteregebaudefunktionen initialisieren
// (es kann mehrere geben)
Vector<Integer> wgebfkt = new Vector<Integer>();
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
634
Verarbeitung von GML-basierten Daten
// Gebaeude-Id lesen
String ID = Gebaeude.getAttribute("gml:id");
// Gebaudefunktion lesen
// (kann auch leer sein)
NodeList fnNodeList =
Gebaeude.getElementsByTagName("gebaeudefunktion");
if(fnNodeList.getLength()!=0){
Text fnText = (Text)((Element)fnNodeList.item(0)).getFirstChild();
gebfkt=Integer.parseInt(fnText.getNodeValue());
}
// Weiteregebaudefunktionen lesen
fnNodeList=
Gebaeude.getElementsByTagName("weitereGebaeudefunktion");
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
635
Verarbeitung von GML-basierten Daten
if(fnNodeList.getLength()!=0){
for(int l=0; l<fnNodeList.getLength() ;l++){
Text fnText = (Text)((Element)fnNodeList.item(l)).getFirstChild();
int wgf=Integer.parseInt(fnText.getNodeValue());
wgebfkt.addElement(wgf);
}
}
// weitere Gebaeudeattribute lesen;
// z.B. die Geometriedaten des Positions-Knoten
...
...
...
} // Ende: alle Gebaeude
}
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
636
7.5 Funktionales Programmieren mit Polygonen
→funktionale Programmiersprachen deutlich weniger verbreitet als imperative Programmiersprachen
→Trennung zwischen ausführbarem Programm und
(präziser) Spezifikation einer
Problemlösung bei funktionalen Programmiersprachen
annähernd aufgehoben
→besonders “rekursive Probleme” sehr direkt lösbar
→darunter viele geometrische
Anwendungen
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
637
Funktionales Programmieren mit Polygonen
→funktionale Programmiersprachen
beruhen auf Lambda-Kalkül (Church, 30er Jahre)
Programm ist Menge von Ausdrücken, die Funktionen
definieren
Konstruktion von komplexen Funktionen durch
Kombination von einfacheren
wichtigstes Konstruktionsprinzip ist Rekursion
Berechnung ist Anwendung einer Funktion auf Liste
von Argumenten
hauptsächlich durch Interpreter realisiert
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
638
Funktionales Programmieren mit Polygonen
→Scheme
eine Variante der funktionalen Sprache LISP (List
Processing Language, 60er Jahre)
freie Interpreter Teil vieler Unix-Systeme
KN@is42:273 scheme
MIT/GNU Scheme running under GNU/Linux
Copyright (C) 1986, 1987, 1988, 1989,
1990, 1991, 1992, 1993, 1994,
1995, 1996, 1997, 1998, 1999, 2000,
2001, 2002, 2003, 2004, 2005,
2006, 2007 Massachusetts Institute of Technology
This is free software;
see the source for copying conditions.
aus: http://kinder.wetter.com/
1 ]=> (/ 40030.0 (* 2.0 6371.0))
;Value: 3.141579029979595
1 ]=> (exit)
KN@is42:274
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
639
Funktionales Programmieren mit Polygonen
→Grundelemente sind Präfixausdrücke mit einem Operator
und mehreren Operanden
→spezielle Operatoren für Namensgebung und zur
Definition von Funktionen:
(define pi 3.1415927)
(define quadrat (lambda (x) (* x x)))
(define punkt-abstand (lambda (p1 p2)
(sqrt
(+ (quadrat
(- (x-koord p2) (x-koord p1)))
(quadrat
(- (y-koord p2) (y-koord p1)))))))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
640
Funktionales Programmieren mit Polygonen
→Hauptdatenstruktur sind Paare (und Listen)
(define paar (cons a b))
(define liste (cons a (cons b (cons c...(cons y ())))...)
→ein Punkt wird als Paar von Koordinaten
dargestellt
(define konstr-punkt (lambda (x y) (cons x y)))
(define x-koord (lambda (xy) (car xy)))
(define y-koord (lambda (xy) (cdr xy)))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
641
Funktionales Programmieren mit Polygonen
→ein Polygon wird wird als Liste von Koordinaten
dargestellt
(define quadrat1 (cons 2025 (cons 2925
(cons 2925 ... (cons 2925 ()))...)
Kurzform:
(define quadrat1 ’(2025 2925 2925 2925
2925 3825 2025 3825 2025 2925))
→einfache Operationen
Punkt hinzufügen
(define ad-punkt (lambda (poly punkt)
(if (null? poly)
(list (x-koord punkt) (y-koord punkt))
(cons (car poly)
(ad-punkt (cdr poly) punkt)))))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
642
Funktionales Programmieren mit Polygonen
erster Punkt
(define punkt1 (lambda (poly)
(konstr-punkt (car poly)
(car (cdr poly)))))
um einen Punkt kürzen
(define trunc-poly (lambda (poly)
(cdr (cdr poly))))
zweiter Punkt
(define punkt2 (lambda (poly)
(punkt1 (trunc-poly poly))))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
643
Funktionales Programmieren mit Polygonen
→Umfang von Polygonen
(define umfang (lambda (poly)
(if (not (null? (trunc-poly poly)))
(+ (punkt-abstand (punkt1 poly)
(punkt2 poly))
(umfang (trunc-poly poly)))
0)))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
644
Funktionales Programmieren mit Polygonen
→Tiefpassfilter (vgl. Abschnitt 3.3)
(define tiefpass (lambda (poly)
(define lok-tiefpass (lambda (poly)
(if (not (null? (trunc-poly poly)))
(ad-punkt
(lok-tiefpass (trunc-poly poly))
(mittelpunkt (punkt1 poly)
(punkt2 poly)))
())))
(ad-punkt (lok-tiefpass poly)
(punkt1 (lok-tiefpass poly)))))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
645
Funktionales Programmieren mit Polygonen
→Douglas/Peucker-Algorithmus
1. Gegeben:
Linienzug L und Grenzwert g,
2. bestimme Gerade zwischen
Anfangs- und Endpunkt,
3. bestimme Punkt mit größtem
Abstand zur Geraden,
4. falls Abstand > g
dann Punkt signifikant,
wiederhole Verfahren für beide Teillinienzüge,
sonst entferne alle Punkte zwischen Anfangs- und
Endpunkt.
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
646
Funktionales Programmieren mit Polygonen
(define douglas-peucker (lambda (poly g)
(if (> (anzahl-punkte poly) 2)
(sequence
(define map (max-abstand-punkt poly))
(if (> (gerade-punkt-abstand
(punkt1 poly)
(letzter-punkt poly)
map)
g)
(concat-poly
(douglas-peucker (teil1 poly map) g)
(douglas-peucker (teil2 poly map) g))
(ad-punkt
(ad-punkt () (punkt1 poly))
(letzter-punkt poly))))
poly)))
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
647
7.6 Zusammenfassung
→Kopplung von SQL mit Programmiersprachen
Embedded SQL
SQLJ
Call-Schnittstelle
JDBC
→Postgres und JDBC
Klasse “PGobject”
Unterklassen “PGpoint”, “PGbox” etc.
→Oracle Spatial und JDBC
Klasse “JGeometry”
Paket “oracle.sdoapi”
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
648
Zusammenfassung
→Verarbeitung von
GML-basierten
Daten
SAX (Simple API for
XML)
DOM (Document
Object Model)
Navigation im
Dokument-Baum
Beispiel: GMLbasierte
Gebäudedaten
→Funktionales Programmieren mit Polygonen
Scheme
Polygon als Liste von
Koordinaten
Umfang von Polygonen
Tiefpassfilter
Douglas/PeuckerAlgorithmus
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
649
Zusammenfassung
erfassen
GIS
präsentieren
verwalten
analysieren
SQL +
höhere Programmiersprache
SQLJ
Objekte
GML
JDBC
Thematik
Geometrie
Vektor
funktionales
Programmie
ren
Spatial Databases und GISe, Kap.7 / K.N., S.T. / SomSem 2009
Embedded
SQL
650
Herunterladen