NAS-Viewer M-V - Datenmodell
Der NAS-Viewer soll NAS-Daten des AAA-Modells (AFIS / ALKIS / ATKIS) laden, speichern, darstellen und teilweise auch bearbeiten können.
Dies soll möglichst performant erfolgen, aber auch genügend Flexibilität bieten, um auf Fortschreibung der Versionen des AAA-Modells reagieren zu können.
Zum Zeitpunkt des Entstehens des NAS-Viewers lag das AAA-Modell bereits in der Version 6.0.1 vor, welche heute (2016) einheitlich in allen Bundesländern zu finden ist.
Das AAA-Modell wird in der GeoInfoDok genau beschrieben. (siehe AdV-Online).
Das AAA-Modell ist sehr umfangreich, weil es zahlreiche internationale Standards heranzieht.
Im Einzelnen werden aber von jedem Standard nur wenige Teile ausgenutzt.
Es erscheint also nicht notwendig, sämtliche Standards vollständig zu implementieren, um mit AAA-Daten umgehen zu können.
Weiterhin unterscheidet sich das "externe" Modell, also die "Normbasierte Austauschschnittstelle" (NAS) nochmal stark vom vollständigen AAA-Modell.
Hier gelten zahlreiche Vereinfachungen, insbesondere bezüglich der Mehrfach-Vererbung.
Als Grundlage der Implementierung des Datenmodells für den NAS-Viewer in Java gelten folgende strategische Überlegungen:
-
Nähe zum Modell:
Generell sollte sich das in Java implementierte Datenmodell nicht wesentlich vom logischen Datenmodell (NAS) unterscheiden, um beim Laden und Speichern komplizierte Konvertierungen der Daten zu vermeiden.
Dieser Grundsatz führt i.d.R. zu einfachem und performantem Code.
-
Reduzierte Komplexität:
Das NAS-Schema in Form der XSD-Dateien ist einerseits wegen der vielen ungenutzten Teile der internationalen Standards unnötig kompliziert,
um es 1 zu 1 in Java-Quellcode zu überführen, lässt andererseits aber auch wichtige Elemente, wie die langschriftliche Form von Enumerationen vermissen.
Das interne AAA-Modell enthält zwar die fehlenden Teile, ist aber noch weiter von den tatsächlichen praktischen Anforderungen abgehoben.
Es erscheint sinnvoller, das Schema in einer anderen passenderen Form zu definieren.
(Hier ist eine spezielle XML-Datei entstanden, die von der Klasse NasModelDef geladen wird.)
-
Schneller Zugriff auf Geometrie:
Die geomerischen Elemente des Modells bedürfen einer besonderen Beachtung. Die vollständige Abbildung des GML-Schemas in Java erscheint viel zu umständlich.
GML unterstützt einige Geometrietypen, die per Definition im AAA-Modell ausgeschlossen sind.
Die Abbildung in Java soll es einerseits erlauben, die GML-Daten so wieder auszugeben, wie sie eingelesen wurden,
andererseits soll aber der Zugriff auf die Geometrie ein zügiges Darstellen am Bildschirm und geometrische Indexierung für beschleunigte Suchvorgänge ermöglichen.
Außerdem ist eine kompakte Speicherung wünschenswert, um möglichst große Datenmengen laden zu können.
-
Sonderfälle sind Sonderfälle:
Aus dem WFS-Standard werden nur wenige Teile genutzt, welche aber so fundamentale Bedeutung haben, dass sie auch einer Sonderbehandlung bedürfen.
Das betrifft die WFS-Operationen (Insert, Delete, Update u. Replace), aber auch die Attribute vom Typ <wfs:Transaction>, welche so wie auch <gml:FeatureCollection> als Sonderfälle behandelt werden.
-
Filterencoding als Sonderfall:
Das OGC-Filterencoding ist recht überschaubar und im Umfang abgegrenzt.
Daher wird es direkt in Java-Quellcode abgebildet, was später den typsicheren Zugriff erleichtert.
-
Große Datenmengen sind typisch für AAA-Daten:
Speicherplatz scheint zwar dank leistungsfähiger Rechentechnik kein Problem mehr zu sein. Jedoch täuscht dieser Eindruck.
Vielmehr sollten sich die Fortschritte in der Hardwareentwicklung als Vorteil beim Anwender dokumentieren und nicht durch ungeschicktes Softwaredesign aufgezehrt werden.
Mit der Entscheidung für Java als Programmiersprache wurde bereits ein Kompromiss eingegangen.
Java bietet zwar verglichen mit der Entwicklung in C/C++ viele Vorteile, z.B. bei der automatischen Speicherverwaltung, der Plattformunabhängigkeit und den vielen bereits im JRE vorhandenen Funktionen.
Aber gerade diese Vorteile gibt es nicht zum Nulltarif. Java braucht immer etwas mehr Arbeitsspeicher und Prozessorleistung als vergleichbare Software, die in C/C++ implementiert ist.
Also gerade weil die Entscheidung für Java gefallen ist, müssen besondere Anstrengungen unternommen werden, um nicht unnötig viele Ressourcen zu "verschwenden".
-
Vorteile von Java ausnutzen:
Einige Teile des Java Runtime Environment (JRE) sind überraschend leistungsfähig. Dazu zählen u. a. die Funktionen zum Umgang mit XML.
Das Lesen auch sehr großer XML-Dateien mit dem SAX2-Parser kann erstaunlich schnell sein.
Im Vergleich mit C++ kostet die "new"-Operation in Java deutlich weniger Laufzeit.
Während kleinteilige Speicherverwaltung in C++ immer problematisch ist, besteht in Java kaum Bedarf hier über Optimierung nachzudenken.
Es gilt diese Vorteile im Zusammenhang mit dem NAS-Datenmodell möglicht zu erhalten und an den Anwender weiterzugeben.
-
Keep it simple:
Generell sollen NAS-Daten im Arbeitsspeicher gehalten werden.
Eine automatische Auslagerung auf die Festplatte bei größeren NAS-Dateien erscheint unnötig kompliziert.
NAS-Dateien von 1 GB und mehr sollen zwar ladbar sein, allerdings wird hier vorausgesetzt, dass ein entsprechend parametrisiertes 64-Bit Java zur Anwendung kommt.
Für noch viel größere Datenmengen (10 GB und mehr) wird man aber doch auf eine DHK zur Zwischenspeicherung der NAS-Daten zurückgreifen müssen.
-
Vollhistorie:
Das AAA-Modell sieht die Versionierung von Objekten vor.
Es soll also möglich sein, mehr als eine Version eines Objektes zu laden.
Die Versionierung kann auch bei der Manipulation von Objekten nützlich sein, indem gleichzeitig die veränderten Version neben der ursprüngliche Version existiert.
-
Flexible Kardinalität:
Einige Attribute können je Objekt mehrfach vorkommen. Viele Attribute sind optional.
Das bedeutet, Attribute sollten generell in beliebiger Häufigkeit vorkommen dürfen.
Eine wichtige Designentscheidung war die Speicherung der Attribute in einer einfach verketteten Liste und zwar stets in der für die NAS erforderlichen Reihenfolge.
Eine Verkette Liste ist äußerst flexibel, d.h. die Anzahl der speicherbaren Elemente ist vollkommen beliebig.
Elemente lassen sich leicht hinzufügen oder entfernen.
Bei einer geringen Anzahl von Elementen wird wenig Speicherplatz zur Verwaltung benötigt.
Der Nachteil des rein sequenziellen Zugriffs auf die Elemente ist bei typischerweise 10 Attributen pro Objekt kaum relevant.
Jedes Attribut hat also eine Referenz "next", die zum nachfolgenden Attribut führt.
In der Implementierung werden mehrere Java-Klassen unterschieden, in denen Attribut-Listen gespeichert werden können.
Diese Klassen implementieren das Interface NasAttContainer.
- NasFeature.ObjVersion
Dies ist die Abbildung einer Objektversion.
- NasFeature
Dies ist die Abbildung eines Objektes, welches einen Identifikator und eine oder mehrere Objektversionen haben kann.
Die Implementierung des Interfaces NasAttContainer delegiert die Aufrufe an die jeweils jüngste (aktuelle) Objektversion.
Mehrere Objektversionen werden in einer einfach verketteten Liste gespeichert.
Da ObjVersion als innere Klasse von NasFeature implementiert ist, besitzt die Objektversion automatisch eine Referenz auf das übergeordnete NasFeature.
Die GeoInfoDok spricht hier vom "Objektbehälter".
- NasRootObject
Jede NAS-Datei hat als Wurzel-Element einen Komplexen Datentyp, z.B. "AX_Bestandsdatenauszug".
Diese Datentypen haben kein Lebenszeitintervall, sind also nicht versionierbar, so dass hier nicht mit Objektversionen gearbeitet werden muss.
- NasAttComplex
Einige Attribute haben einen komplexe Datentypen, d.h. sie können Unterattribute speichern.
Unter Verwendung von komplexen Attribute ergibt sich eine hierachische Struktur der Daten.
Die verschiedenen Arten von Attributen werden durch mehrere von
NasAttBase abgeleitete Java-Klassen implementiert:
- NasAttSimple
Solche Attribute können genau einen Wert speichern. Es kann sich auch um einen Enumerationswert handeln.
Der Wertes wird wie in XML immer als String gespeichert, kann aber für unterschiedliche logische Datentypen verwendet werden, Zahlen, Zeiten, Booleansche Werte o. ä.
- NasAttSimpleUom
Diese Klasse ist von NasAttSimple abgeleitet und kann zusätzliche eine Maßeinheit (UOM = Unit on Measure) speichern.
- NasAttComplex
Diese Klasse hat anstelle eines konkreten Wertes eine untergeordnete Attribut-Liste. (siehe oben)
- NasAttPosition
Dies ist die Basisklasse für Geometrie-Attribute. Sie speichert das Koordinatenreferenzsystem (CRS).
Die Speicherung der Geometriedaten selbst wird durch die abgeleiteten Klassen NasAttPosPoint (2D-Punkte) und NasAttPosGeom (beliebige Geometrie) definiert.
- NasAttPosPoint
Diese Klasse bildet nur ein- oder zweidimensionale Koordinaten ab, also die Geometrie von Punktobjekten oder Höhen.
Der Speicherplatzbedarf ist kleiner als bei NasAttPosGeom. Nur aus diesem Grund wurde diese Klasse geschaffen.
- NasAttPosGeom
Diese Klasse bildet alle übrigen Geometrien ab. Sie speichert die Geometrie in 2 Arrays code[] und koord[].
Der Code ist eine Liste von Geometrietypen jeweils mit Anzahl der untergeordneten Elemente, z.B.: Polygon:1, Ring:1, Curve:1, LineStringSegment:20.
Einige der Geometrieelemente haben direkt Koordinaten, andere sind Aggregate von untergeordneten Geometrieelementen.
Für Geometrieelemente mit Koordinaten, z.B. LineStringSegment, korrespondiert die Anzahl mit Einträgen vom Typ double im Koordinaten-Array.
Diese Art der Speicherung ist sehr kompakt aber flexibel genug, um alle tatsächlich für das AAA-Modell relevanten Geometrien abbilden zu können.
- NasAttRelation
Diese Klasse bildet eine Relation ab. Dafür kann ein Identifikator gespeichert werden.
- NasAttSpecial
Diese Klasse wird benötigt, um Spezialfälle abzudecken. Dazu zählen die Attribute vom Typ wfs:Transaction und gml:FeatureCollection.
- NasAttWfsQuery
Diese Klasse ist von NasAttSpecial abgeleitet und implementiert die Anfragekriterien im Benutzungsauftrag oder die Selektionskriterien der Benutzergruppen.
Die evtl. vorhandenen Filterkriterien werden durch die Klasse OgcFilter abgebildet.
Die definierten Attributarten, Objektarten, komplexen Datentypen und Enumerationen werden in der Java-Klasse NasModelDef gekapselt und mit Hilfe einer XML-Datei initialisiert.
Kern der Klasse ist eine Map mit Elementen vom Typ NasTypeDef.
Das ist die Basisklasse für folgende abgeleitete Klassen:
- NasObjDef
Definition für 3 Stereotypen: Objektarten (Feature), komplexe Datentypen und Unions.
- NasEnumDef
Definition Enumerationen, also Wertelisten mit Paaren aus Code und Beschreibung.
- NasSimpleDef
Definition von einfachen Datentypen, z.B. String, Integer, Boolean, Date usw.
- NasGeometryDef
Definition von Geometrietypen, z.B. GM_SURFACE, GM_POINT, GM_OBJECT usw.
- NasSpecialDef
Definition von Speziellen Datentypen, z.B. wfs:Transaction, wfs:Query usw.
Attribute mit diesen Typen unterliegen immer einer Sonderbehandlung.
Die ersten beiden Datentypen,
NasObjDef und
NasEnumDef sind in der o. g. Map in
NasModelDef registriert und können über ihren Namen gefunden werden.
Die anderen Datentypen werden für die Definition der einzelnen Attribute innerhalb der Objektarten, komplexen Datentypen und Unions benötigt.
Die Definition von Attributen erfolgt mittels Instanzen der Java-Klasse NasAttDef.
Diese wiederum haben eine Referenz typeDef auf NasTypeDef, wodurch der Datentyp des Attributes festgelegt wird.
Darüber hinaus werden der Attributname, die Kardinalität und einige weitere Eigenschaften festgelegt.
...