Geodatenanwendungen
Transcription
Geodatenanwendungen
Geodatenanwendungen Sommersemester 2012 Prof. Dr. Hans-Peter Wiedling Vorgänger ancestor Eltern parent Geschwister sibling Kinder, child Nachfolger descendant Lernziele • • • Die Studierenden erlernen an Praxisbeispielen die Grundlagen zur Entwicklung von Geodatenanwendungen und entsprechender Infrastruktur – Zum Einsatz kommen • XHTML, CSS, JavaScript/DOM, AJAX, HTTP und Google MAPS API • Android für die mobile Komponente • PHP und XSLT Angestrebte Kompetenzen: Die Studierenden verstehen die spezifischen Probleme bei der Planung, Entwicklung und Qualitätssicherung von Geodatenanwendungen und können sicher mit Geodaten umgehen Die Teilnehmer – verstehen das Zusammenspiel der verschiedenen Techniken – lernen die wesentlichen Standards kennen – können komplexe und interaktive Geodatenanwendungen erstellen – erlernen Grundlagen, um sich in weitere Geodatenanwendungen einzuarbeiten Geodatenanwendungen, Seite 2 Prof. Dr.-Ing. Hans-Peter Wiedling Lehrinhalte • Prozesskette Akquisition, Weitergabe, Aufbereitung, Visualisierung und Verknüpfung von Geodaten • Typische Algorithmen auf geografischen Datenstrukturen • Grundlagen in der Programmierung mit der Google MAPS API • Entwicklung einer mobilen Geodatenanwendung unter Android • Strukturtransformation mit XSLT und XPath Geodatenanwendungen, Seite 3 Prof. Dr.-Ing. Hans-Peter Wiedling Bibliographie • http://code.google.com/intl/deDE/apis/maps/documentation/mapsdata/developers_guide_java.html • http://www.android.com • http://www.w3.org/TR/xslt20/ • Arno Becker, Marcus Pant: Android Grundlagen und Programmierung. dpunkt-verlag. 1. Auflage, 2009. ISBN 978-3-89864-574-4 • Frederik Ramm, Jochen Topf: OpenStreetMap Die freie Weltkarte nutzen und mitgestalten. lehmanns media. 1, Auflage 2009. ISBN 978-3-86541320-8 • Reto Meier: Professional Android Application Development. Wiley, 2008, ISBN 978-0-470-34471-2 Geodatenanwendungen, Seite 4 Prof. Dr.-Ing. Hans-Peter Wiedling Motivation Anwendungen, Geodateninfrastruktur Anwendungen • • • • • • • • • Bodenmanagement (Kataster) ... Flottenmanagement ... Routenplanung ... Tourismus, Freizeit ... Social networking ... Entertainment, Gaming, ... Wetterinformation ... Precision Farming ... Verkehrsinformationen (Flugzeug, Schiff, Auto) ... • Neben Kommunikation ist Mobilität ein hohes menschliches Grundbedürfnis mit all seinen wirtschaftlichen und sozialen Aspekten! Geodatenanwendungen, Seite 6 Prof. Dr.-Ing. Hans-Peter Wiedling Umfeldsuche Communites Spiele … Google Open Street Map Radtouren Hessen Deutschlandviewer Precision Farming ... Wetterinformationen ..u. v. m. Geodatenanwendungen, Seite 7 Prof. Dr.-Ing. Hans-Peter Wiedling GDI: Geodateninfrastruktur • „Das ist Ziel, Nutzer von Geodaten und -informationen und deren raumbezogene Anwendungen von Daten in eine vernetzte Geodateninfrastruktur einzubinden“ (aus dem Vortrag von Dr. Schweitzer, Hessisches Landesamt für Bodenmanagement: Geodateninfrastruktur Hessen – Mehrwert für den Nutzer; 11. u. 12. Oktober 2005): Leitprojekte mit Kommunen und Anwendern • Landesbehörden entwickeln gemeinsam mit Wirtschaft und Kommunen Dienste und stellen diese zur Verfügung, die insbesondere einen digitalen prozess-orientierten Datenfluss für Geschäftsprozesse ermöglichen. • Nutzen einer Geodateninfrastruktur aufzeigen • http://www.geodatenzentrum.de/dienste/dop_viewer Geodatenanwendungen, Seite 8 Prof. Dr.-Ing. Hans-Peter Wiedling Die Ziele dieser Leitprojekte • „GDI in die Fläche bringen“ – – – – – – Standards und Komponenten der GDI-Hessen in die breite Nutzung bringen Kommunen und Private einbinden Nutzer steht dabei im Mittelpunkt Wiederverwendbare Komponenten erzeugen Synergieeffekte nutzen durch standardisierte Webservices als Teil einer GDI einmal entwickeln und mehrfach nutzen Geodatenanwendungen, Seite 9 Prof. Dr.-Ing. Hans-Peter Wiedling Geodatenanwendungen, Seite 10 Prof. Dr.-Ing. Hans-Peter Wiedling Webservices • Durch die Nutzung standardisierter Schnittstellen können heterogene Datenquellen, also auch proprietäre Geodatenformate, interoperabel bereitgestellt werden, ohne diese Datenquellen selbst in ein anderes Format überführen und redundant halten zu müssen. • Anwendungen können die angebotenen Geodatendienste direkt ansprechen und verschafft dem Anbieter die nötige Investitionssicherheit, da die Bereitstellung auf aktuellem Stand der Technik ermöglicht wird. Geodatenanwendungen, Seite 11 Prof. Dr.-Ing. Hans-Peter Wiedling GDI als serviceorientierte Architektur (SOA) Das Architekturkonzept der GDI-DE spiegelt sich aus technischer Sicht in dem Publish-Find-Bind-Muster der serviceorientierte Architektur (SOA) wider: Der Anbieter (Provider) von Geodaten/-diensten veröffentlicht diese durch Registrierung in einem Katalog bzw. Verzeichnis (publish). 2. So werden diese für den Anwender (Consumer) recherchierbar: Der Anwender durchsucht den Katalog nach Geodaten/-diensten. Der Katalog liefert ein Suchergebnis zurück (find). 3. Der Anwender (Consumer) kann die gefundenen Geodaten/-dienste ansprechen und gemäß Nutzungsbedingungen verwenden (bind). 1. Geodatenanwendungen, Seite 12 Prof. Dr.-Ing. Hans-Peter Wiedling Architektur GDI-DE Quelle: Architektur der Geodateninfrastruktur Deutschland Version 2.0 (beta) Geodatenanwendungen, Seite 13 Prof. Dr.-Ing. Hans-Peter Wiedling Prozesskette Akquisition, Anreichern Idee, Planung, Bestandsaufnahme Sammeln, Verwalten, Verknüpfen, Archivieren Verknüpfen Kontrollierte Weitergabe Anzeigen, Nutzen, Recherche Geodatenanwendungen, Seite 14 Prof. Dr.-Ing. Hans-Peter Wiedling Datenstrukturen und Math. Berechnungen Satellitendaten/Orthophotos Punkt-, Linien- und Flächeninformation Distanz, Inside, Remove und Simplify Digitale Orthophotos • • Orthophotos sind eine realitätstreue Darstellung der Erdoberfläche. Sie entstehen durch eine differenzielle Entzerrung der Original-Luftbilder. Die Digitalen Orthophotos werden im Blattschnitt der Deutschen Grundkarte (2 x 2 km) nach bundeseinheitlichen Standards erstellt. Die Genauigkeit beträgt ± 1m. Die digitalen (Farb-) Orthophotos liegen für Hessen flächendeckend mit einer Bodenauflösung von 0,4 m (DOP40) vor. Für Teilgebiete sind auch Color-Infrarotbilder verfügbar. Quelle: http://www.hvbg.hessen.de/internethkvv/broker.jsp?uMen=cf970661-e6e5-8201-44b946194b80f348 Geodatenanwendungen, Seite 16 Prof. Dr.-Ing. Hans-Peter Wiedling Ressource Bild: Ein Blick hinter die Kulissen Geodatenanwendungen, Seite 17 Prof. Dr.-Ing. Hans-Peter Wiedling Das Bild besteht aus Kacheln 0 .. tx .. maxtilex - 1 0 .. ty .. maxtiley - 1 Geodatenanwendungen, Seite 18 Prof. Dr.-Ing. Hans-Peter Wiedling Karten als Web-Service • Mit jedem Zoom und Pan werden die Kacheln alle einzeln per Request geladen • Kacheln werden auch schon über die sichtbare Kartenansicht hinaus, herunter, erst in einem Bereich, in dem keine Kacheln existieren, ist es nötig neue Kacheln nachzuladen. • Die Anzahl der Kacheln steigt dabei exponentiell. Dabei findet die Bildpyramide Anwendung und die Kacheln werden dabei nach der hierarchischen Quadtree-Struktur unterteilt (Parameter beim Request, Bsp: http://kh3.google.de/kh?n=404&v=20&t=trtqtrtqssrtqtrqtqrr Geodatenanwendungen, Seite 19 Prof. Dr.-Ing. Hans-Peter Wiedling Punkt-, Weg- und Flächeninformation <node>, <way> und closed way (aus OSM) • Ein Knoten (node) besteht zumindest aus Positionsinformation (Längenund Breitengrad), üblicherweise einem Zeitstempel und gegebenenfalls aus einer Höheninformation: <node id="25496583" lat="51.5173639" lon="-0.140043" version="1" changeset="203496" user="80n" uid="1238" visible="true" timestamp="2007-01-28T11:40:26Z"> <tag k="highway" v="traffic_signals"/> </node> • Knoten können mehrere Wege oder Gebieten zugeordnet sein • Ein Weg (way) besteht aus mindestens 2 und höchstens 2000 Knoten • Knoten können mehreren Wegen zugeordnet sein – – http://www.topografix.com/GPX/1/1/ http://wiki.openstreetmap.org/wiki/Data_Primitives#XML_example Geodatenanwendungen, Seite 20 Prof. Dr.-Ing. Hans-Peter Wiedling <way> • Wege sind Punktfolgen, die neben den Punkten (hier nd) zusätzliche Informationen (Name, Klassifikation, ...) enthalten: <way id="5090250" visible="true" timestamp="2009-01-19T19:07:25Z" version="8" changeset="816806" user="Blumpsy" uid="64226"> <nd ref="822403"/> <nd ref="21533912"/> <nd ref="821601"/> <nd ref="21533910"/> <nd ref="135791608"/> <nd ref="333725784"/> <nd ref="333725781"/> <nd ref="333725774"/> <nd ref="333725776"/> <nd ref="823771"/> <tag k="highway" v="unclassified"/> <tag k="name" v="Clipstone Street"/> <tag k="oneway" v="yes"/> </way> • Flächen (Seen, Gebäude, ...) sind beschrieben als geschlossene Punktfolgen Geodatenanwendungen, Seite 21 Prof. Dr.-Ing. Hans-Peter Wiedling Geopunkt class GpsData { public String public double public double public double ...// weitere time; lat;// Latitude/Breitengrad lon;// Longitude/Längengrad elevation; // Altitude/Höhenangabe Merkmale, z.B. Genauigkeit public GpsData ( double lat, double lon, double elevation, String time) { this.time = time; this.lat = lat; this.lon = lon; this.elevation = elevation; } } // GpsData Geodatenanwendungen, Seite 22 Prof. Dr.-Ing. Hans-Peter Wiedling Ein bisschen Mathematik ... • R = Q + t * v, mit v = P – Q Gerade: t∈ℜ Strahl: Kante: t >= 0 0 <= t <= 1 Skizze R Q P v • Die Angaben haben immer einen Bezugspunkt (Ursprung), auch wenn die Achsen oder der Ursprung nicht angegeben sind. Geodatenanwendungen, Seite 23 Prof. Dr.-Ing. Hans-Peter Wiedling POI in nächster Nachbarschaften (Nearest Neighbour), Abstandabschätzungen • In planaren Abbildungen werden die folgenden Abstandsformeln zwischen zwei Punkten verwendet: • Euklidscher Abstand: d2(neighbour) = ( this.x - neighbour.x )2 + ( this.y - neighbour.y )2 neighbour ist ein weiteres (benachbartes) Objekt; • Häufig findet man auch folgende Abstandsformeln: – Maximum-Distanz: • d(neighbour,obj)= max (neighbouri-obji) oder – Manhatten- bzw. Taxi-Distanz • d(neighbour,obj)= Σ neighbouri-obji • Da es sich um Abstände auf der Erdoberfläche und somit einer Sphere handelt, kann der Euklidsche Abstand aufgrund sich kumulierender Ungenauigkeiten nicht angewendet werden. Geodatenanwendungen, Seite 24 Prof. Dr.-Ing. Hans-Peter Wiedling Distanz Punkt-Kante (I) L(t) = P0 + t * v und v = P1 - P0 Skalarprodukt verwenden: P2 P1 (P2-L(t)) * v = 0 (P2 – P – t * v) * v = 0 (P2 - P ) * v = t * v * v t = ((P2 - P0) * v) / (v * v) P’2 v P0 (nicht kürzen; v ist ein Vektor!) t in (I) einsetzen liefert benötigten Punkt auf der Kanten, dann kann die Distanz dist berechnet werden: dist = | P2 – P0 + ((P2 - P0) * v) / (v * v) * v | Alternative Berechnung: Information über die Fläche nutzen ... Geodatenanwendungen, Seite 25 Prof. Dr.-Ing. Hans-Peter Wiedling Distanzberechnung über die Fläche |P0P1 x P1P2| |P2P2‘| = | (P0P1) | | P1P2 x P2P0 | liefert die Größe der aufgespannten Fläche; wenn man nun die Fläche des Parallelogramms durch die Länge der einen Seite teilt, erhält man die Länge der anderen Seite – genau das suchen wir! Bemerkung: im 2D entspricht |P0P1 x P1P2| der Determinanten. Die Determinante kann wie folgt berechnet werden: – im 2D: det a b c d =a*d–b*c Prinzip: Geodatenanwendungen, Seite 26 Prof. Dr.-Ing. Hans-Peter Wiedling Quelle: „Geoinformatik in Theorie und Praxis“ von Norbert de Lange Geodatenanwendungen, Seite 27 Prof. Dr.-Ing. Hans-Peter Wiedling Distanz • Distanzberechnungen finden also auf einer Kugeloberfläche (Großkreis) statt. • Die Kugeloberfläche ist nur eine Annährung an die tatsächliche Oberfläche der Erde! Geodatenanwendungen, Seite 28 Prof. Dr.-Ing. Hans-Peter Wiedling Abstand auf der Kugeloberfläche (Großkreis) public static double distance(GpsData p1, GpsData p2) { double d; double R = 6371; // Erdradius in km d = Math.acos(Math.sin(Math.toRadians(p1.lat)) * Math.sin(Math.toRadians(p2.lat)) + Math.cos(Math.toRadians(p1.lat)) * Math.cos(Math.toRadians(p2.lat)) * Math.cos(Math.toRadians(p2.lon - p1.lon))); return d * R; } // distance Quelle: http://www.movable-type.co.uk/scripts/latlong.html Bem.: Angaben müssen im Bogenmaß erfolgen (radian = grad * π / 180) Geodatenanwendungen, Seite 29 Prof. Dr.-Ing. Hans-Peter Wiedling Distanz zwischen 2 Punkten (Links) • • Formelsammlung (als Einstieg): http://williams.best.vwh.net/avform.htm#Dist Distanzformel (Großkreis) d zwischen zwei Punkten mit den Koordinaten {lat1,lon1} und {lat2,lon2} lautet: d = acos(sin(lat1)*sin(lat2)+cos(lat1)*cos(lat2)*cos(lon1-lon2)) Für kurze Distanzen eignet sich auf die folgende Formel (weniger Rundungsfehler): d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 + cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2)) d mit radius multiplizieren! • Wenn man es ganz genau machen möchte: http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf • Evtl. auch noch interessant sind die Projektionen: http://mathworld.wolfram.com/StereographicProjection.html http://www.moenk.de/index.php?serendipity[subpage]=downloadmanager&thiscat=4&file=17 • Geodatenanwendungen, Seite 30 Prof. Dr.-Ing. Hans-Peter Wiedling Konvexe und konkave Flächen Konkav Konvex • Bedingung/Test: Man nehme bel. Punkte, die innerhalb der Fläche (oder auf deren Rand) liegen, und verbinde sie zu einer Linie, dann müssen auch alle Punkte, die auf dieser Linie liegen, innerhalb der Fläche liegen Bedingung erfüllt: Fläche konvex Bedingung nicht erfüllt: Fläche konkav • obwohl die Bedingung mathematisch nicht zu beanstanden ist, können wir praktisch nicht mit ihr arbeiten Alternativen: – jeder Innenwinkel ist ≤ 180° – Schnittpunktberechnung zwischen bel. Kanten darf keine Lösung besitzen Geodatenanwendungen, Seite 31 Prof. Dr.-Ing. Hans-Peter Wiedling Inside Test • Anzahl Schnittpunkte zwischen Strahl und Kanten ist ungerade, dann liegt der Punkt innerhalb 1 2 4 3 1 • Vorab kann ein Test mit der Bounding Box erfolgen und somit der Berechnungsaufwand reduziert werden: xmin <= x <= xmax && ymin <= y <= ymax 2 Geodatenanwendungen, Seite 32 Prof. Dr.-Ing. Hans-Peter Wiedling Konvexe Hülle • umschließt alle Punkte einer Menge • Für jede Kante gilt alle Punkte liegen in einer Halbebene • Diese Kanten können mit Hilfe der Determinanten berechnet werden: – Die Vorzeichen müssen für alle Punkte gleich sein, dann handelt es sich um eine Kante Geodatenanwendungen, Seite 33 Prof. Dr.-Ing. Hans-Peter Wiedling Simplyfication/Ausdünnen/Bereinigen • Geopunkte am Anfang oder am Ende einer Aufzeichnung können streuen. • Das Ziel ist dann, diese Punkte durch wenige zu ersetzen: Dazu können z. B. die Koordinaten des Schwerpunkts der entsprechenden Punkt oder immer wiederholt von drei Punkt gebildet werden. Der Schwerpunkt ist das arithmetische Mittel der Koordinaten der Punkte: • Punktfolgen für Wege werden geglättet und letztendlich mit weniger Punkten beschrieben: dazu wird aus der Punktfolge P0 .. Pn-1, der Punkt gesucht, der am weitesten von P0Pn-1 entfernt ist Geodatenanwendungen, Seite 34 Prof. Dr.-Ing. Hans-Peter Wiedling Glätten: Douglas-Peucker-Algorithmus P0 Pn-1 Pd • Das Verfahren sucht zunächst in der Punktfolge, den Punkt Pd, der von PoPn-1 am weitesten entfernt ist. • Falls Pd weiter als ein vorgegebenes Maß entfernt ist, wird das Verfahren für die Teilpunktfolgen wiederholt. http://de.wikipedia.org/wiki/Douglas-Peucker-Algorithmus Geodatenanwendungen, Seite 35 Prof. Dr.-Ing. Hans-Peter Wiedling Viewing mit Google Maps API AJAX, DOM, Google Maps API, POI, Routen : Asynchronous JavaScript and XML • AJAX steht für zwei mächtige Browsertechniken welche bereits seit Jahren existieren, jedoch zunächst von Webentwicklern wenig beachtet wurden. Diese Techniken gewinnen an Beachtung, seit Services wie Google Maps, Google Mail oder Google Suggest diese verwenden. • Mit diesen Techniken können – Requests an den Server abgesetzt werden, ohne die Seite neu laden zu müssen und – XML-Dokumente geparst und bearbeitet werden • Seiten im Netz http://developer.mozilla.org/de/docs/AJAX:Getting_Started http://de.wikipedia.org/wiki/XMLHttpRequest Geodatenanwendungen, Seite 37 Prof. Dr.-Ing. Hans-Peter Wiedling AJAX: eine neue Technologie? • AJAX wird häufig als neue Technologie dargestellt, mit der sich den Web-Entwicklern ganz neue Möglichkeiten eröffnen: Bereits 1999 wurde diese Technologie unter dem Namen XMLHTTPRequest von Microsoft eingeführt. • Der Begriff AJAX geht auf einen im Februar 2005 veröffentlichten Artikel Ajax: A New Approach to Web Applications von Jesse James Garrett von der Firma Adaptive Path zurück. Die XMLHTTPRequest genannte Technologie wird unter dem Namen AJAX vorgestellt und bekannt. • AJAX als Synonym für eine Technologie zur Schaffung Web 2.0 Oberflächen. Geodatenanwendungen, Seite 38 Prof. Dr.-Ing. Hans-Peter Wiedling Prinzipskizze Geodatenanwendungen, Seite 39 Prof. Dr.-Ing. Hans-Peter Wiedling 1. Schritt: Request-Objekt erzeugen var http_request = null; function initRequest() // http_request Objekt anlegen { try { // Mozilla, Opera, Safari sowie Internet Explorer (ab v7) http_request = new XMLHttpRequest(); } // try catch(e) { var avers = ["Microsoft.XmlHttp", "MSXML2.XmlHttp", "MSXML2.XmlHttp.3.0", "MSXML2.XmlHttp.4.0", "MSXML2.XmlHttp.5.0"]; for (var i = avers.length -1; i >= 0; i--) { try {http_request = new ActiveXObject(avers[i]); break; } catch(e1) {} }//for }// catch e if (http_request != null) { if (http_request.overrideMimeType) http_request.overrideMimeType('text/xml'); } else alert('XMLHTTP-Instanz kann nicht erzeugt werden!'); } // initRequest Geodatenanwendungen, Seite 40 Prof. Dr.-Ing. Hans-Peter Wiedling 2. Schritt: Anfrage an den Server senden ... // Funktion, die ausgeführt wird nach Antwort des Servers http_request.onreadystatechange = neuerInhalt; // 1. Parameter: HTTP-Methode GET oder POST // 2. Parameter: abgefragte URL ( es kann kein anderer Server // als der ursprüngliche abgefragt werden!) // 3. Parameter: true (asynchron)/ false (synchron) http_request.open('GET', url, true); // enthält anwendungsspez. Daten für Server (Suchanfrage) http_request.send(null); ... Bem.: bei der Methode POST sollte der MIME-Typ angepasst werden: http_request.setRequestHeader ('Content-Type', 'application/x-www-formurlencoded'); Geodatenanwendungen, Seite 41 Prof. Dr.-Ing. Hans-Peter Wiedling 3. Schritt: Die Antwort des Servers auswerten ... function neuerInhalt() { // Callback if (http_request.readyState == 4) { // Prüfung des Requests if (http_request.status == 200) { // Prüfung der Antwort alert(http_request.responseText); var xmldoc = http_request.responseXML; (*) } } else { alert('Beim Request ist ein Problem aufgetreten.'); } } Bem.: • http_request.responseText liefert Antwort als Textstring • http_request.responseXML gibt die Antwort des Servers als ein XMLDocument-Objekt; unter dem IE gab es Probleme mit der Auswertung; siehe Folgeseite • Hier (*) können JavaScript DOM-Funktionen können genutzt werden Geodatenanwendungen, Seite 42 Prof. Dr.-Ing. Hans-Peter Wiedling Umgang mit ResponseXML im IE if (window.ActiveXObject) { var toAppend = document.createElement('xml'); //responseText in innerHTML einfügen toAppend.setAttribute('innerHTML',http_request.responseText); // mit einem eindeutigen ID kennzeichnen toAppend.setAttribute('id', 'aUniqueID'); // gesamten Zweig irgendwo einhängen document.body.appendChild(toAppend); // XML Zweig anhand der ID suchen und als xmldoc ansprechbar machen xmldoc = document.getElementById('_MakeAUniqueID'); // Tag wieder entfernen document.body.removeChild(document.getElementById('aUniqueID')); } ... Xmldoc verwenden ... Es gibt nach wie vor Browserunterschiede! Geodatenanwendungen, Seite 43 Prof. Dr.-Ing. Hans-Peter Wiedling 4. Schritt: Antwort als XML-Objekt verarbeiten ... var xmldoc = http_request.responseXML; var root_node = xmldoc.getElementsByTagName('root').item(0); alert(root_node.firstChild.nodeValue); ... Der gesamte Prozess wird durch ein Benutzerereignis ausgelöst: <a href="javascript:macheRequest('tour.gpx')">Route anzeigen</a> Geodatenanwendungen, Seite 44 Prof. Dr.-Ing. Hans-Peter Wiedling Methoden des XMLHTTPRequest-Objekts (I) • • • • abort() – Stoppt die gegenwärtige Server-Anfrage getAllResponseHeaders() – Gibt die vom Server gesendeten Header als String zurück. getResponseHeader("headerLabel") – Gibt den benannten Header als String zurück. open("method", "URL"[, asyncFlag[, "userName"[, "password"]]]) – Öffent eine Verbindung zum Server. Parameter:method: GET | POST | PUT | HEAD POST solte verwendet werden, wenn die gesendeten Daten größer als 500 bytes sind. HEAD wird verwendet, wenn nur Response-Header und keine Daten angefordert werden. Dieses kann z.B. verwendet werden, wenn für eine Datei auf dem Server das Datum der letzen Änderung (Last-Modified) abgefragt werden soll. URL: Pfad (relative oder absolut) + ggf. Querystring asyncFlag: true | false Asynchrone (true) oder synchrone (false) DatenübertragunguserName: password: Benutzername und Passwort für eine Ressource auf dem Server Geodatenanwendungen, Seite 45 Prof. Dr.-Ing. Hans-Peter Wiedling Methoden des XMLHTTPRequest-Objekts (II) • send(content) – Sendet die Daten an den Server.Parameter:content: null bei GET oder ein Query-String bei POST • setRequestHeader("label", "value") – Hierüber können Header gesetzt werden, z.B. der Content-Type. • setMimeType("mimetype") – setzen des Mimetyps der angeforderten Daten (Response). Wird vom Internet Explorer nicht unterstützt. Parameter: mimetype der MimeType als String (z.B. "text/xml") Geodatenanwendungen, Seite 46 Prof. Dr.-Ing. Hans-Peter Wiedling Eigenschaften des XMLHTTPRequest-Objekts • onreadystatechange – Event-Handler der jedesmal aufgerufen wird, wenn sich der Verbindungsstatus (readyState) ändert • readyState – Enthält den aktuellen Verbindungsstatus. Mögliche Werte: 0 = Verbindung noch nicht geöffnet ('open()' noch nicht aufgerufen) 1 = Noch keine Anfrage gesendet ('send()' noch nicht aufgerufen) 2 = Anfrage gesendet, Antwort-Header und Antwort-Status kann abgefragt werden. 3 = Daten vom Server kommen nach und nach an. 'responseText' enthält die bislang vom Server gesendeten Daten. 4 = Kommunikation mit dem Server ist abgeschlossen. Alle Daten sind angekommen (status = 200), wenn kein Fehler aufgetreten ist. Geodatenanwendungen, Seite 47 Prof. Dr.-Ing. Hans-Peter Wiedling Eigenschaften des XMLHTTPRequest-Objekts • responseText – Enthält die vom Server gesendeten Daten als Text • responseXML – Enthält die vom Server gesendeten Daten als XML-Daten. Wenn die Daten als Plaintext gesendet worden sind, enthält responseXML null. • status – Enthält den HTTP-Status der Verbindung als Zahl (z.B. 200 für Erfolg oder 0 bei Erfolg bei Dateizugriff oder 404, wenn die angeforderte Ressource nicht existiert) • statusText – Enthält den HTTP-Status als Text-Meldung (z.B. "Not found") Geodatenanwendungen, Seite 48 Prof. Dr.-Ing. Hans-Peter Wiedling Kommunikation mit AJAX • Die Kommunikation mit dem Server über AJAX ist einfach umzusetzen • Die Schwierigkeit liegt eher in Browserspezfika; bestimmte Methoden und Verhaltensweisen sind von den Browsern unterschiedlich implementiert • Achten Sie auf die Trennung von Layout und Inhalt; das erleichtert die Entwicklungs- und Wartungsarbeit • Die Interaktion mit der Seite durch Benutzerin/Benutzer stellt nicht selten relativ hohe Anforderungen an die Synchronisation der Ereignisse • (Umfangreiche) Tests sind unvermeidlich: „Code a litte – Test a little“ Geodatenanwendungen, Seite 49 Prof. Dr.-Ing. Hans-Peter Wiedling Ein Beispiel mit AJAX und DOM • Von einem Server (z.B. www.tourismus.de) können entweder Sehenswürdigkeiten (poi.gpx) oder Touren (tour.gpx) abgerufen werden • Die Ergebnisse werden in HTML eingefügt Anfrage wird konfiguriert via AJAX und DOM werden die Tabellen befüllt Geodatenanwendungen, Seite 50 Prof. Dr.-Ing. Hans-Peter Wiedling HTML Code (1/2): Formular <style> tr.title {background-color:#00bb00} </style> <body onload="initRequest()"> <h1>Besuchen Sie das Jugendstilzentrum Darmstadt</br> <img src="darmstadt.jpg" width="40%"></h1> <form> <table> <tr> <td>Sehenswürdigkeit: </td> <td> <INPUT TYPE="Text" NAME="query" id="query" value="poi" SIZE="10" MAXLENGTH="20"></td> <td></td></tr> <tr><td>Art: </td> <td><input type="checkbox" name="art[]" id="bauwerk" value="Bauwerk"> Bauwerk<br> <input type="checkbox" name="art[]" id="kirche" value="Kirche"> Kirche<br> <input type="checkbox" name="art[]" id="museum" value="Museum"> Museum</td><td></td> </tr> <tr> <td>Entfernung: </td> <td> <INPUT TYPE="Text" NAME="dist" id="dist" value="km" SIZE="6" MAXLENGTH="20"></td> <td> <INPUT TYPE="button" NAME="senden" VALUE="Auswahl" onclick="javascript:request('antwort.php')"></td> </tr></table></form> Geodatenanwendungen, Seite 51 Prof. Dr.-Ing. Hans-Peter Wiedling HTML Code (2/2): Ergebnisbereich(e) <div id="poi" style="visibility:visible"> <p>Point of Interest:</p> <table border="1" id="wp" width="170"> <tbody> <tr class="title"> <th>Nr</th><th>lat</th><th>lon</th><th>POI</th></tr> </tbody> </table> </div> <div id="tour" style="visibility:visible"> <p>Tour:</p> <table border="1" id="route" width="290"> <tbody id="route"> <tr class="title"><th>Nr</th><th>lat</th><th>lon</th></tr> </tbody> </table> </div> </body> </html> Geodatenanwendungen, Seite 52 Prof. Dr.-Ing. Hans-Peter Wiedling Request erzeugen function request(url) { initRequest(); waypoints = true; // CallbackFunktion, weil Aufruf asynchron http_request.onreadystatechange = showWaypoints; query = document.getElementById ('query'); sstr = "select=" + query.value; dist = document.getElementById ('dist'); dstr = "+dist=" + dist.value; bstr = ""; bauwerk = document.getElementById ('bauwerk'); if ( bauwerk.checked) bstr = "+art[]=bauwerk"; kstr = ""; kirche = document.getElementById ('kirche'); if ( kirche.checked) kstr = "+art[]=kirche"; mstr = ""; museum = document.getElementById ('museum'); if ( museum.checked) mstr = "+art[]=museum"; url = url + "?" + sstr + dstr + bstr + kstr + mstr; http_request.open('GET', url, true); http_request.send(null); } function initRequest() // http_request Objekt anlegen { http_request = new XMLHttpRequest(); ... } Geodatenanwendungen, Seite 53 Prof. Dr.-Ing. Hans-Peter Wiedling Waypoints anzeigen function showWaypoints (xmldoc) { var wpt = xmldoc.getElementsByTagName('wpt'); var tabelle = document.getElementById('wp'); for (i = 0; i < wpt.length; i++) { row = document.createElement ("tr"); nrnode = document.createElement ("td"); nrnode.appendChild ( document.createTextNode(i) ); row.appendChild (nrnode); latnode = document.createElement ("td"); lat = wpt[i].getAttribute('lat'); latnode.appendChild ( document.createTextNode(lat) ); row.appendChild (latnode); lonnode = document.createElement ("td"); lon = wpt[i].getAttribute('lon'); lonnode.appendChild ( document.createTextNode(lon) ); row.appendChild (lonnode); } } Geodatenanwendungen, Seite 54 Prof. Dr.-Ing. Hans-Peter Wiedling Geocode • Google bietet über deren Google Maps API den so genannten Geocoder an. Geocoding bezeichnet die Ermittlung einer Position anhand einer Adresse. Als Adresse akzeptiert der Dienst Angaben vom Land bis hin zu einer Straßenangabe. Je genauer die Adresse ange-geben wird, desto genauer kann die Antwort, also die Position, sein. Die Adressangabe liegt als Text vor und wird an Googles Server gesendet, welcher mit den enthaltenen Informatio-nen versucht eine passende Position zu ermitteln und diese als Ergebnis zurückzuliefern. • Findet der Google Service ein oder mehrere passende Positionen, sendet er diese per default als JSON-Objekt (JavaScript Object Notation). JSON ermöglicht einen einfachen Da-tenaustausch und den Zugriff auf enthaltene Daten mit JavaScript. Alternativ kann auch ein XML-Format angefordert werden. Bei mehreren Ergebnissen, muss die Anwendung ent-scheiden, wie sie damit umgehen möchte. Eine Möglichkeit kann sein, dem Nutzer eine Auswahl aller Ergebnisse anzubieten. Geodatenanwendungen, Seite 55 Prof. Dr.-Ing. Hans-Peter Wiedling Geocode • Wenn Google kein Ergebnis ermitteln kann, kann dies anhand eines, in der Antwort mit gesendeten, Status erkannt werden. Das unten stehende Code-Beispiel zeigt den Aufruf und die Auswertung einer Geocoder Anfrage. • Hierbei wird zuerst ein Objekt des Geocoders der Google API erstellt. Von dem Objekt wird die geocode-Methode mit zwei Parametern aufgerufen. Parameter eins ist die Adresse, für die die Position gesucht wird. Der zweite Parameter ist eine JavaScript-Funktion, welche das Ergebnis verarbeitet. Diese Funktion erhält das besagte JSON- oder XML-Objekt und den Status der Anfrage. Wurde mindestens ein Ergebnis gefunden (Status OK), kann das JSON- bzw.XML-Objekt ausgewertet werden. Im Beispiel werden die enthaltenen Informationen nur für das erste Ergebnis ausgelesen und in Variablen gespeichert. Geodatenanwendungen, Seite 56 Prof. Dr.-Ing. Hans-Peter Wiedling Geocode var geocoder = new google.maps.Geocoder(); var address = "Darmstadt, Germany"; geocoder.geocode({'address':address}, function(result, status) { if ( status == google.maps.GeocoderStatus.OK) { var lat = result[0].geometry.location.lat(); var lon = result[0].geometry.location.lng(); } else { alert("Geocoder Fehler: "+status); } }); Geodatenanwendungen, Seite 57 Prof. Dr.-Ing. Hans-Peter Wiedling Geolocation • Auch auf Geolocation wurde oben bereits im Rahmen von HTML5 kurz eingegangen. Im Gegensatz zu einer Adressangabe ermöglicht die W3C HTML5-Spezifikation den Einsatz der Geolocation-API. Der Entwickler muss sich nicht darum kümmern, woher die Informationen kommen. Als Quelle dienen GPS, Funkzelle und IP-Adresse. Da ein Browser nicht alle Informationen zur Bestimmung des Aufenthaltsort besitzt, setzt dieser auf externe Dienstleister. • Diese Dienstleister können anhand einer Funkzelle, WLAN oder IP eine ungefähre Position nennen. Gerade bei IP-Adressen, kann die Position nicht genau der eigenen entsprechen, da dynamisch-vergebene IPs eines Internet-Service-Providers keinen Bezug auf eine konkrete Position haben. Geodatenanwendungen, Seite 58 Prof. Dr.-Ing. Hans-Peter Wiedling Geolocation • Benutzer müssen der Datenübermittlung an einen Dienstleister zustimmen. Dadurch wird sichergestellt, dass Webseiten nicht einfach eine Position autonom ermitteln können. • Die Nutzung, mit Hilfe von JavaScript, zeigt das folgende Codebeispiel: – Vor der Nutzung wird geprüft ob der Browser die Geolocation-API unterstützt. – Ist das der Fall, wird über die Methode getCurrentPosition ( callSuccess, callError ); versucht, eine Position zu ermitteln. Bei erfolgreicher Ermittlung wird eine Callback-Methode aufgerufen, in welcher die Positionsdaten ausgewertet werden. Diese Daten liegen jetzt im Dezimalformat (z. B. latitude = 49.867 / longitude = 8.64) vor. – Diese Position kann daraufhin z. B. auf einer Karte zur Informationsdarstellung genutzt werden. Geodatenanwendungen, Seite 59 Prof. Dr.-Ing. Hans-Peter Wiedling Geolocation if ( navigator.geolocation ) { navigator.geolocation.getCurrentPosition ( callSuccess, callError ); } else { //Browser unterstützt Geolocation nicht } function callSuccess(position) { var lat = position.coords.latitude; var lon = position.coords.longitude; } function callError(position) { //Position konnte nicht ermittelt werden. } Geodatenanwendungen, Seite 60 Prof. Dr.-Ing. Hans-Peter Wiedling Geolocation • Ein weiterer optionaler Parameter der Methode, ist maximumAge. Dieser Parameter spezifiziert das maximale Alter der angeforderten gespeicherten Position. • Sind nur ältere Positionen im Zwischenspeicher, wird nach einer neueren gesucht. Geodatenanwendungen, Seite 61 Prof. Dr.-Ing. Hans-Peter Wiedling DHTML: HTML + CSS + JS • DHTML Sichtbarkeit von div-Tags verändern: <div id="tour" style="visibility:visible"> <p>Tour:</p> <table border="1" id="route" width="290"> <tr class="title"><th>Nr</th><th>lat</th><th>lon</th></tr> </table> </div> tour = document.getElementById ('tour'); tour.style.visibility = "hidden"; • • • Weitere Elemente sind die Reihenfolge (z-index), Position, clip-rect. Cross Origin Request Scripts http://ajaxpatterns.org/XMLHttpRequest_Call#The_XMLHttpRequest_API:_A_Summ ary Geodatenanwendungen, Seite 62 Prof. Dr.-Ing. Hans-Peter Wiedling Same Origin Policy • bedeutet, Skriptsprache im Browser erlaubt nur den Zugriff auf den „eigenen“ Server • Ist wichtiges Sicherheitskonzept für Client-/Browserseitige Skriptsprachen • Beispiele sind – Das Zurücksenden von Cookies nur an den ursprünglichen Server – Die Verbindung einer HTTP-Request aus JavaScript zu dem Server, von dem auch das JavaScript bezogen wurde • Dennoch besteht das Interesse, unterschiedliche Server anzufragen – Namensdienste (von Google oder OpenStreetMap) sind Beispiele dafür • Ein Ansatz ist, über einen Proxy die Anfrage zu gewährleisten • JSON (JavaScript Object Notation) ist eine weitere Möglichkeit • Eine andere Möglichkeit ist, den Zugriff über HTTP doch kontrolliert zu erlauben Geodatenanwendungen, Seite 63 Prof. Dr.-Ing. Hans-Peter Wiedling Anfrage über einen Proxy Server • XMLHttpRequest (XHR) an einen fremdem Server ist nicht erlaubt: XHR Client Skript Response XHR nicht erlaubt! • Eigener Server arbeitet als proxy und erfüllt die Anfrage Client Skript XHR Request Response Response Geodatenanwendungen, Seite 64 Prof. Dr.-Ing. Hans-Peter Wiedling Access-Control-Allow-Origin • Mit einem GET oder POST HTTP Request wird ein HTTP Header gesendet: • Der Origin Header enthält Information über den ursprünglichen Server von dem das Script stammt: das Protokoll, die Domäne und den Port • Der Server kann damit entscheiden, ob die Anfrage beantwortet wird oder nicht; Beispiel: – Origin: http://www.MyServer.com • Wenn der Server die Anfrage erlaubt, dann sendet er einen entsprechenden Header zurück: – Access-Control-Allow-Origin: http://www.MyServer.com oder ‘*‘ • Fehlt der Header oder er stimmt nicht überein, dann wird der Request vom Skript im Browser nicht ausgeführt; im anderen Fall wird der Request ausgeführt. Weder der Request noch der Response enthalten Cookie Informationen! Geodatenanwendungen, Seite 65 Prof. Dr.-Ing. Hans-Peter Wiedling Cross Origin Resource Sharing (CORS) Anfrage generiert ... ... HTTP Request Server Response Merkmal wird von HTTP Request Objekt ausgewertet Aus Sicherheitsgründen ist der Zugriff nur auf die ursprüngliche Domäne erlaubt: same origin-policy Ein Ansatz für diese Mashups: Server übernimmt die Anfragen (cross domain proxy) Die Google API und Nominatim senden das Merkmal Geodatenanwendungen, *Seite 66 Access-Control-Allow-Origin: Prof. Dr.-Ing. Hans-Peter Wiedling Cross-Origin Resource Sharing • XDomainRequest wird zunehmend von den Browsern unterstützt: function createCORSRequest(method, url) { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) // dann ist es FireFox, Safari, Chrome { xhr.open(method, url, true); } else if (typeof XDomainRequest != "undefined") // dann ist es IE 8 { xhr = new XDomainRequest(); xhr.open(method, url); } else { xhr = null; } return xhr; } var request = createCORSRequest("get", "http://www.yourServer.com/"); if (request) { request.onload = function(){ //do something with request.responseText }; request.send(); } Geodatenanwendungen, Seite 67 Prof. Dr.-Ing. Hans-Peter Wiedling Zugriff auf Dokumentstruktur via DOM • Die Dokumentstruktur kann aus JavaScript heraus mit den folgenden Methoden manipuliert werden • Das document-Objekt bietet die Methoden – getElementById() direkter Zugriff über die ID des Elements – getElementsByTagName() liefert Array mit Objekten des entsprechenden Tags an, um auf Elemente zuzugreifen. • Ein Element kann auch über das Array childNodes angesprochen werden. Dabei wird das i-te Kind eines Knotens x mit x.childNodes[i] referenziert. Die Eigenschaft firstChild und lastChild repräsentieren das erste und letzte Kind. Das "Durchhangeln" durch den DOM-Baum mit diesem Array ist sehr umständlich. Eine Kombination mit den Methode getElementById() wird daher oft verwendet. Den Inhalt eines Knotens liefert die Eigenschaft "nodeValue". Geodatenanwendungen, Seite 68 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel • So kann auf den Text "Test" im Beispiel innerhalb von JavaScript etwa durch var x1 = document.getElementById("wp"); var y1 = x1.childNodes[1].childNodes[0]; alert(y1.nodeValue); zugegriffen werden. • Eine Veränderung wird im o. a. Beispiel dann durch folgende Zuweisung realisiert: y1.nodeValue = "Point of Interest"; Geodatenanwendungen, Seite 69 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel: DOM Geodatenanwendungen, Seite 70 Prof. Dr.-Ing. Hans-Peter Wiedling HTML: Knoten, Attribute und Inhalt <html><head> <title>Synchrone Ansichten auf Geodaten</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css">…</style> </head> <body id= "body" onload = "initialize()"> <div id="map_canvas" class="mymap" ></div> <table id= "wp" border="1" width="170"> <tbody id="route"> <tr class="title"> <th>POI</th><th>Latitude</th><th>Longitude</th><th>Typ</th></tr> </tbody> <tr id="poi" style="background-color:#bbbbbb"> <td> Luigi</td><td>…</td><td>…</td><td>Pub</td></tr> <tr style="background-color:#bbbbbb"> <td>Kavaliershaus</td><td>…</td><td>…</td><td>Castle</td></tr> </table></body></html> Geodatenanwendungen, Seite 71 Prof. Dr.-Ing. Hans-Peter Wiedling HTML als Baumstruktur Geodatenanwendungen, Seite 72 Prof. Dr.-Ing. Hans-Peter Wiedling Content ändern <script language="JavaScript"> var x1 = document.getElementById("poi"); var y1 = x1.childNodes[1].childNodes[0]; alert("Vorher: "+y1.nodeValue); y1.nodeValue = "Nico"; alert("Nachher: "+y1.nodeValue); </script> Geodatenanwendungen, Seite 73 Prof. Dr.-Ing. Hans-Peter Wiedling Knoten einfügen (1/2) • Im letzten Beispiel wurde die Struktur des DOM-Baumes nicht verändert. Das nächste Beispiel zeigt wie durch die Methoden createTextNode(content), createElement(tag) und appendChild(node) Elemente hinzugefügt werden können: var wpt = xmldoc.getElementsByTagName('wpt'); // z.B. Dokument via AJAX var tabelle = document.getElementById('wp'); for (i = 0; i < wpt.length; i++) { row = document.createElement ("tr"); nrnode = document.createElement ("td"); nrnode.appendChild ( document.createTextNode(i) ); row.appendChild (nrnode); ... Geodatenanwendungen, Seite 74 Prof. Dr.-Ing. Hans-Peter Wiedling Knoten einfügen (2/2) <script language="JavaScript"> var x2 = document.getElementById("body"); var y2 = document.createTextNode("Essen und Trinken"); x2.appendChild(y2); var x3 = document.getElementById ("body"); var y3 = document.createElement ("h1"); var z3 = document.createTextNode ("meine Favoriten"); if (confirm("anhaengen?")) { y3.appendChild(z3); x3.appendChild(y3); } </script> • Knoten werden in den DOM-Baum wird mit der Methode "appendChild()" eingefügt. Geodatenanwendungen, Seite 75 Prof. Dr.-Ing. Hans-Peter Wiedling Knoten löschen (1/2) <script> var x5 = document.getElementById("map_canvas"); var y5 = document.getElementById("body"); /* body */ if (confirm("löschen?")) {y5.removeChild(x5);} </script> • Knoten werden aus dem DOM-Baum wird mit der Methode "removeChild()" gelöscht. Geodatenanwendungen, Seite 76 Prof. Dr.-Ing. Hans-Peter Wiedling Knoten löschen (2/2) • Das Entfernen von Knoten aus dem DOM-Baum wird mit der Methode "removeChild(node)" veranlasst. • Im Beispiel werden alle Kindknoten ab dem Knoten mit dem id „wp" gelöscht und es können erneut Waypoints eingefügt werden: anz = tabelle.childNodes.length; for (i = 0; i < anz-2; i++) tabelle.removeChild (tabelle.childNodes[2]); • Warum werden im Beispiel die Kindknoten an der Position 0 und 1 nicht gelöscht? Geodatenanwendungen, Seite 77 Prof. Dr.-Ing. Hans-Peter Wiedling Attribute ändern und einfügen <script language="JavaScript"> var x4 = document.getElementById("body"); var y4 = document.createElement("img"); y4.setAttribute("src", "http://www.mein-server.de/bild.gif"); if (confirm("anhaengen?")) { x4.appendChild(y4);} </script> • Attribute eines Knotens können mit der Methode "setAttribute(name)" gesetzt oder mit „getAttribute(name, value)" erfragt werden. <script language="JavaScript"> marke = document.getElementById('strecke'); marke.setAttribute ("style", "color:red"); </script> Geodatenanwendungen, Seite 78 Prof. Dr.-Ing. Hans-Peter Wiedling Weitere Eigenschaften und Methoden • attributes liefert die Attribute zum aktuellen Knoten • parentNode liefert den Vorgängerknoten • previousSibling liefert Vorgängerknoten auf gleicher Ebene (jüngerer Geschwisterknoten) nextSibling liefert Nachfolgerknoten auf gleicher Ebene (älterer Geschwisterknoten) • • • • appendChild() fügt einen Teilbaums an einen Knoten (am Ende des Arrays childNodes) ein insertBefore() zum Einfügen eines Knotens (innerhalb des Arrays childNodes) cloneNode() zum Kopieren von Knoten (und Teilbäumen, wenn der 1. Parameter zu true auswertbar ist). Eine Liste aller Methoden und Eigenschaften sind unter www.w3.org zu finden Geodatenanwendungen, Seite 79 Prof. Dr.-Ing. Hans-Peter Wiedling Google Maps JavaScript API V3 Karte, Ausschnitt, Markierungen, Routen, Flächen, Overlays, Interaktion (Listener u. Events) http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/tutorial.html Geodatenanwendungen, Seite 80 Prof. Dr.-Ing. Hans-Peter Wiedling HTML-Rahmen <html> <head> <title>Hello Map</title> Google MAPS API <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript" src="GEOmapAPI.js"></script> <style type="text/css"> div.mymap { width:600; height:300;} Darstellungsbereich </style> für die Karte </head> <body onload="initialize()"> <div id="map_canvas" class = “mymap"></div> </body> </html> Geodatenanwendungen, Seite 81 Prof. Dr.-Ing. Hans-Peter Wiedling Karte und Ausschnitt festlegen var geocoder; var geopoint; Zoomstufe, Mittelpunkt, var map; function initialize() { Kartenart: // Define the two corners of the bounding box HYBRID | ROADMAP | var sw = new google.maps.LatLng(59.0, 13.12); SATELLIT | TERRAIN var ne = new google.maps.LatLng(60.35, 16.90); // Create a bounding box var bounds = new google.maps.LatLngBounds(sw, ne); var latlng = new google.maps.LatLng( 49.895943, 8.804555); var myOptions = { zoom: 12, center: bounds.getCenter(), //latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); // Karte zentrieren map.setCenter(latlng); // oder bounds.getCenter(); geocoder = new google.maps.Geocoder(); // Geocoder erzeugen codeAddress(); // Geocoding anwenden drawMarker(); drawArea(); drawRoute (); // Markierung setzen etc. Geodatenanwendungen, Seite 82 }// initialize Prof. Dr.-Ing. Hans-Peter Wiedling Markierungen // Markierung zeichnen function drawMarker () { var latlng = new google.maps.LatLng( 49.895943, 8.804555); var markerOptions = new Object(); Instanziierung (nicht zwingend) // Literale Syntax markerOptions = {//map: map, Einfache position: latlng, Markierung mit title:"Jogging"}; Position und Titel var marker = new google.maps.Marker(markerOptions); marker.setMap(map); } Geodatenanwendungen, Seite 83 Prof. Dr.-Ing. Hans-Peter Wiedling Routen // Route zeichnen function drawRoute () { var red = '#ff0000'; var lightblue = '#000099'; var thickness = 3; var points = [geopoint, new google.maps.LatLng(49.895943, 8.804555), new google.maps.LatLng(49.895171, 8.802967), new google.maps.LatLng(49.895139, 8.802924)]; var polyline = new google.maps.Polyline({ Namenloses path: points, PolylineOption strokeColor: red, s Objekt strokeOpacity: 1.0, strokeWeight: thickness }); Wegpunkte, Farbe, polyline.setMap(map); Transparenz und Linienbreite } Geodatenanwendungen, Seite 84 Prof. Dr.-Ing. Hans-Peter Wiedling Flächen // Fläche zeichnen function drawArea () { var blue = '#0000ff'; var lightblue = '#000099'; var thickness = 3; var area = [new google.maps.LatLng(49.895843, 8.803555), new google.maps.LatLng(49.895271, 8.805967), new google.maps.LatLng(49.895189, 8.802024)]; var polygon = new google.maps.Polygon({ paths: area, fillColor: lightblue, fillOpacity: 1.0, Eckpunkte, Farbe strokeColor: blue, und Transparenz in strokeOpacity: 1.0, der Fläche, Farbe, strokeWeight: thickness Transparenz und }); polygon.setMap(map); Breite der } Begrenzungslinie Geodatenanwendungen, Seite 85 Prof. Dr.-Ing. Hans-Peter Wiedling Geocode (1/2) • Google bietet über deren Google Maps API den so genannten Geocoder an. Geocoding bezeichnet die Ermittlung einer Position anhand einer Adresse. Als Adresse akzeptiert der Dienst Angaben vom Land bis hin zu einer Straßenangabe. Je genauer die Adresse ange-geben wird, desto genauer kann die Antwort, also die Position, sein. Die Adressangabe liegt als Text vor und wird an Googles Server gesendet, welcher mit den enthaltenen Informatio-nen versucht eine passende Position zu ermitteln und diese als Ergebnis zurückzuliefern. • Findet der Google Service ein oder mehrere passende Positionen, sendet er diese per default als JSON-Objekt (JavaScript Object Notation). JSON ermöglicht einen einfachen Da-tenaustausch und den Zugriff auf enthaltene Daten mit JavaScript. Alternativ kann auch ein XML-Format angefordert werden. Bei mehreren Ergebnissen, muss die Anwendung ent-scheiden, wie sie damit umgehen möchte. Eine Möglichkeit kann sein, dem Nutzer eine Auswahl aller Ergebnisse anzubieten. Geodatenanwendungen, Seite 86 Prof. Dr.-Ing. Hans-Peter Wiedling Geocode (2/2) • Wenn Google kein Ergebnis ermitteln kann, kann dies anhand eines, in der Antwort mit gesendeten, Status erkannt werden. Das unten stehende Code-Beispiel zeigt den Aufruf und die Auswertung einer Geocoder Anfrage. • Hierbei wird zuerst ein Objekt des Geocoders der Google API erstellt. Von dem Objekt wird die geocode-Methode mit zwei Parametern aufgerufen. Parameter eins ist die Adresse, für die die Position gesucht wird. Der zweite Parameter ist eine JavaScript-Funktion, welche das Ergebnis verarbeitet. Diese Funktion erhält das besagte JSON- oder XML-Objekt und den Status der Anfrage. Wurde mindestens ein Ergebnis gefunden (Status OK), kann das JSON- bzw.XML-Objekt ausgewertet werden. Im Beispiel werden die enthaltenen Informationen nur für das erste Ergebnis ausgelesen und in Variablen gespeichert. Geodatenanwendungen, Seite 87 Prof. Dr.-Ing. Hans-Peter Wiedling Geocoder function codeAddress() { var address = document.getElementById("address").value; Geocode if (geocoder) { geocoder.geocode( { 'address': address}, function (results, status) { if (status == google.maps.GeocoderStatus.OK) { //map.setCenter(results[0].geometry.location); geopoint = results[0].geometry.location; var image = 'poi.png'; var marker = new google.maps.Marker({ Marker mit map: map, Image und position: geopoint, //results[0].geometry.location title:"Dieburg", InfoWindow icon: image } ); var info = new google.maps.InfoWindow ( { content: "<img width='40‚ src='winterwald.jpg'/><br\>Winterspaziergang"}); //info.open (map, marker); google.maps.event.addListener(marker, 'click', function() { info.open(map, marker); }); } else {alert("Geocode nicht erfolgreich: "+status); } }); } // if geocoder }// codeAddress Geodatenanwendungen, Seite 88 Prof. Dr.-Ing. Hans-Peter Wiedling Interaktion mit der Map // Listener für click-Ereignis google.maps.event.addListener(map, 'click', addAMarker); ... function addAMarker(event) { var marker = new google.maps.Marker({ position: event.latLng, title: '#' + path.getLength(), map: map }); } Geodatenanwendungen, Seite 89 Prof. Dr.-Ing. Hans-Peter Wiedling Overlays • • Overlays sind Objekte auf der Karte, die an Breitengrad/Längengrad-Koordinaten gebunden sind, sodass sie sich beim Ziehen und beim Vergrößern oder Verkleinern der Karte mitbewegen. Overlays spiegeln Objekte wider, die Sie zur Karte hinzufügen, um Punkte, Linien, Bereiche oder Objektsammlungen zu kennzeichnen. – – – marker.setMap(map); // zuordnen bzw. setzen marker.setMap(null); // von der Karte entfernen // von der Karte entfernen und Marker löschen marker.setMap(null); marker = null – var markersArray = []; markersArray.push (marker); // neuen Marker hinzufügen – // Marker mit best. Merkmal suchen: if (markersArray) { for (i in markersArray) { if (markersArray[i].getTitle() == “h_da“); alert (“Marker gefunden!“); } } – Weitere Aktionen können den Marker ein- bzw. ausschalten Geodatenanwendungen, Seite 90 Prof. Dr.-Ing. Hans-Peter Wiedling Anwendungsspez. Objekterweiterungen • Objekte (Marker, Polyline, Polygon, ...) können in JavaScript im Sinne der Anwendung einfach erweitert werden: var marker = new google.maps.Marker({ map: map, position: aGeopoint, title: "h_da", icon: image, // eigenes Merkmale, z.B. Tag zu markieren myId: 1000 } ); ... alert ("Id: "+ marker.myId); // spez. Auswertung des Merkmals Geodatenanwendungen, Seite 91 Prof. Dr.-Ing. Hans-Peter Wiedling Smartphones Resource, Activity, Google Maps API unter Android Service, Intent und SAXParser, Warum Android? • Open Source, von Google entwickelt mit Apache v2 Lizenz • Für Programmierer mit Java Kenntnissen bietet sich einfacher und schneller Einstieg; das motiviert und liefert bei entsprechender Lernkurve attraktive Resultate • Betriebssystem und kompletter Software Stack für mobile Geräte – Betriebssystem / Treiber – Libraries und Basisdienste – Applikationsmodell / Framework – Anwendungsprogramme – Entwicklungstools • auf vielen Geräten verschiedener Hersteller lauffähig Geodatenanwendungen, Seite 93 Prof. Dr.-Ing. Hans-Peter Wiedling Warum Android? • Offen • Java • umfangreiche Bibliotheken und Frameworks • marktrelevant • http://www.canalys.com/pr/2011/r2011013.html Geodatenanwendungen, Seite 94 Prof. Dr.-Ing. Hans-Peter Wiedling http://www.canalys.com/pr/2011/r2011013.html 18.4.2011 Geodatenanwendungen, Seite 95 Prof. Dr.-Ing. Hans-Peter Wiedling Entwicklung unter Android • Mit entsprechendem plug-in (fast) reguläre Java-Entwicklung mit eclipse • Internetzugang, GPS, graph. Display, GUI, Touchscreen, ... • Spezifika, d.h. wie der Code zu organisieren ist, ergeben sich aufgrund der Plattform und dann auch durch die Bibliothek (android API: http://developer.android.com) – Permissions – Activity – Resource für Layout und Formatierung des GUI sowie für Strings und Konstanten (z. B. Realisierung von Mehrsprachigkeit) – Intent und Service – XML-Parser Geodatenanwendungen, Seite 96 Prof. Dr.-Ing. Hans-Peter Wiedling Ein erstes Beispiel: SMS senden • Das App soll die Möglichkeit bieten, eine SMS zu erstellen und zu versenden • Klasse zum SMS versenden • Überlegung zur GUI (zunächst als Skizze): Label •Komponenten, Layout Sende eine SMS an einen Freund Textfeld Nr: Text: •Eventhandling (Texteingabe, Anklicken) •Mehrsprachigkeit Button Versenden •Beschreibung in Ressourcen Geodatenanwendungen, Seite 97 Prof. Dr.-Ing. Hans-Peter Wiedling Ein erstes Beispiel: SMS senden • Klasse zum SMS versenden: SmsManager Resource mit Layout und Componenten ... und Konstanten Text Layout Label public class mySMSMaker extends Activity Button Manifest Code: Activity Eventhandling Intents ... onClick... <manifest ... <permission> ... Emulation Geodatenanwendungen, Seite 98 Prof. Dr.-Ing. Hans-Peter Wiedling Resource main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <TextView android:layout_width="fill_parent„ android:layout_height="wrap_content" android:text="Empfängernr. " /> <EditText android:id="@+id/txtPhoneNo" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Message" /> <EditText android:id="@+id/txtMessage" android:layout_width="fill_parent" android:layout_height="150px" android:gravity="top" /> <Button android:id="@+id/btnSendSMS" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Send SMS" /> </LinearLayout> Geodatenanwendungen, Seite 99 Prof. Dr.-Ing. Hans-Peter Wiedling AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mySMS.Maker" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".mySMSMaker" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> Permission </intent-filter> ergänzen! </activity> </application> <uses-permission android:name="android.permission.SEND_SMS"> </uses-permission> <uses-permission android:name="android.permission.RECEIVE_SMS"> </uses-permission> </manifest> Geodatenanwendungen, Seite 100 Prof. Dr.-Ing. Hans-Peter Wiedling strings.xml <?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, mySMSMaker!</string> <string name="app_name">SMSMaker</string> <string name="hint">Nummer und Nachricht eingeben</string> </resources> Zugriff über R.string.hint Geodatenanwendungen, Seite 101 Prof. Dr.-Ing. Hans-Peter Wiedling Activity: mySMSMaker (1/3) package mySMS.Maker; import import import import import import import import import android.app.Activity; android.app.PendingIntent; android.content.Intent; android.os.Bundle; android.telephony.gsm.SmsManager; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Toast; public class mySMSMaker extends Activity { Button btnSendSMS; EditText txtPhoneNo; EditText txtMessage; Geodatenanwendungen, Seite 102 Prof. Dr.-Ing. Hans-Peter Wiedling Layouts, Views, ... <Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/> Button myButton = (Button) findViewById(R.id.my_button); Siehe auch • http://developer.android.com/guide/topics /ui/layout-objects.html • http://developer.android.com/resources/t utorials/views/hello-formstuff.html Geodatenanwendungen, Seite 103 Prof. Dr.-Ing. Hans-Peter Wiedling Activity: mySMSMaker (2/3) /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnSendSMS = (Button) findViewById(R.id.btnSendSMS); txtPhoneNo = (EditText) findViewById(R.id.txtPhoneNo); txtPhoneNo.setText("***"); txtMessage = (EditText) findViewById(R.id.txtMessage); btnSendSMS.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { String phoneNo = txtPhoneNo.getText().toString(); String message = txtMessage.getText().toString(); if (phoneNo.length() > 0 && message.length() > 0) sendSMS(phoneNo, message); else Toast.makeText(getBaseContext(), R.string.hint, Toast.LENGTH_SHORT).show(); } }); }// onCreate Fehlerhinweis: Objekt für kurze Zeit anzeigen Geodatenanwendungen, Seite 104 Prof. Dr.-Ing. Hans-Peter Wiedling Activity: mySMSMaker (3/3) private void sendSMS(String phoneNumber, String message) { PendingIntent pi = PendingIntent.getActivity (this, 0, new Intent(this, mySMSMaker.class), 0); SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage(phoneNumber, null, message, pi, null); } } // mySMSMaker Empfänger reciepent Intent Absende r Nachricht sent Intent Geodatenanwendungen, Seite 105 Prof. Dr.-Ing. Hans-Peter Wiedling Activity public class MyLogger extends Activity { private EditText geoData; private GpsData gd; /** Called when the activity is first created. */ Activity public void onCreate(Bundle savedInstanceState) { übernimmt das super.onCreate(savedInstanceState); Eventhandling setContentView(R.layout.main); geoData = (EditText) this.findViewById(R.id.EditText01); geoData.setText("Test my Service"); }// onCreate public void onStop() { super.onStop(); } public void onStart() { super.onStart(); } } // MyLogger Geodatenanwendungen, Seite 106 Prof. Dr.-Ing. Hans-Peter Wiedling Activity • • • • muss im manifest definiert werden stellt view dar interagiert mit dem Benutzer Hat Zustände: – active: Activity ist sichtbar, hat den Focus und alle Ressorucen stehen bereit – paused: Activity ist nicht ganz verdeckt, sie hat aber nicht den Focus, z.B. durch einen Dialog – stopped: wenn sie verdeckt ist, kommt die Activity in den Zustand – inactive: der Übergang erfolgt durch Android • Wenn die Anwendung aus mehreren Views besteht, dann muss – mit setContentView entsprechend umgeschaltet werden oder – die verschiedenen Views in weiteren Activities behandelt werden • Darf nicht blockiert werden: nach 5 sec gibt es eine Meldung! Geodatenanwendungen, Seite 107 Prof. Dr.-Ing. Hans-Peter Wiedling Zustanddiagramm Geodatenanwendungen, Seite 108 Prof. Dr.-Ing. Hans-Peter Wiedling Reaktion auf Zustandsänderungen • Bedarfsweise können in der Activity folgende Methoden überschrieben werden: – void onCreate(Bundle bundle) // unbedingt erforderlich – void onStart() – void onRestart() – void onResume() – void onPause() – void onStop() – void onDestroy() Geodatenanwendungen, Seite 109 Prof. Dr.-Ing. Hans-Peter Wiedling Tipps zum Debuggen • Die Klasse android.util.Log stellt Klassenmethoden für das Logging • bereit: – Fehler: Log.e(String tag, String message ) – Warnungen: Log.w(String tag, String message ) – Informationen: Log.i(String tag, String message ) – Debugging: Log.d(String tag, String message ) – Verbose (ausführliche Erläuterung): Log.v(String tag, String message ) • Alle Methoden haben ein Tag (etwa als Typkennzeichnung) für die Quelle der Meldung und die Nachricht selbst • Anzeige mit – LogCat View in eclipse oder – durch Aufruf des Programms logcat auf der Emulation Geodatenanwendungen, Seite 110 Prof. Dr.-Ing. Hans-Peter Wiedling Resource, Layout, View, Events <Button android:layout_column="2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/send" android:text="go" android:textSize="@dimen/textSize“ android:padding="3dip" android:minWidth="35px" android:layout_gravity= "center_vertical|center_horizontal"> </Button> Objekt und Resource verknüpfen go = (Button) this.findViewById(R.id.send); go.setOnClickListener(perform); ... OnClickListener perform = new OnClickListener() { public void onClick(View arg0) Geodatenanwendungen, Seite 111 { selectTour(); } Prof. Dr.-Ing. Hans-Peter Wiedling }; Layouts - LinearLayout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="red" android:gravity="center_horizontal" android:background="#aa0000" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_weight="1"/> ... <LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"> <TextView android:text="row one" android:textSize="15pt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/> public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } Geodatenanwendungen, Seite 112 Prof. Dr.-Ing. Hans-Peter Wiedling Layouts - TableLayout <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="1"> <TableRow> <TextView android:text="@string/table_layout_4_open" android:padding="3dip" /> <TextView android:text="@string/table_layout_4_open_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> <TableRow> <TextView android:text="@string/table_layout_4_save" android:padding="3dip" /> <TextView android:text="@string/table_layout_4_save_shortcut" android:gravity="right" android:padding="3dip" /> </TableRow> </TableLayout> public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } Geodatenanwendungen, Seite 113 Prof. Dr.-Ing. Hans-Peter Wiedling Layouts - RelativeLayout <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@drawable/blue" android:padding="10px" > <TextView android:id="@+id/label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Type here:" /> <EditText android:id="@+id/entry" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="@android:drawable/editbox_background" android:layout_below="@id/label" /> <Button android:id="@+id/ok" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/entry" android:layout_alignParentRight="true" public void onCreate(Bundle savedInstanceState) { android:layout_marginLeft="10px" super.onCreate(savedInstanceState); android:text="OK" /> setContentView(R.layout.main); <Button android:layout_width="wrap_content" } android:layout_height="wrap_content" android:layout_toLeftOf="@id/ok" android:layout_alignTop="@id/ok" Geodatenanwendungen, Seite 114 android:text="Cancel" /> Prof. Dr.-Ing. Hans-Peter Wiedling </RelativeLayout> UI Componenten: Spinner // Spinner configure spinner = (Spinner) this.findViewById(R.id.Spinner01); ArrayAdapter<Buddy> adapter = 1-aus-n Auswahl new ArrayAdapter<Buddy>(this, adapter ist das android.R.layout.simple_spinner_dropdown_item); Container/ModelObjekt ArrayList<String> buddies = {“Peter“, “Stefan“, “Karin“, “Birgit“}; for (String b : buddies) adapter.add(b); adapter .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinner.setAdapter(adapter); selectListener = new OnItemSelectedListener() { public void onItemSelected(AdapterView parent, View v, int position, long id) { gotoSelected();} Eigene Adapter von public void onNothingSelected(AdapterView arg0) {} BaseAdapter ableiten }; • Object getItem(int position) spinner.setOnItemSelectedListener(selectListener); • View getView(int position, View convertView,Seite ViewGroup Geodatenanwendungen, 115 parent) Prof. Dr.-Ing. Hans-Peter Wiedling Componenten Menu Spinner ProgressDialog Toast modaler Dialog Geodatenanwendungen, Seite 116 Prof. Dr.-Ing. Hans-Peter Wiedling Menu (1/2) <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/terrain_server" android:title="Terrain Server" /> <item android:id="@+id/community_server" android:title="Community Server" /> <item android:id="@+id/tour_server" <item android:id="@+id/edit" android:title="Environment Server" /> android:title="Edit" /> </menu> Geodatenanwendungen, Seite 117 Prof. Dr.-Ing. Hans-Peter Wiedling Menu (2/2) /* Creates the menu items */ public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.options_menu, menu); return true; } /* Handles item selections */ public boolean onOptionsItemSelected(MenuItem item) { Toast info; switch (item.getItemId()) { case R.id.community_server: info = Toast.makeText(this, community, Toast.LENGTH_LONG); info.show(); return true; case R.id.terrain_server: info = Toast.makeText(this, terrain, Toast.LENGTH_LONG); info.show(); return true; case R.id.tour_server: info = Toast.makeText(this, environment, Toast.LENGTH_LONG); info.show(); return true; case R.id.edit: StringDialog dialog = new StringDialog(this, community, environment, terrain, new OnReadyListener()); dialog.show(); return true; }// switch return false; Geodatenanwendungen, Seite 118 }// onOptionsItemSelected Prof. Dr.-Ing. Hans-Peter Wiedling Statt Menu ActionBar und ActionItem Geodatenanwendungen, Seite 119 Prof. Dr.-Ing. Hans-Peter Wiedling (modaler) Dialog (1/2) Aufruf: StringDialog dialog = new StringDialog(this, comment, new OnReadyListener()); dialog.show(); ... private class OnReadyListener implements StringDialog.ReadyListener { public void ready(String comment) { GeoLogger.this.comment = comment; } } public class StringDialog extends Dialog { Konstruktion, da java keine Funktionszeiger für Callbacks kennt // darüber wird Callback realisiert: public interface ReadyListener { public void ready(String comment); } private EditText commentText; String comment; private ReadyListener readyListener; public StringDialog(Context context, String comment, ReadyListener readyListener) { super(context); this.comment = comment; this.readyListener = readyListener; // callback-Objekt } Geodatenanwendungen, Seite 120 Prof. Dr.-Ing. Hans-Peter Wiedling (modaler) Dialog (2/2) ... public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.comment); setTitle("Some Comment on POI"); commentText = (EditText) findViewById(R.id.comment); commentText.setText(this.comment); Button buttonOK = (Button) findViewById(R.id.send); buttonOK.setOnClickListener(new OKListener()); Button buttonCancel = (Button) findViewById(R.id.cancel); buttonCancel.setOnClickListener(new CancelListener()); }// onCreate private class OKListener implements android.view.View.OnClickListener { public void onClick(View v) { Hier erfolgt der comment = commentText.getText().toString(); Callback und der readyListener.ready(comment); // Callback StringDialog.this.dismiss(); // entfernt Dialog Dialog wird beendet } }// OKListener private class CancelListener implements android.view.View.OnClickListener { public void onClick(View v) { commentText.setText(""); comment = commentText.getText().toString(); readyListener.ready(comment); // Callback StringDialog.this.dismiss(); // entfernt Dialog } Geodatenanwendungen, Seite 121 }// CancelListener } Prof. Dr.-Ing. Hans-Peter Wiedling Position erfassen (1/2) public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Componenten verfügbar machen geoData = (EditText) this.findViewById(R.id.EditText01); String context = Context.LOCATION_SERVICE; LocationManager locationManager = (LocationManager) this .getSystemService(context); Location location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); GpsData gpsData = new GpsData( location.getTime(), (float) location.getLongitude(), (float) location.getLatitude(), (float) location.getAltitude()); receiveGpsData(gpsData); ... } Geodatenanwendungen, Seite 122 Prof. Dr.-Ing. Hans-Peter Wiedling Position erfassen (2/2) public void receiveGpsData(GpsData gpsData) { String answer; if (gpsData != null) answer = gpsData.count + "\nLat: " + gpsData.geoBreite + "\nLon: " + gpsData.geoLaenge; else answer = "\nno Position"; geoData.setText(answer); } Geodatenanwendungen, Seite 123 Prof. Dr.-Ing. Hans-Peter Wiedling Positionsänderungen erfassen (1/2) public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Componenten verfügbar machen geoData = (EditText) this.findViewById(R.id.EditText01); Criteria criteria = new Criteria (); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(true); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); Konfiguration der Positionsinformatio n String provider = locationManager.getBestProvider(criteria, true); int minTime = 2000; int minDistance = 5; locationManager.requestLocationUpdates(provider, minTime, minDistance, locationListener); } Änderungen werden nicht abgerufen, sie werden gemeldet Geodatenanwendungen, Seite 124 Prof. Dr.-Ing. Hans-Peter Wiedling Positionsänderungen erfassen (2/2) // LocationListener definieren, um auf Updates zu reagieren LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { GpsData gpsData = new GpsData( location.getTime(), (float) location.getLongitude(), (float) location.getLatitude(), (float) location.getAltitude()); receiveGpsData(gpsData); } public void onStatusChanged(String provider, int status, Bundle extras) { } public void onProviderEnabled(String provider) { receiveGpsData(null); } public void onProviderDisabled(String provider) { } }; Geodatenanwendungen, Seite 125 Prof. Dr.-Ing. Hans-Peter Wiedling Request erzeugen und ausführen httpclient und httppost DefaultHttpClient httpclient = new DefaultHttpClient(); erzeugen HttpPost httppost = new HttpPost(myUrl); httppost.setHeader("Content-Type", "application/x-www-form-urlencoded"); // Daten einfügen List<NameValuePair> pairs = new ArrayList<NameValuePair>(); pairs.add(new BasicNameValuePair("file", "geodaten.xml")); Daten/ String bulkyData = "<bulkyData>"; Paramete for (int i = 0; i < 5; i++) r einfügen bulkyData += "<value>" + String.valueOf(i) + "</value>"; Date d = new java.util.Date(); bulkyData += "<date>" + android.text.format.DateFormat.format("yyyy-MM-dd hh:mm:ss", d)+"</date>"; bulkyData += "</bulkyData>"; pairs.add(new BasicNameValuePair("value", bulkyData)); HTTP Post httppost.setEntity(new UrlEncodedFormEntity(pairs)); Request ausführen String response = "NoConnection"; try { response = httpclient.execute(httppost, new BasicResponseHandler()); } catch (ClientProtocolException e){ e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Geodatenanwendungen, Seite 126 /* ... Antwort auswerten ... */ Prof. Dr.-Ing. Hans-Peter Wiedling return response; ... und auf der Serverseite: <?php $filename = 'test.txt'; $somecontent = "Füge dies der Datei hinzu.\n"; // Wir öffnen $filename im "Anhänge" - Modus. // Der Dateizeiger befindet sich am Ende der Datei, und if (!$handle = fopen($filename, "a")) { print "Kann die Datei " . $filename . " nicht öffnen"; } // Schreibe $somecontent in die geöffnete Datei. fwrite($handle, $somecontent); $someinput = $_POST['value']; Daten/ Paramete r lesen if (!fwrite ($handle, $someinput)) { print "Kann in die Datei " . $filename . " nicht schreiben"; exit; } print "Fertig; die Datei " . $filename . " wurde geschrieben."; fclose($handle); ?> Geodatenanwendungen, Seite 127 Prof. Dr.-Ing. Hans-Peter Wiedling Google Maps API Key generieren http://code.google.com/intl/de-DE/android/add-ons/google-apis/mapkey.html Fingerprint erzeugen: • $ keytool -list -alias androiddebugkey \ -keystore <path_to_debug_keystore>.keystore \ -storepass android -keypass android Keytool in c:\Programme\Java\jdk1.6.0_24\bin • C:\Dokumente und Einstellungen\XXX_XXX\.android\debug.keystore When you are ready to register for a Maps API Key, load this page in a browser: http://code.google. com/android/maps-api-signup.html Zur Registrierung eines Google Maps API Key folgende Schritte ausführen • Google Account einrichten • Android Maps API Nutzungsbestimmungen lesen und zustimmen • MD5 Zertifikat des Fingerprintzertifikats in das Formular enfügen • "Generate API Key" drücken Geodatenanwendungen, Seite 128 Prof. Dr.-Ing. Hans-Peter Wiedling Maps: manifest, resource und code <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.geologger" android:versionCode="1" android:versionName="10"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".GeoLogger" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <uses-library android:name="com.google.android.maps"></uses-library> </application> </manifest> Geodatenanwendungen, Seite 129 Prof. Dr.-Ing. Hans-Peter Wiedling Maps: manifest, resource und code <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey= "Your Google Maps API Key" /> </RelativeLayout> Geodatenanwendungen, Seite 130 Prof. Dr.-Ing. Hans-Peter Wiedling Maps: manifest, resource und code public class GeoLogger extends MapActivity { private MapController mapController; private MapView mapView; private LocationManager locationManager; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView( R.layout.main); // bind the layout to the activity // create a map view RelativeLayout linearLayout = (RelativeLayout) findViewById(R.id.mainlayout); mapView = (MapView) findViewById(R.id.mapview); mapView.setBuiltInZoomControls(true); mapView.setStreetView(true); mapController = mapView.getController(); mapController.setZoom(14); // Zoon 1 is world view ... Map wird eingestellt Geodatenanwendungen, Seite 131 Prof. Dr.-Ing. Hans-Peter Wiedling Maps: manifest, resource und code ... locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); criteria.setAltitudeRequired(true); criteria.setBearingRequired(false); criteria.setCostAllowed(true); criteria.setPowerRequirement(Criteria.POWER_LOW); String provider = locationManager.getBestProvider(criteria, true); int minTime = 2000; int minDistance = 5; locationListener locListener = new locationListener(); locationManager.requestLocationUpdates(provider, minTime, minDistance, locListener); } protected boolean isRouteDisplayed() { Listener wird return false; konditioniert } und erzeugt Geodatenanwendungen, Seite 132 Prof. Dr.-Ing. Hans-Peter Wiedling Maps: manifest, resource und code Listener ... meldet neue public class locationListener implements LocationListener { Position public void onLocationChanged(Location location) { int lat = (int) (location.getLatitude() * 1E6); int lng = (int) (location.getLongitude() * 1E6); GeoPoint point = new GeoPoint(lat, lng); mapController.animateTo(point); //mapController.setCenter(point); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} } } Geodatenanwendungen, Seite 133 Prof. Dr.-Ing. Hans-Peter Wiedling XML-Daten vom Server: SAXParser (1/3) Aufruf: EnvironmentParser public class EnvironmentParser extends DefaultHandler envParser = new EnvironmentParser(); { envParser.parse World world; // anwendungspez. Datenstruktur (env, myWorld); public void parse(String fname, World aWorld) { this.world = aWorld; SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser saxParser = factory.newSAXParser(); /* Parse the xml-data from our URL. */ URL url = new URL(fname); this.world = new World (); }// try catch (Exception e) { System.out.println(e); } return; }// parse Geodatenanwendungen, Seite 134 Prof. Dr.-Ing. Hans-Peter Wiedling XML-Daten vom Server: SAXParser (2/3) public void startElement(String nameSpaceURI, String lName, String qName, Attributes attrs) throws SAXException { // GPX Bsp.: // <trkpt lon="8.650904762635287" lat="49.78993319092846"> // <ele>162.420937930836</ele> // <name>TRC0WPT3</name> // </trkpt> if (lName.equals("trkpt")) { // Anwendungsobjekte erzeugen p = new PointF(Float.parseFloat(attrs.getValue("lon")), Float.parseFloat(attrs.getValue("lat"))); } if (lName.equals("waypoint")) { if (attrs.getValue ("name"). equals ("xxx")) ... } }// startElement Geodatenanwendungen, Seite 135 Prof. Dr.-Ing. Hans-Peter Wiedling XML-Daten vom Server: SAXParser (3/3) /** Methode des DefaultHandlers überschreiben */ public void endElement( String nameSpaceURI, String lName, String qName) throws SAXException { // ... }// endElement /** Methode des DefaultHandlers überschreiben */ public void error(SAXParseException e) { System.out.println("Error: " + e); } /** Methode des DefaultHandlers überschreiben */ public void fatalError(SAXParseException e) { System.out.println("Fatal Error: " + e); } /** Methode des DefaultHandlers überschreiben */ public void warning(SAXParseException e) { System.out.println("Warning: " + e); } } // EnvironmentParser Geodatenanwendungen, Seite 136 Prof. Dr.-Ing. Hans-Peter Wiedling Kommunikation zwischen Activity und Service ... Bundle, Message, IBinder, Intent, Handler/Thread, ... Callback, ... M V C Lernziele • Activity – UI, Interaktion, „schnelle“ Reaktion • Service – zeitintensiv, unterbrechbar, ohne UI • Starten bzw. Verbinden (implizit, explizit) • Austausch von Parametern (beim Aufruf/Start, als Rückgabe/Ergebnis) • Sehr lose Kopplung zwischen Activity und Service, u. U. ist der konkrete Service sogar anonym! • Umsetzung mit Intent, IBinder, Service, Handler, Message, Bundle Geodatenanwendungen, Seite 138 Prof. Dr.-Ing. Hans-Peter Wiedling Kommunikation zwischen Activities: Favoriten verwalten • Mehrere Objekte werden verwaltet • Die Objekte werden in einer Tabelle dargestellt • Um ein Objekt zu modifizieren, wird eine eigene Activity aufgerufen • Jedes Objekt wird in einem Adapter dargestellt • Die Adapter Objekte werden in einem ListView angezeigt • Komfortable Kopplung zwischen Objekt (bzw. Adapter), ListView • Objekte werden in separater Klasse verwaltet Geodatenanwendungen, Seite 139 Prof. Dr.-Ing. Hans-Peter Wiedling Adapter (1/3): Konstruktor class MySimpleArrayAdapter extends ArrayAdapter<Adresse> { private final Context context; private final MyListActivity aActivity; private final ArrayList<Adresse> adr; public MySimpleArrayAdapter(Context context, MyListActivity aActivity, ArrayList<Adresse> adr) { super(context, R.layout.itemlayout, adr); this.context = context; this.aActivity = aActivity; this.adr = adr; } Geodatenanwendungen, Seite 140 Prof. Dr.-Ing. Hans-Peter Wiedling Adapter (2/3): getView @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = (LayoutInflater) context.getSystemService (Context.LAYOUT_INFLATER_SERVICE); View rowView = inflater.inflate(R.layout.itemlayout, parent, false); TextView textView = (TextView) rowView.findViewById(R.id.label); textView.setText(adr.get(position).name); TextView comment = (TextView) rowView.findViewById(R.id.comment); comment.setText(adr.get(position).email); TextView select = (TextView) rowView.findViewById(R.id.selected); if (adr.get(position).benachrichtigen) select.setText("benachrichtigen"); else select.setText("nicht benachrichtigen"); return rowView; } }// MySimpleArrayAdapter Geodatenanwendungen, Seite 141 Prof. Dr.-Ing. Hans-Peter Wiedling Adapter (3/3): Ressource „itemLayout“ <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" > <LinearLayout android:id="@+id/linearLayout1" ...> <ImageView android:id="@+id/icon" ...android:src="@drawable/poi" /> <LinearLayout android:id="@+id/linearLayout2" …android:orientation="vertical"> <TextView android:id="@+id/comment“ ... android:text="comment" android:textSize="20px" /> <LinearLayout android:id="@+id/linearLayout3" … android:orientation="horizontal" > <TextView android:id="@+id/label“ android:text="anschrift"/> <TextView android:id="@+id/selected" …android:text="ausgewählt"/> </LinearLayout> </LinearLayout> </LinearLayout> </LinearLayout> Geodatenanwendungen, Seite 142 Prof. Dr.-Ing. Hans-Peter Wiedling Icon zu Zustandsanzeige // Icon anpassen ... ImageView imageView = (ImageView) rowView.findViewById(R.id.icon); Drawable d; if (adr.get(position).benachrichtigen) // Bedingung abfragen d = aActivity.getResources().getDrawable(R.drawable.green); else d = aActivity.getResources().getDrawable(R.drawable.red); imageView.setImageDrawable(d); Bilder einbinden Geodatenanwendungen, Seite 143 Prof. Dr.-Ing. Hans-Peter Wiedling Intent • Intents sind Absichtserklärungen – Sie verbinden unabhängige Komponenten – Sie sind ein Mechanismus zum Austausch von Daten und Nachrichten • zwischen Komponenten, • zwischen verschiedenen Anwendungen oder • mit der Android Plattform • Tauchen auch häufig in Verbindung mit Services auf • Bei expliziten Intents ist der Empfänger bei der Programmierung des Aufrufs bekannt und kann identifiziert werden • Implizite Intents adressieren keinen bestimmten Empfänger und überlassen es den Komponenten, auf den Intent zu reagieren Geodatenanwendungen, Seite 144 Prof. Dr.-Ing. Hans-Peter Wiedling Intents: Austausch von Nachrichten • Senden: ... Intent i = new Intent(); i.putExtra("key1", "value1"); startActivityForResult(i, REQUEST_CODE); setResult(RESULT_OK, data); ... • Empfangen: ... protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == RESULT_OK && requestCode == REQUEST_CODE) { if (data.hasExtra("key1")) { ... data.getExtras().getString("key1") ... } } } Geodatenanwendungen, Seite 145 Prof. Dr.-Ing. Hans-Peter Wiedling Activity aufrufen und von dort zurückkehren MyListActivity @Override protected void onListItemClick (ListView l, View view, int position, long id) { Adresse.itemSelect = (Adresse) getListAdapter().getItem(position); Intent myIntent = new Intent(view.getContext(), changeAdresseActivity.class); startActivityForResult(myIntent, 0); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); adapter.notifyDataSetChanged(); } changeAdresseActivity : Bundle bundle = new Bundle(); bundle.putString("ret", "OK"); Intent mIntent = new Intent(); mIntent.putExtras(bundle); setResult(RESULT_OK, mIntent); finish(); Geodatenanwendungen, Seite 146 Prof. Dr.-Ing. Hans-Peter Wiedling Callback zwischen Activity und Service • In der Activity: • onCreate ... intent = new Intent(this, MyService.class); // 1. Param: welcher Service soll gestartet werden // 2. Param: onServiceConnected von localServiceVerbindung wird // aufgerufen sobald Verbindung steht // 3. Param: wann soll gestartet werden: // automatisch beim Starten bindService(intent, localServiceVerbindung, Context.BIND_AUTO_CREATE); new MyService(); // Service anonym erzeugen! Geodatenanwendungen, Seite 147 Prof. Dr.-Ing. Hans-Peter Wiedling ServiceConnection • In der Activity private ServiceConnection localServiceVerbindung = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder binder) // wird aufgerufen, wenn Service verbunden wird { mybinder = (MyService.MyBinder) binder; service = mybinder.getService(); service.setCallback(getHandler());// callback } public void onServiceDisconnected(ComponentName className) { } }; Geodatenanwendungen, Seite 148 Prof. Dr.-Ing. Hans-Peter Wiedling Handler: • In der Activity: private Handler getHandler() { final Handler callbackHandler = new Handler() { public void handleMessage(Message msg) { Bundle bundle = msg.getData(); String s = (String)bundle.get("info"); cbText.setText (s); }// handleMessage }; return callbackHandler; } Geodatenanwendungen, Seite 149 Prof. Dr.-Ing. Hans-Peter Wiedling In der Serviceklasse • MyBinder Innere Klasse in der Service MyService public class MyBinder extends Binder { // innere Klasse public MyService getService() { return MyService.this; } } @Override public IBinder onBind(Intent intent) { return serviceBinder; // damit Callback registriert werden kann } // Callback registrieren public void setCallback(Handler callbackHandler) { uiServiceCallbackHandler = callbackHandler; } Geodatenanwendungen, Seite 150 Prof. Dr.-Ing. Hans-Peter Wiedling Service meldet Ergebnis • Im Service (z.B. in einem Thread) ... // Callback organisieren Message msg = new Message(); // msg.obj = beliebiges_Objekt Bundle bundle = new Bundle(); bundle.putString("info", "Complexe Berechnung beendet."); msg.setData(bundle); uiServiceCallbackHandler.sendMessage(msg); // Callback ... Geodatenanwendungen, Seite 151 Prof. Dr.-Ing. Hans-Peter Wiedling Threads, Service und Intent – Kommunikation, Callbacks, IPC • • • • • Für Android ist jede gestartete Anwendung ein eigener Prozess Ein Prozess kann mehrere Threads starten Insbesondere wird der User Interface Thread (UI-Thread) gestartet Wenn der UI-Thread blockiert, reagiert weder Tastatur noch Anzeige Soll ein Thread lose gekoppelt sein, wiederverwendbar und beliebigen Anwendungen zu Verfügung stehe, sollte er in Android als Service realisiert sein PID 1 PID 2 Activity Local Service PID 2 Remote Service Thread 1 Thread 2 Thread 3 IPC Geodatenanwendungen, Seite 152 Prof. Dr.-Ing. Hans-Peter Wiedling AsyncTask für lang laufende Aufgabe class ComplexTask extends AsyncTask <Void, Void, ProgressDialog pDialog; Activity activity; ComplexTask(Activity activity) { super(); this.activity = activity; Vor } Ausführung protected void onPreExecute() { pDialog = ProgressDialog.show(activity, "Complex "Reading data ...", true); } protected Void doInBackground(Void... unused) { for (int i = 0; i < 200; i++) { publishProgress(); for (int j = 0; j < 2000; j++); } Fortschritt return (null); Void> { Computation wait...", Komplexe bzw. zeitintensive Operation Nach } Ausführung protected void onProgressUpdate(Void... unused) { } Geodatenanwendungen, Seite 153 protected void onPostExecute(Void unused) { pDialog.dismiss(); } Prof. Dr.-Ing. Hans-Peter Wiedling }// ComplexTask Service • Ein Service ist eine Applikation, die nicht direkt mit dem User interagiert; sie besitzt keine eigene Benutzeroberfläche • sie läuft im Hintergrund abläuft • kapselt lang laufende Programmteile • ein Thread im Service löst die Aufgabe • sie löst bestimmte Aufgabe import android.app.Service; import android.content.Intent; • Ist eine Software import android.os.IBinder; Komponente • vermeidet ANR public class MyService extends Service { (Application Not public MyService() Responding) { /* TODO Auto-generated constructor stub • Beispiel public IBinder onBind(Intent arg0) – XML Parser { return null; } – Media Player GpsData getGpsData()// z.B. */} {...} } // MyService Geodatenanwendungen, Seite 154 Prof. Dr.-Ing. Hans-Peter Wiedling Kommunikation mit dem Service private myBinder mybinder; private MyService service; private ServiceConnection localServiceVerbindung = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder binder) // wird aufgerufen, wenn Service verbunden wird { } public void onServiceDisconnected(ComponentName className) { } }; Geodatenanwendungen, Seite 155 Prof. Dr.-Ing. Hans-Peter Wiedling Service starten (aus der Activity) ... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ... Intent intent = new Intent(this, MyService.class); // 1. Param: welcher Service soll gestartet werden // 2. Param: onServiceConnected von localServiceVerbindung wird // aufgerufen sobald Verbindung steht // 3. Param: wann soll gestartet werden: // automatisch beim Starten bindService(intent, localServiceVerbindung, Context.BIND_AUTO_CREATE); service = new MyService(); ... Geodatenanwendungen, Seite 156 Prof. Dr.-Ing. Hans-Peter Wiedling Service und Intent (1/2) public class MyService extends Service { private static final String TAG = "MyService"; private myBinder mybinder = new myBinder(); // Schnittstelle nach außen public class myBinder extends Binder { MyService getService() { return MyService.this; } } public String sendData() { new Thread() { public void run() { try { this.sleep(5000); // zeitintensive Operation } catch (Exception e) { } } // run }.start(); return "Hello, this is your service"; } ... und weitere Methoden Geodatenanwendungen, Seite 157 Prof. Dr.-Ing. Hans-Peter Wiedling Service und Intent (2/2) @Override public IBinder onBind(Intent intent) { return mybinder; } @Override public void onCreate() { Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show(); Log.d(TAG, "onCreate"); } @Override public void onDestroy() { Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show(); Log.d(TAG, "onDestroy"); } @Override public void onStart(Intent intent, int startid) { Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show(); Log.d(TAG, "onStart"); } } Geodatenanwendungen, Seite 158 Prof. Dr.-Ing. Hans-Peter Wiedling Permissions und Service eintragen <?xml version="1.0" encoding="utf-8"?> ... <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Permissions fuer GPS und LocationManager --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- wenn man einen LocationProvider zum Testen erstellen will: --> <!-- uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/ --> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> ... <service android:name=".MyService" /> </application> </manifest> Geodatenanwendungen, Seite 159 Prof. Dr.-Ing. Hans-Peter Wiedling Kontinuierliche Abfragen (1/2) private void watch() { WatchThread wt = new WatchThread(this); wt.start(); } // watch // Methode fragt Service ab final Runnable updateHandler = new Runnable() { public void run() { try { String info = service.sendData(); aText.setText(info); } catch (Exception e) {} } }; ... In der Activity Geodatenanwendungen, Seite 160 Prof. Dr.-Ing. Hans-Peter Wiedling Thread class WatchThread extends Thread { Handler handler; myIntent mi; WatchThread(myIntent mi) { this.mi = mi; handler = new Handler(); } public void run() { // updateHandler wird zyklisch aufgerufen int sleep = 2000; // Milliseconds boolean runnable = true; while (runnable) { try { Thread.sleep(sleep); handler.post(mi.updateHandler); } catch (Exception e) {} } // while }// run }// WatchThread Geodatenanwendungen, Seite 161 Prof. Dr.-Ing. Hans-Peter Wiedling Strukturen transformieren XML, XSLT, XPath Transforming (XSLT) Dokumente als Baumstruktur allgemein Vorgänger ancestor Eltern parent Aktueller Knoten self Geschwister sibling Kinder, child Nachfolger descendant Geodatenanwendungen, Seite 163 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung von Dokumenteilen (1/2) • child • descendant • • • • parent ancestor preceding following Kindelemente des Kontextknoten alle Nachfahren des Kontextknotens (nicht nur die unmittelbaren Kinder) unmittelbarer Vorfahre des Kontextknotens alle Vorfahren des Kontextknoten alle Elemente vor dem Kontextknoten alle Element nach dem Kontextknoten Geodatenanwendungen, Seite 164 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung von Dokumenteilen (2/2) • preceding-sibling • following sibling • • • • self descendent–or-self ancestor-or-self attribute • namespace alle Elemente nach dem Kontextknoten auf gleicher Ebene (älteren Geschwister) alle Elemente vor dem Kontextknoten auf gleicher Ebene (jüngeren Geschwister) Kontextknoten selbst Kontextknoten und alle Nachfahren Kontextknoten und alle Vorfahren alle Attribute des Kontextknoten und alle Nachfahren des Kontextknoten Namespace des Kontextknoten Geodatenanwendungen, Seite 165 Prof. Dr.-Ing. Hans-Peter Wiedling Information Processing mit XML • • • • Modellierung und formale Beschreibung mit XML/ DTD Struktur- und Layouttransformationen mit XSL, XSLT Ausgeprägte Verweismöglichkeiten Xlink, XPointer Adressierung in der Dokumentstruktur XPath • ... sowie jede Menge domänenspezifische Festlegungen (svg, gpx, ...) Geodatenanwendungen, Seite 166 Prof. Dr.-Ing. Hans-Peter Wiedling Information Processing mit XML Style Sheet (2) (XSL) WWW offline CD DTD, Schema (XML) Engine Papier (pdf) final form Instanz (XML) Geodaten “alles andere“ (*.gif, *.jpg, *.mp3, Java) Style Sheet (1) (XSL) Transformationen (XSLT) div. prop. Formate smart phone Geodatenanwendungen, Seite 167 Prof. Dr.-Ing. Hans-Peter Wiedling Formale Beschreibung von Dokumenten: DTD • SGML basiert; aber deutlich einfacher Document Type / Schema • Auszeichnungssprache (Markupdeklarationen, Attribute, Entities) • generische Modellierung ... <!ELEMENT trk (name, cmt, trkpt+)> • starke Betonung der log. Struktur <!ELEMENT name ( #PCDATA ) > • damit ist folgendes möglich: <!ELEMENT tkrpt ( ele, time )> <!ATTLIST trkpt lat CDATA – “suche nach POIs“ REQUIRED – “gib nur Routen an“ lon CDATA REQUIRED> <!ELEMENT ele ( #PCDATA ) > <!ELEMENT time ( #PCDATA ) > Geodatenanwendungen, Seite 168 ... Prof. Dr.-Ing. Hans-Peter Wiedling XML: HTML ⊂ XHTML Das W3C hat mit Hilfe von XML die HTML – Sprache neu beschrieben und dazu eine DTD (Document Type Definition) formuliert. Das Ergebnis dieser Bemühungen trägt den Namen XHTML – DTD und ist auf den Internetseiten des W3C zu finden. Geodatenanwendungen, Seite 169 Prof. Dr.-Ing. Hans-Peter Wiedling Qualität von Information • HTML - Taktische Merkmale <h1>Winterwald<p>Treffpunkt für Jogger und Walker am <a src = http://www.winterwald.de><font color = green size+=2> verschneiter Waldweg</A><img src=“wald.jpg“>... • XML - Strategische Aspekte HTML geht mit dem Tagging sehr nachlässig um! <wpt lat="49.901801" lon="8.776510"> <ele>858.0000000</ele> <time>2007-07-22T13:13:46Z</time> <name>winterwald.jpg</name> XML kennt wohlgeformte <cmt>Winterwald</cmt> <desc>verschneiter Waldweg</desc> und gemäß der DTD validierte Dokumente! <sym>Scenic Area</sym> <extensions> <gpxx:WaypointExtension xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3 "><gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode> </gpxx:WaypointExtension></extensions></wpt> Geodatenanwendungen, Seite 170 Prof. Dr.-Ing. Hans-Peter Wiedling XML: Austauschformat und Formale Beschreibungssprache • Ein wichtiger Aspekt dabei ist, dass im Rahmen der DTD alle erlaubten Markups festgelegt werden sowie die Struktur - d.h. Anzahl, Schachtelung und Reihenfolge- , wie diese Markups verwendet werden dürfen, alle Attribute und der Zuordnung zu Markups festgelegt werden • Groß- und Kleinbuchstaben werden im Gegensatz zu HTML in XML (eXtensible Markup Language) unterschieden • Es können einfacher wiederverwendbare Softwarekomponenten entwickelt und eingesetzt werden • Die in den Dokumenten enthaltenen Daten werden maschinenlesbar: – eine Zahl ist nicht nur eine Zahl sondern eine Zahl mit Bedeutung – Preis, Anzahl, Typ, Koordinaten ... - oder ist Java eine Insel, eine Programmiersprache oder ein Ausdruck für starken Kaffee?! Geodatenanwendungen, Seite 171 Prof. Dr.-Ing. Hans-Peter Wiedling Wohlgeformte Dokumente (I) • Ein wohlgeformtes Dokument beginnt mit einem Prolog (Vorspann) und besitzt mindestens eine Elementvereinbarung. • Der Prolog enthält die XML–Deklaration, die festlegt, in welcher XML – Version und Zeichencodierung das Dokument geschrieben wurde. • Zudem kann mit dem Attribut "standalone" festgelegt werden, ob dieses Dokument autonom, d.h. für sich steht, oder eine unter vielen Instanzen einer DTD ist: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> Geodatenanwendungen, Seite 172 Prof. Dr.-Ing. Hans-Peter Wiedling Wohlgeformte Dokumente (II) • Tags in XML müssen stets geschlossen werden • Zu jedem öffnenden Tag muss ein schließendes Tag existieren • Die einzige Ausnahme bilden Einzeltags , die vor der schließenden spitzen Klammer mit einem Schrägstrich geschlossen werden. Beim Schreiben eines XML-Dokuments ist besondere Aufmerksamkeit geboten, denn XML unterscheidet (im Gegensatz zu HTML) zwischen Groß- und Kleinschreibung. Die Bezeichner der öffnenden und schließenden Tags müssen exakt übereinstimmen. Ein Bezeichner darf keine Leerzeichen enthalten. Geodatenanwendungen, Seite 173 Prof. Dr.-Ing. Hans-Peter Wiedling Wohlgeformte Dokumente (III) • HTML ist in dieser Hinsicht weitaus toleranter; dort stellen fehlende Tags keinen Fehler dar; sie erschweren aber die maschinelle Verarbeitung durch Parser. • Beispiel: Normales Tag (Markup) <cmt>Treffpunkt Nordic Walking</cmt> Leeres Tag (Empty Tag) <neuerAbsatz/> Geodatenanwendungen, Seite 174 Prof. Dr.-Ing. Hans-Peter Wiedling Wohlgeformte Dokumente (IV) • Der Wert eines Elementattributes muss in doppelten Anführungszeichen eingeschlossen sein. • Der Name des Attributes ist vorangestellt und wird mit einem Gleichheitszeichen mit dem Wert verbunden. Die Attributbezeichner müssen innerhalb eines Dokumentes eindeutig sein. Des weiteren dürfen Attribute keine spitzen Klammern enthalten. • Beispiel: <wpt lat="49.901801" lon="8.776510"> <ele>858.0000000</ele> <time>2007-07-22T13:13:46Z</time> <name>winterwald.jpg</name> <cmt>Winterwald</cmt> <sym>Scenic Area</sym> </wpt> Geodatenanwendungen, Seite 175 Prof. Dr.-Ing. Hans-Peter Wiedling Wohlgeformte Dokumente (V) • Die Elemente müssen baumartig streng hierarchisch geschachtelt sein. Ein wohlgeformtes Dokument ist gekennzeichnet durch einen streng geordneten Tag-Baum. Daraus folgt unmittelbar, dass jedes Dokument ein Wurzelelement besitzt, in das alle anderen Elemente eingeschlossen sind. Diese Bedingung ergibt sich direkt aus der streng baumartigen Struktur. Enthält ein Dokument nur ein Element, so ist dies als Wurzel anzusehen. In dem Beispiel stellt "E1" das Wurzelelement (Rootelement) dar. • Beispiel: Falsche Schachtelung Richtige Schachtelung <ele>252.000000 <time> <ele>252.000000 </ele> <time> 2009-04-02T06:26:52Z </ele> 2009-04-02T06:26:52Z </time> </time> Geodatenanwendungen, Seite 176 Prof. Dr.-Ing. Hans-Peter Wiedling Elementdeklarationen (I) • Zur syntaktischen Definition bedarf es einigen Vereinbarungen zur Notation. In einer DTD sind spezielle Zeichen für die Notation reserviert: • Zeichen hinter dem Element Bedeutung in der DTD Und-Operator (Sequenz) , Legt fest, welche Elemente erscheinen müssen. Kein Element darf in dem Dokument fehlen. Außerdem wird bei Aufzählungen die Reihenfolge mit festgelegt. | Oder-Operator Er trennt alternative Elemente, von denen nur eines vorhanden sein darf. Geodatenanwendungen, Seite 177 Prof. Dr.-Ing. Hans-Peter Wiedling Elementdeklarationen (II) • Zeichen hinter dem Element (leere Markierung) ? Bedeutung in der DTD Das Element kommt genau einmal vor Option Das Element kann, muss aber nicht vorhanden sein + Iteration Das Element muss n-mal vorhanden sein, mit n=1,2,... . Ein Element muss mindestens vorhanden sein. * Optionale Iteration Das Element kann n-mal vorhanden sein, mit n=0,1,2,... Geodatenanwendungen, Seite 178 Prof. Dr.-Ing. Hans-Peter Wiedling Elementdeklarationen (III) Zeichen & Bedeutung in der DTD Und: Alle so verbundenen Elemente müssen im Dokument vorkommen; die Reihenfolge ist beliebig; Jedes Element darf allerdings nur genau einmal vorkommen nur SGML, nicht XML! () Gruppierung Mit runden Klammern können Elemente beliebig gruppiert werden. Geodatenanwendungen, Seite 179 Prof. Dr.-Ing. Hans-Peter Wiedling Elementdeklarationen (IV) • Wie schon im Abschnitt über Wohlgeformtheit beschrieben, bestehen XML – Dokumente aus Elementen, die durch Tags gekennzeichnet sind. • Um ein Element in der DTD zu deklarieren, muss dessen Name und dessen Bestandteile angegeben werden. Die Elementdefinition hat stets folgende Gestalt: <!ELEMENT Name [Inhalt] > Geodatenanwendungen, Seite 180 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel: einfacher Trace • Mit Hilfe der Operatoren in der Tabelle kann beschrieben werden, wie oft ein Element oder ein Bestandteil daraus in dem Dokument vorkommt: • Ein Trace soll aus – einem Namen, – einer (kurzen) Beschreibung, – dem Segment mit einer Folge von Tracepunkten mit • Höhenangabe und Zeitmarke bestehen. Geodatenanwendungen, Seite 181 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel: einfacher Trace • (sehr einfache) DTD: <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT trk (name, desc, trkseg) > trkseg (trkpt+) > trkpt (ele, time) > name (#PCDATA) > desc (#PCDATA) > ele (#PCDATA) > time (#PCDATA) > – eine (Ausprägung der DTD) Instanz: <trk><name>Jogging im Dieburger Wald</name> <desc>Nordic Walking Treffpunkt</desc> <trkseg><trkpt><ele>252.000000</ele> <time>2009-04-02T06:26:52Z</time> </trkpt></trkseg></trk> Geodatenanwendungen, Seite 182 Prof. Dr.-Ing. Hans-Peter Wiedling Attributlisten • Wie auch schon aus HTML bekannt, können Elemente Attribute enthalten, um die Elemente genauer zu spezifizieren • Die Festlegung der Attribute und deren Zuordnung zu Elementen erfolgt in der DTD • Die Attribute können auch als Subelemente eines Elements eingebettet werden, was aber nicht in allen Fällen sinnvoll ist • Als Orientierungshilfe kann man zusammenfassen, dass Informationen, die nicht für den Endnutzer sichtbar sein sollen oder nur zur Verarbeitung notwendig sind, als Attribute fomuliert werden. Alle anderen Inhalte können als Subelemente definiert werden Geodatenanwendungen, Seite 183 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel: Subelemente vs. Attribute Mit Subelementen: <!ELEMENT trk (name, desc, trkseg) > <!ELEMENT trkseg (trkpt+) > <!ELEMENT trkpt (lat, lon, ele, time) > <!ELEMENT lat (#PCDATA) > <!ELEMENT lon (#PCDATA) > <!ELEMENT ele (#PCDATA) > <!ELEMENT time (#PCDATA) > Mit Attributen: <!ELEMENT <!ELEMENT <!ELEMENT <!ATTLIST trk (name, desc, trkseg) > trkseg (trkpt+) > trkpt (ele, time) > trkpt lat CDATA #REQUIRED lon CDATA #REQUIRED > <!ELEMENT ele (#PCDATA) > <!ELEMENT time (#PCDATA) > Geodatenanwendungen, Seite 184 Prof. Dr.-Ing. Hans-Peter Wiedling Beispiel: einfacher Trace • Mit Subelementen: <trk><name>Jogging im Dieburger Wald</name> <desc>Nordic Walking Treffpunkt</desc> <trkseg><trkpt><lat>49.895943</lon> <lon>8.804555</lon><ele>252.000000</ele> <time>2009-04-02T06:26:52Z</time> </trkpt></trkseg></trk> • Mit Attributen: <trk><name>Jogging im Dieburger Wald</name> <desc>Nordic Walking Treffpunkt</desc> <trkseg><trkpt lat="49.895943" lon="8.804555"> <ele>252.000000</ele><time>2009-04-02T06:26:52Z</time> </trkpt></trkseg></trk> Geodatenanwendungen, Seite 185 Prof. Dr.-Ing. Hans-Peter Wiedling Dokumentinstanz: Inhalt und Struktur • Trägerformat für unterschiedliche Medien Instanz <wpt lat="49.901801" lon="8.776510"> <ele>858.0000000</ele> <time>2007-07-22T13:13:46Z</time> <name>winterwald.jpg</name> <cmt>Winterwald</cmt> <desc>verschneiter Waldweg</desc> <sym>Scenic Area</sym> </wpt> • nach den formalen Regeln der DTD überprüfbar: vollständig wohlgeformt gültig (valid) Geodatenanwendungen, Seite 186 Prof. Dr.-Ing. Hans-Peter Wiedling Style Sheets: medienspezifische Darstellungselemente • Beschreibung von medienspezifischen Layoutmerkmalen Style Sheet (XSL) • in XML Notation • Unterstützung von Verweisen <xsl:template match=“wpt"> <fo:inline-sequence font-weight="bold"> basierend auf der <xsl:apply-templates/> Baumstruktur der Dokumentinstanz </fo:inline-sequence> (XPath, XPointer, XLink) </xsl:template> wpt { display : inline; font-weight : bold } • in der Praxis wird häufig Cascading Style Sheets (CSS) verwendet Geodatenanwendungen, Seite 187 Prof. Dr.-Ing. Hans-Peter Wiedling Struktur- und Styletransformationen • Strukturtransformationen von XML nach Transformationen (XSLT) <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform" xmlns= "http://www.w3.org/TR/xhtml1/strict"> <xsl:template match="/"> <html><head><titleRouten</title> </head><body> <h1>Track:<xsl:value-of select=“/"/> </h1></body></html> </xsl:template> </xsl:stylesheet> – XML – HTML – andere Formate • in XML Notation • verschiedene Tools stehen zur Verfügung – XT – Parserklassen in Java (SAX, Cocoon, Xerces) Geodatenanwendungen, Seite 188 Prof. Dr.-Ing. Hans-Peter Wiedling XSLT: Strukturen transformieren XSLT: EXtensible Stylesheet Language Transformations – http://www.w3.org/1999/XSL/Transform und – http://www.w3.org/TR/xpath-functions/#func-local-name-from-QName • Motivation – Um-strukturieren (XML nach XML, XML nach XHTML, XML nach csv, ...) – Filtern, Um-ordnen – je besser strukturiert desto mehr Möglichkeiten ergeben sich • Voraussetzung: In XML strukturiert • Was CSS für XHTML ist, ist XSLT für XML • Prinzip: templates (Vorlagen, Schablonen) – siehe dazu auch http://www.w3schools.com/xsl/ (Tutorial) – Variable ändern in XSLT nicht ihren Wert • Im Rahmen der Veranstaltung: einf. Anwendung mit XSLT serverseitig unter php Geodatenanwendungen, Seite 189 Prof. Dr.-Ing. Hans-Peter Wiedling XSLT ist ein Beispiel für eine funktionale Programmiersprache • Funktionale Programmierung ist ein Programmierstil, bei dem Programme ausschließlich aus Funktionen bestehen. • Ein Ausdruck hat dort während der Programmausführung immer den gleichen Wert. Es gibt keine Zustandsvariablen die während einer Berechnung geändert werden. Man bezeichnet diese Eigenschaft als Werttreue (engl. referential transparency ). • Grundsätzlich gilt in der Funktionalen Programmierung - jedes Programm ist eine Funktion - jede Funktion kann weitere Funktionen aufrufen - Funktionen werden wie andere Daten behandelt Gerade in dem letzten Punkt unterscheiden sich funktionale von imperativen Sprachen. Die Trennung von Daten und Programmlogik wird aufgehoben. • Funktionale Programme sind übersichtlicher Geodatenanwendungen, Seite 190 Prof. Dr.-Ing. Hans-Peter Wiedling XSLT • Eine in XSLT ausgedrückte Transformation beschreibt Regeln für die Transformation eines Quellbaums in einen Ergebnisbaum. • Diese Transformation wird durch die Assoziation von Mustern mit Templates erreicht. Ein Muster wird gegen Elemente des Quellbaumes getestet. Ein Template wird instanziiert, um einen Teil des Ergebnisbaumes zu erstellen. • Der Ergebnisbaum ist unabhängig vom Quellbaum. • Die Struktur des Ergebnisbaums kann sich von der Struktur des Quellbaums komplett unterscheiden. Bei der Konstruktion des Ergebnisbaums können Elemente des Quellbaumes – gefiltert und – umgeordnet sowie – beliebige Struktur hinzugefügt werden. Geodatenanwendungen, Seite 191 Prof. Dr.-Ing. Hans-Peter Wiedling Unser Beispiel: Das GPX-Dokument <?xml version="1.0" encoding="UTF-8" ?> <gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.13.7" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensions/v3/GpxExtensionsv3.xsd http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"> <wpt lat="49.901801" lon="8.776510"><ele>858.0000000</ele> <time>2007-07-22T13:13:46Z</time><name>winterwald.jpg</name> <cmt>Winterwald</cmt><desc>verschneiter Waldweg</desc> <sym>Scenic Area</sym> <extensions> <gpxx:WaypointExtension xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3"> <gpxx:DisplayMode>SymbolAndName</gpxx:DisplayMode> </gpxx:WaypointExtension> </extensions> </wpt> <trk><name>Jogging im Dieburger Wald</name><desc>kurze Beschreibung</desc> <trkseg> ... <trkpt lat="49.895943" lon="8.804555"><ele>252.000000</ele><time>2009-0402T06:26:52Z</time> </trkpt> </trkseg> </trk> </gpx> Geodatenanwendungen, Seite 192 Prof. Dr.-Ing. Hans-Peter Wiedling XSLT • • • • Templates Identifikation von Dokumentteilen (Adressierung mit XPath) Variable, Parameter Kontrollkonstrukte – Schleifen – Bedingungen • XSLT: 100% XML <?xml version="1.0" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" encoding="ISO-8859-1" indent="no" /> ... </xml> - Hier spielt die Musik Geodatenanwendungen, Seite 193 Prof. Dr.-Ing. Hans-Peter Wiedling Erstes Beispiel: XSLT Wurzelknoten <?xml version="1.0" encoding="ISO-8859-1" ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> Tracepoint-Tag <xsl:output method="html" /> <xsl:template match="/"> <html xmlns:html='http://www.w3.org/TR/xhtml1/'> <body> <xsl:apply-templates /> </body> </html> </xsl:template> <xsl:template match="wpt"> lat = </b> <xsl:value-of select="@lat" /></b> , lon = <xsl:value-of select="@lon" /> <br /> - <font style="color:red"> <xsl:value-of select="." /> </font> </xsl:template> </xsl:stylesheet> Geodatenanwendungen, Seite 194 Prof. Dr.-Ing. Hans-Peter Wiedling <template> Ausdruck weist auf Wert/Inhalt des akt. Knotens Definieren: <xsl:template match="trkpt"> <font style="color:red"> <xsl:value-of select="."/> <xsl:text disable-outputescaping="yes">&euro;</xsl:text> </font> </xsl:template> Entity wird umgesetzt Anwenden: <xsl:apply-templates select="./trkpt"/> Template wird angewendet auf alle Knoten vom Typ trkpt des aktuellen Knotens Geodatenanwendungen, Seite 195 Prof. Dr.-Ing. Hans-Peter Wiedling Schleifen <for each> Tagname ... <xsl:for-each select="wpt"> <li> <xsl:number format="format" /> <xsl:value-of select="."/> </li> </xsl:for-each> Inhalt (z.B. ‘252.0000002009-04-02T06:26:52Z‘) Geodatenanwendungen, Seite 196 Prof. Dr.-Ing. Hans-Peter Wiedling Schleifen <for-each> <table border="1"> <tr bgcolor="#9acd32"> <th>Position</th><th>latitude</th> <th>longitude</th><th>elevation</th> <th>time</th> </tr> <xsl:for-each select="//trkpt"> <tr> <td><xsl:value-of select="position()"/></td> <td><xsl:value-of select="@lat"/></td> <td><xsl:value-of select="@lon"/></td> <td><xsl:value-of select="./ele/text()"/></td> <td><xsl:value-of select="./time/text()"/></td> </tr> </xsl:for-each> </table> Schleife über alle Tracepoint s Geodatenanwendungen, Seite 197 Prof. Dr.-Ing. Hans-Peter Wiedling Fallunterscheidungen <choose> <xsl:choose> absteigend <xsl:when test="$getOrder = 'descending'"> <xsl:apply-templates select="Speisekarte/Pizza"> Block kann <xsl:sort select= mit versch. "*[local-name() = $getSort]" order="descending"/> Bed. wiederholt </xsl:apply-templates> </xsl:when> werden <xsl:otherwise> <xsl:apply-templates select="Speisekarte/Schnitzel"> <xsl:sort select="*[local-name() = $getSort]"/> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> Name des Tag ist ‘Schnitzel‘ Geodatenanwendungen, Seite 198 Prof. Dr.-Ing. Hans-Peter Wiedling Bedingungen <if> Erfüllt, wenn <h2>wpt oder trk</h2> der Knoten <xsl:for-each select="/gpx/wpt | /gpx/trk"> vom typ ‚trk‘ <xsl:if test="local-name() = 'trk'"> ist <xsl:value-of select="./name/text()" /> </xsl:if> </xsl:for-each> Geodatenanwendungen, Seite 199 Prof. Dr.-Ing. Hans-Peter Wiedling <variable> • Definition <xsl:variable name="lecture" select="'Geodatenanwendungen'"/> oder <xsl:variable name="lecture"><h1>Geodatenanwendungen</h1> </xsl:variable> oder <xsl:if test="position()=1"> <xsl:variable name="lecture " select="'Geodatenanwendungen'"/> </xsl:if> <xsl:variable name="place" • select="/gpx/trk/name/text()" /> Anwendung: Variable werden mit $ angesprochen <xsl:copy-of select="$lecture" /> Geodatenanwendungen, Seite 200 Prof. Dr.-Ing. Hans-Peter Wiedling <xsl:with-param>, <xsl:param> <h3>Sehenswürdigkeiten</h3> <xsl:for-each select="gpx/wpt"> <xsl:call-template name="show_title"> <xsl:with-param name="value" select="Name"/> <xsl:with-param name="typ" select="'Name'"/> <xsl:with-param name="original" select="@Name"/> </xsl:call-template> </xsl:for-each> </body> </html> Tag Text Attribut <xsl:template name="show_title" match="wpt"> <xsl:param name="value" select= „Freizeitzentrum" /> default via select <xsl:param name="typ" /> <xsl:param name="original" /> <p ><xsl:value-of select="$typ"/>: <xsl:value-of select="$value" /> <xsl:value-of select="$original"/> </p> </xsl:template> Geodatenanwendungen, Seite 201 Prof. Dr.-Ing. Hans-Peter Wiedling Attribute • Attribute werden in XSLT grundsätzlich mit tagname/@attributname angesprochen, z.B. img/@src für das src-Attribut eines img-Tags. Mit <xsl:template match="img"> Bild: <xsl:value-of select="@src"/> </xsl:template> kann man dann den Namen eines Bildes ausgeben. • Erfolgt die Ausgabe innerhalb von Attributen kann man anstelle eines value-ofs eine geschweifte Klammer verwenden: <xsl:template match="abbildung"> <img src="{@src}" alt="{@alt}"/> </xsl:template> Geodatenanwendungen, Seite 202 Prof. Dr.-Ing. Hans-Peter Wiedling XPath Navigation im Dokument mit Location Step • Die Auswahl der Knoten erfolgt durch eine Navigation durch den Dokumentenbaum. Mit Location Steps können Bewegungen relativ zu einem Knoten im Dokument beschrieben werden. Und Knotenmengen adressiert werden Ein Location Step besteht aus drei Elementen: – eine Dokumentenachse (axis) die Achse definiert das Verhältnis zwischen dem Kontextknoten und dem Schritt, um die relative Position zum aktuellen Knoten anzugeben – einen Knotenmuster (node-test) der Knotentest filtert Knoten, die entlang der Achse gefunden wurden, entsprechend ihres Namens oder ihres Typs – optionale Prädikate (predicate) 0 bis n Prädikate schränken die Ergebnismenge zusätzlich ein, indem sie Eigenschaften von Knoten abfragen Geodatenanwendungen, Seite 203 Prof. Dr.-Ing. Hans-Peter Wiedling Location Steps - Beispiel • Der syntaktische Aufbau eines Location Steps wird mit folgender Regel gebildet: – axis::node-test[predicate] Bei Verwendung mehrerer Prädikate werden diese in eckigen Klammern am Ende hinzugefügt. • Beispiele – descendant::wpt[@lon=‘8.804555'] Selektiert alle Nachfolgerelemente vom Typ wpt des Kontextknotens deren ‘lon'-Attribut ‘8.804555' enthält. – descendant::wpt[@lon=‘8.804555'][position()=last()] Selektiert zunächst wie bei dem Beispiel zuvor, jedoch wird nur das letzte Element ausgegeben. Geodatenanwendungen, Seite 204 Prof. Dr.-Ing. Hans-Peter Wiedling Location Path (1/2) • Durch einen Location Step kann ein neuer Kontextknoten adressiert werden. • Mit Location Path können viele Steps miteinander verknüpft werden und somit einen Pfad bilden. • Die einzelnen Location Steps werden wie bei einer Pfadangabe in einem Dateisystem mit einem Schrägstrich ("/") separiert. • Eine absolute Pfadangabe in einem Dokument erreicht man, indem man den Rootknoten des Dokuments als Kontextknoten betrachtet. • Absolute Pfadangaben beginnen mit einem Schrägstrich, relative Pfadangaben mit einem Location Step. Geodatenanwendungen, Seite 205 Prof. Dr.-Ing. Hans-Peter Wiedling Location Path (2/2) • Beispiel (absolut): – /child::gpx/child::trk[2]/child::name Wählt (alle) ‘name'-Knoten des zweiten ‘trk‘-Knotens unterhalb ‘gpx' aus. • Beispiel (relativ): – preceding-sibling::trk[position()=last()]/child::name Wählt (alle) ‘name'-Knoten in dem ‘trk', das sich vor dem aktuellen Kontextknoten befindet. Geodatenanwendungen, Seite 206 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung mit XPath (1/3) • • • • • • • • • $pi / //p /p p . ./@art ./@art=‘value‘ ../@art • • //p[@preis<9] { ... } Wert der Variable pi Wurzel alle p-Elemente p-Elemente unter der Wurzel Alle Kindknoten von p aktuelles Element Attribut art des aktuellen Knotens Attribut art des aktuellen Knotens mit Wert value Attribut art des Elternelementes (entspricht auch ancestor::name/attribute::art oder parent::name/@art) Alle p-Knoten mit dem Preisattribut < 9 in Strings (z.B. Attributwerten von Tags) stehen Pfadangaben in geschweiften Klammern Geodatenanwendungen, Seite 207 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung mit XPath (2/3) • • • • • • • • • • child:: parent:: descendant:: descendant-or-self:: ancestor:: ancestor-or-self:: following:: following-sibling:: preceding:: preceding-sibling:: • ohne Angabe Kindknoten direkter Vorfahre (alle) Nachfahren (alle) Nachfahren und akt. Knoten Vorfahren auf dem Weg zur Wurzel Vorfahren und akt. Knoten alles danach / rechts vom Knoten selbst alle Knoten, die dem gegenwärtigen folgen alles davor / links vom Knoten selbst alle Knoten, die vor dem gegenwärtigen Knoten stehen abkürzende Schreibweise für Knoten entlang der Kindachse Geodatenanwendungen, Seite 208 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung mit XPath (3/3) • • • • • • • • • self attribute:: namespace last() position() count(node-set) name(node-set?) (Elementname) not ( ... ) aktueller Knoten selbst Attribute des aktuellen Elementes Namensraum des aktuellen Elementes letztes Element in einer Menge Kontextposition (beginnend bei 1) Anzahl der Knoten in node-set erster Knotennname in node-set Namensraumbezeichner wenn vorhanden log. Ausdruck wird negiert Geodatenanwendungen, Seite 209 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung mit XPath – Beispiele (1/2) • //gpx/wpt | //gpx/trk alle wpt- und –trk • * jeder Knoten • @* jedes Attribut • node() alles • /gpx/wpt[last()] letzter wpt-Knoten als Kindknoten von Speisekarte • /gpx/wpt[last()-1] vorletzter wpt-Knoten als Kindknoten vom gpxknoten Geodatenanwendungen, Seite 210 Prof. Dr.-Ing. Hans-Peter Wiedling Adressierung mit XPath – Beispiele (2/2) • /gpx/wpt[position()<3] die ersten beiden wpt-Knoten, die Kindknoten vom wpt-Knoten sind • //name[@lang] Alle name-Knoten mit dem Attribute lang • //name[@lang='eng'] Alle name-Knoten, die ein Attribute lang mit dem Wert eng besitzen • /gpx/wpt[name[text()=‘Jogging‘] Alle wpt-Knoten, die einen name-Knoten mit dem Inhalt ‘Jogging‘ besitzen • /gpx/wpt[name[text()=‘Jogging‘]/name Alle name-Knoten, der wpt, deren name-Knoten einen Inhalt ‘Jogging‘ besitzen Geodatenanwendungen, Seite 211 Prof. Dr.-Ing. Hans-Peter Wiedling Math. Funktionen • arithmetische Terme: – div, mul, +, -, () • Vergleiche: – <, <=, =, !=, >, >=, not (), and, or • Union (Vereinigung) – | • Formatierung <xsl:decimal-format name="european" decimal-separator=',' grouping-separator='.' /> <xsl:value-of select="format-number(24535.2, '###.###,00', 'european')"/> Beispiele: – – format-number(5351,"#,###") liefert 5,351 format-number(5351, "#.00") liefert 5351.00 Geodatenanwendungen, Seite 212 Prof. Dr.-Ing. Hans-Peter Wiedling Math. Funktionen (1/2) • sum, count, average, min, max – <xsl:variable name="the_number_" select="count(//sum)"/> – <xsl:variable name="the_avg" select="sum(//sum/text()) div count(//sum)"/> – <xsl:variable name="the_min"> <xsl:for-each select="//sum/text()"> <xsl:sort data-type="number" order="ascending"/> <xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if> </xsl:for-each> </xsl:variable> – <xsl:variable name="the_max"> <xsl:for-each select="//sum"> <xsl:sort data-type="number" order="descending"/> <xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if> </xsl:for-each> </xsl:variable> Geodatenanwendungen, Seite 213 Prof. Dr.-Ing. Hans-Peter Wiedling xsl:key • definiert einen Zugriffsschlüssel auf Elemente oder Attribute. Für den XSLTProzessor wird die Arbeit erleichtert und die Verarbeitungsgeschwindigkeit erhöht. Über die Funktion kann der Zugriffsschlüssel angewendet werden. • xsl:key hat folgende Attribute: – name (obligatorisch) legt einen Namen für den Schlüssel fest, unter dem er angewendet werden kann. – use (obligatorisch) gibt an, auf was der Schlüssel zugreifen soll. – match (optional) gibt das Knoten-Set bzw. einen Pfad an, an dem der Schlüssel im Elementbaum ansetzen soll: <xsl:key name="schluessel" match="node" use="@id"/> ... <xsl:value-of select="key('schluessel', '@idref')"> ... Geodatenanwendungen, Seite 214 Prof. Dr.-Ing. Hans-Peter Wiedling xsl:key-Beispieldaten <trk> <node id="447845172" lat="49.8655172" lon="8.6462759" user="AlexPleiner" uid="61927" visible="true" version="4" changeset="1995740" timestamp="2009-07-31T16:24:11Z" /> <node id="447845177" lat="49.8656271" lon="8.6465193" user="kiwifromgermany" uid="148951" visible="true" version="3" changeset="1934561" timestamp="2009-07-25T15:14:37Z" /> <node id="447847063" lat="49.8656811" lon="8.6465010" user="glmosm" uid="27716" visible="true" version="4" changeset="3274426" timestamp="2009-12-02T18:54:04Z" /> <node id="447845181" lat="49.8657322" lon="8.6464849" user="kiwifromgermany" uid="148951" visible="true" version="4" changeset="1934561" timestamp="2009-07-25T15:14:38Z" /> <node id="447845184" lat="49.8655227" lon="8.6459363" user="AlexPleiner" uid="61927" visible="true" version="4" changeset="1995740" timestamp="2009-07-31T16:24:11Z" /> <node id="447846909" lat="49.8655220" lon="8.6460901" user="kiwifromgermany" uid="148951" visible="true" version="4" changeset="1934561" timestamp="2009-07-25T15:15:35Z" /> - <way id="38076540" user="snipermatze" uid="90589" visible="true" version="5" changeset="3175388" timestamp="2009-11-21T12:09:38Z"> <nd ref="447845172" /> <nd ref="447845177" /> <nd ref="447847063" /> 215 Geodatenanwendungen, Seite <nd ref="447845181" /> <nd ref="447845184" /> <nd ref="447846909" /> Prof. Dr.-Ing. Hans-Peter Wiedling <nd ref="447845172" /> <tag k="amenity" v="parking" /> </way> xsl:key-Beispiel <xsl:key name="koordinaten" match="node" use="@id" /> <xsl:template match="way"> <table border="1"> <tr bgcolor="#9acd32"> <th>Position</th> <th>ref</th> <th>latitude</th> <th>longitude</th> <th>elevation</th> <th>time</th> </tr> <xsl:for-each select="./nd"> <tr>- <td> <xsl:value-of select="position()" /> </td> <td> <xsl:value-of select="@ref" /> </td> <xsl:variable name="knoten" select="key('koordinaten',@ref)" /> <td> <xsl:value-of select="$knoten/@lon" /> </td> <td> <xsl:value-of select="$knoten/@lat" /> </td> <td> <xsl:text disable-output-escaping="yes"> </xsl:text> <xsl:value-of select="$knoten/@elevation" /> </td> <td> <xsl:value-of select="substring($knoten/@timestamp, 1, 10)" /> <br /> <xsl:value-of select="substring($knoten/@timestamp, 10, string-length($knoten/@timestamp))" /></td> </tr> </xsl:for-each> </table> </xsl:template> Geodatenanwendungen, Seite 216 Prof. Dr.-Ing. Hans-Peter Wiedling Stringfunktionen • substring(s ,start, len) substring in s von start mit der Länge len • string-length(s) Länge von s • contains (s1, s2) true, wenn s1 s2 enthält • replace (s, pattern, substitute) In s wird pattern durch substitute ersetzt • normalize-space (s) entfernt Whitespace • upper-case (s) wandelt s in Großbuchstaben um • lower-case (s) wandelt s in Kleinbuchstaben um • tokenize (s, pattern) zerlegt s gemäß pattern in Stringarray Geodatenanwendungen, Seite 217 Prof. Dr.-Ing. Hans-Peter Wiedling Tutorial zu XPath – http://www.w3schools.com/xpath/xpath_axes.asp und – http://www.w3.org/TR/xpath20/#id-steps Geodatenanwendungen, Seite 218 Prof. Dr.-Ing. Hans-Peter Wiedling Fortsetzung gpx Beispiel (I) <table border="1"> <tr bgcolor="#9acd32"> <th>Position</th> <th>latitude</th> <th>longitude</th> <th>elevation</th> <th>time</th> </tr><xsl:for-each select="//trkpt"> <tr><td><xsl:value-of select="position()" /> </td> <td><xsl:value-of select="@lat" /> </td> <td><xsl:value-of select="@lon" /></td> <td><xsl:value-of select="./ele/text()"/></td> <td><xsl:value-of select="./time/text()"/></td> </tr> </xsl:for-each> </table> Geodatenanwendungen, Seite 219 Prof. Dr.-Ing. Hans-Peter Wiedling Fortsetzung gpx Beispiel (II) sortiert wpt; Kriterium: name; absteigend <table border="1"> <tr bgcolor="#9acd32"> <th>Name</th> <th>Position</th> <th>latitude</th> <th>longitude</th> <th>elevation</th> <th>time</th> </tr> <xsl:for-each select="//wpt"> <xsl:sort select="name" order="ascending" data-type="text" /> <tr><td> <xsl:value-of select="position()" /> </td> <td> <xsl:value-of select="./name/text()" /> </td> <td> <xsl:value-of select="@lat" /> </td> <td> <xsl:value-of select="@lon" /> </td> <td> <xsl:value-of select="./ele/text()" /> </td> <td> <xsl:value-of select="./time/text()" /> </td> </tr> </xsl:for-each> Geodatenanwendungen, Seite 220 Prof. Dr.-Ing. Hans-Peter Wiedling XSLT mit php <?php // XSL-Stylesheet importieren $xslDom = new DOMdocument; $xslDom->load(„jogging.xslt"); $xmlDom = new DOMdocument; $xmlDom->load(„jogging.xml"); $xslt = new XsltProcessor; $xslt->importStylesheet($xslDom); // Transformation ausfuehren echo $xslt->transformToXML($xmlDom); ?> Geodatenanwendungen, Seite 221 Prof. Dr.-Ing. Hans-Peter Wiedling Ubiquität von Information • Systematischer Umgang mit Information spielt eine zentrale Rolle und ist eine Zukunftstechnologie: – Akquisition – Informationen (um-)strukturieren, – selektieren und filtern, – (grafisch) aufbereiten, – verdichten, – interagieren, – sammeln, – verteilen • Dokumentteile adressieren, verknüpfen, verlinken, ... Geodatenanwendungen, Seite 222 Prof. Dr.-Ing. Hans-Peter Wiedling die XML - eine Auszeichnungssprache • Konsistenz, Einheitlichkeit, Wiedererkennungsmerkmale („Corporate Identity“): – “Alle Dokumente haben ein gemeinsames Erscheinungsbild“ • medienneutrale Beschreibung • unterschiedliche Sichten auf die Dokumente • Übertragbarkeit, Erweiterbarkeit • Dokumentendurchgängigkeit und Information Processing: Geodatenanwendungen, Seite 223 Prof. Dr.-Ing. Hans-Peter Wiedling Begriffsklärung - Aspekte medialer Systeme - Beispielsystem - XML - Schlussbemerkung Prozesskette Akquisition, Erstellen, Editieren Idee, Planung, Bestandsaufnahme Sammeln, Verwalten, Verknüpfen, Archivieren Redaktion, Aufbereiten, Schützen vs. Freigeben Kontrollierte Weitergabe Anzeigen, Nutzen, Recherche Ende. Geodatenanwendungen, Seite 224 Prof. Dr.-Ing. Hans-Peter Wiedling