Rheinische Friedrich-Wilhelms-Universität Bonn Institut für Informatik III Flugüberwachungssystem Entwurf und Implementierung eines Werkzeugs zur Überwachung von Flugbewegungen in SQL Diplomarbeit vorgelegt von: Matrikelnummer: Erstgutachter: Dmitri Mizerkin 1987372 Prof. Dr. Rainer Manthey Bonn, November 2009 Inhaltsverzeichnis Inhaltsverzeichnis 1. Einleitung 1 2. Grundlagen 5 2.1. Datenbanksysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2. Relationale Datenbanken . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.1. Normalformen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.2. Regelkonzepte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.3. Anfragesprache SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.3.1. Data Definition Language (DDL) . . . . . . . . . . . . . . . . . . . . . 9 2.3.2. Data Manipulation Language (DML) . . . . . . . . . . . . . . . . . . . 12 2.4. Datenstrom-Management und kontinuierliche Anfragen . . . . . . . . . . . . . 15 3. Organisation der zivilen Luftfahrt 18 3.1. Luftraum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.1. Organisation des Luftraumes . . . . . . . . . . . . . . . . . . . . . . . 18 3.1.2. Flächensystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.3. Luftstraßen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.4. Rufzeichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.1.5. Flugplätze und Flughäfen . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.1.6. Ortungssysteme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2. Fluginformationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2.1. Flugdaten-Erfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2.2. Ableitbare Fluginformationen . . . . . . . . . . . . . . . . . . . . . . . 24 4. Anforderungsanalyse 26 4.1. Allgemeine Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.1.1. Datenorganisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4.1.2. Anfrageverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.2. Systemspezifische Anforderungen . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.2.1. Datenimport . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.2.2. Datenbankzugriff . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.2.3. Definition von Anfragen . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.2.4. Anfrageauswertung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5. Entwurf und Implementierung eines Flugüberwachungssystems 38 I Inhaltsverzeichnis 5.1. Systemarchitektur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 5.2. Entwurf des Datenbankschemas . . . . . . . . . . . . . . . . . . . . . . . . . . 39 5.3. Implementierung der Datenbankanwendung . . . . . . . . . . . . . . . . . . . 41 5.3.1. Realisierung des Datenimports . . . . . . . . . . . . . . . . . . . . . . 43 5.3.2. Speicherung der Flugdaten . . . . . . . . . . . . . . . . . . . . . . . . 43 5.3.3. Speicherung der Flughafeninformationen . . . . . . . . . . . . . . . . . 44 5.3.4. Verwaltung von SQL-Anfragen . . . . . . . . . . . . . . . . . . . . . . 45 5.3.5. Erweiterung der Datenbankanwendung . . . . . . . . . . . . . . . . . . 46 5.4. Programmentwurf und -implementierung . . . . . . . . . . . . . . . . . . . . . 46 5.4.1. Schnittstelle IImportable . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.4.2. Klassen Flight und Airport . . . . . . . . . . . . . . . . . . . . . . . . 48 5.4.3. Import-Klassen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 5.4.4. Klasse SQLExpression . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 5.4.5. Entwicklungswerkzeuge . . . . . . . . . . . . . . . . . . . . . . . . . . 49 5.4.6. Kartendarstellung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 5.4.7. Effizienzsteigerung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 6. Definition und Analyse der Flugkenngrößen 52 6.1. Berechnung der sphärischen Distanz zwischen zwei Punkten . . . . . . . . . . 52 6.2. Berechnung des Treffpunktes zweier beweglichen Körper . . . . . . . . . . . . 54 6.2.1. Berechnung in 2D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 6.2.2. Berechnung in 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 6.2.3. Genauigkeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 6.3. Punkt-in-Polygon-Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 6.3.1. Berechnung des Winkels zwischen zwei Vektoren . . . . . . . . . . . . 59 6.3.2. Vektorprodukt zweier Vektoren . . . . . . . . . . . . . . . . . . . . . . 59 6.3.3. Winkelsummierungsmethode . . . . . . . . . . . . . . . . . . . . . . . 60 7. Berechnung von Flugkenngrößen mittels SQL 62 7.1. Ermittlung aktueller Fluginformationen . . . . . . . . . . . . . . . . . . . . . 62 7.2. Ermittlung von Flugzeugen eines spezifischen Typs . . . . . . . . . . . . . . . 64 7.3. Filterung der Flugzeuge nach Position und Höhe . . . . . . . . . . . . . . . . 65 7.4. Bestimmung von landenden Flugzeugen . . . . . . . . . . . . . . . . . . . . . 66 7.5. Feststellung einer kritischen Annäherung . . . . . . . . . . . . . . . . . . . . . 68 7.6. Flugbewegungen innerhalb eines vordefinierten Gebiets . . . . . . . . . . . . . 69 7.7. Ermittlung von Informationen aus historischen Daten . . . . . . . . . . . . . . 71 7.8. Ermittlung von Flugstatistiken aus historischen Daten . . . . . . . . . . . . . 72 7.9. Wiederverwendung bestehender Kenngrößen . . . . . . . . . . . . . . . . . . . 73 8. Beispielszenario 75 9. Fazit und Ausblick 88 II Inhaltsverzeichnis Literaturverzeichnis 92 Abbildungsverzeichnis 94 Verzeichnis der Listings 95 A. Anhang i A.1. Bestimmung der Zugehörigkeit eines Punktes einer festgelegten Region . . . . ii A.2. Kartendarstellungswerkzeug . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv A.3. Implementierung von Kenngrößen in SQL . . . . . . . . . . . . . . . . . . . . x A.3.1. Benutzerdefinierte Funktion zur Berechnung des sphärischen Abstandes x A.3.2. Benutzerdefinierte Funktion zur Feststellung einer kritischen Annäherung x A.3.3. Benutzerdefinierte Funktion zur Bestimmung der Zugehörigkeit eines Punktes dem Londoner Gebiet . . . . . . . . . . . . . . . . . . . . . . xiii III Abkürzungsverzeichnis Abkürzungsverzeichnis ANSI American National Standards Institute API Application Programming Interface DBMS Database Management System DSMS Data Stream Management System ERM Entity-Relationship-Model FL Flight Level GIS Geographic Information System GLONASS Global Navigation Satellite System GPS Global Positioning System HTML Hypertext Markup Language HTTP Hypertext Transfer Protocol IATA International Air Transport Association ICAO International Civil Aviation Organization ISO International Organization for Standardization IT Information Technology KML Keyhole Markup Language NAVSTAR Navigation System with Time and Ranging OOP Object-Oriented Programming SQL Structured Query Language URL Uniform Resource Locator WGS84 World Geodetic System 1984 IV 1. Einleitung 1. Einleitung Die Entwicklung der Zivilluftfahrt geht immer rasanter voran. Es werden immer mehr Fluggesellschaften gegründet, immer mehr Strecken werden beflogen. Die steigende Konkurrenz auf dem Markt der Zivilluftfahrt sorgt dafür, dass durchschnittliche Preise für Flugtickets fallen, und immer mehr Menschen es sich leisten können, ihre Reiseziele per Flug zu erreichen. Mittlerweile gibt es sehr viele so genannte Billigfliegern, die ihre Gewinne vor allem durch hohe Zahlen der Reisenden erzielen. Aus dem Geschäftsbericht 2008 der größten deutschen Fluggesellschaft Lufthansa wird es ersichtlich, dass die Anzahl der Fluggäste im Vergleich zum Vorjahr um 12,2% gestiegen ist1 . Die Zahlen des größten europäischen Billigfliegers Ryanair weisen eine noch deutlichere Steigungstendenz auf. Die Anzahl der Fluggäste ist im Jahr 2008 um 20% im Vergleich zum Vorjahr gestiegen2 . Die steigende Zahl der Passagiere impliziert die Tatsache, dass sich mehr Flugmaschinen zum gleichen Zeitpunkt in der Luft befinden müssen, und machen das Problem der Überwachung und Koordination der aktiven Flüge immer schwieriger. Die Überwachung von Flugzeugen erfolgt unter Verwendung von speziell dafür entwickelten stationären Systemen, die unterschiedliche Geräte wie Radar oder Sprechfunkanlage aber auch Software umfassen. Automatisierte Bestandteile solcher Systeme müssen vor allem äußerst leistungsfähig sein, weil sie große Mengen von relevanten Informationen schnell und effizient verarbeiten und auswerten müssen. Der hohen Leistungsfähigkeit wird unter anderem Anwenderfreundlichkeit geopfert. Dies bedeutet, dass solche Flugüberwachungssysteme lediglich von qualifizierten Kräften bedient werden können und für Anwender ohne spezielle Ausbildung nicht geeignet sind. Allerdings können Informationen über die Flüge auch für andere Zwecke wie z.B. Marktforschung oder Umweltplanung durchaus interessant sein. Für solche Anwendungen werden manche Daten zum Flugbetrieb wie z. B. Typ oder aktueller Standort des Flugzeuges von zuständigen Behörden zur Verfügung gestellt. Im Internet gibt es inzwischen mehrere Webseiten, die Fluginformationen sammeln und auf Abruf verfügbar machen. Ein gutes Beispiel für eine solche Sammlung ist die Webseite „Open Air Traffic Control“ (OpenATC, http://openatc.com/), die außer der eigentlichen Flugdaten mehrere Visualisierungsmöglichkeiten für diese Daten anbietet. Die auf solchen Seiten verfügbaren Daten sind insofern ausführlich, dass sie als Datenquellen zur Herleitung von anwendungsspezifischen Informationen durchaus tauglich sind. 1 2 [Luf08, S. 74] [Rya08, S. 3] 1 1. Einleitung Eins der Ziele dieser Arbeit ist es nun, ein solches Werkzeug zu entwickeln, das die von unterschiedlichen Diensten zur Verfügung gestellten Flugdaten in ein für schnelle Bearbeitung optimiertes Format bringt und dem Benutzer die Möglichkeit bietet, ihn interessierende Anfragen zu definieren, zu speichern und auszuwerten. Das Zielsystem soll möglichst flexibel und anwenderorientiert sein. Dies bedeutet, dass der Benutzer des Systems auf eine möglichst einfache Art und Weise beliebig komplexe Anfragen betätigen kann. Um es zu erzielen, muss erst eine Konvention über die zu verwendende Anfragedefinitionssprache gefunden werden. Die Sprache kann nicht nach Belieben gewählt werden, sondern muss einen guten Kompromiss zwischen Effizienz der Verarbeitung und Bequemlichkeit des Benutzers darstellen. Zur Steigerung der Verarbeitungseffizienz von Anfragen ist es naheliegend, die Sprache des zu verwendenden Datenverwaltungssystems (Data Management System, DMS) zu benutzen. Aus diesem Grund ist die Wahl der Entwicklungsmittel beim Entwurf eines solchen Systems ausschlaggebend. Es gibt mehrere Varianten, die DMS-Komponente des Systems zu implementieren. Die eine sieht die Neuentwicklung eines DMS vor, was natürlich wegen eines enormen Programmieraufwandes keine gute Lösung ergibt. Auch bei Benutzung eines bestehenden DMS muss die Wahl zwischen zwei unterschiedlichen Konzepten erfolgen. • Datenbankverwaltungssystem (Database Management System, DBMS). Das Zielsystem soll eine Datenbankschicht beinhalten, die die Aufgaben von Speicherung und Verwaltung von Daten übernimmt. In diesem Fall kann auch die Aufgabe der Anfragenauswertung an diese Schicht delegiert werden. Außer der eigentlichen Datenbanktabellen können in einem DBMS weitere Objekte wie Sichten, gespeicherte Prozeduren, benutzerdefinierte Funktionen und Trigger verwaltet werden. Hierfür kann ein beliebiges DBMS (wie z. B. Microsoft SQL Server, MySQL, PostgreSQL usw.) eingesetzt werden. Um diese Variante der Architektur umzusetzen, ist es allerdings notwendig, zusätzlich einen Mechanismus zum Einlesen von Daten und Speicherung dieser in der Datenbasis zu realisieren. • Datenstromverwaltungssystem (Data Stream Management System, DSMS). Für das Zielsystem wird eine Instanz in einem DSMS (wie z. B. PIPES [MC04], STREAM [The03] oder AURORA [Dan03]) eingerichtet, die Daten von gegebenen Quellen als Datenströme verwaltet. Die vom Benutzer definierten Anfragen werden in geeignete Ausführungspläne umgesetzt, mit Hilfe deren neue Daten bereits bei Ankunft verarbeitet und in Form von vorbereiteten Snapshots in einer hinterlegten Datenbank gespeichert werden. Die Wahl zwischen den beiden Varianten der Implementierung muss anhand der Anforderungen an das Zielsystem erfolgen. Die Benutzung eines DSMS hat einen klaren Vorteil, der darin besteht, dass sich der Entwickler nicht darum kümmern muss, wie die Daten von der jeweiligen Internetressource in das System einfließen. Darüber hinaus wird das DSMS bei Erstellung der Ausführungspläne auch die Aufgabe der Anfragenoptimierung übernehmen. Die einzige Aufgabe, die bei der Entwicklung des Systems noch zu implementieren wäre, ist also lediglich die Anfragenverwaltung. Das Problem ist dabei aber, dass die in das System einge- 2 1. Einleitung lesenen Daten für verschiedene Anfragen mehrmals in Form von unterschiedlichen Snapshots gespeichert werden müssen. Darüber hinaus muss es berücksichtigt werden, dass es ebenso möglich sein muss, Anfragen an das System zu stellen, die aus dem Gesamtdatenbestand statistische Informationen herleiten. Dies würde bedeuten, dass jeder Ausschnitt des Datenflusses einmal unverändert und mehrmals in Form von Snapshots gespeichert werden müsste. Der dadurch entstehende potenziell enorme Anspruch an den zur Verfügung stehenden Speicherplatz macht die Benutzung eines DBMS und zusätzliche Implementierung eines Datenimportmechanismus zu einer vernünftigeren Lösung. Schließlich stellt die Möglichkeit, SQL anstatt dessen wenig bekannten Erweiterungen zur Anfragendefinition zu benutzen, einen weiteren Vorteil der DBMS-Variante dar. Die Entscheidung, SQL als Standardsprache zur Definition von Anfragen zu benutzen, stellt ein weiteres Ziel, das die aktuelle Arbeit verfolgt. Zur Erinnerung besteht das erste Ziel der Arbeit darin, ein System zur Herleitung von Informationen aus den Flugdaten zu entwickeln, das hohe Effizienz und Flexibilität aufweist. Die Frage ist nun, ob diese wichtigen Merkmale des Systems bei Benutzung von SQL erhalten bleiben. Die Untersuchung der Eignung von SQL für Definition von flexiblen, komplexen und dennoch effizienten Anfragen ist ein wichtiger Teil der aktuellen Arbeit und kann als Hauptziel betrachtet werden. Im Laufe der aktuellen Arbeit wurde ein Werkzeug zur Beobachtung von Flugzeugen entworfen und implementiert. Ein Modul dieses Systems sorgt dafür, dass die Datenbasis regelmäßig um neu angekommene Flugdaten erweitert wird. Die Verwaltung von Datenimports erfolgt im System durch Benutzer, der den Datenfluss auf eine relativ einfache Art und Weise entsprechend seinen Bedürfnissen anpassen kann. Die Definition von Flugkenngrößen erfolgt mittels einer etwas angepassten Version von SQL. Die Komplexität der möglichen Anfragen ist also lediglich durch die Möglichkeiten von SQL beschränkt. Allerdings hat sich SQL als eine sehr ausdrucksstarke Anfragesprache erwiesen, mit Hilfe deren viele denkbaren Kenngrößen, die auf den aktuellen aber auch auf historischen Daten basieren, definiert werden können. Die vorhin erstellten Anfragen werden im System mit Hilfe eines DBMS ausgewertet. Vermöge interner Optimierungsmechanismen des DBMS ist der zeitliche Aufwand der Anfrageauswertung relativ gering, damit wird auch die gewünschte Effizienz des Werkzeugs gewährleistet. Strukturell ist die Arbeit so aufgebaut, dass sich der Leser erst mit den technischen und fachlichen Grundlagen vertraut machen kann. So werden in Kapitel 2 Grundlagen der Datenbanksysteme, Anfragesprache SQL sowie der Datenströmen und kontinuierlichen Anfragen in Grundzügen vorgestellt. Die aufgeführten Informationen dienen einem besseren Verständnis der Diskussion über die Möglichkeiten, das Zielsystem zu realisieren. Darüber hinaus soll die Definition von Anfragen im System mit Hilfe von SQL erfolgen, daher sind Kenntnisse über diese Anfragesprache notwendig, um das System bedienen zu können. In Kapitel 3 werden einige Abläufe in der zivilen Luftfahrt erklärt und die Bedeutung von Daten zum Flugbetrieb erläutert. Diese Informationen können später bei der Analyse und Implementierung von interessanten Kenngrößen benutzt werden. Die Kapiteln 4 und 5 beschäftigen sich mit dem 3 1. Einleitung im Rahmen dieser Arbeit entwickelten Flugüberwachungssystem. Zunächst werden die Anforderungen an das Zielsystem gestellt und analysiert. Danach findet die Diskussion über den Entwurf und Implementierung des Systems statt, die sich erst mit der Implementierung der Datenbankanwendung und anschließend mit der technischen Realisierung der Benutzeroberfläche beschäftigt. In Kapitel 6 werden mögliche Anfragen vorgestellt. Da einige von diesen durch Anwendung von Lösungen mathematischer Probleme implementiert werden können, werden solche Lösungen weiter in diesem Kapitel vorgestellt. Anschließend werden die Möglichkeiten, die genannten Kenngrößen mittels SQL zu realisieren, in Kapitel 7 diskutiert. Der gesamte Arbeitsablauf im System wird in Kapitel 8 an einem Beispielszenario erläutert. Hierbei wird auch die Performanz des Systems analysiert. Abschließend wird in Kapitel 9 über die Ergebnisse der aktuellen Arbeit sowie die Möglichkeiten der Weiterentwicklung diskutiert. Im Anhang finden sich die Angaben zu den im Laufe dieser Arbeit benutzten Quellen. Außerdem werden hier die Implementierungen einiger Funktionen und Kenngrößen beigefügt, die es ermöglichen, genauere Analyse der Systemleistung sowie der Realisierung einiger Anfragen durchzuführen. In der Arbeit werden Begriffe und Abkürzungen, die für das Verständnis des Inhaltes relevant sind, bei ihrer Definition durch Fettdruck gekennzeichnet. Wichtige Abkürzungen und Begriffe, die vorhin definiert wurden, sowie Erklärungen, die entgegengesetzt werden, werden im Kursiv gedruckt. 4 2. Grundlagen 2. Grundlagen Die Architektur eines Flugüberwachungswerkzeugs, das die Definition und Auswertung von Flugkenngrößen vereinfachen wird, sieht den Einsatz eines Datenbanksystems vor. Dieses soll benutzt werden, um die Daten strukturiert lokal zu speichern aber auch um die definierten SQL-Anfragen auswerten zu können. Die Benutzung eines Datenbanksystems erfordert vom Benutzer gewisse Kenntnisse über relationale Datenbanken sowie die Anfragesprache SQL. Dieses Kapitel beschäftigt sich gerade mit solchen technischen Grundlagen, mit denen man sich vor der Benutzung von einem solchen Werkzeug vertraut machen muss. Die aufgeführten Grundlagen der relationalen Datenbanken beruhen im Wesentlichen auf Informationen aus [AK06] ergänzt durch Angaben aus [Man07] und [WIK09]. Für die Erläuterungen zur Anfragesprache SQL im Abschnitt 2.3 wurde hauptsächlich [Mic09] als Quelle benutzt. Schließlich stammen die Angaben zu Datenstromverwaltungssystemen hauptsächlich aus [MC04]. 2.1. Datenbanksysteme Elektronische Datenspeicherungsmedien spielen in der heutigen Welt eine immer größer werdende Rolle. Dies ist dadurch bedingt, dass sich die Informationsmengen laut den statistischen Angaben alle 5 Jahre verdoppeln. Diese Statistik motiviert große IT-Konzerne dazu, neuere, schnellere und zuverlässigere Datenbanksysteme zu entwickeln. Ein Datenbanksystem besteht im Wesentlichen aus zwei wichtigen Teilen: • Als Datenbasis wird die Menge der im System gespeicherten Daten, die miteinander in Beziehung stehen, bezeichnet. • Unter einem Datenbankverwaltungssystem (DBMS) versteht man die Menge der Funktionen, die für den Zugriff auf und Verwaltung von Datenbasis zuständig sind. Diese Komponenten werden oft zusammengefasst als DBMS bezeichnet. Die Entscheidung über den Einsatz eines Datenbanksystems wird meistens dann getroffen, wenn Redundanzen und Inkonsistenzen im Datenbestand vermieden werden sollen. Unter einer Redundanz versteht man ein mehrfaches Vorhandensein derselben Daten in der Datenbasis. Eine Inkonsistenz tritt dann auf, wenn die Informationen zu einem Objekt im Datenbestand mehrmals mit unterschiedlichen Merkmalen vorkommen. Zur Vermeidung sol- 5 2. Grundlagen cher unerwünschten Zustände in der Datenbasis sowie zur effizienten Verarbeitung von Daten wird das relationale Datenmodell benutzt. 2.2. Relationale Datenbanken Das relationale Datenmodell besteht in der mengenorientierten Datenverwaltung und wurde Anfang siebziger Jahre entworfen. Diese Art der Datenverwaltung hat schließlich dafür gesorgt, dass sich das relationale Datenmodell gegenüber satzorientierten Modellen wie hierarchisches oder Netzwerkmodell durchgesetzt hat. Dieser Erfolg ist vor allem der Datenzugriffsschnelligkeit und Begünstigung von Design- und Optimierungsmethoden zu verdanken. Die Grundidee des relationalen Datenmodells ist, dass es im Wesentlichen nur zweidimensionale Tabellen (Relationen) gibt, in denen jede Zeile einem Datenobjekt entspricht. Eine Relation besteht aus Zeilen, die Tupeln des gegebenen Relationstyps entsprechen. Jedes Tupel besteht aus einer Menge von Attributen, die den Spalten der Tabelle entsprechen. Die Daten aus verschiedenen Relationen werden mit Hilfe von Schlüsseln mengenorientiert verknüpft. Ein Schlüssel ist eine minimale Menge von Attributen, die einen Datensatz innerhalb aller Datenobjekte des gleichen Typs eindeutig identifizieren. Oft wird ein einzelnes künstlich eingebautes Attribut als Schlüssel benutzt. Manchmal gibt es zu einer Relation mehrere Schlüsselkandidaten. In diesem Fall wird einer von diesen zum Primärschlüssel gewählt. Der Entwurf einer relationalen Datenbank beginnt mit der Abgrenzung eines Teils der realen Welt. Hierfür wird meistens ein Entity-Relationship-Model (ERM) aufgebaut, das die Objekte der Datenbank (Entities) und die Beziehungen (Relationships) zwischen diesen abbildet. Zu den Entitäten gehören die Abbildungen von Gegenständen aus der realen Welt (z. B. Person, Buch, Auto) in der Datenbank. Die Beziehungen zwischen Entitäten bilden die Zusammenhänge zwischen diesen Gegenständen ab (z. B. liest, fährt). 2.2.1. Normalformen Das Konzept der Normalisierung des Datenbankschemas wird angewendet, um in der Datenbank möglicherweise vorhandene Redundanzen und Inkonsistenzen aufzulösen, aber auch, um den Speicherplatz womöglich zu sparen. Die Normalisierung erfolgt durch Anwendung von so genannten Normalisierungsalgorithmen und versteht normalerweise Übertragung einiger Spalten aus einer Tabelle in eine neue Relation und Verknüpfung der neuen Tabelle mit der ursprünglichen. Nach einer erfolgreichen Normalisierung befindet sich die Datenbank in einer entsprechenden Normalform. Es gibt mehrere Normalformen, die heutzutage verwendet werden [AK06]. • Die erste Normalform (1NF) verlangt, dass alle Attribute nur Werte aus bestimmten atomaren Wertebereichen (Domänen) annehmen. Somit sind zusammengesetzte Domä- 6 2. Grundlagen nen wie z. B. Mengen oder Relationen innerhalb eines Attributes nicht zulässig. In anderen Worten wird es verlangt, dass die Attribute nicht weiter zerlegt werden können. Es gibt allerdings neuere Entwicklungen, die auf die erste Normalform verzichten. Die entsprechenden Modelle werden N F 2 - oder geschachtelte Modelle genannt und erlauben nicht nur mengenwertige sondern auch relationswertige Attribute. • Die zweite Normalform (2NF) ist eingehalten, wenn die erste Normalform vorliegt und jedes Nichtschlüssel-Attribut der Relation von jedem diese Relation identifizierenden Schlüsselkandidaten voll funktional abhängig ist. Eine Verletzung der zweiten Normalform führt zu Inkonsistenzen in der Datenbank. • Die dritte Normalform (3NF) verlangt, dass keine Nichtschlüssel-Attribute von einer Attributmenge abhängig sind, die keinen Schlüssel bildet. Durch die Verletzung der dritten Normalform kann z. B. ein Fakt in der Datenbank mehrmals gespeichert sein, d.h. eine Redundanz ist gegeben. Die Verletzungen der dritten Normalform können durch Anwendung vom so genannten Synthesealgorithmus aufgelöst werden. • Die Boyce-Codd Normalform (BCNF) ist eine Verschärfung von 3NF und stellt sicher, dass keine Informationseinheiten in der Datenbank mehrmals vorhanden sind. Ein Relationsschema R ist in der BCNF, wenn für jede funktionale Abhängigkeit α → β entweder β ⊆ α (die Abhängigkeit ist trivial) oder α ist Superschlüssel von R gilt. Die Zerlegung einer Relation in BCNF -Teilrelationen erfolgt durch Anwendung des Dekompositionsalgorithmus. • Die vierte Normalform (4NF) ist eine weitere Verschärfung von BCNF, die durch mehrwertige Abhängigkeiten verursachte Redundanzen ausschließt. Dies bedeutet, dass es keine voneinander unabhängige 1:n Beziehungen innerhalb einer Relation geben kann. • Eine Relation ist in der fünften Normalform (5NF), wenn sie sich nicht in weitere Relationen zerlegen lässt, ohne dass einige Informationen verloren gehen. In der Praxis wird normalerweise die dritte Normalform angestrebt. Zu bemerken ist, dass die 1NF und 2NF bei durchdachter Modellierung intuitiv eingehalten werden. 2.2.2. Regelkonzepte Ende der siebziger Jahre wurde die Funktionalität des relationalen Datenmodells um drei Regelkonzepte mit unterschiedlichen Zielsetzungen erweitert - deduktive, aktive und normative Regeln. • Deduktive Regeln dienen der deklarativen Spezifikation von Datenmengen. Sie beschreiben die Gesetze, nach welchen ableitbare Daten aus den Basisdaten hergeleitet werden müssen. In Datenbanken werden deduktive Regeln mit Hilfe von Sichtdefinitionen formuliert, wobei die daraus entstehenden Sichten virtuell oder materialisiert sein können. Bei jedem Aufruf einer virtuellen Sicht müssen die ableitbaren Daten er- 7 2. Grundlagen neut hergeleitet werden und werden nach dem Aufruf nicht dauerhaft gespeichert. Bei materialisierten Sichten werden die ableitbaren Daten in der Datenbasis persistent gespeichert und müssen daher nicht bei jedem Aufruf der Sicht erneut hergeleitet werden. Dafür müssen bei jeder Änderung an der Datenbasis die betroffenen materialisierten Sichten erneut aufgebaut werden. Für die Aktivierung von deduktiven Regeln ist die Inferenzkomponente des DBMS zuständig. • Aktive Regeln werden zur Definition von Systemreaktionen auf unterschiedliche Vorgänge im System benutzt. In Datenbanksystemen sind aktive Regeln meistens über das Triggerkonzept realisiert. Das Konzept lässt sich durch ECA-Regeln darstellen, die aus drei Komponenten bestehen: Ereignis (Event), Bedingung (Condition) und Aktion (Action). Wenn also ein Ereignis auftritt, wird die vorgeschriebene Bedingung überprüft und ggf. die festgelegte Aktion ausgelöst. • Normative Regeln werden zur Spezifikation von Konsistenzanforderungen an Basissowie ableitbare Daten benutzt. Diese Regeln werden in Datenbanksystemen durch Integritätsbedingungen realisiert, die unsinnige Zustände und Zustandsübergänge des Systems verhindern. Es wird zwischen statischen und dynamischen Integritätsbedingungen unterschieden. Durch statische Bedingungen werden Konsistenzanforderungen an die Datenbasis gestellt (z. B. Alter > 0). Dagegen zeichnen dynamische Integritätsbedingungen unzulässige Zustandsübergänge aus (z. B. Alter darf nicht kleiner werden). In dieser Arbeit werden für die Definitionen von Kenngrößen mit Hilfe des zu entwickelnden Werkzeugs ausschließlich deduktive Regeln benutzt. Bei der Implementierung der Datenbankanwendung, die gekoppelt mit der Benutzeroberfläche das Gesamtsystem bilden soll, werden allerdings auch normative Regeln benutzt, um z. B. Primär- und Fremdschlüssel der Datenbanktabellen festzulegen. 2.3. Anfragesprache SQL Strukturierte Anfragesprache SQL (Structured Query Language) ist eine Datenbanksprache, die zur Definition, Manipulation und Abfrage von Datensätzen benutzt wird. Syntaktisch hat SQL einen einfachen Aufbau und lehnt an die englische Sprache an3 . Der erste SQLStandard wurde 1986 von American National Standards Institute (ANSI ) verabschiedet und im Jahr 1989 von International Organisation for Standardization (ISO) ratifiziert. Die neuste Version von SQL entstand im Jahr 2008 und trägt den Namen SQL:2008. Die SQL-Syntax kann sich in verschiedenen Datenbanksystemen leicht unterscheiden. Die Unterschiede betreffen meistens einige Schlüsselwörter. Beispielsweise erfolgt die Auswahl einer gewissen Anzahl von Datensätzen aus der Ergebnismenge in Microsoft SQL Server (MSSQL-Syntax) durch Angabe des Schlüsselwortes TOP direkt nach dem SELECT -Schlüsselwort. 3 Der Name „SQL“ leitet sich von der Anfang 70er Jahre von IBM entworfenen Anfragesprache SEQUEL (Structured English Query Language) ab. 8 2. Grundlagen Dagegen wird dieselbe Funktionalität in MySQL durch Angabe des Schlüsselwortes LIMIT am Ende des Befehls erzielt. Darüber hinaus können sich die Quotierungen unterscheiden. Beispielsweise werden Datumswerte in MS Access durch Rauten (#) gekennzeichnet, wobei sie in meisten Datenbanksystemen analog zu Zeichenfolgen in Apostrophe eingeschlossen werden sollen. Genauer betrachtet umfasst SQL mehrere Datenbanksprachen. Einen Teil davon bildet Data Definition Language (DDL), die Erstellung von Datenbankobjekten (Tabellen, Sichten usw.) ermöglicht. Die eigentliche Datenabfrage erfolgt mit Hilfe von Data Manipulation Language (DML). Schließlich ermöglicht Data Control Language (DCL) die Verwaltung von Berechtigungen auf Datenbankobjekte. Zu DCL ist es anzumerken, dass die Erteilung von Rechten auf ein Datenbankobjekt (Basistabelle, Sicht, gespeicherte Prozedur usw.) an einen Datenbankbenutzer durch Ausführung einer GRANT-Anweisung erfolgt. Die vorhin erteilten Rechte können durch einen REVOKE-Befehl wieder entnommen werden. Die erste Version der Anwendung zum Überwachen von Flugkenngrößen sieht keine Benutzerverwaltung vor. Es sei allerdings bemerkt, dass eine solche Erweiterung der Anwendung durchaus möglich ist, damit ist der Einsatz von DCL im Rahmen der genannten Anwendung ebenso möglich. Die Teilsprachen DDL und DML der Gesamtsprache SQL werden in folgenden Abschnitten detailliert erläutert. Dabei wird hauptsächlich die MSSQL-Syntax benutzt. 2.3.1. Data Definition Language (DDL) Die Datendefinitionssprache DDL wird in Datenbanksystemen verwendet, um Datenstrukturen zu beschreiben, zu ändern sowie vorhandene Datenbankobjekte zu löschen. Ein üblicher Befehl dieser Sprache fängt mit den Schlüsselwörtern CREATE, ALTER oder DROP an. Daraufhin folgt der Name des betreffenden Datenbankobjektes und ggf. die Beschreibung der Struktur bzw. Änderungen an der Struktur. Eine Basistabelle wird durch Anweisung CREATE TABLE erstellt. Im Listing 2.1 wird am Beispiel der Tabelle Import der zu entwickelnden Datenbankanwendung des Flugüberwachungswerkzeugs die Verwendung dieses Befehls in der MSSQL-Syntax dargestellt. Listing 2.1: Der SQL-Erstellungsbefehl der Tabelle „Import“ 1 2 3 4 5 6 7 8 CREATE TABLE [Import]( [ID] [ bigint ] IDENTITY(1,1) NOT NULL, [DateTime] [datetime] NOT NULL, [AutomaticImport] [bit] NOT NULL, [AutomaticImportInterval] [int] NULL, [ImportableObjectType] [nvarchar](255) NOT NULL, CONSTRAINT [PKImport] PRIMARY KEY ([ID]) ) 9 2. Grundlagen Nach dem Namen des betreffenden Datenbankobjektes folgt die Beschreibung der Tabellenattribute und Einschränkungen. Die Attributenbeschreibungen beginnen mit dem Namen des Attributes. Darauf folgt der Datentyp und zusätzliche Spezifikationen. Die Spezifikation NOT NULL gibt an, dass der Attributenwert nicht leer sein darf. Durch IDENTITY (1, 1) wird in der benutzen SQL-Syntax die Identitätseigenschaft gekennzeichnet. Für das Datenbankfeld ID wird damit beim Einfügen einer neuen Zeile ein ganzzahliger Wert vom DBMS automatisch vergeben. Die Zahlen in Klammern bedeuten, dass diese Identitätszahlen mit 1 beginnen müssen, und der jeweils nächste Wert um 1 größer sein muss als der vorherige. Durch Spaltenspezifikationen können zusätzlich folgende Eigenschaften definiert werden: • Festlegung des Standardwertes durch Angabe des Schlüsselwortes DEFAULT; • Festlegung der Eindeutigkeit der Werte der betreffenden Spalte durch Angabe des Schlüsselwortes UNIQUE; • Definition von Wertebereichseinschränkungen durch Angabe des Schlüsselwortes CHECK. Die Spezifikation von Tabelleneinschränkungen erfolgt durch Angabe des Schlüsselwortes CONSTRAINT. Analog zu den Attributenspezifikationen folgt darauf der Name der Einschränkung und ihre Beschreibung. Die Spezifikation CONSTRAINT [PKImport] PRIMARY KEY ([ID]) erstellt eine Einschränkung mit dem Namen PKImport, die das Attribut ID der Basistabelle Import zum Primärschlüssel deklariert. Die Änderungen an einer bestehenden Tabelle können mit Hilfe einer ALTER TABLE Anweisung vorgenommen werden. Zu den möglichen Änderungen an einer Tabelle gehören folgende drei Aktionen: • Hinzufügen einer neuen Spalte oder Einschränkung durch Angabe der Schlüsselwörter ADD bzw. ADD CONSTRAINT; • Änderung an der Spezifikation einer bestehenden Spalte durch Angabe der Schlüsselwörter ALTER COLUMN; • Löschung einer bestehenden Spalte oder Einschränkung durch Angabe der Schlüsselwörter DROP COLUMN bzw. DROP CONSTRAINT. Ein Beispiel der Änderung der Spezifikation einer bestehenden Tabelle ist im folgenden Listing 2.2 gegeben. Listing 2.2: Der SQL-Erstellungsbefehl des Fremdschlüssels für Tabelle „Flight“ 1 2 3 4 5 ALTER TABLE [Flight] ADD CONSTRAINT [FK_Flight_Import] FOREIGN KEY([ImportID]) REFERENCES [Import] ([ID]) ON UPDATE CASCADE ON DELETE CASCADE 10 2. Grundlagen Durch die gegebene Änderung wird zur Spezifikation der Tabelle Flight eine Einschränkung hinzugefügt, die die Spalte ImportID zu einem Fremdschlüssel mit dem Verweis auf die Primärschlüssel-Spalte ID der Tabelle Import deklariert. Zu einer Fremdschlüssel-Deklaration gehört oft die Angabe der erforderlichen Aktionen, die das DBMS vornehmen soll, wenn ein Datensatz aus der Primärschlüssel-Tabelle gelöscht wird (ON DELETE) oder sich der Wert in der Primärschlüssel-Spalte ändert (ON UPDATE). Zu den möglichen Optionen gehören dabei folgende Aktionen: • Änderung der referenzierenden Fremdschlüssel-Werte bzw. Löschung der referenzierenden Datensätzen durch Angabe des Schlüsselwortes CASCADE; • Keine Aktion durch Angabe der Schlüsselwörter NO ACTION; • Ab der Version 9.0 (SQL Server 2005) werden zusätzliche Optionen SET DEFAULT und SET NULL unterstützt, durch Angabe deren der referenzierte FremdschlüsselWert auf den Standardwert bzw. auf NULL-Wert gesetzt wird. Mit Hilfe des Befehls DROP TABLE und der Angabe des Tabellennamens werden bestehende Basistabellen aus der Datenbank gelöscht. Die CREATE - und DROP -Befehle werden ebenso zur Erstellung der Sicht-, Funktions-, Prozedur-, Trigger- und Indexdefinitionen benutzt. Indizes werden für Spalten erstellt, um durch das Belegen des zusätzlichen Speicherplatzes die Suche in und die Sortierung nach dieser Spalte zu beschleunigen. Für Primär- und Fremdschlüssel werden normalerweise Indizes automatisch vom DBMS angelegt. Die Definitionskopf und -rumpf werden bei der Erstellung von Funktionen und Prozeduren durch das Schlüsselwort AS getrennt. Die Erstellung einer Sicht erfolgt durch Ausführung eines Befehls, der auf folgende Art und Weise aufgebaut ist: CREATE VIEW ViewName AS ... Nach dem Schlüsselwort AS folgt die Herleitung der ableitbaren Daten aus der Datenbasis, die mit Hilfe von DML definiert wird. Ähnlich zu den Sichtdefinitionen werden Prozedur-, Funktions- und Triggerdeklarationen aufgebaut. Hierbei werden lediglich anstelle des Schlüsselwortes VIEW die Schlüsselwörter PROCEDURE, FUNCTION bzw. TRIGGER benutzt. Zwischen dem Prozedurnamen und dem Schlüsselwort AS wird der Prozedurkopf angegeben, der aus Eingabeparametern besteht. Bei der Definition von Funktionen wird der Funktionskopf zusätzlich um das Schlüsselwort RETURNS und den geeigneten Rückgabetyp erweitert. 11 2. Grundlagen 2.3.2. Data Manipulation Language (DML) Data Manipulation Language ist eine Teilsprache von SQL, die es ermöglicht, auf die Datenbasis zuzugreifen und Datensätze zu verwalten. Zu den üblichen Befehlen von DML gehören folgende Anweisungen: • Der SELECT-Befehl wird benutzt, um die Daten aus einer oder mehreren Datenbanktabellen oder -Sichten auszulesen und auszugeben. • Durch Ausführung einer INSERT-Anweisung werden neue Daten in die Datenbasis eingefügt. • Der UPDATE-Befehl ermöglicht die gleichzeitige Änderung eines oder mehrerer Attributwerte einer Menge von betreffenden Datensätzen. • Mit Hilfe einer DELETE-Anweisung können ein oder mehrere Datensätze aus der Datenbasis gelöscht werden. Die DML-Anweisungen bestehen aus einer oder mehreren Klauseln. Zusätzlich zu den oben genannten Schlüsselwörtern gehören folgende Klauseln zu DML: • Die INTO-Klausel wird innerhalb einer INSERT - oder SELECT -Anweisung benutzt, um das Datenbankobjekt festzulegen, in welches die betreffenden Datensätze eingefügt werden sollen. • Die FROM-Klausel wird innerhalb einer SELECT - oder DELETE -Anweisung benutzt, um das Datenbankobjekt festzulegen, aus dem die betreffenden Datensätze ausgewählt bzw. gelöscht werden sollen. • Die WHERE-Klausel wird innerhalb einer SELECT -, UPDATE - oder DELETE -Anweisung benutzt, um die Filterbedingung festzulegen, nach der die betreffenden Datensätze aus der Gesamtmenge ausgesucht werden. • Durch Angabe der TOP-Klausel legt man fest, wie viele Datensätze aus der Gesamtmenge durch die aktuelle Anweisung betroffen werden. • Die GROUP BY-Klausel gruppiert Datensätze nach den gegebenen Attributen zur Durchführung einer oder mehrerer Aggregationsfunktionen. • Die ORDER BY-Klausel führt eine Sortierung von Datensätzen nach einer gegebenen Liste von Attributen durch. • Die DISTINCT-Klausel wird verwendet, wenn Duplikate (mehrfach vorkommende Tupel mit denselben Attributenwerten) aus der Ergebnismenge aussortiert werden müssen. Die Anweisung INSERT INTO wird benutzt, um neue Daten in eine bestehende Tabelle einzufügen. Nach den Schlüsselwörtern folgt der Name der bestehenden Basistabelle und die Aufzählung der betreffenden Spalten. Danach sind zwei Varianten möglich: entweder folgt das Schlüsselwort VALUES und die Aufzählung der neuen Werte, die in die genannte Spalten 12 2. Grundlagen eingefügt werden sollen, oder eine SELECT -Anweisung. Dabei muss die Reihenfolge der angegebenen Werten genau der der genannten Attribute entsprechen. Als Beispiel betrachte man folgende Anweisungen. Listing 2.3: SQL-Anweisung zum Einfügen einer neuen Zeile in die Tabelle „Import“ 1 2 INSERT INTO Import ([DateTime], [AutomaticImport], [ImportableObjectType]) VALUES ({fn NOW()}, 0, ’FlightMonitor.ClassLibrary.Flight’); Die Anweisung fügt in die Tabelle Import einen neuen Eintrag ein. Der Ausdruck { fn NOW() } stellt einen Aufruf der internen Funktion dar, die das aktuelle Datum mit der Uhrzeit zurückgibt. Listing 2.4: SQL-Anweisung zum Einfügen des Ergebnisses eines SELECT-Ausdrucks in die Tabelle „Import“ 1 2 3 4 INSERT INTO Import ([DateTime], [AutomaticImport], [AutomaticImportInterval], [ ImportableObjectType]) SELECT [DateTime], [AutomaticImport], [AutomaticImportInterval], [ImportableObjectType] FROM Import WHERE Import.ID = 1; Die angegebene Anweisung fügt in die Tabelle Import Kopien von bestehenden Zeilen mit ID 1. Nach der Spezifikation der Tabelle Import kann die SELECT -Anweisung höchstens eine Zeile zurückgeben. Eine DELETE-Anweisung wird verwendet, um Datensätze aus einer bestehenden Tabelle zu löschen. Dabei kann in der WHERE -Klausel ein Filter angegeben werden, der bestimmt, welche Datensätze tatsächlich gelöscht werden. Listing 2.5: SQL-Anweisung zum Löschen von Datensätzen aus der Tabelle „Import“ 1 2 3 DELETE TOP (10) FROM Import WHERE DATEDIFF(day, [DateTime], {fn NOW()}) > 10; Der gegebene Befehl löscht die ersten 10 Datensätze, die dem angegebenen Filter entsprechen. In der WHERE -Klausel wird die interne Funktion DATEDIFF benutzt, die die Anzahl von angegebenen Intervallen zurückgibt, die zwischen den gegebenen Datumswerten liegen. Im gegebenen Fall sind es Datensätze, die älter als 10 Tage sind. Anweisungen vom Typ SELECT FROM werden benutzt, um die Daten aus der Datenbasis herzuleiten. Zwischen den beiden Schlüsselwörtern muss die Auflistung der auszugebenden Attribute angegeben werden. Wenn alle Attribute der Ergebnismenge ausgegeben werden müssen, verwendet man an dieser Stelle eine Wildcard (*). Die Herleitung von Daten aus mehreren Tabellen erfolgt durch Verknüpfung von Tabellen. Es sind folgende Arten von Verknüpfungen möglich: 13 2. Grundlagen • Durch INNER JOIN werden Tabellen derart verknüpft, dass die Ergebnismenge ausschließlich Tupel enthält, die in beiden Tabellen vorhanden sind. • Die durch Anwendung von LEFT / RIGHT OUTER JOIN resultierende Ergebnismenge enthält Tupel für jede Zeile, die in mindestens einer (linker oder rechter) der verknüpften Tabellen vorhanden ist. Enthält die jeweils andere Tabelle keinen entsprechenden Datensatz, so erhält das resultierende Tupel NULL-Werte in allen Feldern, die den Attributen dieser Tabelle entsprechen. • Ein CROSS JOIN führt eine Mengenmultiplikation der Datensätze durch. Die Ergebnismenge enthält dadurch einen Datensatz für jede Kombination von Zeilen aus den beiden Tabellen. Im Listing 2.6 findet man einen SQL-Skript, der die Verknüpfung von Tabellen Flight und Import durchführt. Die Ergebnismenge enthält damit für jede Zeile der Tabelle Flight einen Datensatz, der mit den Attributen der Tabelle Import angereichert ist. Listing 2.6: SQL-Anweisung zum Verknüpfen von Tabellen „Flight“ und „Import“ 1 2 3 4 SELECT ∗ FROM Flight INNER JOIN Import ON Flight .ImportID = Import.ID; Es sei bemerkt, dass dasselbe Ergebnis auch ohne explizite Angabe des Schlüsselwortes JOIN erzielbar ist (siehe Listing 2.7). Listing 2.7: SQL-Anweisung zum Verknüpfen von Tabellen „Flight“ und „Import“ ohne das Schlüsselwort „JOIN“ 1 2 3 SELECT ∗ FROM Flight, Import WHERE Flight.ImportID = Import.ID; Aggregationsfunktionen werden benutzt, um Gruppenergebnisse wie Anzahl, Summe, Maximum, Minimum oder den durchschnittlichen Wert zu bestimmen. Dabei kann die Ergebnismenge nur Attribute enthalten, nach welchen die Gruppierung erfolgt. Listing 2.8 demonstriert die Verwendung der genannten Aggregationsfunktionen. Listing 2.8: Bestimmung der Gruppenergebnisse zu jedem Import 1 2 3 4 5 6 7 SELECT ImportID, COUNT(ID) AS Amount, MAX(Speed) AS MaxSpeed, MIN(Speed) AS MinSpeed, AVG(Speed) AS AvgSpeed, SUM(Speed) AS SumSpeed FROM Flight GROUP BY ImportID 14 2. Grundlagen Die Anweisung SELECT INTO wird benutzt, um materialisierte Sichten zu erstellen. Durch Ausführung des Befehls werden die ableitbaren Daten im Grunde aus der Datenbasis hergeleitet und in einer neu angelegten Tabelle gespeichert. Aktualisierung von Attributenwerten einer Menge von Datensätzen erfolgt durch Ausführung einer UPDATE-Anweisung. Im Listing 2.9 findet man einen SQL-Befehl, der die Syntax einer UPDATE -Anweisung darstellt. Listing 2.9: Verschiebung des Datumswertes des Imports mit ID 1 um einen Tag nach vorne 1 2 3 UPDATE Import SET DateTime = DATEADD(day, 1, DateTime) WHERE ID = 1; Im Rahmen dieser Arbeit werden hauptsächlich SELECT -Anweisungen zur Herleitung von Flugkenngrößen aus der Datenbasis benötigt. Das Anlegen, Bearbeiten und Löschen von Basisdaten erfolgen durch die Benutzeroberfläche und müssen nicht durch Benutzer mittels SQL durchgeführt werden. 2.4. Datenstrom-Management und kontinuierliche Anfragen Eine Datenbank bildet einen Teil der realen Welt ab, der nur kontrolliert aktualisiert werden kann. In der Realität gibt es aber Datenquellen, die einen unendlichen Datenfluss liefern, d.h. ständig oder in unregelmäßigen Abständen neue Datensätze zur Verfügung stellen. Beispielsweise finden solche Datenquellen Anwendung im Verkehrsmanagement, Sensordatenverarbeitung, Börsenticker usw. Solche Daten werden Datenströme (Data Streams) genannt. Für die Verarbeitung von Anfragen, die auf Datenströmen angewendet werden sollen, gibt es prinzipiell anderen Ansatz als der eines DBMS. Systeme, die diesen Ansatz realisieren, werden Datenstromverwaltungssysteme (DSMS) genannt. Die Untersuchungen im Bereich Datenstromverarbeitung gehen immer rasanter voran, geprägt insbesondere durch die praktische Relevanz des Themas. Das Ziel eines DSMS ist es eine Alternative zur persistenten Speicherung und Verarbeitung innerhalb eines DBMS zu verschaffen. Angestrebt ist dabei die datengetriebene Verarbeitung von Datenströmen und adaptives Verhalten des Systems hinsichtlich der aktuellen Datenankunftsraten. Man spricht von einer langen Lebensdauer bei den Anfragen an den Datenströmen und nennt die Anfragen selbst kontinuierlich, da sich die Ergebnisse der Auswertung bei Ankunft von neuen Daten ändern können. Dies resultiert im Bedarf, andere Optimierungsansätze für Anfragen als die von DBMS zu entwerfen. Dabei verzichtet man auf die übliche Beschreibung von Anfragen mit Hilfe von Operatorbäumen und beschreibt Datenstromanfragen mittels Graphen von Operatoren. Diese Art der Beschreibung ermöglicht unter anderem Wiederverwendung einzelner Teilgraphen des Operatorgraphs. 15 2. Grundlagen Ein allgemeines Problem aller DSMS stellt die Anpassung des Systems an die Anforderungen einer konkreten Applikation dar. Beispielsweise gibt es immer einen Trade-off zwischen Schnelligkeit und Speicherverbrauch, sowie zwischen Speicherverbrauch und Qualität der approximativen Auswertung einer Anfrage, die sich als eine Möglichkeit der Berechnung der Ergebnismenge bei kontinuierlichen Anfragen anbietet. Die Realisierung von kontinuierlichen Anfragen ist mit Hilfe der üblichen Mechanismen eines DBMS nicht möglich. Einerseits ist ein Datenstrom potentiell unbeschränkt, somit ist die persistente Speicherung der Gesamtmenge der Daten bei einem endlichen Speicherplatz nicht möglich. Andererseits steigt der Aufwand der Datenverarbeitung und Anfragenauswertung für größere Mengen von Basisdaten, daher ist die persistente Speicherung von Datenströmen nicht wünschenswert. Dies bedeutet, dass jeder Datensatz bereits bei Ankunft verarbeitet werden soll, daher lassen sich auch die üblichen Operatorimplementierungen eines DBMS nicht ohne Weiteres in ein DSMS übernehmen. Zu einer der effizientesten Techniken bei Verwaltung von Datenströmen haben sich so genannte Fensteranfragen etabliert. Dies hat mehrere Gründe. • Durch Ausführung der Operatoren auf einer endlichen Teilmenge der unendlichen Gesamtmenge von Daten kann das blockierende Verhalten der Operatoren aufgelöst werden. In anderen Worten ist es möglich, eine Ausgabe für Operatoren zu produzieren, die die Gesamtmenge von Daten als Eingabe bekommen müssen. • Die Speicheranforderungen von Operatoren werden beschränkt. • In meisten Datenströmen sind neuere Datensätze relevanter als die älteren. Es sei bemerkt, dass wenn die im letzten Punkt beschriebene Situation tatsächlich vorliegt, können ältere Datensätze, die einen geringen Einfluss auf das Ergebnis einer Anfrage haben, aus dem System gelöscht werden. Dies optimiert die Geschwindigkeit der Anfragenauswertung und löst das blockierende Verhalten einiger Operatoren auf, da diese immer auf einer endlichen Datenmenge arbeiten müssen. Bei Fensteranfragen spielt die Ankunftszeit des jeweiligen Datensatzes entscheidende Rolle, da diese den Beginn des Gültigkeitsintervalls des Datensatzes angibt. Daher soll jeder Datensatz im allgemeinen Fall einen Zeitpunkt zugeordnet bekommen. Beim Vorhandensein eines Zeitpunktes unter den Merkmalen des Datensatzes kann dieser Wert als Anfang des Gültigkeitsintervalls übernommen werden. Die am weitesten verbreiteten Strategien bei Fensteranfragen sind gleitende und feste Fenster. • Bei gleitenden Fenstern (sliding windows) erhalten alle Datensätze die gleiche Gültigkeitsdauer D. Damit sind zu einem konkreten Zeitpunkt nur die Datensätze gültig, die maximal D Zeiteinheiten zuvor gültig wurden. 16 2. Grundlagen • Bei festen Fenstern (fixed windows) wird die Zeitachse in Abschnitte gleicher Länge unterteilt. Jeder Datensatz, dessen Anfangszeitpunkt innerhalb eines Abschnittes liegt, bekommt den Endzeitpunkt des Abschnittes als Gültigkeitsende zugeteilt. Zur Beschreibung des Ausführungsplans in DSMS wird erweiterte relationale Algebra benutzt. Die Formulierung von Anfragen durch Benutzer kann mit Hilfe einer beliebigen deskriptiven Anfragesprache erfolgen. Bisher konnte sich für die Definition von kontinuierlichen Anfragen keine Sprache etablieren. Üblicherweise wird hierfür SQL benutzt. Manche Projektgruppen entwickeln ihre eigene Anfragesprachen wie z. B. CQL (Continuous Query Language) [The03], die aber meistens an die SQL-Syntax als Basis anlehnen. Zu den in der jeweiligen Sprache formulierten Anfragen werden dann logische Anfragepläne der erweiterten relationalen Algebra generiert. Im Grunde verwaltet ein DSMS eine Menge von Sammlungen von Datensätzen für unterschiedliche Anfragen, die im System verwaltet werden. Diese Sammlungen werden Snapshots genannt. Beim Eintreffen von neuen Datensätzen werden diese verarbeitet und die entsprechende Snapshots erweitert. Neben dem Einfügen und Anfragen von Daten wird noch die Fähigkeit zur Reorganisation der Snapshots benötigt. Während einer solchen Reorganisation werden Elemente der Snapshots entfernt, die keinen Einfluss auf das Ergebnis der geeigneten Anfrage haben können. Es sei bemerkt, dass sich das Gesamtkonzept von DSMS nicht im Rahmen dieser Arbeit umsetzen lässt, da es unter anderem angestrebt ist, Herleitung statistischer Informationen aus der Gesamtmenge zu ermöglichen. In diesem Fall sind alle historischen Daten relevant, somit können ältere Datensätze nicht gelöscht werden. Verwaltung von Snapshots zu jeder der potenziell beliebig vielen mit Hilfe des Werkzeugs erstellten Anfragen ist wegen des enormen Anspruchs auf den Speicherplatz nicht möglich. 17 3. Organisation der zivilen Luftfahrt 3. Organisation der zivilen Luftfahrt Einer der wichtigsten Zwecke der aktuellen Arbeit ist die Untersuchung, in wiefern die Anfragesprache SQL zur Definition und Auswertung von Flugkenngrößen benutzt werden kann. Die verfügbaren Datenquellen, die beim Testen des zu entwickelnden Flugüberwachungssystems benutzt werden, werden im letzten Abschnitt dieses Kapitels vorgestellt. Diese liefern gewisse Informationen zu den aktuellen Flügen sowie anderen Objekten, die im Zusammenhang mit den Fluginformationen interessante Konstellationen darstellen können. Bevor man aber die Daten betrachtet, die von diesen Quellen zur Verfügung gestellt werden, ist es durchaus sinnvoll, sich mit den wichtigsten Begriffen der Luftfahrt vertraut zu machen. Dieses Wissen ist wichtig, um die Bedeutung der verfügbaren Größen zu verstehen, um daraus eventuell weitere interessante Fakten ermitteln zu können. In diesem Kapitel werden wesentliche Begriffe der Organisation der zivilen Luftfahrt hauptsächlich mit Anlehnung an Informationen aus [Men93] und [Mar00] erläutert. 3.1. Luftraum Die Menge der Verkehrswege, die zur Verbindung aller möglichen Start- und Zielorten der Luftfahrzeuge dienen, wird im Luftfahrtjargon Luftraum4 genannt. Damit sich mehrere Flugzeuge gleichzeitig zu ihren Zielorten bewegen können, steht der Luftraum unter ständiger Beobachtung. Dies bedeutet, dass sich in der Luft befindende Luftfahrzeuge regelmäßig Daten zu ihren wichtigsten Merkmalen an die jeweilige Bodenstation schicken müssen. Zu diesen Merkmalen gehören Kennung, aktuelle Position, Höhe und Geschwindigkeit sowie Richtung bzw. Peilung5 - der Winkel zwischen der Längsachse des Luftfahrzeugs und der Verbindungslinie zwischen dem Luftfahrzeug und Bodenstation. Diese Informationen werden vom zuständigen Überwachungssystem bearbeitet. Im Falle einer kritischen Situation werden Piloten der betroffenen Flugzeuge über die Lage informiert und mit angemessenen Anweisungen ausgestattet. 3.1.1. Organisation des Luftraumes Für die Gestaltung des globalen Luftraumes ist die Internationale Zivilluftfahrtorganisation (International Civil Aviation Organization, ICAO) zuständig, deren Aufgaben 4 5 [Men93, S. 47] [Men93, S. 205] 18 3. Organisation der zivilen Luftfahrt durch das Abkommen über die Internationale Zivilluftfahrt von Chicago in 1944 definiert sind. Zu diesen Aufgaben gehören Gewährleistung des sicheren Wachstums der internationalen Zivilluftfahrt, Entwicklung von Luftstraßen, Flughäfen und Luftfahrteinrichtungen und Förderung der Flugsicherheit6 . 3.1.2. Flächensystem Die geographische Position eines Luftfahrzeuges wird üblicherweise durch drei Koordinaten Länge, Breite und Höhe - dargestellt. Über die Bemessung von Länge und Breite wird weiter im Abschnitt 3.1.6 gesprochen. Im aktuellen Abschnitt wird es erläutert, wie die Bemessung der Höhe eines Flugzeuges durchgeführt wird. Um die Höhenangaben unabhängig vom Relief des Bodens zu halten, wird diese durch den Luftdruck repräsentiert. Dafür wird der Luftraum in Bereiche des gleichen Luftdrucks unterteilt, die Flugflächen7 (Flight Levels, FL) genannt werden. Die Angabe der aktuellen Flugfläche bezeichnet nun die Höhe in Fuß über der von ICAO definierten Standardisobare von 1013,25 hPa, die auch Normatmosphäre genannt wird. Beispielsweise bedeutet die Höhenangabe FL60, dass sich das Flugzeug auf der Höhe von 6000 Fuß über der Standardisobare befindet. Die Umstellung des Höhenmessers auf Flugflächen erfolgt beim Steigflug erst nach dem Erreichen der Übergangshöhe (Transition Altitude, TA) von entweder 5000 Fuß über dem Meeresspiegel oder 2000 Fuß über dem Boden des Flugplatzes, je nach dem was höher ist. Beim Sinkflug wird der Höhenmesser nach dem erreichen von FL0 (Transition Level, TRL) wieder auf relative Höhe über dem Flugplatz umgestellt. Dieses Verfahren ist wegen den Abweichungen des realen Luftdrucks vom idealisierten Druckverlauf der Normatmosphäre für die genaue Messung der Höhe nicht geeignet. Da aber alle Flugzeuge die gleichen Messfehler aufweisen, kann jedem Luftfahrzeug die geeignete Flugfläche eindeutig zugeordnet und somit die eventuellen Kollisionen im Luftraum vermieden werden. 3.1.3. Luftstraßen Die Flugbahn eines Luftfahrzeugs wird nicht nach Belieben gewählt, sondern muss über die vorher definierten Bereiche des Luftraumes verlaufen. Jeder dieser Bereiche hat die Form eines Großkreissegments und befindet sich in der Reichweite einer Funknavigationsanlage. Die Aneinanderstaffelungen dieser Segmente ergeben Luftstraßen (auch Luftkorridore, Routenführungen8 , Airways genannt). Diese Korridore haben üblicherweise eine Breite von bis zu 18 Kilometer. Ihre Bezeichnungen bestehen aus einer Farbe und einer Zahl, z. B. „Amber One“ (A1 ) oder „Blue Three“ (B3 ) [Fra02]. [Men93, S. 7] [Men93, S. 51] 8 [Men93, S. 59] 6 7 19 3. Organisation der zivilen Luftfahrt Neben den aus Luftstraßen bestehenden Routennetzen existieren auch Streckenführungen in der Nähe der Flughafengebiete: Standard Arrival Routes (STAR), die vom Routennetz zu den Flugplätzen führen, und Standard Instrument Departure Routes (SID), die von den Flugplätzen zum Routennetz führen9 . Die Aufgabe der Routenführung von Flugzeugen über das Routennetz übernimmt das Flight Management System (FMS). Hierfür muss der Co-Pilot vor dem Start der Maschine Daten des bevorstehenden Fluges in das System per Tastatur eingeben10 . 3.1.4. Rufzeichen Alle Objekte, die im Rahmen des Luftverkehrs miteinander kommunizieren, besitzen ihre eigene Rufzeichen (Callsigns). Diese Kenner werden jedem Objekt von ICAO eindeutig zugeordnet und müssen beim Kommunizieren zur Identifikation des jeweiligen Objektes angegeben werden. ICAO-Kenner der Flugplätze bestehen aus vier Buchstaben: der erste Buchstabe bezeichnet die Zone, der zweite - das jeweilige Land, und die letzten zwei bestimmen eindeutig den Flugplatz innerhalb des Landes. Beispielsweise ist EDDL das ICAO-Rufzeichen des internationalen Flughafens von Düsseldorf11 . In Fluggastinformationssystemen werden allerdings meistens IATA-Codes verwendet, die von der International Air Transport Association vergeben werden. Das IATA-Kennzeichen des Düsseldorfer Flughafens ist DUS. Als an einer solchen Kommunikation teilnehmende Seite besitzen auch einzelne Flüge ihre ICAO- und IATA-Kennzeichen. ICAO-Kenner der Flüge bestehen normalerweise aus drei Buchstaben gefolgt von zwei bis vier alphanumerischen Zeichen. Die ersten Buchstaben der ICAO-Kennzeichen der Flüge betrieben von Lufthansa AG sind DLH. Die ersten zwei Buchstaben des IATA-Kenners von Lufthansa sind LH. 3.1.5. Flugplätze und Flughäfen Die Quellen und Senken aller Verkehrswege, zwischen denen Luftverkehr stattfindet, werden Flugplätze genannt. Innerhalb der Menge aller Flugplätze unterscheidet man zwischen Landeplätzen und Flughäfen. Die letzteren bedürfen nach Art des vorgesehenen Flugbetriebs einer Sicherung durch einen Bauschutzbereich nach §12 des Luftverkehrs-Gesetzes und werden genehmigt als Verkehrs- und Sonderflughäfen12 . Für die Flugsicherung an den Flugplätzen sind Lotsen zuständig, die den Verkehr mit Hilfe eines Radarsystems überwachen. Die Hauptaufgabe der Fluglotsen ist die Koordination des Flugverkehrs an den Start- und Landebahnen, die durch Kommunikation mit den Piloten er[Men93, S. 59] [Mar00, S. 19] 11 [Mar00, S. 20] 12 [Men93, S. 73] 9 10 20 3. Organisation der zivilen Luftfahrt zielt wird. Dabei werden zusätzlich zur Verfügbarkeit der jeweiligen Landebahn auch andere technische Sicherheitsmaßnahmen eingehalten. Beispielsweise müssen die Lotsen kontrollieren, dass eine weitere Maschine erst dann ihre Landung aufnimmt, wenn sich die Wirbelschleppen (gegenseitige Luftwirbel), die das vorhin gelandete Flugzeug hinterlassen hat, aufgelöst haben. Durch solche Sicherheitsmaßnahmen werden Start- und Landefrequenzen geregelt und demzufolge die Pünktlichkeit im Linienverkehr gefördert [WIK09]. 3.1.6. Ortungssysteme Zur Feststellung der aktuellen Position eines Luftfahrzeuges (oder allgemein eines Punktes) werden so genannte Ortungssysteme eingesetzt. Diese können je nach Art absolute oder relative Positionen liefern. Während in der Nähe der Flugplätze relative Positionen als besser angebracht erscheinen, sind absolute Positionen in die globale Überwachung des Luftverkehrs leichter integrierbar. Auf dem Konzept von geographischen Positionen beruhen Geoinformationssysteme (GIS), die den Raum mit Hilfe von zwei Dimensionen - Breite (Latitude) und Länge (Longitude) organisieren und indizieren13 . Die allgemeine Idee solcher GIS ist, geographische Positionen absolut zu orten. Kombiniert mit einer Karte ermöglicht ein GIS die Feststellung, wo sich ein Punkt relativ zu bekannten geographischen Positionen befindet, was für Menschen intuitiv ist. Das am meisten benutzte Referenzsystem, das auf dem neusten Stand des Wissens über die genaue Positionen der Mitte und der Pole der Erdkugel sowie über die Form der Erde basieren, ist das geodätische Referenzsystem WGS84 (World Geodetic System 1984)14 . Dieses System wird als Grundlage für Positionsbestimmung mittels globalen Ortungssystems (Global Positioning System, GPS) benutzt. GPS, ursprünglich NAVSTAR (NAVigation System with Time And Ranging), ist ein Navigationssystem, das im Jahr 1993 in Betrieb genommen wurde und später in 1995 die volle Funktionsbereitschaft erreicht hat [WIK09]. GPS besteht aus drei wesentlichen Teilen: Weltraumsegment, Benutzersegment und Kontrollsegment [Zog06]: • Das Weltraumsegment besteht zurzeit aus 29 Satelliten, die auf sechs verschiedenen Bahnen um die Erde kreisen. Die Satelliten sind so verteilt, dass von jedem Punkt der Erdoberfläche aus ständig mindestens vier Satelliten sichtbar sind. Bei Anforderung sendet jeder Satellit ein Signal ans Benutzersegment. • Das Kontrollsegment besteht aus einem Hauptquartier, der sich im US-Staat Colorado befindet, fünf mit Atomuhren ausgestatteten Stationen, die in der nähe des Äquators verteilt sind, und drei Kontrollstationen, die Informationen an die Satelliten übermitteln. Die Aufgaben des Kontrollsegments sind: Beobachtung der Satellitenbewegun13 14 [Ken02, S. 2] [Ken02, S. 12] 21 3. Organisation der zivilen Luftfahrt gen, Überwachung der Satellitenuhren, Synchronisierung der Satelliten, Übermitteln der Bahndaten, Übermittlung der Informationen über technischen Zustand der Satelliten, Uhrenfehler usw. • Das Benutzersegment ist für den Empfang und Synchronisierung der Satellitensignale sowie Umrechnung dieser in eine geographische Position zuständig. Um die Position genau ermitteln zu können, sind Signale von vier verschiedenen Satelliten benötigt. Die geographische Position wird aus der für Ausbreitung der Satellitensignale benötigten Zeit errechnet. Die Bestimmung der Positionen mittels GPS ist natürlicherweise mit gewissen Messfehlern verbunden. Allerdings wenn die Anzahl der sichtbaren Satelliten ausreichend ist, kann man davon ausgehen, dass die von GPS gelieferten Positionen 2-5 Meter von den tatsächlichen Positionen abweichen können [Ken02]. Eine Alternative zu GPS ist das russische Navigationssystem GLONASS (GLObal NAvigation Satellite System). Das Projekt begann im Jahr 1972, der Vollausbau wurde 1996 erreicht. Das Funktionsprinzip ähnelt sich dem von GPS mit dem Unterschied, dass die Signale von Satelliten auf verschiedenen Frequenzen verschickt werden. Damit hat es einen besseren Schutz gegen Manipulation (wie z. B. GPS-Jammer). Leider besteht das System im Moment aus nur 20 Satelliten, was für die volle Funktionsbereitschaft nicht ausreichend ist. Für das Jahr 2010 ist ein weiterer Ausbau des Systems bis auf 30 Satelliten geplant. Auch die EU plant den Bau eines ähnlichen Systems Galileo, das ab dem Jahr 2013 betriebsbereit sein soll [WIK09]. Es gibt allerdings mehrere Gründe, aus welchen die Bemessung von geographischen Positionen mittels Länge und Breite nicht allzu praktisch erscheint. Einerseits ist die Berechnung der Distanz zwischen zwei Punkten der Erdoberfläche gegeben durch Länge und Breite keine triviale Aufgabe (näheres hierzu findet man im Abschnitt 6.1). Andererseits sind die Längen der Bogen auf den Längen- und Breitenskalen stets unterschiedlich sogar am Äquator, was in ungenauen Formen der gemessenen Objekte in einer flachen Karte resultiert. Diese Probleme lassen sich jedoch mit Hilfe von Projektion beseitigen [Ken02]. 3.2. Fluginformationen Die Kommunikation zwischen Luftfahrzeugen und Bodenstationen erfolgt durch eine Art von Funkdienst, die beweglicher Funkdienst genannt wird. Die Nachrichten zwischen den Teilnehmern des Luftverkehrs und Bodenstationen werden per Sprechfunk übermittelt. Es werden neben den Not- und Dringlichkeitsmeldungen auch Meldungen von folgenden Typen übermittelt [Mar00]: • Peilungsangaben; • Wetterinformationen; 22 3. Organisation der zivilen Luftfahrt • Standortmeldungen, zu denen neben den Positionsangaben Meldungen gehören, die für im Flug befindliche Luftfahrzeuge von unmittelbarer Bedeutung sind; • Flugbetriebsmeldungen, zu denen Informationen über die Wartung von Luftfahrzeugen, Meldungen über die Änderungen in Flugbetriebsplänen sowie andere Meldungen gehören, die für die Sicherheit oder Regelmäßigkeit des Flugbetriebes wichtig sind. In dieser Arbeit werden hauptsächlich die Daten, die aus Peilungsangaben, Standort- und einige Flugbetriebsmeldungen stammen, vom besonderen Interesse sein. 3.2.1. Flugdaten-Erfassung Die Informationen zu den Flügen können ins System entweder direkt von einer Bodenstation (Flughafen, Radarstation), einer Zivilluftfahrtbehörde, die die Sammlung solcher Daten durchführt, oder von Internetressourcen (wie z. B. OpenATC, http://openatc.com/ oder FlightAware, http://flightaware.com/), die solche Daten zu Testzwecken frei zur Verfügung stellen, eingelesen werden. In dieser Arbeit werden hauptsächlich Daten von OpenATC als Quelle benutzt. Da die Belastung der Luftstraßen in der letzten Zeit enorm gestiegen ist, ist die Anzeige der Informationen über alle aktuellen Flüge zu einer sehr komplexen Aufgabe geworden. Aus Performance-Gründen liefern die erwähnten Internetressourcen Daten über spezifische Flüge. Eine der Einschränkungen der beiden Ressourcen ist eine strenge Definition der beobachtenden Region. FlightAware zeigt nur die Daten der Flüge im nordamerikanischen Raum an. OpenATC liefert ausschließlich die Daten der Flüge im europäischen Raum. Darüber hinaus hat OpenATC die Einschränkung, dass es lediglich die ersten 200 aktuellen Flüge angezeigt werden. Dies bedeutet im Grunde, dass sich die von OpenATC gelieferten Informationen meistens auf Flugzeuge beziehen, die entweder von oder nach Großbritannien fliegen. Als Hauptquelle der Fluginformationen wird in dieser Arbeit die Ressource OpenATC betrachtet, weil diese Ressource Daten in einer gut strukturierten Form liefert. Es werden folgende Daten zur Verfügung gestellt: • Das Rufzeichen des Fluges, z. B. „AFL231“; • Der Typ des Flugzeuges, z. B. “A320“; • Das Registrierungskennzeichen des Flugzeuges, z. B. „VP-BWM“; • Der Transpondercode, der von Piloten gesendet wird, um die Art des aktuellen Ereignisses (unter anderem eines Notfalls) anzugeben, wie z. B. „2742“. • Die geographische Position des Flugzeuges gegeben durch Breite, Länge und Höhe (Altitude), z. B. das Tripel „N 51° 49.4’“, „E 5° 19.1’“ und „FL200“; • Die vertikale Geschwindigkeit des Flugzeuges in Fuß pro Minute, z. B. „-2240ft/min“; • Die horizontale Geschwindigkeit des Flugzeuges in Knoten, z. B. „471kts“; 23 3. Organisation der zivilen Luftfahrt • Die Peilung des Flugzeuges in Grad, z. B. „221°“; • Die Zeit in Sekunden, die seit dem Eintreffen des aktuellen Datensatzes vergangen ist, z. B. „12s ago“. Ebenso wie Fluginformationen können auch aktuelle Daten der Flughäfen im Internet gefunden werden. In dieser Arbeit werden Flughafeninformationen der Ressource OpenFlights (http://openflights.svn.sourceforge.net) als Quelle benutzt. Ein Datensatz aus der Gesamtmenge der Flughafeninfos hat den folgenden Aufbau: • Die laufende Nummer des Flughafens in der Liste, z. B. „344“; • Der Name des Flughafens, z. B. „Köln Bonn“; • Die Stadt, in der sich der Flughafen befindet, z. B. „Cologne“; • Der Name des Landes, z. B. „Germany“; • Der IATA-Code des Flughafens, z. B. „CGN“; • Der ICAO-Code des Flughafens, z. B. „EDDK“; • Die geographische Position des Flughafens gegeben durch Breite, Länge und Höhe, z. B. das Tripel „50.865917“, „7.142744“, „302“, wobei die Höhe in Fuß über dem Meeresspiegel angegeben wird; • Die Bezeichnung der Region, zu der der Flughafen gehört, z. B. „E“ für Europa. Durch eine Internet-Recherche können auch frei verfügbare Informationen zu weiteren interessanten Objekten gefunden werden. Im Rahmen dieser Arbeit werden allerdings nur Flugdaten und Flughafeninformationen zur Demonstration der Funktionalität des entwickelten Flugüberwachungssystems benutzt. 3.2.2. Ableitbare Fluginformationen Neben den Informationen, die direkt verfügbar sind, gibt es jede Menge von Daten, die aus den bestehenden Informationen ableitbar sind. Die einfachsten davon sind Daten, die sich aus einem oder mehreren Merkmalen eines importierten Objektes durch Anwendung des Fachwissens herleiten lassen. Beispielsweise kann man anhand des Rufzeichens eines Fluges leicht entscheiden, zu welcher Fluggesellschaft dieser gehört. Andererseits können aus den Basisdaten auch Informationen hergeleitet werden, die Zustände der Objekte angeben oder Zusammenhänge zwischen Objekten der gleichen oder verschiedenen Typen widerspiegeln. Als Beispiel betrachte man etwa folgende Frage: „Welche Flugzeuge sind maximal 20 km von einem Flughafen entfernt?“ Solche Informationen sind in den Flugdaten nicht explizit enthalten, können aber dennoch aus der Datenbasis hergeleitet werden. Hierfür ist es lediglich nötig, aus den Positionen der Flugzeuge und Flughäfen die 24 3. Organisation der zivilen Luftfahrt entsprechenden Distanzen auszurechnen. Solche ableitbare Daten werden weiterhin Anfragen, Kenngrößen oder Indikatoren genannt. Mögliche Indikatoren können prinzipiell in zwei Gruppen unterteilt werden. Zur ersten Gruppe gehören Anfragen, deren Auswertung eine Liste von Objekten des gleichen Typs liefern, die bestimmte Bedingungen erfüllen (wie z. B. das oben gegebene Beispiel). Die zweite Gruppe bilden die Anfragen, deren Ergebnis ein skalarer Wert ist. Diese stellen oft eine einfache Anwendung einer Funktion (z. B. „Anzahl“) auf das Ergebnis einer Anfrage der ersten Gruppe dar oder ergeben sich durch Anwendung einer Projektion, die aus einem Attribut besteht, auf eine Basis- oder abgeleitete Relation. Ferner können Filterbedingungen der Indikatoren entweder Zusammenhänge zwischen gleichen oder verschiedenen Objekttypen darstellen oder komplett auf den Merkmalen einer Objektgruppe aufbauen. Die möglichen Kenngrößen werden in Kapitel 6 dieser Arbeit vorgestellt und untersucht und weiter in Kapitel 7 mittels SQL implementiert. 25 4. Anforderungsanalyse 4. Anforderungsanalyse Speicherung der im Abschnitt 3.2.1 beschriebenen Daten sowie Erstellung von Indikatoren, die auf diesen Daten basieren, setzen ein geeignetes Werkzeug voraus. Mit Hilfe dieses Werkzeugs sollen Anfragen definiert, Daten zur Auswertung der Anfragen aufbereitet und die Ergebnisse der Auswertung angezeigt werden können. Dieses Kapitel beschäftigt sich mit der Analyse der Anforderungen an ein solches System. 4.1. Allgemeine Anforderungen Der gesamte Arbeitsablauf im Zielsystem kann in zwei große Routinen unterteilt werden: • Datenorganisation fasst die Aufgaben zusammen, die Daten auf die Arbeit mit dem Werkzeug vorbereiten. • Anfrageverwaltung fasst die Funktionen zur Definition und Auswertung von Anfragen zusammen. Übersichtlichkeitshalber werden die Anforderungen an genannte Teile des Systems einzeln betrachtet. 4.1.1. Datenorganisation Damit das Zielsystem funktionieren kann, müssen die geeigneten Daten in das System einfließen. Das Einlesen von Flugdaten stellt direkt die erste funktionale Anforderung an das System dar. Es sind auch Situationen denkbar, wenn ein erneuter Import von Daten ohne jeglicher Einwirkung des Benutzers erfolgen soll (z. B. für den Zweck der ständigen Verfolgung eines Flugzeuges). Wie bereits im Abschnitt 3.2.1 erwähnt, ist die Anzeige von Daten aller aktiven Flüge eine sehr komplexe Aufgabe. Daher beschränken sich die Datenquellen auf die Anzeige einer relativ kleinen Menge von Fluginformationen. Die Unvollständigkeit der Daten, die von den Quellen zur Verfügung gestellt werden, machen die Auswahlmöglichkeit der Quelle zu einer weiteren funktionalen Anforderung an das Zielsystem. Zusätzlich zu den Flugdaten können auch Informationen zu anderen Objekttypen für potenzielle Anfragen interessant sein. Zu diesen gehören Flughafeninfos, Wetterinfos, Infos über den 26 4. Anforderungsanalyse genauen Verlauf von Flugstrecken usw. Der Import von Daten anderer interessanten Objekte ist also eine weitere wichtige Aufgabe, die das System gewährleisten muss. Eine Anfrage kann auf aktuellen sowie auch auf historischen Daten aufbauen. Dies bedeutet, dass die importierten Daten im System für eventuelle spätere Auswertung abgespeichert werden müssen, selbst wenn diese im Moment des Datenimports nicht direkt benötigt werden. Um diesen Prozess zu optimieren soll das Zielsystem mit einem Datenbanksystem gekoppelt sein und über Funktionen verfügen, die den Datenfluss zwischen der Benutzeroberfläche und dem Datenbanksystem realisieren. Zu diesen Funktionen gehören Speicherung von Daten, Auslesen und Bearbeitung der zuvor gespeicherten Datensätze sowie Löschung der Datensätze, die nicht mehr benötigt werden. 4.1.2. Anfrageverwaltung Nachdem die Anforderungen an das System bezüglich Datenorganisation definiert wurden, kommt man zur eigentlichen Aufgabe des Werkzeugs - zur Anfrageverwaltung. Es muss möglich sein, vom Benutzer definierte Anfragen in der Datenbank speichern und aus der Datenbank wieder abrufen zu können. Darüber hinaus soll es möglich sein, zuvor gespeicherte Anfragen zu ändern und die Änderungen zu speichern. Schließlich muss das System Löschung von gespeicherten Anfragen unterstützen, die nicht mehr benötigt werden. Die Anfragen, die im System gespeichert werden, müssen in irgendeiner Form durch Benutzer definierbar sein. Dafür könnte man im Grunde eine beliebige Sprache benutzen, die Ausdrücke müssen lediglich vor der Auswertung in ein für das Datenbanksystem verständliches Format übersetzt werden. Um diese zusätzliche Übersetzungsarbeit zu vermeiden, setze man zur Definition der Anfragen direkt die Anfragesprache SQL ein. Hierbei soll das System vor der Speicherung der Anfragen diese auf Korrektheit überprüfen können und ggf. dem Benutzer ein angemessenes Feedback zu den Fehlern geben. Bei der Definition nicht-trivialer Anfragen in SQL, die z. B. Unteranfragen oder komplexe mathematische Berechnungen enthalten, kann der Gesamtausdruck unübersichtlich werden. Aus diesem Grund soll der Benutzer die Möglichkeit haben, Anfragen in Blöcke zu teilen, diese einzeln zu speichern und daraus die Zielanfrage zusammenzubauen. Als Beispiel betrachte man etwa die Notwendigkeit, sphärische Distanz15 zwischen Flugzeugen in WHERE -Klausel zu berechnen. Hierbei würde es sich bieten, Berechnung sphärischer Distanz als gespeicherte Funktion in der Datenbank vorab zu speichern und lediglich den Aufruf der Funktion mit den aktuellen Parametern in die WHERE -Klausel einzuschließen. Diese Überlegungen führen zu einer weiteren Anforderung an das System, die darin besteht, Speicherung von Sichten, gespeicherten Prozeduren und benutzerdefinierten Funktionen in der Datenbank aus dem Werkzeug heraus zu ermöglichen. Zusätzlich sollte ein zuvor gespeicherter Indikator als Unteranfrage bei der Definition einer neuen Kenngröße benutzt werden können. 15 Die Definition sphärischer Distanz sowie die entsprechenden Berechnungsmöglichkeiten findet man weiter im Abschnitt 6.1 dieser Arbeit. 27 4. Anforderungsanalyse 4.2. Systemspezifische Anforderungen Im folgenden Verlauf wird es über verschiedene Objekttypen gesprochen. Hierbei wird es zwischen folgenden Begriffen unterschieden. • Der Begriff Klasse steht allgemein für Typdefinitionen in objektorientierter Programmierung (OOP ). • Ein Objekt ist je nach Kontext als eine Verallgemeinerung jedes möglichen Gegenstandes oder Vorganges oder als Instanz einer Klasse in OOP zu verstehen. • Ein Datenobjekt (auch Datensatz ) steht für eine Zeile einer geeigneten Datenbanktabelle des Systems, die durch ein Objekt im Programm abgebildet wird. • Eine Entität ist eine Klasse, deren Instanz ein Datenobjekt ist. Einige Systemobjekte werden oft nicht einzeln sondern in Listen verwaltet. Hierbei soll ebenso eine Unterscheidung zwischen verschiedenen Arten von Listen erfolgen. • Eine interne Liste ist eine Objektmenge, die ausschließlich im internen Speicher des Programms existiert und nicht unmittelbar für den Benutzer sichtbar ist. • Eine sichtbare Liste ist eine Objektliste, die mit Hilfe der von der Programmierumgebung zur Verfügung stehenden Mitteln in der Benutzeroberfläche angezeigt wird. Aus den im vorherigen Abschnitt genannten Systemanforderungen lassen sich direkt vier wichtigsten Module herausfaktorisieren: • Datenimport-Modul soll für das Einlesen der Flugdaten sowie Informationen zu den weiteren interessanten Objekten zuständig sein. • Datenbankzugriffs-Modul realisiert die Verwaltung (Speicherung, Auslesen, Bearbeitung und Löschung) von Datensätzen. • Anfragedefinitionsmodul ermöglicht, Anfragen sowie Sichten, Prozeduren und Funktionen zu erstellen, zu ändern, auf Korrektheit zu überprüfen und anschließend aus diesen Aktionen entstehende Aufträge (z. B. Speicherung oder Löschung von Daten) an das Datenbankzugriffs-Modul weiterzugeben. • Im Anfrageauswertungsmodul erfolgt die Auswertung der zuvor erstellten Anfragen und die Darstellung der Ergebnisse in unterschiedlichen Formen. Darüber hinaus stellen sich zwei Akteure des Systems heraus. • Benutzer. Dieser Akteur steht für den eigentlichen Anwender des Systems, der die Funktionen des Überwachungswerkzeugs im vollen Umfang benutzen kann. • Automatismus. Dieser Akteur steht für den Prozess, der einige Funktionen des Überwachungssystems nach Ablauf einer vom Benutzer bestimmten Zeitspanne automatisch ausführt. 28 4. Anforderungsanalyse Man betrachte nun die genannten Module unabhängig voneinander. Für jedes Modul wird zunächst ein Anwendungsfalldiagramm gebaut, das festlegt, welche Anwendungsfälle im entsprechenden Modul möglich sind und welche Akteure im jeweiligen Anwendungsfall einbezogen sind. Anschließend werden die essenziellen Anwendungsfälle etwas genauer beschrieben. 4.2.1. Datenimport Es ist klar, dass die Auswertung von SQL-Anfragen im Zielsystem nur dann Sinn ergibt, wenn für die Anfragen relevante Daten zur Verfügung stehen. Die Aufgabe des DatenimportModuls ist Vorbereitung des Systems auf die Arbeit mit SQL-Anfragen durch Einlesen von interessanten Daten in die Datenbasis. Der Import von Daten in das System kann auf verschiedene Weisen organisiert werden. Man kann zu jedem interessanten Objekt ein Snapshot in der Datenbank verwalten, indem man einen Dienst programmiert, der das Snapshot immer auf dem neusten Stand behält und die veralteten Daten archiviert oder löscht. Das Problem dieser Herangehensweise besteht in unnötiger Computerauslastung, die durch die Notwendigkeit, alte Datensätze zu archivieren, entstehen würde. Löschung von alten Datensätzen würde die Möglichkeit ausschließen, Informationen aus historischen Daten herzuleiten. Eine bessere Lösung in dieser Hinsicht bietet folgendes Import-System an. Man führe zunächst die Entität „Import“ ein. Dies ist eine Entität, die einen Fenster des Datenstroms bezeichnet und zusätzlich zum genauen Zeitpunkt des Einlesens von Daten eine Liste von importierten Objekten enthält. So kann man immer den Import mit dem spätesten Zeitpunkt und daraus die aktuellsten (zuletzt importierten) Datensätze im System finden. Die genauen Anwendungsmöglichkeiten des Datenimport-Moduls aus Sicht der Akteure lassen sich folgender Grafik entnehmen. 29 4. Anforderungsanalyse Abbildung 4.1.: Anwendungsfalldiagramm: Datenimport-Modul 30 4. Anforderungsanalyse In der nachfolgenden Tabelle sind kurze Beschreibungen der Anwendungsfälle zu finden. Name des Anwen- Beschreibung dungsfalls Neuen Import erstel- Um die Datenobjekte im System auf den neusten Stand zu brin- len gen, wird ein Importvorgang durchgeführt. Nach Erstellung eines neuen Imports enthält das entsprechende Import-Objekt eine Liste der importierten Datensätze. Ein neuer Import kann entweder manuell vom Benutzer erstellt werden oder wird nach Ablauf eines vordefinierten Zeitintervalls automatisch angelegt. Vor Durchführung eines Importvorganges ist der Typ der zu importierenden Daten festzulegen. Nach der Ausführung des geeigneten Importers werden importierte Objekte in der Datenbank gespeichert und eventuell geöffnete Ansichten der Benutzeroberfläche aktualisiert. Import automatisch Für einen bereits erstellten Import kann festgelegt werden, dass durchführen lassen nach dem Ablauf eines bestimmten Zeitintervalls ein Import von Objekten des gleichen Typs erstellt werden soll. Hierfür soll der Benutzer einen Import zur automatischen Durchführung markieren und das gewünschte Zeitintervall eingeben. Dabei werden die Merkmale des ausgewählten Imports, die den Import als Muster für die automatische Durchführung kennzeichnen, in der Datenbank aktualisiert. Automatische Die vorhin eingestellte automatische Ausführung eines Imports Durchführung eines soll abgeschaltet werden können. Hierfür entfernt der Benut- Imports deaktivieren zer die Markierung, die angibt, dass ein Import von Objekten des entsprechenden Typs automatisch durchgeführt werden soll. Das Zeitintervall der automatischen Durchführung wird zurückgesetzt und die entsprechenden Merkmale des Imports in der Datenbank aktualisiert. Objekte eines Im- Durch das Auswählen und Öffnen eines zuvor erstellten Imports ports anzeigen lassen kann der Benutzer sich die importierten Datenobjekte anzeigen lassen. Bei dieser Aktion erscheint eine sichtbare Liste, in der alle zum gegebenen Import gehörende Datenobjekte angezeigt werden. Bei der Anzeige der Datenobjekte soll zur Unterscheidung mindestens ein identifizierendes Feld benutzt werden. 31 4. Anforderungsanalyse Import löschen Benutzer kann einen Import sowie die zugehörigen Daten aus dem System entfernen. Dabei wird ein Löschvorgang von geeigneten Datensätzen im DBMS ausgelöst. Falls der betroffene Import zur internen Liste der automatisch auszuführenden Imports gehört, wird dieser aus der Liste entfernt. 4.2.2. Datenbankzugriff Das Datenbankzugriffs-Modul stellt im Grunde eine Schicht zwischen der Programmlogik und dem DBMS dar. Diese Schicht wird von anderen Modulen angesprochen, wenn Datenbankaktionen benötigt werden. Die Hauptaufgabe des Moduls ist Übersetzung der Programmbefehle in die datenbankspezifische Befehlssprache und Ausführung der geeigneten Datenbankoperationen. Bei Verwendung objektorientierter Programmierung macht es durchaus Sinn, die genannte Schicht als eine Art von Blackbox zu gestalten, so dass man bei Durchführung der Datenbankoperationen an Entitäten nicht um die Datenbankstruktur kümmern muss. Es wurde beschossen, SQL zur Definition von Anfragen zu benutzen. Aus diesem Grund werden zusätzlich zu den vordefinierten Datenbankoperationen an Entitäten weitere Funktionen zur Ausführung von beliebigen SQL-Anfragen und -Befehlen16 benötigt. Alle Anwendungsfälle dieses Moduls gehören in die untere Schicht der Programmarchitektur und werden komplett von NHibernate übernommen (näheres hierzu in Abschnitten 5.1 und 5.4.5), daher wird es hier auf die ausführliche Beschreibung der Anwendungsfälle verzichtet. 4.2.3. Definition von Anfragen Der wichtigste funktionale Teil des zu entwickelnden Flugüberwachungssystems ist die Anfrageverwaltung. Die Anfragen sollen vom Benutzer mittels SQL frei definierbar sein. Allerdings soll das System in der Lage sein zu entscheiden, in welcher Form die Ergebnisse der Auswertung einer SQL-Anfrage dargestellt werden müssen. Dafür soll der Benutzer bei der Definition einer Anfrage den Rückgabetyp der Anfrage festlegen. Der Rückgabetyp kann entweder ein Skalar sein oder eine Liste von Datenobjekten, deren Darstellungsmaske im System vordefiniert werden muss. Das Anfragedefinitionsmodul fasst die Aufgaben der Verwaltung von SQL-Anfragen zusammen. Der einzige Akteur, der diese Aufgaben im System durchführen kann, ist der Benutzer. Die wichtigsten Funktionen sind in Abbildung 4.2 skizziert und in der nachfolgenden Tabelle erläutert. 16 Hierbei sollte aus Sicherheitsgründen jedoch eine Überprüfung des Befehls erfolgen und ggf. die Ausführung geblockt werden, um z. B. Löschung von Systemtabellen zu verweigern. 32 4. Anforderungsanalyse Abbildung 4.2.: Anwendungsfalldiagramm: Anfragedefinitionsmodul Name des Anwen- Beschreibung dungsfalls Anfrage erstellen Durch Eingabe eines SQL-Befehls kann der Benutzer eine Anfrage unter dem angegebenen Namen in der Datenbank speichern, um diese anschließend mit Hilfe des Anfrageauswertungsmoduls auswerten zu lassen. Bei der Definition einer SQLAnfrage gibt der Benutzer den Namen der Anfrage sowie den zugehörigen Anfragetext ein und legt den Rückgabetyp fest. Beim Speichern des Indikators wird es überprüft, ob der Name und der Anfragetext eingegeben wurden, ob der eingegebene Name bereits vergeben ist und ob der Anfragetext syntaktische Fehler enthält. Anschließend wird die eingegebene SQL-Kenngröße in der Datenbank gespeichert. Anfrage bearbeiten Der Name, der Text und der Rückgabetyp einer zuvor erstellten SQL-Kenngröße können vom Benutzer geändert werden. Hierfür kann der Benutzer die Definition einer Kenngröße im AnfrageEingabefenster öffnen und ihre Merkmale bearbeiten. Nachdem die Änderungen am Indikator vorgenommen wurden, erfolgt eine erneute Korrektheitsüberprüfung und die Anfrage wird in der Datenbank aktualisiert. 33 4. Anforderungsanalyse Anfrage löschen Eine zuvor erstellte SQL-Kenngröße kann vom Benutzer aus dem System gelöscht werden. Bei dieser Aktion soll der Benutzer aufgefordert werden, die Löschung zu bestätigen, da die betroffenen Daten durch den Vorgang aus der Datenbank unwiderruflich gelöscht werden. Nachdem der Benutzer den Vorgang bestätigt hat, wird im DBMS ein entsprechender Löschauftrag initiiert. Sicht / Prozedur / Bei Erstellung einer SQL-Anfrage wird dem Benutzer zusätzlich Funktion erstellen angeboten, den eingegebenen Befehl als Sicht, gespeicherte Prozedur oder benutzerdefinierte Funktion im DBMS abzulegen. Dieser Befehl kann bei Erstellung einer anderen SQL-Kenngröße benutzt werden, um doppelte Eingabe des gleichen Befehlstextes zu vermeiden. Bei der Definition einer Sicht kann der Benutzer den Namen der Sicht sowie den geeigneten SELECT Befehl eingeben. Aus diesen Angaben wird beim Speichern der Sicht ein CREATE -Befehl generiert und im DBMS ausgeführt. Bei der Definition einer gespeicherten Prozedur oder einer benutzerdefinierten Funktion muss der Benutzer den kompletten CREATE -Befehl eingeben, da diese Datenbankobjekte normalerweise Parameter enthalten. Der Befehl wird anschließend im DBMS ohne jegliche Veränderungen ausgeführt. 4.2.4. Anfrageauswertung Die eigentliche Überwachung von Flugzeugen kann durch Ausführung von zuvor definierten SQL-Anfragen erfolgen. Zusätzlich zur Tabellendarstellung von Ergebnissen soll der Anwender die Möglichkeit bekommen, eine viel übersichtlichere Kartendarstellung zu benutzen. Dabei muss man bedenken, dass das Kartenwerkzeug beim erneuten Auswerten der Ergebnisse ebenfalls aktualisiert werden muss, damit die Daten in verschiedenen Ansichten konsistent bleiben. Die wichtigsten Aufgaben des Anfrageauswertungsmoduls lassen sich der Abbildung 4.3 entnehmen. 34 4. Anforderungsanalyse Abbildung 4.3.: Anwendungsfalldiagramm: Anfrageauswertungsmodul 35 4. Anforderungsanalyse Die Beschreibungen der Anwendungsfälle finden sich in folgender Tabelle. Name des Anwen- Beschreibung dungsfalls Ergebnis der Aus- Nachdem eine Anfrage erstellt wurde, kann diese auf den im wertung einer Anfra- System bereits vorhandenen Daten ausgeführt werden. Beim ge öffnen Auswerten wird zunächst der Rückgabetyp der Kenngröße ermittelt. Falls die ausgewählte SQL-Anfrage eine Objektliste als Rückgabe liefert, wird eine Tabelle mit dem Ergebnis der Auswertung angezeigt. Im Falle einer skalarer Anfrage wird der Rückgabewert angezeigt. Ergebnis der Aus- Als eine bessere Darstellungsmöglichkeit der Ergebnisse einer wertung in Karte an- Anfrage mit Objektlisten-Rückgabe bietet sich die Kartenan- zeigen lassen sicht. Der Benutzer soll daher die Möglichkeit haben, nach der Auswertung einer Objektlisten-Anfrage die Ergebnisse in Karte anzeigen zu lassen. Durch diese Aktion öffnet sich ein geeignetes Fenster, in welchem eine Karte des betreffenden Gebiets angezeigt wird. In diesem Fenster werden über dem Kartenmaterial an geeigneten Stellen Symbole eingeblendet, die Objekte der Ergebnisliste bezeichnen. Ergebnis der Aus- Wenn eine Anfrage ausgewertet wurde, kann der Benutzer das wertung Ergebnis jederzeit aktualisieren lassen. Dies ist z. B. dann sinn- aktualisie- ren voll, wenn der Benutzer in der Zwischenzeit einen erneuten manuellen Import durchgeführt hat. Das Ergebnis der Auswertung wird auch dann aktualisiert, wenn der Benutzer vorher die automatische Aktualisierung des Ergebnisses eingeschaltet hat, und des dafür eingestellte Zeitintervall abgelaufen ist. Wenn die Kartenansicht bereits geöffnet ist, wird diese aktualisiert, damit die Ergebnismenge in verschiedenen Ansichten konsistent bleibt. Ergebnis der Aus- Das Ergebnis der Auswertung kann in regelmäßigen Abstän- wertung automatisch den automatisch aktualisiert werden, wenn z. B. ein automa- aktualisieren lassen tisch durchzuführender Import im System vorhanden ist. Dafür muss ein Aktualisierungsmechanismus gestartet werden. Diesen kann der Benutzer aktivieren, indem er einen Zeitintervall festlegt, nach Ablauf dessen die gewählte Anfrage erneut ausgewertet wird. 36 4. Anforderungsanalyse Automatische Ak- Falls der Benutzer keinen Bedarf mehr hat, das aktuelle Er- tualisierung des gebnis automatisch aktualisieren zu lassen (z. B. wenn er Zeit Ergebnisses deakti- für die Untersuchung des aktuellen Ergebnisses braucht), kann vieren er die automatische Aktualisierung abschalten. Durch das Abschalten der automatischen Aktualisierung wird der dafür zuständiger Timer angehalten. 37 5. Entwurf und Implementierung eines Flugüberwachungssystems 5. Entwurf und Implementierung eines Flugüberwachungssystems Im letzten Kapitel wurden die Anforderungen an das zu entwickelnde Flugüberwachungswerkzeug gestellt. Dadurch wurde die benötigte Funktionalität festgelegt, die das Zielsystem gewährleisten muss. Darüber hinaus wurden essenzielle Module genannt, aus den das System bestehen soll. Die nächste Aufgabe ist nun, diese Module in Detail zu beschreiben, erforderliche Entwicklungsmittel und -techniken abzugrenzen, um das Werkzeug zu realisieren. 5.1. Systemarchitektur Das zu entwickelnde System muss aus mindestens zwei Schichten bestehen: Datenbankanwendung, die zur Speicherung und Verwaltung von gespeicherten Daten dient, und Benutzeroberfläche, die den Austausch von Daten und Befehlen zwischen dem Benutzer und der Datenbank realisiert. Weiterhin wurde im Abschnitt 4.2.2 über die Vorteile einer Persistenzschicht zwischen der Benutzeroberfläche und der Datenbank gesprochen. Darüber hinaus soll das System über Module verfügen, die gewisse Informationen aus dem Internet in das System einfließen lassen. Abbildung 5.1 widerspiegelt den schematischen Aufbau des Zielsystems. Die Verwaltung von im System gespeicherten Daten erfolgt mit Hilfe eines Datenbankservers. Dieser besteht aus zwei Komponenten. • Die Datenbank enthält zusätzlich zu den fest abgespeicherten Daten abgeleitete Objekte wie virtuelle und materialisierte Sichten; • Das DBMS pflegt die Daten und stellt diese auf Anfrage zur Verfügung. Zwischen dem Datenbankserver und der eigentlichen Anwendung befindet sich eine Persistenzschicht. Durch diese Schicht erfolgt die Abbildung von Datenobjekten auf Objekte der Benutzeroberfläche. Mittlerweile gibt es mehrere fertige Lösungen für das Problem der Persistenz von Entitäten. Diese Lösungen werden Entity Frameworks (EFs) genannt. Während das Ziel, das solche EFs verfolgen, gleich ist, sind die Ausführungen durchaus unterschiedlich. Beispielsweise erzielt ADO.NET Entity Framework [Pap07] die Zuordnung zwischen Programm- und Datenobjekten durch das Generieren zu jeder zu persistierenden Klasse einer zusätzlichen partiellen Klasse, die Datenbankzugriffs-Methoden enthält. Dagegen generiert NHibernate [NHi07] zu jeder Entität eine zusätzliche abgeleitete Klasse, die zu persistierende Klassen-Eigenschaften überschreibt. In dieser Arbeit wird die Persistenzschicht mittels 38 5. Entwurf und Implementierung eines Flugüberwachungssystems Abbildung 5.1.: Architektur des Flugüberwachungssystems NHibernate implementiert, da die Funktionsweise dieses EFs mehr Kontrolle über den Code der Klassen-Eigenschaften überlässt. Die Benutzeroberfläche enthält Ansichten und Funktionen, die im vorherigen Kapitel gestellten Anforderungen realisieren. Aus dem ganzen Funktionsumfang zeichnen sich zwei Module aus, die mit externen Daten arbeiten: die Kartenanwendung und das Import-Modul. Die Kartenanwendung soll auf Kartenmaterial zugreifen können, das im Internet verfügbar ist, und dieses für die Darstellung der Karte benutzen. Das Import-Modul verwaltet Datenströme, erzeugt aus externen Daten strukturierte Objekte, stellt diese der Benutzeroberfläche zur Verfügung und übergibt sie zur Speicherung an die Persistenzschicht. Über die essenziellen Schritte beim Entwurf und Entwicklung der Benutzeroberfläche sowie der Datenbankanwendung wird in den folgenden Abschnitten ausführlich diskutiert. 5.2. Entwurf des Datenbankschemas Beim Entwerfen des Datenbankschemas verzichte man auf die Beschreibung der konzeptuellen Ebene und beschäftige sich direkt mit der logischen Ebene, da bereits aus der Architektur des Systems ein spezifischeres Datenmodell hervorgeht. Der Import-Mechanismus des Systems wurde im Abschnitt 4.2.1 beschrieben. Dieser sieht Verwaltung von Datenstrom-Fenster (Imports) mittels Datenbankserver vor. 39 5. Entwurf und Implementierung eines Flugüberwachungssystems Zu einem Import ist der zugehörige Erstellungszeitpunkt zu speichern. Anhand dieser Informationen kann das Alter der zugehörigen Datensätze leicht bestimmt werden. Darüber hinaus gehört zu jedem Import eine Liste von Datensätzen von unterschiedlichen Typen. Aus diesen Informationen ergibt sich das Datenbankschema, das in der Abbildung 5.2 skizziert ist. Abbildung 5.2.: Datenbankschema des Flugüberwachungssystems In der Abbildung sind folgende Elemente durch entsprechende Notation zu unterscheiden: • Dunkelblaue Rechtecke bezeichnen Entitäten; • Durch Ovale sind Eigenschaften (Felder) der Entitäten dargestellt; • Orangefarbige Ovale bezeichnen Primärschlüssel-Felder; • Hellblaue Ovale bezeichnen Fremdschlüssel-Felder; • Durch Raute wird die Beziehung zwischen zwei Entitäten dargestellt. Die Entität DataObject ist die allgemeine Bezeichnung für alle im System verwaltende Datenobjekttypen. Im Laufe dieser Arbeit werden zwei Objekttypen verwaltet: Flugdaten und Flughafeninformationen. Diese beiden Objekttypen werden in der Datenbankanwendung auf die gleiche Weise behandelt. Wie bereits erwähnt, enthält ein Import eine Liste von Datenobjekten. Diese Liste kann in speziellen Fällen leer sein. Dies ist nämlich dann der Fall, wenn entweder keine Informationen im Moment des Einlesevorganges zur Verfügung stehen oder wenn der Import-Algorithmus beim Einlesen der Daten feststellt, dass sich keine Datenobjektmerkmale seit dem letzten Import geändert haben sowie keine neuen Datenobjekte dazugekommen sind. Ob die Speicherung eines leeren Imports sinnvoll ist, soll bei Entwicklung der Programmoberfläche entschieden werden. 40 5. Entwurf und Implementierung eines Flugüberwachungssystems Für Entität SQLExpression können keine offensichtlichen Beziehungen zu anderen Entitäten festgestellt werden. SQL-Anfragen sollen datenbanktechnisch unabhängig von anderen Datenobjekten gehalten werden, da diese Objekte vom Benutzer des Systems frei definierbar sein müssen. Die genaue Struktur der Entitäten wird bei der Implementierung der Datenbankanwendung erläutert. 5.3. Implementierung der Datenbankanwendung Nachdem alle essenziellen Anwendungsfälle sowie das Datenbankschema definiert wurden, kann man sich überlegen, in welcher Form die Daten in der Datenbank gespeichert werden sollen. Aus den Anwendungsfällen ergeben sich erstmal vier Datenobjekte und demzufolge vier Tabellen: eine für Imports, zwei für in Rahmen dieser Arbeit zu implementierende Datenobjekttypen (Flüge und Flughäfen) und eine für SQL-Anfragen. Die Trennung zwischen SQL-Anfragen und weiteren Datenobjekten ist klar: die entsprechende Tabelle soll unabhängig von anderen Datenobjekten sein. Im restlichen Teil ist Import sicherlich das zentrale Objekt. Die weiteren Entitäten sollen mit dem entsprechenden Import streng verknüpft sein: jede Entität wird im Rahmen eines Imports eingelesen und muss daher genau einem Import zugeordnet sein. Man fasse nun das gesamte Wissen in einem Datenbankdiagramm (Abbildung 5.3) zusammen und betrachte die resultierenden Tabellen einzeln in Detail. 41 5. Entwurf und Implementierung eines Flugüberwachungssystems Abbildung 5.3.: Datenbankstruktur des Flugüberwachungssystems 42 5. Entwurf und Implementierung eines Flugüberwachungssystems 5.3.1. Realisierung des Datenimports Die Informationen über die bereits durchgeführten Dateneinlesevorgänge sollen in der Tabelle Import gespeichert werden. Der SQL-Erstellungsbefehl für diese Tabelle wurde im Listing 2.1 des Abschnittes 2.3.1 aufgeführt. Die wichtigsten Daten, die zu einem Einlesevorgang zu speichern sind, ist der Typ des importierten Datenobjekts (Spalte ImportableObjectType) sowie der Zeitpunkt, an dem der Vorgang erfolgte (Spalte DateTime). Der Typ wird gebraucht, um zwischen Imports von verschiedenen Datenobjekttypen unterscheiden zu können. Der Zeitpunkt wird benötigt, um die vorhandenen Imports zeitlich anordnen zu können. Darüber hinaus speichere man zu einem Import die Informationen dazu, ob dieser als Muster für weitere automatisierte Einlesevorgänge dienen muss. Hierfür werden in der Tabelle ein boolesches Feld AutomaticImport sowie ein ganzzahliges Feld AutomaticImportInterval angelegt. Der Wert im Feld AutomaticImportInterval legt die Häufigkeit der automatischen Einlesevorgänge fest. 5.3.2. Speicherung der Flugdaten Tabelle Flight ist die erste und die wichtigste Datenobjekttabelle der Datenbank. Sie soll die Daten über die Flüge enthalten, die von den genannten Internetressourcen heruntergeladen werden. Listing 5.1 enthält den SQL-Erstellungsbefehl der Tabelle. Listing 5.1: Der SQL-Erstellungsbefehl der Tabelle „Flight“ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CREATE TABLE [Flight]( [ID] [ bigint ] IDENTITY(1,1) NOT NULL, [ImportID] [bigint ] NOT NULL, [CallSign] [nvarchar](50) NOT NULL, [Type] [nvarchar](50) NULL, [ Registration ] [nvarchar](50) NULL, [Code] [int ] NOT NULL, [Latitude] [decimal](18, 6) NOT NULL, [Longitude] [decimal](18, 6) NOT NULL, [Altitude] [nvarchar](20) NOT NULL, [AltitudeMeter] [ bigint ] NOT NULL, [ Incline ] [ int ] NOT NULL, [Speed] [ int ] NOT NULL, [Angle] [ int ] NOT NULL, [LastHeard] [int ] NOT NULL, CONSTRAINT [PK_Table_1] PRIMARY KEY([ID]) ) Der Aufbau der Tabelle entspricht den auf OpenATC verfügbaren Daten. Hierzu ist es anzumerken, dass die Höhe eines Flugzeuges in Fuß angegeben wird, was für die meisten Benutzer 43 5. Entwurf und Implementierung eines Flugüberwachungssystems nicht aussagekräftig ist. Die Umrechnung der Höhe des jeweiligen Flugzeuges in Meter17 soll beim Importieren erfolgen und in der zusätzlichen Spalte AltitudeMeter gespeichert werden. Schließlich soll die Spalte LastHeard das relative Alter des jeweiligen Datensatzes in Sekunden angeben. So ist es möglich, den genauen Zeitpunkt zu bestimmen, an dem der entsprechende Datensatz von der Radarstation empfangen wurde. Hierfür soll man die in der Spalte LastHeard angegebene Anzahl von Sekunden vom Zeitpunkt des Imports subtrahieren. Die Anknüpfung der Tabelle Flight an die Tabelle Import erfolgt über die ID-Spalte des Imports. Dafür wird eine Fremdschlüssel-Einschränkung benötigt. Erstellung der Einschränkung erfolgt durch Ausführung des SQL-Befehls aus dem Listing 2.2 (siehe Abschnitt 2.3.1). 5.3.3. Speicherung der Flughafeninformationen Die SQL-Anfragen im System sollen nicht ausschließlich auf den Daten der Flüge basieren. Es wurde bereits erwähnt, dass auch weitere Objekttypen durchaus interessant sein können. Als Beispiel dafür betrachte man Informationen zu den Flughäfen, die für einige potenzielle SQL-Anfragen durchaus von Interesse sind. Daten der Flughäfen werden in der Tabelle Airport der Datenbank gespeichert. Der Aufbau der Tabelle entspricht den Daten der Internetressource OpenFlights. Der entsprechende SQLErstellungsbefehl ist im Listing 5.2 beigefügt. Listing 5.2: Der SQL-Erstellungsbefehl der Tabelle „Airport“ 1 2 3 4 5 6 7 8 9 10 11 12 13 CREATE TABLE [Airport]( [ID] [ bigint ] IDENTITY(1,1) NOT NULL, [ImportID] [bigint ] NOT NULL, [AirportName] [nvarchar](100) NOT NULL, [City] [nvarchar](100) NOT NULL, [Country] [nvarchar](100) NOT NULL, [Latitude] [decimal](18, 6) NOT NULL, [Longitude] [decimal](18, 6) NOT NULL, [Altitude] [ bigint ] NOT NULL, [IATACode] [nvarchar](3) NOT NULL, [ICAOCode] [nvarchar](4) NOT NULL, CONSTRAINT [PK_Airport]([ID]) ) In der genannten Quelle wird die Höhe des jeweiligen Flughafens in Fuß über dem Meeresspiegel angegeben. Dabei ist die relativ genaue Umrechnung in Meter durchaus möglich. Man muss lediglich die in Fuß angegebene Höhe mit 0.3048 multiplizieren [WIK09]. Die Umrechnung wird beim Importieren der Flughäfen durchgeführt und in dieser Form in der Spalte Altitude gespeichert. 17 Es handelt sich um einen geschätzten Wert, da die Höhe meistens in Form einer Flugfläche angegeben ist und sich daher nicht genau in absolute Höhe umrechnen lässt. 44 5. Entwurf und Implementierung eines Flugüberwachungssystems Genauso wie im Falle der Fluginformationen ist eine Anknüpfung von den importierten Flughafeninformationen an das jeweilige Import-Objekt nötig. Diese erfolgt auf die gleiche Weise über die ID des Imports. Der Erstellungskript der Fremdschlüssel-Einschränkung lässt sich dem Listing 5.3 entnehmen. Listing 5.3: Der SQL-Erstellungsbefehl des Fremdschlüssels für Tabelle „Airport“ 1 2 3 4 5 ALTER TABLE [Airport] ADD CONSTRAINT [FK_Airport_Airport] FOREIGN KEY([ImportID]) REFERENCES [Import] ([ID]) ON UPDATE CASCADE ON DELETE CASCADE 5.3.4. Verwaltung von SQL-Anfragen Die SQL-Anfragen, die vom Benutzer definiert werden, sollen anschließend in der Tabelle EXSQLExpression gespeichert werden. Der Name der Tabelle enthält das Präfix EX, das alle Tabellen des Moduls Expressions kennzeichnen soll. Die Diskussion darüber, welche Tabellen in diesem Modul noch denkbar sind, findet in Kapitel 9 dieser Arbeit statt. Die Struktur der Tabelle EXSQLExpression lässt sich dem Listing 5.4 entnehmen. Listing 5.4: Der SQL-Erstellungsbefehl der Tabelle „EXSQLExpression“ 1 2 3 4 5 6 7 8 9 CREATE TABLE [EXSQLExpression]( [ID] [ bigint ] IDENTITY(1,1) NOT NULL, [Name] [nvarchar](255) NOT NULL, [SQL] [ntext] NOT NULL, [CreationDate] [datetime] NOT NULL, [ResultListType] [nvarchar](255) NULL, [Description] [nvarchar](255) NOT NULL, CONSTRAINT [PK_EXSQLExpression]([ID]) ) Die eigentliche SQL-Anfrage wird in der Spalte SQL gespeichert. Im allgemeinen Fall kann die SQL-Definition einer Kenngröße beliebig lang sein, daher wurde hierfür als Datentyp NTEXT gewählt. Der Name einer SQL-Anfrage wird vergeben, um Verwendung einer bereits definierten SQL-Anfrage bei der Definition einer anderen Kenngröße zu ermöglichen. Dafür sollte der Benutzer den Namen der SQL-Kenngröße, die er als Unteranfrage benutzen möchte, etwa in spitze Klammer einschließen. Die genauere Erklärung, wie diese Erweiterung der Anfragedefinition funktioniert, findet sich im Abschnitt 7.9. Wie bereits im Anwendungsfall „Anfrage erstellen“ erwähnt, wird der Benutzer aufgefordert, bei Erstellung einer Anfrage den Rückgabetyp festzulegen. So kann der Auswertungsalgorithmus für jede auszuwertende Kenngröße eine geeignete Darstellung finden. Der Rückgabetyp wird in der Datenbank in der Spalte ResultListType gespeichert. Ist dieser Wert nicht angegeben (NULL), so liefert die Anfrage einen skalaren Wert. Ansonsten findet der Algorithmus 45 5. Entwurf und Implementierung eines Flugüberwachungssystems ein für eine Liste vom angegebenen Typ geeignetes Steuerelement und lässt das Ergebnis der Auswertung der ausgewählten Kenngröße mit Hilfe dessen darstellen. 5.3.5. Erweiterung der Datenbankanwendung Die aktuelle Implementierung der Datenbankanwendung ermöglicht einfaches Hinzufügen weiterer Tabellen zur Speicherung importierbarer Objekte. Hierzu ist es lediglich nötig, eine Tabelle anzulegen, die analog zu den Tabellen Flight und Airport durch ID des Imports mit der Import-Tabelle verknüpft ist. Schematisch ist die genannte Vorgehensweise in der Abbildung 5.4 zu sehen. Abbildung 5.4.: Erweiterung der Datenbank 5.4. Programmentwurf und -implementierung Die nächste Aufgabe beim Aufbau des Systems ist Erstellung eines Abbildes der Datenobjekte in der Benutzeroberfläche. Man führe diese Analyse ähnlich wie im letzten Kapitel durch. Zunächst wird in diesem Abschnitt ein Klassendiagramm erstellt. Danach werden die wichtigsten Klassen und Schnittstellen etwas genauer erläutert. Die essenziellen Entitäten des Programms und ihre Zusammenhänge sind in der Abbildung 5.5 zu sehen. 46 5. Entwurf und Implementierung eines Flugüberwachungssystems Abbildung 5.5.: Klassendiagramm des Flugüberwachungssystems Bei der Beschreibung der Entitäten wird es hier mit den allgemeinen Klassen und Schnittstellen angefangen, die dann im weiteren Verlauf präzisiert werden. 5.4.1. Schnittstelle IImportable Um importierbare Entitäten im Rahmen der Imports allgemein betrachten zu können, führe man eine Schnittstelle IImportable ein. Alle Objekttypen, die in das System innerhalb eines Imports eingelesen werden, müssen nun diese Schnittstelle implementieren. Allgemeine Eigenschaften der Schnittstelle lassen sich aus der Idee der Erweiterbarkeit der Datenbank leicht herleiten (siehe Abschnitt 5.3.5). Es sind nämlich die ID des Datenbankobjektes und der zugehörige Import. Zusätzlich wird ein Bezeichnungsfeld benötigt, das diese Objekte eindeutig identifiziert. Dieses Feld wird für die Anzeige der Objekte eines erstellten Imports benötigt. Man füge 47 5. Entwurf und Implementierung eines Flugüberwachungssystems daher der Schnittstelle ein schreibgeschütztes Feld Caption hinzu, das von jeder Entität, die die Schnittstelle implementiert, auf ihre eigene Art realisiert werden soll. 5.4.2. Klassen Flight und Airport Die importierbaren Klassen Flight und Airport (sowie weitere eventuell noch zu implementierende Entitäten) müssen nun lediglich die Schnittstelle IImportable implementieren, damit Objekte dieser Klassen zu Imports zusammengefasst werden könnten. Die weiteren Felder der beiden Klassen entsprechen genau dem Aufbau der Tabellen Flight bzw. Airport (siehe Abschnitte 5.3.2 und 5.3.3 sowie die Abbildung 5.2). Hierbei muss lediglich erwähnt werden, dass es sinnvoll ist, geographische Positionen der Flüge und Flughäfen zu einer Klasse GeoCoordinate zusammenzufassen, da Länge, Breite und Höhe eines geographischen Ortes in diesem konkreten Fall nur in Form eines Tripels Sinn ergeben. Das Anzeigefeld Caption wird von den beiden Klassen auf verschiedene Weise implementiert. • Bei den importierten Flügen wird das Rufzeichen als Anzeigefeld verwendet, z. B. „EZY5453“. • Für die importierten Flughäfen besteht der Wert in diesem Feld aus dem Namen des Flughafens gefolgt vom Land und dem IATA-Code des Flughafens, z. B. „Schönefeld, Germany (SXF)“. 5.4.3. Import-Klassen Eine der wichtigsten Aufgaben bei der Implementierung vom Import-Mechanismus ist die Verallgemeinerung der importierbaren Objekte. Man definiere dafür zuerst eine abstrakte Klasse18 Import, die alle Eigenschaften außer dem schreibgeschützten Typ der zu importierenden Objekte ImportableObjectType implementiert. Diese Eigenschaft muss von den abgeleiteten Klassen wie z. B. FlightImport und AirportImport realisiert werden. Mit Hilfe dieser Vorgehensweise kann die Liste der importierten Objekte gleich für alle Import-Typen behandelt werden. Hierfür definiere man diese in der Klasse Import als allgemeine Liste von Objekten, die Schnittstelle IImportable implementieren. Die abgeleiteten Klassen der abstrakten Klasse Import geben jetzt zusätzlich zu dem Typ der importierbaren Datenobjekte auch die Datenbanktabelle an, aus welcher die entsprechende Objektliste ausgelesen werden soll. Vor der Implementierung des Import-Mechanismus soll der Begriff eines Importers eingeführt werden. Ein Importer ist eine systeminterne Klasse, deren Instanzen Daten vom voreingestellten Typ in das System einlesen. Das Ergebnis der Ausführung eines Importers ist ein Import. 18 Eine abstrakte Klasse kann in OOP nur zur Vererbung benutzt werden. Es können keine Instanzen einer abstrakten Klasse erstellt werden. 48 5. Entwurf und Implementierung eines Flugüberwachungssystems Aus den Systemanforderungen stellt sich die Notwendigkeit heraus, Imports automatisch durchführen zu lassen. Ein automatischer Importer soll dafür zuständig sein, zur internen Liste der angegebenen Imports automatisch neue Imports der Daten der entsprechenden Typen zu erstellen. Zu jedem Objekt dieser internen Liste verwaltet der automatische Importer einen Timer mit dem entsprechenden Zeitintervall. Nach Ablauf eines dieser Intervalle wird der geeignete Import ausgesucht, ein Importer vom erforderlichen Typ erstellt und ausgeführt und der daraus resultierender neuer Import in der Datenbank gespeichert. Auf solche Art soll es gewährleistet werden, dass die Daten im System immer auf einem relativ aktuellen Stand sind. 5.4.4. Klasse SQLExpression Um die vom Benutzer erstellten SQL-Anfragen mittels NHibernate in der Datenbank speichern zu können, wird eine eigene Entität SQLExpression benötigt. Der Aufbau dieser Klasse entspricht genau dem Aufbau der Tabelle EXSQLExpression (siehe Abschnitt 5.3.4). Diese Klasse hat keine Abhängigkeiten im System und wird daher nicht weiter erläutert. 5.4.5. Entwicklungswerkzeuge Bei Entwicklung des Zielsystems ist es sinnvoll an bestehende Mittel anzulehnen. Aus diesem Grund wird hier als Programmierumgebung Microsoft Visual Studio 2008 mit unterschiedlichen Erweiterungen für spezielle Funktionen benutzt. Diese Programmierumgebung bietet eine umfangreiche Menge von Programmiermittel, die den aktuellen Bedarf völlig erfüllt. Darüber hinaus erfolgt Kompilierung des Programmcodes in Visual Studio durch Microsoft .NET Framework, das mehrere Programmiersprachen unterstützt. Somit können unterschiedliche Module des Systems je nach Geschmack in verschiedenen Sprachen programmiert werden. Allgemein sollte das System unabhängig vom Typ des Datenbanksystems laufen. Bei Verwendung von NHibernate erfolgt die Umstellung des Datenbanksystems durch einfache Angabe der zu verwendenden Datenbank-Syntax. Dabei sollte man beachten, dass die Syntax der im System definierten SQL-Anfragen jedoch vom gewählten Datenbanksystem abhängt. Beispielsweise wird sich eine Kenngröße, die unter Verwendung vom SQL Server definiert wurde, nicht unbedingt unverändert mit Hilfe von MySQL auswerten lassen. Man verwende Microsoft SQL Server 2008 (MSSQL 2008) als Standard. Dieses System bietet außer üblichen Datensatzverwaltung die Möglichkeit, Sichten, gespeicherte Funktionen und Prozeduren zu erstellen. Darüber hinaus kann bei Bedarf die Synchronisierung zweier Datenbanken einfach mit Hilfe von Werkzeugen des SQL Servers durchgeführt werden. Die SQL-Erstellungsbefehle der Datenbanktabellen wurden im Abschnitt 5.2 dieses Kapitels in MSSQL2008 -Syntax angegeben. 49 5. Entwurf und Implementierung eines Flugüberwachungssystems 5.4.6. Kartendarstellung Um die Karte darstellen und Objekte in dieser einblenden zu können, wird ein Kartenwerkzeug benötigt, das in das Programm integrierbar ist. An dieser Stelle wird eine etwas komplexere Lösung in Hinsicht auf die Architektur benutzt, da Werkzeuge, die in das System leicht integrierbar sind, meistens kommerziell sind. Man baue ein Kartenformular, in dem ein einfaches Browser-Steuerelement (Skybound Gecko v. 1.9.0.0 [Sky08]) angezeigt wird. Dieses Steuerelement verweist auf eine interne Webseite, die für die Kartendarstellung zuständig ist. Den Code der Webseite findet man im Anhang A.2. Seitens HTML ist es eine Webseite mit mehreren Platzhaltern für unterschiedliche Webobjekte und Daten. Der essenzielle Teil der Webseite ist der JavaScript-Code, der auf der API von OpenLayers (http://www.openlayers.org/) aufbaut. Die Struktur sowie die Funktionsweise des Kartenwerkzeugs ist in der Abbildung 5.6 anschaulich zu sehen. Abbildung 5.6.: Aufbau des Kartenwerkzeugs Die Anzeige der Objekte in der Karte erfolgt durch Erstellung und Speicherung einer KMLDatei und Übergabe des Speicherortes dieser Datei an die Webseite. Wenn eine solche Datei angegeben wurde, wird in der Karte eine zusätzliche Schicht erzeugt, die die KML-Datei mit Hilfe der Funktionalität von OpenLayers darstellt. Zusätzlich zur Anzeige der Ergebnisse der Auswertung einer SQL-Anfrage soll es auch möglich sein, mit Hilfe des Kartenwerkzeugs interessante geographische Regionen im Rahmen der Anfragedefinition festzulegen. Hierfür wird in der HTML-Ansicht ein Platzhalter mit ID „coordinates“ angelegt, der bei der Definition des geographischen Gebietes mit den Koordinaten der entsprechenden Eckpunkten gefüllt wird. Weiterhin soll die Karte aktualisiert werden, wenn z. B. die Auswertung der ausgewählten Anfrage nach Durchführung eines automatischen Imports wieder angestoßen wird. Dabei soll aber der aktuelle Kartenausschnitt unverändert bleiben. Um dies zu ermöglichen, werden die 50 5. Entwurf und Implementierung eines Flugüberwachungssystems Koordinaten der Mitte sowie die aktuelle Zoom-Stufe in den Platzhaltern mit IDs „centerdiv “ bzw. „zoomdiv “ bei jeder Zoom-Änderung sowie Kartenverschiebung gespeichert. Die Werte aus diesen Platzhaltern werden bei Aktualisierung der Ansicht ausgelesen und in die URL der aufzurufenden Webseite eingeschlossen. 5.4.7. Effizienzsteigerung Es wurde bereits erwähnt, dass im System vorab gespeicherte SQL-Anfragen bei Definition anderer Kenngrößen als Quellen benutzt werden dürfen. Dies wird dadurch ermöglicht, dass man im Anfrageverwaltungsmodul Meta-Parameter zulässt, deren Namen bei Erstellung und Bearbeitung einer SQL-Anfrage in spitzen Klammern eingeschlossen werden sollen. Der Anfrageauswertungs-Mechanismus soll dann den Anfragetext erst auf Existenz solcher MetaParameter prüfen und diese ggf. durch die entsprechenden Anfragedefinitionen ersetzen. Zusätzlich zu Unteranfragen sind auch andere Einsatzmöglichkeiten für Meta-Parameter denkbar, vor allem zur Steigerung der Effizienz der Auswertungsfunktion. Manche der zu definierenden Anfragen werden ausschließlich auf aktuellen Daten basieren. Für alle solchen SQLAnfragen wäre es nötig, zuerst die ID des letzten Imports des interessierenden Objekttyps zu ermitteln. Dies kann durch eine zusätzliche Unteranfrage mit Maximum-Aggregationsfunktion über die ID der Imports erzielt werden, was in einem zusätzlichen Aufwand resultiert. Alternativ kann zu diesem Zweick in den SQL-Ausdruck eine Existenzprüfung auf Imports mit höheren ID-Werten eingeschlossen werden (siehe Diskussion im Abschnitt 7.1). Der resultierende Aufwand hierfür wäre jedoch relativ hoch, da die Existenzprüfung ebenfalls durch eine zusätzliche Unteranfrage erfolgen würde. Um Erstellung der SQL-Anfragen, die auf aktuellen Daten basieren, zu vereinfachen und Effizienz ihrer Auswertung zu erhöhen, halte man beim Laden des Systems die ID-Werte der letzten Imports von verschiedenen Typen im Speicher fest. Der Auswertungs-Mechanismus soll dann dahingehend angepasst werden, dass er diese Werte durch Meta-Parameter bei der Definition einer SQL-Kenngröße verfügbar macht. Auf diese einfache Weise wird die Komplexität der SQL-Anfragen, die auf aktuellen Daten arbeiten, deutlich reduziert. 51 6. Definition und Analyse der Flugkenngrößen 6. Definition und Analyse der Flugkenngrößen Nachdem ein Flugüberwachungswerkzeug entwickelt wurde, kann man sich mögliche Typen von interessanten Flugkenngrößen überlegen, die mit Hilfe dieses Werkzeugs realisiert und beobachtet werden können. Es sind folgende Anfragen vorstellbar, die auf den Flugdaten aufbauen: • Ermittlung aktueller Fluginformationen; • Filterung aktueller Fluginformationen nach verschiedenen Merkmalen der Flüge; • Bestimmung von Zusammenhängen zwischen den aktuellen Flügen wie z. B. Entfernung zwischen Flugzeugen oder die Lage ihrer Flugbahnen relativ zueinander; • Ermittlung der Flugzeuge in einem bestimmten Areal; • Bestimmung von Flugstatistiken. Manche der oben definierten Indikatoren können ohne Weiteres implementiert werden, da sie ausschließlich auf den im System vorhandenen Daten aufbauen, und die Realisierung der zu verwendenden Filterbedingung keine sonderlichen Kenntnisse voraussetzt. Für die Implementierung der anderen muss man jedoch erst die Filterbedingung untersuchen und auf ein bekanntes mathematisches Problem reduzieren, um es anschließend lösen zu können. Dieser Abschnitt beschäftigt sich gerade mit solchen noch zu lösenden Problemen. 6.1. Berechnung der sphärischen Distanz zwischen zwei Punkten Da die Koordinaten der Flugzeuge, die ursprünglich über GPS erfasst werden, im Bezugssystem WGS84 vorliegen, ist die Berechnung der Distanz zwischen ihnen keine triviale mathematische Aufgabe. Darüber hinaus muss man an dieser Stelle bedenken, dass die Flugbahnen der Luftfahrzeuge (seitlich gesehen) praktisch um die Erde kreisen. Aus diesem Grund entspricht die Distanz zwischen zwei Flugzeugen nicht der Länge der Linie, die die entsprechenden zwei Punkte verbindet, sondern der Länge der sie verbindenden Kurve, die entlang der Erdkrümmung verläuft. Die geometrische Bedeutung der Länge einer solchen Kurve findet man in der sphärischen Geometrie unter dem Begriff sphärischer Abstand19 . Der sphärische Abstand (Distanz) 19 [Dör50, S. 303] 52 6. Definition und Analyse der Flugkenngrößen zweier Punkte der Kugelfläche ist die Länge des kürzeren der beiden sie verbindenden Hauptbogen (Siehe Abbildung 6.1). Abbildung 6.1.: Sphärischer Abstand zwischen zwei Punkten P1 und P2 der Kugeloberfläche [Kom09] Die sphärische Distanz oder kürzeste Entfernung g zweier Orte einer Kugelfläche findet man durch Anwendung des Cosinussatzes auf das Kugeldreieck N P1 P2 , wobei N die Koordinate des Nordpols, P1 und P2 die Koordinaten der beiden Orte gegeben durch Breiten lat1 bzw. lat2 und Längen lon1 bzw. lon2 bezeichnen20 : N P1 = π 2 − lat1 , N P2 = π 2 − lat2 , ∠P1 N P2 = lon1 − lon2 und P1 P2 = g. Nach dem Cosinussatz gilt: cos (g) = sin (lat1 ) sin (lat2 ) + cos (lat1 ) cos (lat1 ) cos (lon1 − lon2 ) ⇒ g = arccos (sin (lat1 ) sin (lat2 ) + cos (lat1 ) cos (lat2 ) cos (lon1 − lon2 )) Es wurde die sphärische Distanz in Grad (Seemeilen) gefunden. Um jetzt den Abstand S in Meter zu finden, muss man diese mit dem Radius der Erde an der betrachteten Stelle multiplizieren. Man nehme einfachheitshalber an, dass die Erde kugelförmig ist21 . Für WGS84 20 21 Vgl. [Dör50, S. 433] Tatsächlich ist die Erde ein Ellipsoid mit unterschiedlichen äquatorialen und polaren Radien 53 6. Definition und Analyse der Flugkenngrößen ist der Radius der Erdkugel gleich 6378137 Meter22 . Damit ist die gesuchte Distanz zwischen zwei Flugzeugen gegeben durch: S = arccos (sin (lat1 ) sin (lat2 ) + cos (lat1 ) cos (lat2 ) cos (lon1 − lon2 )) · 6378137. Die Annahme, dass die Erde kugelförmig ist, impliziert eine gewisse Ungenauigkeit der Berechnung. Diese liegt im schlimmsten Fall knapp über einem Promille23 . Für relativ kleine Gebiete wie z. B. Westeuropa ist die Genauigkeit also verträglich. Für größere Gebiete sollen zur Steigerung der Genauigkeit andere Verfahren wie z. B. besselsche Formel24 eingesetzt werden. 6.2. Berechnung des Treffpunktes zweier beweglichen Körper Die Frage, ob sich zwei Flugzeuge kritisch annähern oder generell auf entgegengesetzten Flugbahnen befinden, kann bei Flugüberwachung durchaus interessant sein. Dieses Problem kann auf die Berechnung des Treffpunktes zweier sich bewegenden Körper reduziert werden. 6.2.1. Berechnung in 2D Gegeben sind 2 punktförmige Körper A (x1 , y1 ) und B (x2 , y2 ), ihre Peilungen α und β und die Geschwindigkeiten v1 und v2 . Zu bestimmen ist, ob sich diese Punkte in einem dritten Punkt C (x, y) treffen. Abbildung 6.2.: Berechnung des Treffpunktes zweier beweglichen Körper [Gil97, S. 470] [Mey02, S. 2] 24 [Gil97, S. 470] 22 23 54 6. Definition und Analyse der Flugkenngrößen Man löse die gegebene Aufgabe auf folgende Weise: 1. Für gegebene Punkte A und B baue beliebige Richtungsvektoren ~a und ~b, deren Richtungen den von Geschwindigkeitsvektoren v~1 bzw. v~2 entsprechen; 2. Finde die Gleichungen vom Typ y = k · x + b der Geraden a und b, die durch Punkte A bzw. B entlang Geschwindigkeitsvektoren v~1 bzw. v~2 verlaufen: a(x) = k1 · x + b1 , b(x) = k2 · x + b2 ; 3. Finde den Punkt C (x, y), wo sich beide Geraden schneiden; 4. Berechne die Zeitspannen t1 und t2 , die die Punkte A bzw. B brauchen, um am Punkt C anzukommen; 5. Vergleiche die Zeitspannen. Zum beschriebenen Lösungsansatz sind folgende Ausnahmen denkbar: 1. Die Geschwindigkeit mindestens eines der Flugzeuge ist gleich 0. Dadurch ist die Berechnung der entsprechenden Zeitspanne nach Formel der Mechanik t = S v, wobei t die Zeitspanne, S die Entfernung und v die Geschwindigkeit bezeichnen, nicht möglich. 2. Bei α = π 2, α= 3π 2 , β= π 2 oder β = 3π 2 kann die entsprechende Gerade nicht in Form y = k · x + b beschrieben werden. Wenn man die Aufgabe bedenkt, für Lösung welcher die gesuchte Bedingung eingesetzt werden soll, kommt man zum Schluss, dass die erste Ausnahme trivial ist: wenn sich eins der Flugzeuge nicht bewegt, kann es sich nicht in der Luft befinden. Damit ist weder Kollision noch kritische Annäherung der Flugzeuge möglich. Die zweite Ausnahme ist dagegen nicht trivial. Wenn ein Punkt einen der genannten Richtungswinkel hat, ändert sich seine x-Koordinate nicht. Damit muss der Schnittpunkt der Geraden, auf den sich die Punkte, auf eine spezielle Weise ausgerechnet werden. Man nehme ohne Einschränkung der Allgemeinheit an, der Richtungswinkel des Punktes A sei gleich π 2. Wenn nun der zweite Punkt ebenso einen der Ausnahmewinkel hat, können sie nur dann kollidieren, wenn ihre x-Koordinaten gleich sind und sie sich in entgegengesetzten Richtungen bewegen. Wenn der zweite Punkt keinen „kritischen“ Winkel hat, so kann die Gleichung der Gerade, auf der er sich bewegt, in gewünschter Form beschrieben werden. Den Schnittpunkt beider Geraden kann man nun leicht finden, indem man die x-Koordinate des ersten Punktes in die Geradengleichung des zweiten Punktes einsetzt. Man nehme nun an, dass die beschriebenen Ausnahmenfälle ausgeschlossen sind. Damit 3π können die Richtungswinkel der Punkte nur Werte in Bereichen 0, π2 ∪ π2 , 3π 2 ∪ 2 , 2π annehmen. Um die Richtungsvektoren zu berechnen, betrachte man Punkte auf den Geraden a und b, die sich durch minimale Änderung ∆x der entsprechenden Koordinate x ergeben: 55 6. Definition und Analyse der Flugkenngrößen ( ∆x = , α ∈ 0, π2 ∪ 1 3π 2 , 2π , sonst. −1 In anderen Worten ist die Änderung der Koordinate x positiv, wenn sich der Richtungswinkel im 1. oder 4. Quadrant des kartesischen Koordinatensystem befindet, und negativ sonst. Die entsprechende Änderung der Koordinate y ist in diesem Fall gleich tanγ, wobei es gilt: γ = ∆x · α. Für den Punkt B werden die entsprechenden Größen analog definiert. Hierbei werden lediglich die Parameter ∆x und γ durch den entsprechenden Richtungswinkel β dargestellt. Um zwischen den zugehörigen Parametern der beiden Punkte unterscheiden zu können, statte man diese weiterhin mit den entsprechenden Indizes aus: ∆xa und γa für den Punkt A und ∆xb und γb für den Punkt B. Die Gleichungen der entsprechenden Geraden sind dann wie folgt definiert. Gerade a: x−x1 ∆xa = y−y1 tanγa ⇔y= tanγa ∆xa ·x− tanγa ∆xa Gerade b: x−x2 ∆xb = y−y2 tanγb ⇔y= tanγb ∆xb ·x− tanγb ∆xb · x 1 + y1 . · x 2 + y2 . Aus diesen Gleichungen halte man nun die entsprechenden Koeffizienten k und b fest: tanγa ∆xa a b1 = − tanγ ∆xa b k2 = tanγ ∆xb b b2 = − tanγ ∆xb k1 = · x1 + y1 · x2 + y2 Um die Koordinaten des Schnittpunktes C (x, y) der beiden Geraden zu finden (wenn ein solcher existiert), genügt es, die rechten Teile der beiden Geradengleichungen gleichzusetzen und die resultierende Gleichung nach x aufzulösen. Man definiere die Koordinaten x und y durch die Koeffizienten k1 , k2 , b1 und b2 . k1 x + b1 = k2 x + b2 ⇔ k1 x − k2 x = b2 − b1 ⇔ x = 1 y = k1 kb21 −b −k2 + b1 = k1 b2 −k1 b1 +k1 b1 −k2 b1 k1 −k2 = k2 b1 −k1 b2 k2 −k1 . b2 −b1 k1 −k2 ; Die Existenz des Schnittpunktes hängt nun von den Nennern der beiden Ausdrücke ab. Somit ist die erste Trefferbedingung gegeben durch: 1. k2 − k1 6= 0. Der Schnittpunkt beider Geraden muss nicht unbedingt auf dem Weg der beiden Körper A und B liegen: es kann durchaus sein, dass sich mindestens einer von den Körpern vom Schnittpunkt der beiden Flugbahnen entfernt. Um sicherzustellen, dass sich die beiden Körper ~ und BC ~ bauen und die Vorzeichen dem Schnittpunkt annähern, kann man Vektoren AC der einzelnen Koordinaten mit diesen der beiden Richtungsvektoren ~a = (∆xa , tanγa ) und ~b = (∆xb , tanγb ) vergleichen. Sind die Vorzeichen gleich, so bewegt sich der jeweilige Körper in Richtung des Schnittpunktes. Damit erhält man die zweite Trefferbedingung: 56 6. Definition und Analyse der Flugkenngrößen 2. sign(x − x1 ) = sign(∆xa ) ∧ sign(y − y1 ) = sign(tanγa ) ∧ sign(x − x2 ) = sign(∆xb ) ∧ sign(y − y2 ) = sign(tanγb ). Nun hat man die Koordinaten des Treffpunktes C zweier Körper A und B parat. Mit diesem Wissen wird die Berechnung der Zeitspanne, die die Punkte brauchen, um am Punkt C anzukommen, sehr einfach: t1 = dist(A,C) , v1 t2 = dist(B,C) , v2 wobei dist(A, C) und dist(B, C) die sphärische Distanzen zwischen Punkten A und C bzw. B und C bezeichnen. Zu bestimmen ist nur noch, ob die beiden Körper am Treffpunkt gleichzeitig ankommen. Dies impliziert die Gleichheit beider Zeitspannen t1 und t2 . Somit erhält man die dritte Trefferbedingung: 3. dist(A,C) v1 = dist(B,C) . v2 Wenn nun alle drei Trefferbedingungen gleichzeitig erfüllt sind, treffen sich beide bewegliche Punkte an einem geographischen Ort. 6.2.2. Berechnung in 3D Die oben beschriebenen Trefferbedingungen gelten auch im dreidimensionalen Raum mit dem Unterschied, dass sich die Punkte zum Zeitpunkt der Annäherung auf der gleichen Höhe befinden müssen, damit diese als kritisch gilt. Zur Erinnerung ist die Zeit, die die Punkte benötigen, um aneinander kritisch zu nähern, gegeben durch: t1 = dist(A,C) v1 und t2 = dist(B,C) . v2 Hat man die Starthöhen h1 , h2 und Steigungen s1 , s2 der Punkte parat, so lassen sich die Höhen der Punkte am Zeitpunkt der kritischen Annäherung berechnen. Damit ist die vierte Trefferbedingung gegeben durch: 4. h1 + s1 · t1 = h2 + s2 · t2 . 6.2.3. Genauigkeit Die definierten Trefferbedingungen zweier Körper gelten im Idealfall, wenn die Körper punktförmig sind. In der Tat werden aber diese Bedingungen zur Beobachtung von Flugzeugen eingesetzt, deren Abmessungen nicht vernachlässigt werden können. Darüber hinaus ist die Situation, wenn zwei Flugzeuge an genau einem Punkt ankommen, höchstens unwahrscheinlich. Dennoch gelten als kritisch Konstellationen zweier Flugzeuge, die relativ nah aneinander vorbei fliegen. All dies bringt zur Idee, eine kritische Distanz zwischen zwei Flugzeugen zu definieren und Abweichungen in die definierten Trefferbedingungen einzubeziehen. Seien zwei Punkte M und N der Flugbahnen zweier Flugzeuge in der Abbildung 6.2 so gegeben, dass sie von den beiden Flugzeugen gleichzeitig erreicht werden. Die Distanz zwi- 57 6. Definition und Analyse der Flugkenngrößen schen diesen gelte als kritisch. Man beobachte, dass sich die Flugbahnen bei einer solchen Annäherung nach dem Erreichen dieses kritischen Bereiches dennoch schneiden würden. Das heißt, dass die Trefferbedingungen 1-3 auch diesen Fall abdecken. Nun ist der einzige Teil der Trefferbedingungen, der durch die Einführung kritischer Distanz angepasst werden muss, der Zeitpunkt, an dem der Punkt C in der Abbildung 6.2 von den beiden Flugzeugen erreicht wird. Man nehme an, die mittlere Geschwindigkeit eines Flugzeuges sei 800km/h = 222, 2m/s. Bei dieser Geschwindigkeit würde ein Flugzeug in einer Sekunde über 222 Meter zurücklegen. Man nehme nun die Distanz von maximal 444 Meter als kritisch an. Daraus ergibt sich die unkritische Zeitdifferenz des Erreichens eines Punktes von zwei Flugzeugen, die dann gleich 2 Sekunden ist. Durch Einführung dieser Abweichung verändern sich etwas die Trefferbedingungen 3 und 4, die dann wie folgt aussehen. dist(B,C) 3. dist(A,C) − < 2; v1 v2 4. h1 + s1 · dist(A,C) − h2 − s2 · v1 dist(B,C) v2 < 444. Es sei bemerkt, dass sich die angenommene kritische Distanz nun bei Bedarf sehr leicht verändern lässt. 6.3. Punkt-in-Polygon-Problem Beantwortung der Frage, ob sich ein Flugzeug innerhalb eines Areals befindet, kann auf das Punkt-in-Polygon-Problem reduziert werden. Für dieses Problem gibt es mehrere Lösungen. Die einfachste davon ist die Strahlmethode: man zeichne aus dem betrachteten Punkt heraus einen beliebigen Strahl und zähle, wie viele Seiten des Polygons dieser schneidet. Wenn die Anzahl ungerade ist, so liegt der Punkt innerhalb des Polygons, sonst liegt er außerhalb des Polygons. Es ist aber wünschenswert, dass die Lösung in Form eines SQL-Ausdrucks definierbar ist. In dieser Form kann der StrahlmethodenAlgorithmus leider nicht ausgedrückt werden. Als eine bessere Lösung des gegebenen Problems in Hinsicht auf Darstellbarkeit in Form eines SQL-Ausdrucks bietet sich die Winkelsummierungsmethode25 . Wie der Name schon sagt, impliziert die Methode eine Aufsummierung der Winkel. Anhand des Ergebnisses der Summierung kann anschließend die Frage beantwortet werden, ob der Punkt im Polygon liegt. Anwendung der Winkelsummierungsmethode auf den aktuellen Fall erfordert daher zusätzlich eine Lösung für das Problem der Berechnung des Winkels zwischen zwei Vektoren. 25 [Iva74, S. 13] 58 6. Definition und Analyse der Flugkenngrößen 6.3.1. Berechnung des Winkels zwischen zwei Vektoren Der Winkel α zwischen zwei Vektoren ~a und ~b lässt sich aus der Formel des Skalarproduktes26 leicht herleiten: ~a · ~b = |~a| · ~b · cosα ⇒ cosα = ~a·~b |~a|·|~b| ⇒ α = arccos ~a·~b |~a|·|~b| (I) Hier stellt sich schon das nächste Problem. Bei Lösung des gegebenen Problems betrachtet man nur spitze Winkel. Kosinus ist eine gerade Funktion, d.h. für spitze Winkel liefert sie stets positive Werte, egal welches Vorzeichen der Winkel hat. Aus diesem Grund liefert auch die Arkuskosinus-Funkion im gegebenen Fall immer nur positive Winkel. Für die aktuelle Aufgabe ist das Vorzeichen des Winkels jedoch maßgeblich und ist als relative Drehrichtung zu verstehen (siehe Abschnitt 6.3.3, Abbildung 6.4). Es ist also nicht möglich, die aktuelle Aufgabe allein mit Hilfe der Formel (I) zu lösen. 6.3.2. Vektorprodukt zweier Vektoren Man teile die Typen der Winkel zwischen zwei Vektoren in zwei Gruppen ein: • Drehungen im mathematisch positiven Drehsinn. Die entsprechenden Winkel sind positiv. • Drehungen im mathematisch negativen Drehsinn. Die entsprechenden Winkel sind negativ. Im Grunde kann eine solche Einteilung durch Multiplikation der Winkel mit einem Faktor f erzielt werden: ( 1 für den mathematisch positiven Drehsinn f= −1 für den mathematisch negativen Drehsinn Der jeweilige Faktor kann nun mit Hilfe des Vektorproduktes27 (Kreuzproduktes) gefunden werden. Die Bedeutung des Vektorproduktes ist in der Abbildung 6.3 zu sehen: Die Vektoren ~a × ~b und ~b × ~a sind entgegengesetzt orientiert und haben den gleichen Betrag aber unterschiedliche Vorzeichen. ax bx Das vektorielle Produkt der Vektoren ~a = ay und ~b = by aus R3 ist gegeben durch: az bz 26 27 [MA96, S. 107] [MA96, S. 116] 59 6. Definition und Analyse der Flugkenngrößen Abbildung 6.3.: Bedeutung des Vektorproduktes zweier Vektoren [MA96, S. 113] ~a × ~b = (ay bz − az by ) e~x + (az bx − ax bz ) e~y + (ax by − ay bx ) e~z ay bz − az by = az bx − ax bz . ax by − ay bx Für zwei Punkte einer Ebene sind die Koordinaten az und bz konstant. Man nehme einfachheitshalber an az = 0 und bz = 0. Dann ist das Kreuzprodukt zweier Vektoren einer Ebene gegeben durch: 0 ~a × ~b = 0 . ax by − ay bx Man benutze nun das Vorzeichen der dritten Koordinate des Kreuzproduktes als den gesuchten Faktor f , der den Drehsinn der Winkel zwischen Vektoren angibt. 6.3.3. Winkelsummierungsmethode Nun hat man alle erforderlichen Lösungen der Teilprobleme parat. Jetzt kann das eigentliche Punkt-in-Polygon-Problem gelöst werden. Es sei ein Polygon als Folge von Punkten P [1], P [2], ..., P [N ] gegeben. Die Aufgabe ist zu prüfen, ob ein beliebiger Punkt A innerhalb des aus den gegebenen Punkten bestehenden Polygons liegt. Um das Problem zu lösen, berechne man die Winkel α1 = (P [1], A, P [2]) , α2 = (P [2], A, P [3]) , ..., αN = (P [N ], A, P [1]) P P mit dem jeweiligen Vorzeichen und summiere diese auf: = α1 + α2 + ... + αN . Falls =0 P gilt, so liegt der Punkt außerhalb des Polygons. Sonst gilt = ±2π, und der Punkt liegt somit innerhalb des Polygons. Eine Beispielsinstanz für das Punkt-in-Polygon-Problem ist in der Abbildung 6.4 zu sehen: a) Punkt X liegt außerhalb des Polygons. Die Winkel mit positivem Drehsinn sind grün gezeichnet, mit negativem Drehsinn - rot. Die Summe der Winkel ergibt 0. b) Punkt X liegt innerhalb des Polygons. Alle Winkel sind positiv (oder negativ, je nach gewählter Richtung) und die Summe der Winkel ergibt somit ±2π. 60 6. Definition und Analyse der Flugkenngrößen Abbildung 6.4.: Winkelsummierungsmethode Nun muss man lediglich sicherstellen, dass alle Grenzfälle abgedeckt sind. Es sind zwei Grenzfälle denkbar: 1. Punkt X liegt auf einer Seite (z. B. AB) des Polygons; 2. Punkt X liegt auf einer Ecke (z. B. A) des Polygons. Im ersten Fall würde ∠AXB = π gelten und die Methode würde weiterhin funktionieren. Interessanter ist der zweite Fall: da Punkt X genau auf dem Punkt A liegt, sind die Winkel ∠AXB und ∠EXA undefiniert28 . Aus diesem Grund muss vor dem Einsatz der Winkelsummierungsmethode eine Überprüfung erfolgen, ob der zu betrachtende Punkt X auf einem der Eckpunkte liegt. In diesem Fall kann es ohne jeglicher Berechnung behauptet werden, dass sich der Punkt innerhalb des Polygons befindet. Es sei allerdings bemerkt, dass ein solcher Grenzfall höchstens unwahrscheinlich ist. Im Abschnitt A.1 des Anhangs findet sich die Implementierung einer Funktion in VB.NET, die einen SQL-Ausdruck zur Bestimmung der Zugehörigkeit eines Punktes einem festgelegten Bereich mittels Winkelsummierungsmethode generiert. Dabei wird zur Festlegung der geographischen Region die Kartenanwendung des entwickelten Systems benutzt. 28 ~ im Nenner erscheinen und Division Bei Berechnung der genannten Winkel würde die Länge des Vektors AX durch 0 verursachen. 61 7. Berechnung von Flugkenngrößen mittels SQL 7. Berechnung von Flugkenngrößen mittels SQL Im letzten Kapitel wurden Beispielsanfragen von verschiedenen Typen definiert und ihre möglichen mathematischen Lösungen präsentiert. Diese Beispeilsanfragen können nun in SQL übersetzt werden, um diese anschließend mit Hilfe des in Kapitel 5 realisierten Flugüberwachungssystems auswerten zu lassen. In diesem Kapitel findet die Diskussion über die Realisierungsmöglichkeiten verschiedener Flugkenngrößen statt. Definitionen der Beispielsanfragen werden zur Analyse erst im TupelKalkül aufgeschrieben und dann in SQL implementiert. Die besten Lösungen in Bezug auf Effizienz und Übersichtlichkeit können dann als endgültige Indikatoren zur Beobachtung der interessanten Ergebnismengen benutzt werden. 7.1. Ermittlung aktueller Fluginformationen Das im Abschnitt 4.2.1 erläuterte Import-Verfahren vereinfacht die Auswahl der aktuellen Datensätze. Man muss lediglich die ID des letzten Imports wissen, in Rahmen dessen Flüge importiert wurden. Als Beispiel für eine Kenngröße, die aktuelle Fluginformationen liefert, stelle man etwa die folgende: Welche Flugzeuge sind im Moment unterwegs? Das Ergebnis der Auswertung dieser Anfrage muss alle Flüge enthalten, die zum letzten Import des Objekttyps „Flight“ gehören. Eine Variante der Implementierung dieser Anfrage aufgeschrieben im Tupel-Kalkül sieht wie folgt aus: {f |f ∈ F lugzeug ∧ ¬∃i ∈ Import (i.ImportableObjectT ype = „F light“∧ i.ID > f.ImportID)}. Der Ausdruck lässt sich einfach in SQL übersetzen. Der entsprechende Code ist im Listing 7.1 zu finden. 62 7. Berechnung von Flugkenngrößen mittels SQL Listing 7.1: 1. Variante des Codes der Anfrage „Welche Flugzeuge sind im Moment unterwegs?“ 1 2 3 4 5 6 7 8 SELECT f.∗ FROM Flight f WHERE NOT EXISTS ( SELECT ID FROM Import i WHERE i.ImportableObjectType = ’FlightMonitor.ClassLibrary.Flight’ AND i.ID > f.ImportID ) Es sei bemerkt, dass die angegebene Anfrage einen EXISTS -Ausdruck mit einer Unteranfrage enthält. In manchen DBMS wie z. B. MySQL können Unteranfragen nicht effizient verarbeitet werden, weil hierfür keine automatische Optimierung vorgesehen ist. Daher kann die Komplexität der Anfrage in O-Notation als O (n · m) geschätzt werden, wobei m die Anzahl von Imports im System und n die Anzahl der Flüge in einem Import bezeichnen29 . Im Abschnitt 5.4.7 wurde erwähnt, dass die ID-Werte der letzten Imports verschiedener Objekttypen im Speicher festgehalten werden und bei Definition der Anfrage durch MetaParameter hervorgerufen werden können. Somit wird die Anzeige der Liste der aktuellen Flüge zu einer relativ einfachen Aufgabe. Der entsprechende Kalkül-Ausdruck für diese Variante sieht nun wie folgt aus: {f |f ∈ F lugzeug ∧ f.ImportID = hLastF lightImportIDi} Der die aktuelle Kenngröße implementierende SQL-Code, der diesem Ausdruck entspricht, kann Listing 7.2 entnommen werden. Listing 7.2: 2. Variante des Codes der Anfrage „Welche Flugzeuge sind im Moment unterwegs?“ 1 2 3 SELECT Flight.∗ FROM Flight WHERE ImportID = <LastFlightImportID> Für eventuelle spätere Wiederverwendung gebe man dieser Kenngröße den Namen „LastImportFlights“. Als Rückgabetyp der Anfrage ist hier eine Liste von Datenobjekten vom Typ Flight zu verwenden. Es sei bemerkt, dass ein genaueres Ergebnis erzielt werden kann, wenn man von der Uhrzeit des Imports das Alter des jeweiligen Datensatzes subtrahiert und das Resultat zur Bestimmung der Aktualität des betroffenen Datensatzes benutzt. Man könnte die Anfrage beispielsweise so umformulieren, dass es nur Datensätze in der Ergebnismenge landen, die zum Zeitpunkt der Anfrageauswertung maximal 30 Sekunden alt waren. 29 Die tatsächliche Komplexität ist allerdings kleiner, da sowohl Spalte ID der Tabelle Import als auch Spalte ImportID der Tabelle Flight indiziert sind. 63 7. Berechnung von Flugkenngrößen mittels SQL 7.2. Ermittlung von Flugzeugen eines spezifischen Typs Die Ermittlung der Flugzeuge von einem spezifischen Typ erfolgt durch Anwendung eines Filters auf die Spalte Type der Tabelle Flight. Als Beispiel für eine Anfrage dieses Typs definiere man etwa die folgende: Wie viele Flugzeuge des Typs Airbus A320 sind im Moment unterwegs? Für die Implementierung dieser Anfrage sind zwei Filter anzuwenden: 1. Filterung der Flüge nach ID des letzten Imports; 2. Filterung der Flugzeuge nach dem gegebenen Typ (Airbus A320). Sicherlich wird der SQL Server die Anfrage vor der Ausführung analysieren, um die Filterreihenfolge erst zu optimieren. Um dennoch datenbanksystemunabhängig bleiben zu können, kann man nicht von der automatischen Optimierung ausgehen. Es wird weiterhin angenommen, dass die Filterausdrücke in der angegebenen Reihenfolge ausgewertet werden. Damit muss die Reihenfolge so festgelegt werden, dass die Filterausdrücke von links nach rechts möglichst viele Datensätze aussortieren. Zuerst ist es zu entscheiden, wie der erste Filter realisiert werden muss. Hierfür gibt es mindestens zwei Möglichkeiten. Die erste besteht darin, die im Abschnitt 7.1 definierte Kenngröße mit Hilfe von Meta-Parametern als Unteranfrage zu verwenden und unnötige Datensätze durch Überprüfung der Mengenzugehörigkeit (Schlüsselwort IN ) auszumustern. Der entsprechende Ausdruck im Tupel-Kalkül sähe dann folgendermaßen aus: {f |f ∈ F light ∧ f ∈ hLastImportF lightsi ∧ f.T ype = „A320“}. Die zweite Möglichkeit sieht Benutzung der gleichen Filterbedingung wie in 7.1 (WHERE ImportID = hLastF lightImportIDi). Es wurde bereits erwähnt, dass die Verwendung von Unteranfragen in einigen DBMS mit großem Aufwand verbunden ist. Daher soll hier die zweite Variante bevorzugt werden. Nun muss die Entscheidung getroffen werden, welche Filterbedingung als erste anzuwenden ist. Es muss bekanntlich diejenige sein, die größere Mengen von Datensätzen aus dem Ausgangsdatenbestand aussortiert und/oder schneller anwendbar ist. Filterung nach ID des Imports belässt maximal 200 Datensätze im Ergebnis30 . Darüber hinaus wurde die Spalte ImportID der Tabelle Flight als Fremdschlüssel mit dem Verweis auf die ID-Spalte der Tabelle Import angelegt und ist somit indiziert. Andererseits ist es schwer vorzusehen, wie viele Datensätze durch Anwendung des zweiten Filters ausgefiltert werden. Wenn der Datenbestand groß genug ist, werden sicherlich mehr als 200 Datensätze dem Filter entsprechen, da der Flugzeugtyp Airbus A320 relativ oft beflogen wird. Darüber hinaus ist die Spalte Type der Tabelle Flight nicht indiziert. Somit wird es deutlich, dass Filterung nach ID des Imports zuerst erfolgen soll. 30 Bei Verwendung von OpenATC als Datenquelle. 64 7. Berechnung von Flugkenngrößen mittels SQL Dieser Variante der Implementierung der aktuellen Anfrage entspricht folgender Ausdruck im Tupel-Kalkül: {f |f ∈ F light ∧ f.ImportID = hLastF lightImportIDi ∧ f.T ype = „A320“}. Die Anzahl der Flugzeuge vom gegebenen Typ kann nun durch Anwendung von Aggregationsfunktion COUNT ermittelt werden. Somit kann der SQL-Text der Anfrage wie im folgenden Listing 7.3 aufgeschrieben werden. Listing 7.3: Code der Anfrage „Wie viele Flugzeuge des Typs Airbus A320 sind im Moment unterwegs?“ 1 2 3 4 SELECT COUNT(Flight.ID) AS A320Count FROM Flight WHERE ImportID = <LastFlightImportID> AND Type = ’A320’ Man gebe der Kenngröße den Namen „LastImportA320Count“ und lege einen Skalar als Rückgabetyp fest. 7.3. Filterung der Flugzeuge nach Position und Höhe Eine Filterung nach Position und Höhe könnte z. B. interessant sein, um festzustellen, für welche Flüge genaue Höhenangaben vorliegen31 . Die Höhe des jeweiligen Flugzeuges wird sowohl als Text in der Spalte Altitude der Tabelle Flight als auch umgerechnet in Meter in der Spalte AltitudeMeter gespeichert. Dabei lässt es sich anhand des Wertes in der Spalte Altitude leicht feststellen, welche Flugzeuge sich unter FL0 befinden: • Bei Flugzeugen, die sich über FL0 befinden, besteht der Höhenwert aus zwei Buchstaben „FL“ gefolgt von der jeweiligen Flugflächennummer. • Bei Flugzeugen, die sich unter FL0 befinden, besteht der Höhenwert aus der Höhenangabe in Fuß gefolgt von zwei Buchstaben „ft“. Ausmusterung der veralteten Datensätzen erfolgt wie bei den beiden oben beschriebenen Kenngrößen. Die Filterreihenfolge soll unter Berücksichtigung der Beobachtungen aus dem Abschnitt 7.2 festgelegt werden. Somit ist der gesamte Code der Anfrage gegeben durch: Listing 7.4: Code der Anfrage „Welche Flugzeuge befinden sich aktuell unter FL0?“ 1 2 3 4 SELECT Flight.∗ FROM Flight WHERE ImportID = <LastFlightImportID> AND Altitude LIKE ’%ft’ Für die aktuelle Kenngröße vergebe man den Namen „LastImportFlightsUnderFL0“ und lege als Rückgabetyp eine Liste von Datenobjekten vom Typ Flight fest. 31 Für Flugzeuge, die FL0 noch nicht erreicht bzw. FL0 unterschritten haben, liegt die genaue Höhenangabe in Fuß über dem Flugplatz vor. 65 7. Berechnung von Flugkenngrößen mittels SQL 7.4. Bestimmung von landenden Flugzeugen Als Beispiel für eine Anfrage, die nicht ausschließlich auf den im System befindenden Flugdaten aufbaut, könnte etwa folgende betrachtet werden: „Wie viele Flugzeuge befinden sich im Landeanflug?“ Man muss zur Lösung der Aufgabe einen Filter anwenden, der Flüge mit negativer Steigung ausgibt. Das Problem ist aber, dass Flugzeuge ihre Höhe auch während des Fluges ändern können, um z. B. schwere Turbulenzen zu vermeiden. Für eine genaue Ermittlung der Menge von landenden Flugzeugen sind Flugpläne erforderlich, die unter anderem den Bestimmungsort (vorzugsweise mit den geeigneten GPS Koordinaten) des jeweiligen Fluges beinhalten. Die Flugplan-Informationen können allerdings mittels der aktuellen Variante des Werkzeugs nicht in die Datenbank importiert werden. Eine andere Variante, diese Anfrage zu implementieren, besteht darin, aus der Menge aller Flugzeuge, deren Höhe sich verringert, nur diejenige ausgeben zu lassen, die sich zusätzlich relativ nah zu einem Flughafen befinden. Die Flughafeninfos, unter anderem ihre geographischen Orte, können in das System mit Hilfe der bestehenden Import-Funktionalität des Werkzeugs importiert werden. Damit kann eine solche Bedingung durchaus realisiert werden. Formal aufgeschrieben sieht die genannte Anfrage wie folgt aus: {f |f ∈ F lugzeug ∧ f.Incline < 0 ∧ CloseT oAirport (f )}. Man betrachte die Relation CloseT oAirport. Diese beinhaltet einen versteckten Ausdruck, der für jedes Tupel vom Typ Flugzeug in der Menge aller Flughäfen mindestens einen finden soll, der zum angegebenen Flugzeug „nah genug“ liegt. Als „nah genug“ nehme man etwa einen Radius von 20km = 20000m um den jeweiligen Flughafen. Damit der Gesamtausdruck keine versteckten Tupel enthält, soll die Relation CloseT oAirport weiter aufgespaltet werden: {f |f ∈ F lugzeug ∧ f.Incline < 0 ∧ ∃f h ∈ F lughaf en (dist (f, f h) <= 20000)}. Die Daten der Flughäfen, die in der Tabelle Airport der Datenbank abgespeichert werden, enthalten GPS -Positionen der Flugplätze. Die Entfernung zwischen einem Flugzeug und einem Flughafen, die durch Relation dist im Tupel-Ausdruck repräsentiert wird, lässt sich mit Hilfe der Formel aus dem Abschnitt 6.1 berechnen. Die Berechnung der Distanz zwischen zwei Punkten kann in diesem konkreten Fall in SQL auf zwei Weisen realisiert werden: 1. Direkte Anwendung der Formel in der WHERE -Klausel; 2. Speicherung der Formel in Form einer benutzerdefinierten Funktion in der Datenbank32 . Die Wahl zwischen den beiden Varianten der Implementierung soll mit Hinsicht auf die gewünschte Optimierung erfolgen. Die erste Variante soll benutzt werden, wenn die Effizienz der Auswertung der aktuellen Anfrage wichtig ist. In der Tat braucht der Datenbankserver weniger Zeit zur Ausführung der ersten Variante, da die Formel direkt angewendet werden kann. Bei der zweiten Variante braucht das DBMS für jeden Kandidat-Datensatz zusätzliche 32 Diese Variante ist natürlich nur dann möglich, wenn das hinter der Software stehende DBMS Erstellung von benutzerdefinierten Funktionen zulässt. 66 7. Berechnung von Flugkenngrößen mittels SQL Zeit für den Aufruf der Funktion sowie für die Erteilung des Speichers für lokale Variablen der Funktion. Dennoch sollte die Implementierung der Entfernungsformel als benutzerdefinierte Funktion bevorzugt werden, wenn diese von anderen Anfragen benutzt werden soll, um den Code zentral zu halten. Man wähle für die Implementierung der aktuellen Kenngröße die zweite Variante aus folgenden Gründen: • Die Entfernungsfunktion wird für mehrere noch zu implementierende Anfragen benötigt. • Anwendung von zusätzlichen Filtern auf die Datenmenge reduziert die Menge der KandidatDatensätze im gegebenen Fall dermaßen, dass der zusätzliche Aufwand zum Aufrufen der benutzerdefinierten Funktion verträglich wird. Die Berechnung der Distanzfunktion erfolgt genau nach der im Abschnitt 6.1 definierten Formel. Die Implementierung der Funktion in SQL ist im Anhang A.3 Abschnitt A.3.1 zu finden. Nun kann die Zielkenngröße zusammengesetzt werden. Spaltenbezogene Filter sollen in der WHERE -Klausel vor dem Aufruf der Distanzfunktion angewendet werden, da sie deutlich weniger Aufwand verursachen und die Anzahl der Kandidat-Datensätze, für die die aufwändige Distanzfunktion aufgerufen werden soll, potenziell sehr stark reduzieren. Es sind zusätzlich folgende Filter notwendig: • Filter nach ID des Flugimports, um die Datenmenge nur auf die Flüge des letzten Imports zu beschränken; • Filter nach ID des Flughafenimports, um die Datenmenge nur auf die Flughäfen des letzten Imports zu beschränken; • Filter nach Steigung, um die Kandidat-Menge der Flüge nur auf diejenigen zu beschränken, deren Höhe sich verringert. Die Reihenfolge der spaltenbezogenen Filterbedingungen soll entsprechend den Überlegungen aus den vorherigen Abschnitten festgelegt werden. Somit sieht der gesamte SQL-Code der aktuellen Kenngröße folgendermaßen aus: Listing 7.5: Code der Anfrage „Welche Flugzeuge befinden sich im Landeanflug?“ 1 2 3 4 5 6 7 8 9 SELECT f.∗ FROM Flight f WHERE f.ImportID = <LastFlightImportID> AND f.Incline < 0 AND EXISTS ( SELECT ID FROM Airport a WHERE a.ImportID = <LastAirportImportID> AND dbo.getDistance(f.Longitude, f.Latitude, a.Longitude, a.Latitude) <= 20000 ) 67 7. Berechnung von Flugkenngrößen mittels SQL Man gebe der Kenngröße den Namen „LastImportLandingFlights“ und lege eine Liste von Datenobjekten vom Typ Flight als Rückgabetyp fest. Die Ausführung dieser Anfrage auf einer Testdatenmenge hat ergeben, dass die Auswertung knapp über 3 Sekunden in Anspruch nimmt. Zum Vergleich dauert die Auswertung der gleichen Anfrage, in der die Berechnung der Distanz direkt in der WHERE -Klausel erfolgt, unter einer Sekunde. Das bedeutet, dass die Effizienz der Kenngröße bei Bedarf (etwa bei Verwendung in der Definition einer anderen Anfrage) deutlich verbessert werden kann. 7.5. Feststellung einer kritischen Annäherung Sicherheit ist einer der Grundbausteine im Luftverkehr. Zur wichtigsten Sicherheitsmaßnahmen gehört eine ständige Beobachtung des Luftverkehrs und ein rechtzeitiges Eingreifen in kritischen Situationen. Kritische Annäherung zweier oder mehrerer Flugzeuge ist sicherlich eine der Situationen, die so früh wie möglich festgestellt werden müssen, damit Piloten der betroffenen Flugzeuge rechtzeitig über die Lage informiert werden können. In diesem Abschnitt wird eine Kenngröße definiert, die folgende Frage beantwortet: „Welche Flugzeuge nähern sich kritisch?“ Eine mathematische Lösung des Problems kritischer Annäherung zweier Flugzeuge wurde im Abschnitt 6.2 erläutert. Im Grunde stellt die Lösung nicht nur kritische Annäherung der Flugzeuge fest, sondern allgemein, ob sich zwei Flugzeuge auf Flugbahnen befinden, die sich in einem Punkt schneiden. Die gefundene Lösung besteht aus vier Bedingungen, die gleichzeitig erfüllt sein müssen, damit die Situation als kritisch eingestuft werden kann. Dabei müssen nur Flüge betrachtet werden, die aktuell unterwegs sind, d.h. zu demselben Import gehören. Eine weitere Filterbedingung soll dafür sorgen, dass die Kollisionsfunktion nur für verschiedene Flugzeuge aufgerufen wird33 . Der entsprechende Ausdruck im Tupel-Kalkül ist gegeben durch: {f1 |f1 ∈ F lugzeug ∧ f1 .ImportID = hLastF lightImportIDi ∧ ∃f2 ∈ F lugzeug (f2 .ID 6= f1 .ID ∧ f2 .ImportID = f1 .ImportID ∧ ConvergeCritically (f1 , f2 ))}. Im vorherigen Abschnitt wurde bereits darüber diskutiert, dass komplexere Filterbedingungen für eine bessere Lesbarkeit in Form einer benutzerdefinierten Funktion gespeichert werden können. Die daraus resultierende Definition der entsprechenden Kenngröße wird dann allerdings nicht optimal in Bezug auf die Laufzeit der Auswertung. In diesem konkreten Fall würde allerdings die Benutzung der Bedingungen direkt in WHERE -Klausel die Übersichtlichkeit des Ausdrucks komplett zerstören. Aus diesem Grund wird die Speicherung der Bedingungen in Form einer benutzerdefinierten Funktion bevorzugt. 33 Ein Aufruf der Kollisionsfunktion mit den gleichen Angaben für die beiden zu überprüfenden Flugzeuge wird logischerweise eine Kollision feststellen. 68 7. Berechnung von Flugkenngrößen mittels SQL Der Code der benutzerdefinierten Funktion doCollide ist im Abschnitt A.3.2 des Anhangs zu finden. Bei der Definition der Funktion wurden etliche Optimierungen vorgenommen: die Bedingungen, die es erlauben festzustellen, dass keine kritische Annäherung möglich ist, werden so früh wie möglich überprüft. Der gesamte Code der resultierenden Kenngröße ist folgendem Listing 7.6 zu entnehmen. Listing 7.6: Code der Anfrage „Welche Flugzeuge nähern sich kritisch?“ 1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT f1.∗ FROM Flight f1 WHERE f1.ImportID = <LastFlightImportID> AND EXISTS ( SELECT f2.ID FROM Flight f2 WHERE f2.ID <> f1.ID AND f2.ImportID = f1.ImportID AND dbo.doCollide(f1.Longitude, f1.Latitude, f1.AltitudeMeter, f1. Incline , f1 .Speed / 3.6, f1 .Angle ∗ PI() / 180, f2 .Longitude, f2 .Latitude, f2 .AltitudeMeter, f2. Incline , f2 .Speed / 3.6, f2 .Angle ∗ PI() / 180) = 1 ) Beim Aufrufen der Funktion doCollide sind folgende Umwandlungen notwendig: • Die Geschwindigkeiten der Flugzeuge werden in der Datenbank in Stundenkilometern gespeichert. Daher müssen diese beim Aufruf in Meter-Pro-Sekunde umgerechnet werden (1km/h = 1000/3600m/s = 0, 2777777778m/s). • Die Peilungen der Flugzeuge werden in der Datenbank in Grad gespeichert. Die Berechnungen in der Funktion doCollide erfolgen jedoch in Radiant. Aus diesem Grund ist vor dem Aufruf eine Umrechnung von Grad in Radiant notwendig (1◦ = π 180 = 0.0174532925). Man vergebe der Funktion den Namen „LastImportCriticallyConvergingFlights“ und lege eine Liste von Datenobjekten des Typs Flight als Rückgabetyp fest. Ein Test der Performanz hat erwiesen, dass die durchschnittliche Laufzeit der Anfrage bei knapp zwei Sekunden liegt. Damit ist die aktuelle Implementierung der Lösung des Problems akzeptabel. 7.6. Flugbewegungen innerhalb eines vordefinierten Gebiets Im Abschnitt 6.3.3 wurde die Winkelsummierungsmethode erläutert, die es ermöglicht festzustellen, ob sich ein Punkt innerhalb eines Polygons befindet. Diese Methode kann nun zur Feststellung der Zugehörigkeit der Position eines Flugzeuges einem bestimmten Gebiet benutzt werden. Man formuliere beispielsweise folgende Anfrage: Welche Flugzeuge befinden 69 7. Berechnung von Flugkenngrößen mittels SQL sich momentan über London? Formal aufgeschrieben sieht die genannte Kenngröße wie folgt aus: {f |f ∈ F lugzeug ∧ f.ImportID = hLastF lightImportIDi ∧ IsOverLondon (f )}. Hierbei bestimmt die Relation IsOverLondon, ob sich das angegebene Flugzeug innerhalb des vordefinierten Gebiets befindet. In der Tat wird zur Feststellung der Zugehörigkeit einem vordefinierten Gebiet lediglich die geographische Position des Flugzeuges benötigt. Damit soll der Verweis auf die Relation im gegebenen Beispiel durch folgenden Ausdruck erfolgen: IsOverLondon (f.Longitude, f.Latitude). Die Festlegung des Londoner Gebiets erfolgt durch Angabe der Eckpunkte eines Polygons, das ungefähr die Stadtgrenzen von London widerspiegelt. Zur Definition eines geographischen Gebietes ist in der Benutzeroberfläche des entwickelten Flugüberwachungssystems eine Erweiterung vorgesehen. Diese startet die Kartenanwendung im Areal-Auswahlmodus und generiert aus dem angegebenen Areal einen SQL-Ausdruck, der sich durch Anwendung der Winkelsummierungsmethode auf die Eckpunkte des angegebenen Areals ergibt. Man nehme an, dass das Gebiet von London durch folgende Koordinaten definiert ist: (−0.398254, 51.694693) , (−0.596008, 51.510452) , (−0.4422, 51.323747) , (−0.041199, 51.249882) , (0.390015, 51.433464) , (0.332336, 51.640181) , (−0.052185, 51.70831). Der durch den Einsatz der genannten Erweiterung generierter SQL-Ausdruck umgeschrieben in Form einer benutzerdefinierten Funktion findet man im Anhang A.3.3. Zur schnelleren Feststellung des Vorkommens des Grenzfalls (ob sich der angegebene Punkt genau an einem Eck des Polygons befindet) wurde die generierte Bedingung in zwei Teile zergliedert. Es sei allerdings bemerkt, dass ein solcher Grenzfall sehr selten vorkommt. Damit dient die Aufteilung der Bedingung lediglich einer besseren Lesbarkeit des Codes und bringt in der Regel keinen zeitlichen Gewinn. Der gesamte SQL-Code der Kenngröße ist im Listing 7.7 gegeben. Listing 7.7: Code der Anfrage „Welche Flugzeuge befinden sich momentan über London?“ 1 2 3 4 SELECT f.∗ FROM Flight f WHERE f.ImportID = <LastFlightImportID> AND dbo.isOverLondon(f.Longitude, f.Latitude) = 1 Man gebe der Kenngröße den Namen „LastImportFlightsOverLondon“ und lege eine Liste vom Typ Flight als Rückgabetyp fest. Da die Zugehörigkeit der Koordinaten des jeweiligen Flugzeuges dem definierten Gebiet durch den Aufruf einer benutzerdefinierten Funktion erfolgt, ist ein Test der resultierenden Laufzeit der Anfrage empfehlenswert. Ein solcher Test hat ergeben, dass die Ausführung der gegebenen Anfrage in weniger als einer Sekunde erfolgt. Damit ist die Definition der Kenngröße in der beschriebenen Form zulässig. 70 7. Berechnung von Flugkenngrößen mittels SQL 7.7. Ermittlung von Informationen aus historischen Daten Bisher wurden ausschließlich Anfragen betrachtet, die auf aktuellen Flug- und Flughafendaten aufbauen. Es sind aber sicherlich solche Kenngrößen vorstellbar, die sich aus Analyse von historischen Daten ergeben. Als Beispiel nehme man etwa die folgende Anfrage: Welche Fluggesellschaft betreibt die meisten Flüge zwischen 18 und 20 Uhr? Die Flugpläne, anhand deren die Lösung der aktuellen Aufgabe erfolgen könnte, stehen in der aktuellen Version des Werkzeugs leider nicht zur Verfügung. Es ist allerdings bekannt, dass die Rufzeichen der Flüge die Kürzel der betreibenden Fluggesellschaften enthalten. Durch Anwendung dieser Kenntnis kann nun die gesuchte Kenngröße aus den Fluginformationen hergeleitet werden. Die Implementierung der aktuellen Anfrage erfolgt durch sukzessives Lösen folgender Teilaufgaben: 1. Finde alle eindeutige Rufzeichen der Flüge, die zu einem Import gehören, der zwischen 18 und 20 Uhr erstellt wurde. 2. Erzeuge aus den Rufzeichen die ICAO-Kennungen der jeweiligen Fluggesellschaften durch das Abschneiden aller Symbole ab der 4. Position aus dem jeweiligen Rufzeichen; 3. Zu jeder ICAO-Kennung finde die Anzahl der eindeutigen Rufzeichen in der Ergebnismenge; 4. Sortiere die Datenmenge nach der Anzahl der Rufzeichen absteigend; 5. Gebe die ICAO-Kennung des ersten Datensatzes als Ergebnis aus. Hierbei soll auf das formale Aufschreiben der Kenngröße verzichtet werden, da die obere Beschreibung der Implementierung an SQL-Konstrukte anlehnt, die im Tupel-Kalkül nicht ausgedrückt werden können (z. B. Gruppierung und Sortierung). Die Ermittlung der Imports, die zwischen 18 und 20 Uhr erstellt wurden, erfolgt im SQL Server durch den Aufruf der Funktion DATEPART. Für die aktuelle Aufgabe sieht die Anwendung dieser Funktion wie folgt aus: DATEPART(hh, i.DateTime) BETWEEN 18 AND 20, wobei i eine Zeile der Tabelle Import bezeichnet und hh eine Konstante des SQL Servers ist, die den Stunden-Teil des Datums bezeichnet. Die Bestimmung des ICAO-Kenners aus dem Rufzeichen eines Fluges erfolgt durch den Aufruf der Funktion SUBSTRING. Die aufgabenspezifische Anwendung dieser Funktion kann auf folgende Weise aufgeschrieben werden: SUBSTRING(f.CallSign, 1, 3), wobei f eine Zeile der Tabelle Flight repräsentiert. Durch sukzessive Lösung der beschriebenen Aufgaben unter Verwendung von genannten Systemfunktionen des SQL Servers kommt man schließlich an die Implementierung der aktuellen Kenngröße, die im Listing 7.8 beschrieben ist. 71 7. Berechnung von Flugkenngrößen mittels SQL Listing 7.8: Code der Anfrage „Welche Fluggesellschaft betreibt die meisten Flüge zwischen 18 und 20 Uhr?“ 1 2 3 4 5 6 7 8 SELECT TOP 1 Company FROM ( SELECT DISTINCT SUBSTRING(f.CallSign, 1, 3) AS Company, f.CallSign FROM Flight f INNER JOIN Import i ON i.ID = f.ImportID WHERE DATEPART(hh, i.DateTime) BETWEEN 18 AND 20) Companies GROUP BY Company ORDER BY COUNT(CallSign) DESC Man gebe der Kenngröße den Namen MaxOperatingCompanyBetween18And20 und lege ein Skalar als Rückgabetyp fest. Hierzu ist es anzumerken, dass das Ergebnis maximal ein ICAO-Kennzeichen enthält, auch im Fall, wenn es mehrere Fluggesellschaften gibt, die die gleiche Anzahl von Flügen im angegebenen Zeitraum betreiben. Um alle Kennungen auszugeben, die der gegebenen Bedingung entsprechen, muss man eine Liste vom Typ Zeichenfolge als Rückgabe setzen und eine Darstellungsmaske für die Anzeige von Zeichenfolgen-Listen im Programm implementieren. Es sei zusätzlich bemerkt, dass man für ein genaueres Ergebnis der auf historischen Daten basierenden Anfragen vorher eine genügend große Anzahl von Imports durchführen muss. In diesem konkreten Fall kann ein relativ genaues Ergebnis für die betroffene Region dadurch erzielt werden, dass man Flugimports eine komplette Woche lang zwischen 18 und 20 Uhr in regelmäßigen Abständen erstellen lässt. 7.8. Ermittlung von Flugstatistiken aus historischen Daten Der letzte Typ von Kenngrößen, die im Rahmen dieser Arbeit betrachtet wird, ist die Ermittlung von statistischen Daten anhand historischer Informationen. Eine interessante Anfrage von diesem Typ kann z. B. folgendermaßen lauten: Wie viele Flüge hat es maximal zwischen 13 und 15 Uhr im Gebiet London gegeben? Zur Lösung dieser Aufgabe muss im Grunde ein zwischen 13 und 15 Uhr erstellter Import gefunden werden, der die meisten Flüge enthält, deren geographische Positionen zur Londoner Region gehören. Es ist durchaus sinnvoll, die Zielanfrage wie im letzten Abschnitt in Teilaufgaben zu zerlegen, um diese nacheinander zu lösen. Aus der Analyse der Zielanfrage ergeben sich folgende Teilaufgaben: 1. Finde alle Flüge, die zu einem zwischen 13 und 15 Uhr erstellten Import gehören; 2. Wähle aus der Ergebnismenge die Flüge aus, die sich über dem Londoner Gebiet befinden; 3. Gebe die maximale Anzahl von Flügen aus der Ergebnismenge gruppiert nach der ID des jeweiligen Imports aus. 72 7. Berechnung von Flugkenngrößen mittels SQL Die Definition der Bedingung, die nur Flüge im gegebenen Zeitraum findet, erfolgt analog zur entsprechenden Bedingung aus dem letzten Abschnitt. Aufgabenspezifisch kann diese wie folgt aufgeschrieben werden: DATEPART(hh, i.Datetime) BETWEEN 13 AND 15, wobei i eine Zeile der Tabelle Import repräsentiert. Um festzustellen, ob sich die Flüge, die im Zwischenergebnis enthalten sind, über Londoner Gebiet befanden, benutze man die im Abschnitt 7.6 definierte Funktion dbo.isOverLondon (siehe Abschnitt A.3.3 des Anhangs). Schließlich lassen sich die Anzahl und das Maximum durch Konstrukte COUNT bzw. MAX des SQL Servers ermitteln. Damit kann die genannte Kenngröße durch den Code des Listings 7.9 definiert werden. Listing 7.9: Code der Anfrage „Wie viele Flüge hat es maximal zwischen 13 und 15 Uhr im Gebiet London gegeben?“ 1 2 3 4 5 6 7 8 SELECT MAX(Amount) AS Maximum FROM ( SELECT COUNT(f.ID) AS Amount FROM Flight f INNER JOIN Import i ON i.ID = f.ImportID WHERE DATEPART(hh, i.Datetime) BETWEEN 13 AND 15 AND dbo.isOverLondon(f.Longitude, f.Latitude) = 1 GROUP BY f.ImportID) AS Counts Man gebe der Kenngröße als Namen MaxFlightCountOverLondonBetween13And15 und lege ein Skalar als Rückgabetyp fest. Auf die gleiche Art und Weise können nun weitere Statistiken ermittelt werden, die mit Hilfe von SQL definierbar sind. 7.9. Wiederverwendung bestehender Kenngrößen Durch Verwendung von Meta-Parametern bei der Anfragendefinition ist es möglich, durchaus komplexe Kenngrößen zu implementieren. Dabei können die durch Meta-Parameter dargestellten vorhandenen Anfragen auf die gleiche Weise wie die Datenbanktabellen und -sichten benutzt werden. Es ist lediglich notwendig, der bestehenden Kenngröße, die bei der Definition einer neuen Anfrage benutzt wird, einen Alias-Namen zu vergeben. Die Vergabe der Alias-Namen erfolgt nach syntaktischen Regeln von SQL. Zur Demonstration der Wiederverwendung bestehender Kenngrößen formuliere man etwa folgende Anfrage: Welche landende Flugzeuge befinden sich momentan über London? Die Anfrage kann im Tupel-Kalkül auf folgende Art aufgeschrieben werden. {f |f ∈ F lugzeug ∧ IsOverLondon (f ) ∧ IsLanding (f )}. Die zur Lösung aktueller Aufgabe notwendigen Relationen IsOverLondon und IsLanding entsprechen den Kenngrößen LastImportFlightsOverLondon bzw. LastImportLandingFlights, 73 7. Berechnung von Flugkenngrößen mittels SQL die bereits in vorherigen Abschnitten definiert wurden. Damit kann die aktuelle Anfrage durch den im Listing 7.10 angegebenen SQL-Code implementiert werden. Listing 7.10: Code der Anfrage „Welche landende Flugzeuge befinden sich momentan über London?“ 1 2 3 SELECT f.∗ FROM <LastImportFlightsOverLondon> fol INNER JOIN <LastImportLandingFlights> lf ON lf.ID = fol.ID Bei der Definition solcher komplexen Kenngrößen soll man allerdings damit rechnen, dass die Laufzeit der Auswertung nicht optimal sein wird. In der Tat kommt in der gegebenen Implementierung der Kennhgröße die Bedingung f.ImportID = hLastF lightImportIDi doppelt vor (im Text der beiden Unteranfragen). Allgemein soll man auf die Wiederverwendung von Kenngrößen verzichten, wenn einer der folgenden Fälle vorliegt: • Es wird eine laufzeitintensive Bedingung doppelt angegeben; • Der Datenbankserver führt vor der Ausführung des Befehls keine Optimierung des Befehlstextes durch; • Durch direkte Angabe der Filterbedingung mindestens einer Unteranfrage geht die Lesbarkeit des Befehlstextes nicht verloren. Im gegebenen Fall handelt es sich um Unteranfragen, durch Verwendung denen eine sehr einfache Filterbedingung doppelt definiert wird (Filterung nach einem indizierten Feld), die schnell ausgewertet werden kann. Darüber hinaus kann es hier davon ausgegangen werden, dass der SQL Server vor der Ausführung des Befehls eine Optimierung vornimmt, durch welche die wiederholte Auswertung der Filterbedingung ignoriert wird. Dagegen wurde die Lesbarkeit des Befehls durch Wiederverwendung von Kenngrößen enorm verbessert. Damit ist eine solche Implementierung der aktuellen Kenngröße gerechtfertigt. 74 8. Beispielszenario 8. Beispielszenario Nachdem das Flugüberwachungssystem entwickelt und die Implementierungsmöglichkeiten einiger Kenngrößen diskutiert wurden, kann es angefangen werden, mit dem Programm zu arbeiten. In diesem Kapitel wird der Standardablauf im Flugüberwachungssystem erläutert. Im aktuellen Beispielszenario wird es gezeigt, wie man mit Hilfe des Werkzeugs die Beispielsanfrage „Welche Flugzeuge befinden sich momentan über London?“ erstellen und auswerten kann. Links im Hauptfenster des Programms erscheint das Systemmenü. Der Aufbau des Menüs ist in der Abbildung 8.1 zu sehen. Alle wesentlichen Module des Systems sind über dieses Menü verfügbar. Abbildung 8.1.: Hauptmenü des Flugüberwachungssystems Als Erstes soll man den Informationsfluss für das System einrichten. Hierfür öffne man die Importmaske über die Schaltfläche Imports im Hauptmenü. Ein Screenshot des Formulars findet man in der Abbildung 8.2. 75 8. Beispielszenario Abbildung 8.2.: Importlistenformular Alle wesentlichen Aktionen, die über diese Maske vorgenommen werden können, sind über die Befehlsleiste verfügbar, die sich ganz oben befindet. Es können folgende Aktionen vorgenommen werden: • Erstellung eines neuen Datenimports über die Schaltfläche New ; • Anzeige der importierten Datenobjekte über die Schaltfläche Open; • Löschung eines bereits erstellten Imports über die Schaltfläche Delete; • Auswahl des anzuzeigenden Import-Typs über die Auswahlliste Import type; • Schließen des aktuellen Formulars über die Schaltfläche Close. Zur Erstellung eines neuen Imports klicke man auf die Schaltfläche New. Es wird ein Importer gestartet, der Objekte des oben angegebenen Typs von der entsprechenden Internetressource in das System einliest. Um andere Typen von Objekten in das System importieren zu lassen, soll man in der Auswahlliste den entsprechenden Objekttyp auswählen und einen neuen Import erstellen. Wenn die Daten erfolgreich importiert wurden, erscheint der neu erstellte Import in der Liste. Damit die Daten im System immer auf dem neusten Stand sind, soll man den gerade erstellten Import automatisch erneut erstellen lassen. Hierfür setze man bei diesem Import ein Häkchen in der Spalte Auto-Import. Danach muss die Zeitspanne eingegeben werden, nach Ablauf deren ein neuer Import erstellt werden soll. Dafür klicke man in der Spalte Auto-Import 76 8. Beispielszenario interval auf den Button mit der Beschriftung „...“. Nach dieser Aktion wird man aufgefordert, das Zeitintervall einzugeben (siehe Abbildung 8.3). Durch die Eingabe der Zeitspanne wird der ausgewählte Import zur internen Liste der automatischen Imports hinzugefügt und ein Timer gestartet, der die Zeit bis zum Erstellen eines Imports des gleichen Typs runter zählt. Abbildung 8.3.: Festlegung des Zeitintervalls bei der Aktivierung der automatischen Durchführung eines Imports Nun ist ein neuer Import von Flugdaten durchgeführt worden, und aus diesem wird regelmäßig ein neuer gleicher Import erstellt. Damit kann das Importlisten-Fenster geschlossen und die Arbeit mit dem System fortgesetzt werden. Die Liste der im System vorhandenen SQL-Kenngrößen kann man ansehen, indem man auf die Schaltfläche Queries im Hauptmenü klickt. Es wird ein Fenster angezeigt, in dem die Namen, die Beschreibungen und die Erstellungsdatums der im System vorhandenen Imports in Form einer Tabelle angezeigt werden (siehe Abbildung 8.4). 77 8. Beispielszenario Abbildung 8.4.: Anfrageliste Über die Funktionsleiste der Maske, die sich wie üblich oben befindet, sind folgende Aktionen möglich: • Erstellung einer neuen Anfrage, Datenbanksicht, gespeicherten Prozedur oder benutzerdefinierten Funktion über die Schaltfläche New ; • Bearbeitung einer vorhandenen Anfrage über die Schaltfläche Open; • Löschung einer vorhandenen Anfrage über die Schaltfläche Delete; • Schließen des aktuellen Fensters über die Schaltfläche Close. Man starte die Erstellung der benutzerdefinierten Funktion zur Feststellung der Zugehörigkeit einer geographischen Position dem Londoner Gebiet durch klicken auf die Schaltfläche New. Es erscheint ein Formular, in dem die Daten der neuen SQL-Anfrage eingegeben werden können. Man klicke im Feld Query SQL mit der rechten Maustaste und wähle die Erweiterung Define area (siehe Abbildung 8.5) aus. 78 8. Beispielszenario Abbildung 8.5.: Aufruf der Programmerweiterung zum Festlegen eines Areals Vor der Auswahl der interessierenden Region in Karte muss man die Feldnamen für Länge (Longitude) und Breite (Latitude) des zu prüfenden Objektes eingeben (siehe Abbildung 8.6). Diese Felder werden beim Generieren des SQL-Ausdrucks benötigt. Bei der Definition einer benutzerdefinierten Funktion sollte man anstelle der Feldnamen die Namen der entsprechenden Variablen eingeben, die Koordinaten des zu prüfenden Punktes bezeichnen. Man gebe hier den Wert @lon als Namen des Longitude-Feldes und @lat für das Latitude-Feld ein und bestätige die Eingabe durch klicken auf OK -Button. 79 8. Beispielszenario Abbildung 8.6.: Eingabe der Koordinaten-Feldnamen bei der Auswahl eines Areals Es erscheint das Kartenwerkzeug, in dem das Areal festgelegt werden kann. Man bewege die Karte an die gewünschte Stelle, ändere bei Notwendigkeit die Zoom-Stufe, wähle oben rechts das Auswahl-Werkzeug und lege die Punkte der Region fest durch Anklicken der Karte. Die Eingabe des Areals wird durch ein Doppelklick beendet. Die ausgewählte Region ist nun durch ein orangefarbiges Polygon hervorgehoben (siehe Abbildung 8.7). Diese wird durch Klicken auf die Schaltfläche Apply selection übernommen. 80 8. Beispielszenario Abbildung 8.7.: Festlegung des Areals bei der Definition einer Anfrage Nachdem das Gebiet mit Hilfe des Kartenwerkzeugs angegeben wurde, generiert das Programm einen SQL-Ausdruck, der im Feld Query SQL des Anfragendefinitionsformulars erscheint. Man teile den Ausdruck entsprechend der Definition der benutzerdefinierten Funktion zur Feststellung der Zugehörigkeit eines Punktes einem vorgegebenen Gebiet, die im Abschnitt A.3.3 des Anhangs zu finden ist, und schreibe den gesamten Funktionserstellungsbefehl in das Feld. Der Befehlstext wird ausgeführt durch Klicken auf der Schaltfläche Save as (siehe Abbildung 8.8). 81 8. Beispielszenario Abbildung 8.8.: Erstellung einer Funktion aus dem Anfragedefinitions-Formular Jetzt kann die eigentliche SQL-Anfrage erstellt werden. Man erstelle eine neue Anfrage durch Klicken im Anfragenfenster auf die Schaltfläche New und gebe folgende Werte in entsprechende Felder ein (siehe Abbildung 8.9): • LastImportFlightsOverLondon als Namen der Anfrage; • Welche Flugzeuge befinden sich momentan über London? als Beschreibungstext; • Den Code aus dem Listing 7.7 als SQL-Text. 82 8. Beispielszenario Abbildung 8.9.: Erstellung einer SQL-Anfrage Die neue SQL-Anfrage wird im System durch das Klicken auf die Schaltfläche Save gespeichert und erscheint anschließend in der Liste der im System vorhandenen Kenngrößen. Die erstellte Kenngröße kann nun ausgewertet werden. Man öffne das Auswertungsformular durch Klicken auf den Button Views im Hauptmenü. Im dadurch geöffneten Fenster soll man oben in der Auswahlliste die gewünschte Kenngröße auswählen und durch das Klicken auf den Button Show auswerten lassen (siehe Screenshot 8.10). Es erscheint eine Liste der zum letzten Import gehörenden Flugzeuge, die sich zum Zeitpunkt der Importerstellung über London befanden. 83 8. Beispielszenario Abbildung 8.10.: Anzeige der Ergebnisse der Auswertung einer SQL-Anfrage Um die Ergebnisse der Auswertung in Karte anzeigen zu lassen, klicke man auf die Schaltfläche Visualize. Dadurch wird eine KML-Datei mit den Daten der Flugzeuge aus der Ergebnismenge erzeugt und der Pfad zu dieser KML-Datei an das Kartenwerkzeug übergeben. Einen Ausschnitt der Karte, die nach dieser Aktion angezeigt wird, findet man in der Abbildung 8.11. 84 8. Beispielszenario Abbildung 8.11.: Anzeige der Anfragenergebnisse in der Karte 85 8. Beispielszenario Um die Flugbewegungen im Gebiet London zu beobachten, soll man die automatische Aktualisierung der Ergebnismenge aktivieren. Hierzu soll ein Häkchen gesetzt werden, das die Aktualisierung aktiviert, und das Zeitintervall der Aktualisierung festgelegt werden (siehe Screenshot 8.12). Abbildung 8.12.: Festlegung der automatischen Aktualisierung der Ergebnismenge Wenn die Aktualisierung der Erbenismenge aktiviert wurde, wird die bis zur nächsten Aktualisierung verbleibende Zeit unten angezeigt. Nach Ablauf dieser Zeitspanne wird es ggf. auf die Erstellung eines neuen Imports gewartet. Sobald ein neuer Import vorhanden ist, werden die Daten in der Tabelle aktualisiert. Wenn zusätzlich das Kartenwerkzeug geöffnet ist, wird die Karte mit den neuen Flugdaten neu geladen. Zur Einschätzung der Performanz des Werkzeugs wurde in die Anfrageausführungsansicht eine Funktion eingebaut, die für die Ausführung der ausgewählten Anfrage benötigte Zeit misst. Zusätzlich zur Dauer der Auswertung einer Kenngröße im Werkzeug wird auch die Zeit gemessen, die das DBMS benötigt, um zur angegebenen Anfrage das Ergebnis zu liefern. In folgender Tabelle sind die Ausführungszeiten zu allen im Laufe der aktuellen Arbeit definierten Kenngrößen zu finden. Indikator Laufzeit Laufzeit (DBMS) Welche Flugzeuge sind im Moment unterwegs? 0.038 0.019 Wie viele Flugzeuge des Typs Airbus A320 sind im 0.007 0.003 Moment unterwegs? 86 8. Beispielszenario Welche Flugzeuge befinden sich aktuell unter FL0? 0.047 0.003 Welche Flugzeuge befinden sich im Landeanflug? 3.459 3.441 Welche Flugzeuge nähern sich kritisch? 1.455 1.439 Welche Flugzeuge befinden sich momentan über Lon- 0.067 0.029 0.015 0.012 0.093 0.062 don? Welche Fluggesellschaft betreibt die meisten Flüge zwischen 18 und 20 Uhr? Wie viele Flüge hat es maximal zwischen 13 und 15 Uhr im Gebiet London gegeben? Das einzige Ergebnis, das nicht zufriedenstellend erscheint, liefert die Anfrage „Welche Flugzeuge befinden sich im Landeanflug?“ Wie bereits im letzten Kapitel erwähnt, liegt die lange Ausführungszeit zum größten Teil daran, dass für jeden Kandidat-Datensatz die benutzerdefinierte Funktion „getDistance“ aufgerufen werden soll. Diese Problematik wurde bereits im Abschnitt 7.4 behandelt. Das Problem lässt sich durch direkte Berechnung der Distanz zwischen Flugzeugen und Flughäfen in der Filterbedingung beheben. Die Ausführung einer solchen Variante der Anfrage erfolgt in 0.854 Sekunden im Flugüberwachungssystem und in 0.829 im DBMS. 87 9. Fazit und Ausblick 9. Fazit und Ausblick Das Hauptziel der aktuellen Arbeit war die Untersuchung der Einsatzmöglichkeiten von Anfragesprache SQL zur Definition und Auswertung von Flugkenngrößen. Hierfür wurde ein datenbankgestütztes System zur Beobachtung und Ermittlung von Flugstatistiken entworfen und implementiert. Das resultierende Werkzeug kann potenziell in vielen Branchen eingesetzt werden, da die Anfragesprache SQL, die für die Definition von Kenngrößen verwendet wird, äußerst flexibel und ausdrucksstark ist. Mit Hilfe von SQL können aus vorhandenen Informationen leicht und effizient neue ableitbare Indikatoren erzeugt werden. Die Funktionalität des entwickelten Werkzeugs umfasst drei wichtigsten Module: das Import, Anfragedefinitions- und Anfrageauswertungsmodul. Das Import-Modul fasst die Funktionen zusammen, die für das Herunterladen von unterschiedlichen Daten aus dem Internet über das HTTP -Protokoll zuständig sind. Diese Daten werden anschließend in der mit dem Werkzeug gekoppelten Datenbank abgelegt und für die Herleitung ableitbarer Informationen durch Auswertung von definierten Anfragen zur Verfügung gestellt. Durch die Funktionalität des Anfragedefinitionsmoduls erfolgt die Erstellung und Verwaltung von SQL-Anfragen. Hierbei ist es möglich, auf das DBMS zur Erstellung von Datenbankobjekten wie z. B. Sichten, gespeicherte Prozeduren und benutzerdefinierte Funktionen direkt zuzugreifen. Schließlich bietet das Anfrageauswertungsmodul dem Anwender die Möglichkeit, vorhin erstellte Kenngrößen auswerten zu lassen. Da das Werkzeug speziell für den Zweck der Beobachtung von Flügen entwickelt wurde, bietet das Modul zusätzlich die Möglichkeit, im Ergebnis der Auswertung enthaltene Objekte, die über eine geographische Position verfügen, mit Hilfe von einer Karte graphisch darstellen zu lassen. In der Arbeit wurden folgende Themen behandelt. Die Grundzüge der Datenbanksysteme wurden in Kapitel 2 vorgestellt. Im ersten Teil des Kapitels wurden theoretische Grundlagen eingeführt. An diese wurde bei der Entwicklung der Datenbankanwendung des Systems angelehnt. Im ersten Abschnitt des Kapitels wurden verschiedene Regelkonzepte der Datenbanksysteme präsentiert. Auf das Konzept der deduktiven Regeln wurde später bei der Definition von Anfragen zurückgegriffen. Die wichtigsten Teile der Anfragesprache SQL, die bei der Erstellung von Kenngrößen mit Hilfe des entwickelten Werkzeugs benutzt werden, wurden erläutert. Im letzten Teil wurde das Konzept der Datenströme behandelt. Die Grundidee des Konzeptes besteht darin, dass ein für die Einrichtung eines kontinuierlichen Datenflusses zuständiges Datenstromverwaltungssystem (DSMS ) die eintreffenden Daten in anfragespezifischen Snapshots abspeichert. Diese Vorgehensweise erweist sich als ungeeignet für ein System, das zusätzlich zu Anfragen, die auf den aktuellen Daten aufbauen, Erstellung von statistischen 88 9. Fazit und Ausblick Kenngrößen ermöglicht, die auf dem gesamten Datenbestand basieren. Bei der Entwicklung des Import-Mechanismus wurde jedoch die Idee des in diesem Abschnitt vorgestellten Konzeptes der Zeitfenster verwendet. In Kapitel 3 wurden die Grundlagen der zivilen Luftfahrt vorgestellt. Dieses fachliche Wissen wurde später benutzt, um aus den verfügbaren Flugdaten interessante Informationen abzuleiten. Hier wurde ebenso die Struktur der auf den verwendeten Datenquellen verfügbaren Daten beschrieben. Als Hauptquelle der aktuellen Flugdaten wurde die Internet-Ressource OpenATC (http://www.openatc.com/) benutzt. Die aktuellsten Flughafeninformationen wurden der Seite des Projektes OpenFights (http://openflights.org/) entnommen. Über die Möglichkeiten, durch Anwendung des fachlichen Wissens auf die Rohdaten, weitere Informationen herzuleiten, wurde im letzten Abschnitt des Kapitels diskutiert. Die Anforderungen an das zu entwickelnde System wurden in Kapitel 4 gestellt. Das gesamte System wurde erst in zwei größere Teile, Datenorganisation und Anfrageverwaltung, zerlegt. Es wurden allgemeine Anforderungen an die genannten Teile formuliert. Im weiteren Verlauf der Analyse wurden die genannten Teile weiter in vier Module zergliedert. Es wurden systemspezifische Anforderungen separat für Datenimport-, Datenzugriffs-, Anfragedefinitions- und Anfrageauswertungsmodule in Form der Anwendungsfälle formuliert. In Kapitel 5 fand die Diskussion über den Entwurf und Implementierung des Systems statt. Als Erstes wurde die Architektur des Werkzeugs beschrieben. Danach wurde die Datenbankanwendung entworfen und implementiert. Hierbei wurde über die Struktur der Datenbank diskutiert und diese anschließend mittels SQL realisiert. Es wurde das Konzept des Imports eingeführt, das an die Idee der Zeitfenster in einem DSMS anlehnt. Die Möglichkeit, die bestehende Datenbank um weitere importierbare Objekttypen zu erweitern, wurde beschrieben. Im Laufe des Entwurfs der Benutzeroberfläche wurden systemspezifische Schnittstellen und Entitäten erläutert. Anschließend wurden die bei der Entwicklung benutzten Werkzeuge genannt. Im letzten Abschnitt des Kapitels wurden einige Ideen erläutert, die es ermöglichen, Systemleistung zu steigern. Diese Ideen wurden bei der Realisierung des Werkzeugs im vollen Umfang umgesetzt. Die Leistung des entwickelten Systems lässt sich durch Definition und Umsetzung von Beispielsanfragen testen. Hierfür wurden in Kapitel 6 Kenngrößen unterschiedlicher Arten definiert. Da für die Implementierung einiger der vorgeschlagenen Beispielsanfragen komplexe Berechnungen notwendig sind, wurden die betreffenden Kenngrößen untersucht und auf Lösungen von bekannten mathematischen Problemen reduziert. Die eigentlichen Umsetzungen der vorgestellten Beispielsindikatoren wurden in Kapitel 7 erläutert. Dabei wurde erst die Bedeutung der jeweiligen Kenngröße definiert. Anschließend fand die Diskussion über die Implementierungsmöglichkeiten der Indikatoren statt. Da bei der Lösung einiger Beispielsanfragen benutzerdefinierte Funktionen im DBMS erstellt wurden, wurden für betroffene Anfragen die Laufzeiten der Auswertungen grob geschätzt. 89 9. Fazit und Ausblick Im letzten Kapitel der Arbeit wurde der allgemeine Ablauf im System erläutert. Es wurde gezeigt, wie man mit Hilfe des Werkzeugs den Datenfluss einrichten, Anfragen erstellen, speichern, auswerten und das Ergebnis der Auswertung visualisieren kann. Abschließend wurden für alle betrachteten Indikatoren die Laufzeiten der Auswertungen angegeben, um die Effizienz des Systems genauer einzuschätzen. Anhand der genannten Beispiele wurde gezeigt, dass man mit Hilfe vom entwickelten Werkzeug Anfragen unterschiedlicher Art und Komplexität erstellen und auswerten lassen kann. Logischerweise wurden dabei nicht alle denkbaren Typen von Anfragen behandelt. Dies liegt zum Teil daran, dass zur Demonstration der Funktionalität des Systems lediglich Datenflüsse für Objekte von zwei Typen realisiert wurden. Diese Objekttypen sind Flug- und Flughafeninformationen. Die letzteren werden gebraucht, um einige von Fragen, die an das System potenziell gestellt werden, genauer beantworten zu können. Eine Erweiterung der Funktionalität des Datenfluss-Moduls ist hierbei bedacht worden und kann als einer der Ansätze für die Weiterentwicklung betrachtet werden. Man betrachte beispielsweise folgende Anfrage: „Welche Flüge sind verspätet?“ Diese kann anhand der aktuell im System gespeicherten Daten nicht beantwortet werden. Um die Anfrage beantworten zu können, werden zusätzlich Flugplan-Informationen benötigt. Daten vom solchen Typ sind mit Sicherheit im Internet zu finden (schließlich bieten alle Fluggesellschaften und Flughäfen einen Überblick über die Abflug- und Ankunftszeiten der aktuellen Flüge an). Daher kann auch für diese Informationen ein Datenfluss im entwickelten Werkzeug eingerichtet werden. Stehen Flugpläne im System zur Verfügung, so kann die genannte Frage anhand der Differenz zwischen der aktuellen Uhrzeit und der geplanten Ankunftszeit des jeweiligen Fluges beantwortet werden. Als ein weiterer möglicher Baustein kann eine Visualisierung der Anfragedefinition betrachtet werden. Bei der Entwicklung des Werkzeugs wurde davon ausgegangen, dass der Anwender über ausreichende Kenntnisse von SQL verfügt. Dies beschränkt den Kreis der potenziellen Benutzer des Systems drastisch, da solche technischen Kenntnisse nicht von jedem zu erwarten sind. Dieses Manko kann dadurch behoben werden, dass das Programm SQL nur intern bei der Auswertung von Kenngrößen benutzt und dem Anwender visuelle Zusammensetzung von Anfragen aus unterschiedlichen Teilen (z. B. Projektion, Filterbedingung usw.) anbietet. Die Definition von Kenngrößen auf diese Weise könnte der Visualisierung von SQL-Anfragen in MS Access oder SQL Server ähneln. Diese Bestandteile der erstellten Anfrage können in einzelnen Tabellen in der Datenbank gespeichert werden und lediglich bei der Auswertung der Anfrage in SQL übersetzt werden. In der Datenbank ist für Tabellen, in denen die einzelnen Teile einer Anfrage abgespeichert werden, das Präfix EX vorgesehen. Zu diesem Teil der Datenbank gehört sicherlich auch die Tabelle EXSQLExpression, in der direkt in SQL definierte Kenngrößen gespeichert werden. Der Datenfluss wird im System aktuell mittels Zeitfenster organisiert. Diese Vorgehensweise stellt allerdings nicht für alle Anwendungstypen die optimale Lösung dar. Man betrachte etwa 90 9. Fazit und Ausblick die Notwendigkeit, über eventuelle Änderungen an der Ergebnismenge so schnell wie möglich informiert zu werden. In diesem Fall ist ein datengetriebener Datenfluss vorzuziehen. Eine mögliche Verbesserung des Werkzeugs besteht darin, dass es das aktuell angezeigte Ergebnis der Auswertung durch neu eingetroffene Daten vervollständigt. Dieser Ansatz der Datenstromtheorie könnte also als ein weiterer Baustein bei der Weiterentwicklung des Werkzeugs betrachtet werden. 91 Literaturverzeichnis Literaturverzeichnis AK06 Alfons Kemper, André E.: Datenbanksysteme: eine Einführung. 6. Passau : Oldenbourg, 2006 2, 2.2.1 Dan03 Daniel J. Abadi et al.: Aurora: a new model and architecture for data stream management. Version: August 2003. http://www.cs.brown.edu/research/aurora/ vldb03_journal.pdf, Abruf: 29.10.2009 1 Dör50 Dörrie, Heinrich: Ebene und sphärische Trigonometrie. München : Oldenbourg, 1950 19, 20 Fra02 Frankfurter flächen Allgemeine und Was Zeitung: Luftkorridore? Version: Juli sind 2002. Flughttp: //www.faz.net/s/Rub02DBAA63F9EB43CEB421272A670A685C/ Doc~EB18FD10AFF4B494FA7CA1D3AE80509C7~ATpl~Ecommon~Scontent.html, Abruf: 23.08.2009 3.1.3 Gil97 Gilbert Strang, Kai Borre: Linear algebra, geodesy, and GPS. Wellesley, MA, USA : Wellesley-Cambridge Press, 1997 22, 24 Iva74 Ivan E. Sutherland, Robert F. Sproull, Robert A. Schumacker: A Characterization of Ten Hidden-Surface Algorithms. In: ACM Computing Surveys (CSUR) 6 (1974), März, Nr. 1 25 Ken02 Kennedy, Michael: The Global Positioning System and GIS : An Introduction. 2. USA : CRC Press, 2002 13, 14, 3.1.6 Kom09 Kompf, Martin: Entfernungsberechnung: Exakte Entfernungsberechnung für die Kugeloberfläche. Version: 2009. http://www.kompf.de/gps/distcalc.html, Abruf: 22.08.2009 6.1, 9 Luf08 Lufthansa: Lufthansa Geschäftsbericht 2008. Version: Januar 2008. http: //konzern.lufthansa.com/de/downloads/presse/downloads/publikationen/ DLH_D_GB2008.pdf, Abruf: 02.08.2009 1 MA96 Manfred Andrié, Paul M.: Lineare Algebra und Geometrie für Ingenieure. 3. Düsseldorf : VDI Verlag, 1996 26, 27, 6.3, 9 Man07 Manthey, Rainer: Folien zur Vorlesung "Deduktive Datenbanken". Bonn, 2007 2 92 Literaturverzeichnis Mar00 Marten, Michael: Flugfunk - Kommunikation und Navigation in der Luftfahrt. Meckenheim : Siebel Verlag, 2000 3, 10, 11, 3.2 MC04 Michael Cammert, Jürgen Krämer Bernhard S. Christoph Heinz H. Christoph Heinz: 2004. Anfrageverarbeitung an Datenströmen. Version: November http://dbs.mathematik.uni-marburg.de/publications/myPapers/2004/ CHKS04.pdf, Abruf: 12.10.2009 1, 2 Men93 Mensen, Heinrich: Moderne Flugsicherung. 2. Berlin : Springer-Verlag, 1993 3, 4, 5, 6, 7, 8, 9, 12 Mey02 Meyer, Ingo: Entfernung und Beamrichtung berechnen (lang). Version: August 2002. http://www.dl-qrp-ag.de/faqag/locator2.pdf, Abruf: 26.09.2009 23 Mic09 Microsoft: MSDN Das Microsoft Developer Network. Version: Oktober 2009. http://msdn.microsoft.com/, Abruf: 09.10.2009 2 NHi07 NHibernate: NHibernate Reference Documentation. Version: Mai 2007. https://www.hibernate.org/hib_docs/nhibernate/1.2/reference/en/pdf/ nhibernate_reference.pdf, Abruf: 29.10.2009 5.1 Pap07 Papa, John: Datenpunkte: Übersicht über ADO.NET Entity Framework. Version: Juli 2007. http://msdn.microsoft.com/de-de/magazine/cc163399.aspx, Abruf: 31.08.2009 5.1 Rya08 Ryanair: Ryanair Annual Report 2008. Version: Januar 2008. http://www. ryanair.com/site/about/invest/docs/2008/Annualreport2008web.pdf, Abruf: 02.08.2009 2 Sky08 Skybound Software: GeckoFX Forum. Version: Februar 2008. http://geckofx. org/, Abruf: 25.09.2009 5.4.6 The03 The STREAM Group: STREAM: The Stanford Stream Data Manager. Version: März 2003. http://ilpubs.stanford.edu:8090/583/, Abruf: 25.10.2009. (2003-21) 1, 2.4 WIK09 Wikipedia: die freie Enzyklopädie. Version: Oktober 2009. http://de.wikipedia. org, Abruf: 09.10.2009 2, 3.1.5, 3.1.6, 5.3.3 Zog06 Zogg, Jean-Marie: Grundlagen der Satellitennavigation. Version: Mai 2006. http: //www.u-blox.de/customersupport/docs/GPS_Basics(GPS-X-01006).pdf, Abruf: 17.05.2008 3.1.6 93 Abbildungsverzeichnis Abbildungsverzeichnis 4.1. Anwendungsfalldiagramm: Datenimport-Modul . . . . . . . . . . . . . . . . . 30 4.2. Anwendungsfalldiagramm: Anfragedefinitionsmodul . . . . . . . . . . . . . . . 33 4.3. Anwendungsfalldiagramm: Anfrageauswertungsmodul . . . . . . . . . . . . . . 35 5.1. Architektur des Flugüberwachungssystems . . . . . . . . . . . . . . . . . . . . 39 5.2. Datenbankschema des Flugüberwachungssystems . . . . . . . . . . . . . . . . 40 5.3. Datenbankstruktur des Flugüberwachungssystems . . . . . . . . . . . . . . . . 42 5.4. Erweiterung der Datenbank . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 5.5. Klassendiagramm des Flugüberwachungssystems . . . . . . . . . . . . . . . . 47 5.6. Aufbau des Kartenwerkzeugs . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 6.1. Sphärischer Abstand zwischen zwei Punkten P1 und P2 der Kugeloberfläche [Kom09] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 6.2. Berechnung des Treffpunktes zweier beweglichen Körper . . . . . . . . . . . . 54 6.3. Bedeutung des Vektorproduktes zweier Vektoren [MA96, S. 113] . . . . . . . . 60 6.4. Winkelsummierungsmethode . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 8.1. Hauptmenü des Flugüberwachungssystems . . . . . . . . . . . . . . . . . . . . 75 8.2. Importlistenformular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 8.3. Festlegung des Zeitintervalls bei der Aktivierung der automatischen Durchführung eines Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 8.4. Anfrageliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 8.5. Aufruf der Programmerweiterung zum Festlegen eines Areals . . . . . . . . . 79 8.6. Eingabe der Koordinaten-Feldnamen bei der Auswahl eines Areals . . . . . . 80 8.7. Festlegung des Areals bei der Definition einer Anfrage . . . . . . . . . . . . . 81 8.8. Erstellung einer Funktion aus dem Anfragedefinitions-Formular . . . . . . . . 82 8.9. Erstellung einer SQL-Anfrage . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 8.10. Anzeige der Ergebnisse der Auswertung einer SQL-Anfrage . . . . . . . . . . 84 8.11. Anzeige der Anfragenergebnisse in der Karte . . . . . . . . . . . . . . . . . . . 85 8.12. Festlegung der automatischen Aktualisierung der Ergebnismenge . . . . . . . 86 94 Verzeichnis der Listings Verzeichnis der Listings 2.1. Der SQL-Erstellungsbefehl der Tabelle „Import“ . . . . . . . . . . . . . . . . . 9 2.2. Der SQL-Erstellungsbefehl des Fremdschlüssels für Tabelle „Flight“ . . . . . . 10 2.3. SQL-Anweisung zum Einfügen einer neuen Zeile in die Tabelle „Import“ . . . 13 2.4. SQL-Anweisung zum Einfügen des Ergebnisses eines SELECT-Ausdrucks in die Tabelle „Import“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5. SQL-Anweisung zum Löschen von Datensätzen aus der Tabelle „Import“ . . . 13 2.6. SQL-Anweisung zum Verknüpfen von Tabellen „Flight“ und „Import“ . . . . . 14 2.7. SQL-Anweisung zum Verknüpfen von Tabellen „Flight“ und „Import“ ohne das Schlüsselwort „JOIN“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.8. Bestimmung der Gruppenergebnisse zu jedem Import . . . . . . . . . . . . . . 14 2.9. Verschiebung des Datumswertes des Imports mit ID 1 um einen Tag nach vorne 15 5.1. Der SQL-Erstellungsbefehl der Tabelle „Flight“ . . . . . . . . . . . . . . . . . 43 5.2. Der SQL-Erstellungsbefehl der Tabelle „Airport“ . . . . . . . . . . . . . . . . 44 5.3. Der SQL-Erstellungsbefehl des Fremdschlüssels für Tabelle „Airport“ . . . . . 45 5.4. Der SQL-Erstellungsbefehl der Tabelle „EXSQLExpression“ . . . . . . . . . . 45 7.1. 1. Variante des Codes der Anfrage „Welche Flugzeuge sind im Moment unterwegs?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 7.2. 2. Variante des Codes der Anfrage „Welche Flugzeuge sind im Moment unterwegs?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 7.3. Code der Anfrage „Wie viele Flugzeuge des Typs Airbus A320 sind im Moment unterwegs?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 7.4. Code der Anfrage „Welche Flugzeuge befinden sich aktuell unter FL0?“ . . . . 65 7.5. Code der Anfrage „Welche Flugzeuge befinden sich im Landeanflug?“ . . . . . 67 7.6. Code der Anfrage „Welche Flugzeuge nähern sich kritisch?“ 69 . . . . . . . . . . 7.7. Code der Anfrage „Welche Flugzeuge befinden sich momentan über London?“ 70 7.8. Code der Anfrage „Welche Fluggesellschaft betreibt die meisten Flüge zwischen 18 und 20 Uhr?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 7.9. Code der Anfrage „Wie viele Flüge hat es maximal zwischen 13 und 15 Uhr im Gebiet London gegeben?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 7.10. Code der Anfrage „Welche landende Flugzeuge befinden sich momentan über London?“ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 95 Verzeichnis der Listings A.1. Quellcode der Funktion zur Bestimmung der Zugehörigkeit eines Punktes einer festgelegten Region . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii A.2. HTML-Quellcode des Kartendarstellungswerzeugs . . . . . . . . . . . . . . . . iv A.3. JavaScript-Quellcode des Kartendarstellungswerzeugs . . . . . . . . . . . . . . iv A.4. Benutzerdefinierte Funktion zur Berechnung des sphärischen Abstandes . . . x A.5. Benutzerdefinierte Funktion zur Feststellung einer kritischen Annäherung . . x A.6. Benutzerdefinierte Funktion zur Bestimmung der Zugehörigkeit eines Punktes dem Londoner Gebiet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii 96 A. Anhang A. Anhang In diesem Anhang finden sich die Quelltexte der folgenden Teile des vorgestellten Flugüberwachungssystems: • Funktion zum Erstellen eines SQL-Ausdrucks zur Bestimmung der Zugehörigkeit eines Punktes einer festgelegten Region; • Code des Kartendarstellungswerkzeugs; • Benutzerdefinierte SQL-Funktionen, die bei Implementierung von Beispielskenngrößen benutzt wurden. i A. Anhang A.1. Bestimmung der Zugehörigkeit eines Punktes einer festgelegten Region Listing A.1: Quellcode der Funktion zur Bestimmung der Zugehörigkeit eines Punktes einer festgelegten Region 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ’ <summary> ’ Startet das Kartenwerkzeug im Areal-Auswahlmodus und erstellt einen ’ SQL-Ausdruck, der mittels Winkelsummierungsmethode die Zugehörigkeit ’ eines Punktes dem festgelegten Polygon bestimmt. ’ </summary> ’ <returns>SQL-Ausdruck, der bestimmt, ob ein Punkt innerhalb eines ’ festgelegten Polygons liegt</returns> ’ <remarks></remarks> Public Shared Function GetArealSqlExpression() As String ’Koordinaten-Felder abfragen Dim fields() As String = frmLatLonFields.GetCoordinateFields() If fields Is Nothing Then Return Nothing Dim lonField As String = fields(0) Dim latField As String = fields(1) 15 16 17 18 19 ’Map-Control in Areal-Selektions-Modus anzeigen Dim polyList As IList(Of IList(Of ClassLibrary.GeoCoordinate)) polyList = frmMapControl.StartAreaSelection() If polyList Is Nothing Then Return Nothing 20 21 22 23 24 25 ’Expression erstellen Dim expr As String = String.Empty For Each l As IList(Of ClassLibrary.GeoCoordinate) In polyList ’Falls expr nicht leer, ein OR hinzufügen If Not String.IsNullOrEmpty(expr) Then expr += " OR " + ControlChars.NewLine 26 27 Dim subExpr As String = String.Empty 28 29 30 31 32 33 34 35 ’Den ersten Punkt zusätzlich ans Ende der Liste anfügen, ’um ein geschlossenes Polygon zu erhalten l .Add(l(0)) For i As Integer = 0 To l.Count − 2 ’Aufeinanderfolgende Koordinaten auslesen Dim c1 As ClassLibrary.GeoCoordinate = l(i) Dim c2 As ClassLibrary.GeoCoordinate = l(i + 1) 36 37 38 39 40 41 42 43 ’Ausdruck zum Ausrechnen des Winkels erstellen If Not String.IsNullOrEmpty(subExpr) Then subExpr += " + " subExpr+="ACOS((("+c1.Longitude.ToString.Replace(",",".")+"-"+lonField+")*"+ _ "("+c2.Longitude.ToString.Replace(",",".")+"-"+lonField + ")+"+ _ "("+c1.Latitude.ToString.Replace(",",".")+"-"+latField+")*"+ _ "("+c2.Latitude.ToString.Replace(",",".")+"-"+latField+"))/"+ _ "(SQRT(SQUARE("+c1.Longitude.ToString.Replace(",",".")+"-"+lonField+")+"+ _ ii A. Anhang "SQUARE("+c1.Latitude.ToString.Replace(",",".")+"-"+latField+"))*"+ _ "SQRT(SQUARE("+c2.Longitude.ToString.Replace(",",".")+"-"+lonField+")+"+ _ "SQUARE("+c2.Latitude.ToString.Replace(",",".")+"-"+latField+"))))*"+ _ "SIGN(("+c1.Longitude.ToString.Replace(",",".")+"-"+lonField+")*"+ _ "("+c2.Latitude.ToString.Replace(",",".")+"-"+latField+")-"+ _ "("+c1.Latitude.ToString.Replace(",",".")+"-"+latField+")*"+ _ "("+c2.Longitude.ToString.Replace(",",".")+"-"+lonField+"))" 44 45 46 47 48 49 50 51 Next 52 53 54 55 56 ’Ausdruck runden, um Ungenauigkeiten der Berechnung zu glätten subExpr = "ROUND(" + subExpr + ", 6) = ROUND(2*PI(), 6)" expr += "(" + subExpr + ")" Next 57 58 59 60 61 62 63 64 65 ’Prüfung auf Grenzfall 2: Punkt liegt an einer Ecke Dim coExpr As String = String.Empty For Each list As IList(Of ClassLibrary.GeoCoordinate) In polyList For Each Point As ClassLibrary.GeoCoordinate In list If Not String.IsNullOrEmpty(coExpr) Then coExpr += " OR " coExpr += "(" + latField + "=" + Point.Latitude.ToString + " AND " + lonField + "=" + Point.Longitude.ToString + ")" Next Next 66 67 68 ’coExpr einklammern If Not String.IsNullOrEmpty(coExpr) Then coExpr = "(" + coExpr + ")" 69 70 71 ’expr einklammern If polyList .Count > 1 Then expr = "(" + expr + ")" 72 73 74 ’Ein OR zwischen den beiden Bedingungen einfügen If Not String.IsNullOrEmpty(coExpr) Then expr = coExpr + " OR " + expr 75 76 77 78 ’Ergebnis zurückgeben Return expr End Function iii A. Anhang A.2. Kartendarstellungswerkzeug Listing A.2: HTML-Quellcode des Kartendarstellungswerzeugs 1 2 3 4 <html xmlns="http://www.w3.org/1999/xhtml"> <head> <META http−equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Map−Control</title> 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 <link rel="stylesheet" href="res/style.css" type="text/css" /> <link rel="stylesheet" href="res/blueprint.css" type="text/css" /> <style type="text/css"> #controls { width: 512px; } #map { width: 100%; height: 100%; } </style> <script src="OpenLayers/OpenLayers.js"></script> <script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.1"></script> <script type="text/javascript"> ... </script> </head> <body onload="init()"> <div id="map" class="smallmap"></div> <div id="coordinates"></div> <div id="zoomdiv"> <div style="display:none" id="zoom">5</div> </div> <div id="centerdiv"> <div style="display:none" id="x">7</div> <div style="display:none" id="y">50</div> </div> </body> </html> Listing A.3: JavaScript-Quellcode des Kartendarstellungswerzeugs 1 2 3 4 5 6 7 8 9 //Array zum Speichern von Get-Variablen erstellen und füllen var HTTP_GET_VARS = new Array(); var strGET = document.location.search.substr(1,document.location.search.length); if (strGET != ’’) { var gArr = strGET.split(’&’); for(i=0; i<gArr.length; ++i) { v = ’’; vArr = gArr[i]. split (’=’); if (vArr.length > 1) iv A. Anhang v=vArr[1]; HTTP_GET_VARS[unescape(vArr[0])] = unescape(v); 10 11 } 12 13 } 14 15 16 17 18 19 20 //Funktion zum Holen der Get-Variablen aus dem Array function GET(v) { if (! HTTP_GET_VARS[v]) return ’’; return HTTP_GET_VARS[v]; } 21 22 23 //Globale Variablen definieren var map, vectors, controls , select ; 24 25 26 //KML-Dateiname auslesen var kmlfile = GET(’kmlfile’); 27 28 29 30 31 //Mitte und Zoom-Stufe auslesen var mapcenterx = GET(’mapcenterx’); var mapcentery = GET(’mapcentery’); var mapzoom = GET(’mapzoom’); 32 33 34 35 36 37 //Initialisierung von OpenLayers function init(){ //Get-Variablen auslesen var selectarea = GET(’selectarea’); var showkml = GET(’showkml’); 38 39 40 41 42 43 44 45 46 47 48 //Karte erstellen var options = { projection : new OpenLayers.Projection(’EPSG:900913’), displayProjection : new OpenLayers.Projection(’EPSG:4326’), units : ’m’, numZoomLevels: 18, maxResolution: 156543.0339, maxExtent: new OpenLayers.Bounds(−10037508, −10037508, 10037508, 10037508.34) }; map = new OpenLayers.Map(’map’, options); 49 50 51 52 53 54 55 56 57 58 59 //Virtual Earth Layers erstellen und zur Karte hinzufügen var veroad = new OpenLayers.Layer.VirtualEarth( ’Virtual Earth Roads’, {’type’: VEMapStyle.Road, ’sphericalMercator’: true} ); var veaer = new OpenLayers.Layer.VirtualEarth( ’Virtual Earth Aerial’, {’type’: VEMapStyle.Aerial, ’sphericalMercator’: true} ); var vehyb = new OpenLayers.Layer.VirtualEarth( v A. Anhang ’Virtual Earth Hybrid’, {’type’: VEMapStyle.Hybrid, ’sphericalMercator’: true} 60 61 ); map.addLayers([veroad, veaer, vehyb]); 62 63 64 if (( selectarea )&&(selectarea != 0)) { //Vektor-Layer zum Zeichnen von Polygonen erstellen vectors = new OpenLayers.Layer.Vector(’Selected Areas’); vectors .events. register (’featureadded’, vectors, CreateFeatureCoordinateFields); map.addLayer(vectors); 65 66 67 68 69 70 //Control zum Zeichnen von Polygonen hinzufügen map.addControl(new OpenLayers.Control.EditingToolbar(vectors)); 71 72 } 73 74 //Weitere Controls hinzufügen: //1. Zum Wechseln zwischen Layers //2. Zur Anzeige der Position des Cursors map.addControl(new OpenLayers.Control.LayerSwitcher()); map.addControl(new OpenLayers.Control.MousePosition()); 75 76 77 78 79 80 if ((showkml)&&(showkml != 0)) { AddFMLayerToMap(); } 81 82 83 84 //Karte zentrieren if (! map.getCenter()) { if ((mapcenterx)&&(mapcentery)) { if (! mapzoom) mapzoom = 5; map.setCenter(OpenLayers.Layer.SphericalMercator.forwardMercator(mapcenterx/1, mapcentery/1) , mapzoom/1); OnZoomEnd(); OnMoveEnd(); } else map.setCenter(OpenLayers.Layer.SphericalMercator.forwardMercator(7, 50), 5); } 85 86 87 88 89 90 91 92 93 94 95 96 97 //Events registrieren map.events.on({ ’zoomend’: OnZoomEnd, ’moveend’: OnMoveEnd }); 98 99 100 101 102 103 } 104 105 106 107 108 //Bei Änderung der Zoom-Stufe den neuen Wert im Form speichern function OnZoomEnd() { var zoomdiv = document.getElementById(’zoomdiv’); while (zoomdiv.hasChildNodes()) vi A. Anhang zoomdiv.removeChild(zoomdiv.childNodes[0]); 109 110 var zoominput = document.createElement(’div’); zoominput.style.display = ’none’; zoominput.id = ’zoom’; zoominput.innerHTML = map.getZoom(); zoomdiv.appendChild(zoominput); 111 112 113 114 115 116 } 117 118 119 120 121 122 //Bei Änderung der Mitte die neuen Werte im Form speichern function OnMoveEnd() { var centerdiv = document.getElementById(’centerdiv’); while (centerdiv.hasChildNodes()) centerdiv .removeChild(centerdiv.childNodes[0]); 123 var x = map.getCenter().lon; var y = map.getCenter().lat; var p = OpenLayers.Layer.SphericalMercator.inverseMercator(x, y); 124 125 126 127 var centerinputx = document.createElement(’div’); centerinputx. style . display = ’none’; centerinputx.id = ’x’; centerinputx.innerHTML = p.lon; centerdiv .appendChild(centerinputx); 128 129 130 131 132 133 var centerinputy = document.createElement(’div’); centerinputy. style . display = ’none’; centerinputy.id = ’y’; centerinputy.innerHTML = p.lat; centerdiv .appendChild(centerinputy); 134 135 136 137 138 139 } 140 141 142 143 144 //Flight-Monitor KML-Layer zur Karte hinzufügen function AddFMLayerToMap() { if (map.getLayersByName(’Flight-Monitor’).length > 0) map.removeLayer(map.getLayersByName(’Flight-Monitor’)[0]); 145 146 147 148 149 150 151 152 153 154 155 //KML Layer zur Anzeige der Flüge erstellen var flights = new OpenLayers.Layer.GML(’Flight-Monitor’, kmlfile, { projection : new OpenLayers.Projection(’EPSG:4326’), format: OpenLayers.Format.KML, formatOptions: { extractStyles : true, extractAttributes : true, maxDepth: 2 } }); 156 157 158 //Layers zur Karte hinzufügen map.addLayer(flights); vii A. Anhang 159 //Selektions-Control zur Karte hinzufügen und aktivieren select = new OpenLayers.Control.SelectFeature(flights); map.addControl(select); select . activate () ; 160 161 162 163 164 //Events zur Selektion von Features aus der KML-Datei registrieren flights .events.on({ ’featureselected’: OnFeatureSelect, ’featureunselected’: OnFeatureUnselect }); 165 166 167 168 169 170 } 171 172 173 174 function OnPopupClose(evt) { select . unselectAll () ; } 175 176 177 178 //Beim Anklicken eines Features Popup anzeigen function OnFeatureSelect(event) { var feature = event.feature ; 179 //Sicherung gegen Javascript var content = ’<h2>’ + feature.attributes.name + ’</h2>’ + feature.attributes.description; if (content.search(’<script’) != −1) { content = content.replace(/</g, ’&lt;’); } 180 181 182 183 184 185 //Popup mit dem Inhalt des Features anzeigen popup = new OpenLayers.Popup.FramedCloud(’chicken’, feature .geometry.getBounds().getCenterLonLat(), new OpenLayers.Size(100, 100), content, null , true, OnPopupClose); feature .popup = popup; map.addPopup(popup); 186 187 188 189 190 191 192 193 194 } 195 196 197 198 199 200 201 202 203 204 function OnFeatureUnselect(event) { //Popup killen var feature = event.feature ; if (feature .popup) { map.removePopup(feature.popup); feature .popup.destroy(); delete feature .popup; } } 205 206 207 208 //Koordinaten des festgelegten Polygons im Form speichern function CreateFeatureCoordinateFields() { //Evtl. vorhandene Koordinatenfelder löschen viii A. Anhang RemoveFeatureCoordinateFields(); 209 210 if (vectors . features .length > 0) { var coords = document.getElementById(’coordinates’); 211 212 213 for (var i = 0; i < vectors. features .length; i++) { //Koordinatenfeld erstellen var div = document.createElement(’div’); div. id = ’coords_’ + i; div. style . display = ’none’; 214 215 216 217 218 219 //Koordinaten im Format <Lon1>,<Lat1>;<Lon2>,<Lat2>;... in das Feld schreiben div.innerHTML = GetVertices(vectors.features[i].geometry); 220 221 222 //Koordinatenfeld dem Bereich hinzufügen coords.appendChild(div); 223 224 } 225 } 226 227 } 228 229 230 231 232 233 234 235 //Koordinaten des festgelegten Polygons aus dem Form löschen function RemoveFeatureCoordinateFields() { var coords = document.getElementById(’coordinates’); //Alle Kinderknoten löschen while (coords.hasChildNodes()) coords.removeChild(coords.childNodes[0]); } 236 237 238 239 //Koordinatenstring zu einer Geometrie erstellen function GetVertices(g) { var result = ’’; 240 //Komponenten der gegebenen Geometrie auslesen var v = g.components[0].components; 241 242 243 if (v.length > 0) { for (var i = 0; i < v.length − 1; i++) { if ( result != ’’) result += ’;’; 244 245 246 247 //Koordinaten umwandeln und zum Ergebnis hinzufügen var p = OpenLayers.Layer.SphericalMercator.inverseMercator(v[i].x, v[i ]. y); result += p.lon + ’,’ + p.lat; 248 249 250 } } return result; 251 252 253 254 } ix A. Anhang A.3. Implementierung von Kenngrößen in SQL A.3.1. Benutzerdefinierte Funktion zur Berechnung des sphärischen Abstandes Listing A.4: Benutzerdefinierte Funktion zur Berechnung des sphärischen Abstandes 1 2 3 4 5 6 7 8 9 10 11 CREATE FUNCTION dbo.getDistance ( @lon1 DECIMAL(18,6), @lat1 DECIMAL(18,6), @lon2 DECIMAL(18,6), @lat2 DECIMAL(18,6) ) RETURNS DECIMAL(18,6) AS BEGIN DECLARE @result DECIMAL(18,6); 12 13 SET @result = acos(sin(@lat1)∗sin(@lat2)+cos(@lat1)∗cos(@lat2)∗cos(@lon1−@lon2))∗6378137; 14 15 16 RETURN @result; END A.3.2. Benutzerdefinierte Funktion zur Feststellung einer kritischen Annäherung Listing A.5: Benutzerdefinierte Funktion zur Feststellung einer kritischen Annäherung 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 CREATE FUNCTION dbo.doCollide ( @lon1 DECIMAL(18,6), @lat1 DECIMAL(18,6), @alt1 DECIMAL(18,6), @incline1 DECIMAL(18,6), @speed1 DECIMAL(18,6), @alpha DECIMAL(18,6), @lon2 DECIMAL(18,6), @lat2 DECIMAL(18,6), @alt2 DECIMAL(18,6), @incline2 DECIMAL(18,6), @speed2 DECIMAL(18,6), @beta DECIMAL(18,6) ) RETURNS BIT AS BEGIN /* Ausnahme 1: Geschwindigkeit = 0 */ x A. Anhang 20 21 IF ((@speed1 = 0) OR (@speed2 = 0)) RETURN 0; 22 23 24 25 26 27 28 29 30 /* Ausnahme 2: Beide Winkel = pi/2 oder 3*pi/2 */ IF ((@alpha = PI() / 2) OR (@alpha = 3 ∗ PI() / 2) AND (@beta = PI() / 2) OR (@beta = 3 ∗ PI() / 2)) BEGIN IF ((@lon1 = @lon2) AND ((@alpha > @beta) AND (@lat1 > @lat2) OR (@alpha < @beta) AND ( @lat1 < @lat2))) RETURN 1; ELSE RETURN 0; END 31 32 33 34 35 36 37 DECLARE DECLARE DECLARE DECLARE DECLARE DECLARE @deltaxa DECIMAL(18,6); @deltaxb DECIMAL(18,6); @gammaa DECIMAL(18,6); @gammab DECIMAL(18,6); @k1 DECIMAL(18,6); @k2 DECIMAL(18,6); 38 39 40 41 42 43 44 45 46 47 48 49 /* Delta(xa) und Gamma(a) setzen */ IF ((@alpha = PI() / 2) OR (@alpha = 3 ∗ PI() / 2)) SET @deltaxa = 0; ELSE BEGIN IF (((@alpha >= 0) AND (@alpha < PI() / 2)) OR ((@alpha > 3 ∗ PI() / 2) AND (@alpha < 2 ∗ PI()))) SET @deltaxa = 1; ELSE SET @deltaxa = −1; END SET @gammaa = @deltaxa ∗ @alpha; 50 51 52 53 54 55 56 57 58 59 60 61 /* Delta(xb) und Gamma(b) setzen */ IF ((@beta = PI() / 2) OR (@beta = 3 ∗ PI() / 2)) SET @deltaxb = 0; ELSE BEGIN IF (((@beta >= 0) AND (@beta < PI() / 2)) OR ((@beta > 3 ∗ PI() / 2) AND (@beta < 2 ∗ PI()) )) SET @deltaxb = 1; ELSE SET @deltaxb = −1; END SET @gammab = @deltaxb ∗ @beta; 62 63 64 65 /* k1 und k2 berechnen */ IF (@deltaxa <> 0) SET @k1 = tan(@gammaa) / @deltaxa; xi A. Anhang 66 67 68 69 70 71 ELSE SET @k1 = 0; IF (@deltaxb <> 0) SET @k2 = tan(@gammab) / @deltaxb; ELSE SET @k2 = 0; 72 73 74 75 /* 1. Trefferbedingung */ IF (@k2 − @k1 = 0) RETURN 0; 76 77 78 79 80 DECLARE DECLARE DECLARE DECLARE @b1 DECIMAL(18,6); @b2 DECIMAL(18,6); @x DECIMAL(18,6); @y DECIMAL(18,6); 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 /* Berechnung des Kreuzpunktes */ IF ((@deltaxa <> 0) AND (@deltaxb <> 0)) BEGIN SET @b1 = − tan(@gammaa) / @deltaxa ∗ @lon1 + @lat1; SET @b2 = − tan(@gammab) / @deltaxb ∗ @lon2 + @lat2; SET @x = (@b1 − @b2) / (@k2 − @k1); SET @y = (@k2 ∗ @b1 − @k1 ∗ @b2) / (@k2 − @k1); END ELSE BEGIN /* Falls eine der Geraden nicht in Form y = kx + b beschrieben werden kann */ IF (@deltaxa = 0) BEGIN SET @x = @lon1; SET @y = @k2 ∗ @x − tan(@gammab) / @deltaxb ∗ @lon2 + @lat2; END ELSE BEGIN SET @x = @lon2; SET @y = @k1 ∗ @x − tan(@gammaa) / @deltaxa ∗ @lon1 + @lat1; END END 104 105 106 107 108 109 110 /* 2. Trefferbedingung */ IF ((SIGN(@x − @lon1) <> SIGN(@deltaxa)) OR (SIGN(@y − @lat1) <> SIGN(tan(@gammaa))) OR (SIGN(@x − @lon2) <> SIGN(@deltaxb)) OR (SIGN(@y − @lat2) <> SIGN(tan(@gammab)))) RETURN 0; 111 112 113 DECLARE @t1 DECIMAL(18,6); DECLARE @t2 DECIMAL(18,6); 114 115 /* Berechnung von Zeitspannen */ xii A. Anhang 116 117 SET @t1 = dbo.getDistance(@x, @y, @lon1, @lat1) / @speed1; SET @t2 = dbo.getDistance(@x, @y, @lon2, @lat2) / @speed2; 118 119 120 121 /* 3. Trefferbedingung */ IF (ABS(@t1 − @t2) >= 2) RETURN 0; 122 123 124 125 /* 4. Trefferbedingung */ IF (ABS((@alt1 + @incline1 ∗ @t1) − (@alt2 + @incline2 ∗ @t2)) >= 444) RETURN 0; 126 127 128 RETURN 1; END A.3.3. Benutzerdefinierte Funktion zur Bestimmung der Zugehörigkeit eines Punktes dem Londoner Gebiet Listing A.6: Benutzerdefinierte Funktion zur Bestimmung der Zugehörigkeit eines Punktes dem Londoner Gebiet 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE FUNCTION dbo.isOverLondon ( @lon DECIMAL(18,6), @lat DECIMAL(18,6) ) RETURNS BIT AS BEGIN IF ((@lat=51.694693 AND @lon=−0.398254) OR (@lat=51.510452 AND @lon=−0.596008) OR (@lat=51.323747 AND @lon=−0.4422) OR (@lat=51.249882 AND @lon=−0.041199) OR (@lat=51.433464 AND @lon=0.390015) OR (@lat=51.640181 AND @lon=0.332336) OR (@lat=51.70831 AND @lon=−0.052185) OR (@lat=51.694693 AND @lon=−0.398254)) RETURN 1; 17 18 19 IF (ROUND(ACOS(((−0.398254−@lon)∗(−0.596008−@lon)+(51.694693−@lat)∗(51.510452−@lat))/( SQRT(SQUARE(−0.398254−@lon)+SQUARE(51.694693−@lat))∗SQRT(SQUARE (−0.596008−@lon)+SQUARE(51.510452−@lat))))∗SIGN((−0.398254−@lon)∗(51.510452−@lat) −(51.694693−@lat)∗(−0.596008−@lon)) + ACOS(((−0.596008−@lon)∗(−0.4422−@lon) +(51.510452−@lat)∗(51.323747−@lat))/(SQRT(SQUARE(−0.596008−@lon)+SQUARE (51.510452−@lat))∗SQRT(SQUARE(−0.4422−@lon)+SQUARE(51.323747−@lat))))∗SIGN ((−0.596008−@lon)∗(51.323747−@lat)−(51.510452−@lat)∗(−0.4422−@lon)) + ACOS(((−0.4422− @lon)∗(−0.041199−@lon)+(51.323747−@lat)∗(51.249882−@lat))/(SQRT(SQUARE(−0.4422−@lon )+SQUARE(51.323747−@lat))∗SQRT(SQUARE(−0.041199−@lon)+SQUARE(51.249882−@lat ))))∗SIGN((−0.4422−@lon)∗(51.249882−@lat)−(51.323747−@lat)∗(−0.041199−@lon)) + ACOS (((−0.041199−@lon)∗(0.390015−@lon)+(51.249882−@lat)∗(51.433464−@lat))/(SQRT(SQUARE xiii A. Anhang (−0.041199−@lon)+SQUARE(51.249882−@lat))∗SQRT(SQUARE(0.390015−@lon)+SQUARE (51.433464−@lat))))∗SIGN((−0.041199−@lon)∗(51.433464−@lat)−(51.249882−@lat)∗(0.390015− @lon)) + ACOS(((0.390015−@lon)∗(0.332336−@lon)+(51.433464−@lat)∗(51.640181−@lat))/( SQRT(SQUARE(0.390015−@lon)+SQUARE(51.433464−@lat))∗SQRT(SQUARE(0.332336− @lon)+SQUARE(51.640181−@lat))))∗SIGN((0.390015−@lon)∗(51.640181−@lat)−(51.433464− @lat)∗(0.332336−@lon)) + ACOS(((0.332336−@lon)∗(−0.052185−@lon)+(51.640181−@lat) ∗(51.70831−@lat))/(SQRT(SQUARE(0.332336−@lon)+SQUARE(51.640181−@lat))∗SQRT( SQUARE(−0.052185−@lon)+SQUARE(51.70831−@lat))))∗SIGN((0.332336−@lon)∗(51.70831− @lat)−(51.640181−@lat)∗(−0.052185−@lon)) + ACOS(((−0.052185−@lon)∗(−0.398254−@lon) +(51.70831−@lat)∗(51.694693−@lat))/(SQRT(SQUARE(−0.052185−@lon)+SQUARE (51.70831−@lat))∗SQRT(SQUARE(−0.398254−@lon)+SQUARE(51.694693−@lat))))∗SIGN ((−0.052185−@lon)∗(51.694693−@lat)−(51.70831−@lat)∗(−0.398254−@lon)), 6) = ROUND(2∗PI(), 6)) RETURN 1; 20 21 22 RETURN 0; END xiv A. Anhang Eidesstattliche Erklärung Hiermit erkläre ich, dass ich diese Diplomarbeit selbstständig durchgeführt, keine anderen als die angegebenen Quellen und Hilfsmittel benutzt sowie Zitate als solche kenntlich gemacht zu haben. Köln, den 21. November 2009 Dmitri Mizerkin xv