Geometrie-Modul

Das Geometrie-Modul enthält die Tabellen zur Speicherung sowohl expliziter als auch impliziter Geometrien von Stadtobjekten. Implizite Geometrien können gemäß dem gleichnamigen Konzept in CityGML als Vorlage (Template) für mehrere Features wiederverwendet werden.

image geometryModule
Figure 1. Geometrie-Modul des relationalen Schemas der VCDB v5.

GEOMETRY_DATA Tabelle

Die GEOMETRY_DATA Tabelle dient als zentraler Speicherort sowohl für explizite als auch implizite Geometrien der Features in der VCDB. Sie unterstützt verschiedene Geometrietypen, einschließlich Punkten, Linien, flächenhaften Geometrien und Volumengeometrien.

Explizite Geometrien

Explizite Geometrien werden über Realwelt-Koordinaten beschrieben und in der geometry Spalte gespeichert. Diese Spalte verwendet einen vordefinierten räumlichen Datentyp des zugrunde liegenden Datenbanksystems. Alle Geometrien müssen mit 3D-Koordinaten angegeben werden, deren Werte dem Koordinatenreferenzsystem (CRS) entsprechen müssen, das für die VCDB-Instanz festgelegt wurde. Um effiziente räumliche Abfragen zu ermöglichen, ist die geometry Spalte standardmäßig indiziert.

Die Verbindung zwischen einem Stadtobjekt in der FEATURE Tabelle und seiner Geometrie erfolgt über eine Geometrie-Property in der PROPERTY Tabelle. Zusätzlich enthält die GEOMETRY_DATA Tabelle einen Fremdschlüssel feature_id, der auf das zugehörige Feature verweist. Damit sind bidirektionale Abfragen möglich – vom Feature zu den zugehörigen Geometrien oder umgekehrt.

Implizite Geometrien

Implizite Geometrien werden in der implicit_geometry Spalte der GEOMETRY_DATA Tabelle gespeichert. Im Gegensatz zu expliziten Geometrien verwenden implizite Geometrien lokale Koordinaten, wodurch sie als Template für mehrere Stadtobjekte in der Datenbank dienen können. Aus diesem Grund werden sie in einer eigenen Spalte gespeichert und nicht in der geometry Spalte. Da implizite Geometrien nicht eindeutig einem einzelnen Feature zugeordnet sind, wird der Wert der feature_id Spalte auf NULL gesetzt. Stattdessen werden sie über die IMPLICIT_GEOMETRY Tabelle referenziert.

Aufgrund der lokalen Koordinaten werden implizite Geometrien typischerweise nicht für räumliche Abfragen verwendet. Die implicit_geometry Spalte ist daher standardmäßig nicht indiziert.

JSON-basierte Metadaten

Die Nutzund der vordefinierten räumlichem Datentypen zur Speicherung sowohl expliziter als auch impliziter Geometrien bringt zwei zentrale Herausforderungen mit sich:

  1. Geometrietypen: CityGML-Features verwenden eine Vielzahl unterschiedlicher Geometrietypen, von primitiven Geometrien (Punkte, Linien, Flächen und Volumengeometrien) bis hin zu zusammengesetzten und aggregierten Geometrien. Alle Geometrietypen basieren auf dem ISO 19107 Spatial Schema Standard. Die vordefinierten räumlichen Datentypen decken jedoch meist nur eine Teilmenge dieser Geoemtrietypen ab, was die vollständige Abbildung aller CityGML-Geometrien erschwert.

  2. Wiederverwendung und Referenzierung: CityGML erlaubt die Wiederverwendung von (Teil-)Geometrien durch Referenzierung und ermöglicht die Zuweisung von Texturen und Farben. Um dies zu ermöglichen, benötigen Geometrien und ihre Bestandteile eindeutige Identifier. Die räumlichen Datentypen speichern jedoch typischerweise nur die reinen Koordinatenwerte und bieten keine native Unterstützung für Identifier. Dies erschwert die Referenzierung und Wiederverwendung.

Frühere Versionen der VCDB haben dies gelöst, indem flächenhafte Geometrien in ihre einzelnen Polygone zerlegt wurden, die dann zusammen mit einem eindeutigen Identifier in jeweils eigenen Zeilen gespeichert wurden. Über eine hierarchische Tabellenstruktur wurden die Einzelpolygone entsprechend ihrem ursprünglichen Geometrietyp logisch gruppiert. Diese Lösung ermöglichte zwar eine effiziente Referenzierung, hatte aber den Nachteil, dass Geometrien für räumliche Abfragen zur Laufzeit erst wieder zusammengestzt werden mussten. Dadurch wurden diese Abfragen langsamer und weniger effizient. Weiterhin erhöhte die Lösung den Speicherbedarf und war nur für flächenhafte Geometrien umgesetzt, nicht jedoch für Punkte oder Linien.

Die VCDB v5 löst dieses Problem, indem die gesamte Geometrie ohne weitere Zerlegung direkt in einem der vordefinierten räumlichen Datentypen gespeichert wird. Damit wird die Performance räumlicher Abfragen erheblich verbessert und der Speicherbedarf deutlich reduziert. Um dennoch die Wiederverwendbarkeit und Referenzierbarkeit von Geometrien und ihrer Bestandteile zu ermöglichen und die unterschiedlichen CityGML-Geometrietypen zu unterstützen, werden zusätzlich JSON-basierte Metadaten in der Spalte geometry_properties gespeichert.

Die Struktur und Verwendung dieser Metadaten wird im Folgenden anhand der Speicherung einer CityGML Solid-Geometrie in PostgreSQL/PostGIS veranschaulicht. Der hierfür erforderliche PostGIS-spezifische räumliche Datentyp ist POLYHEDRALSURFACE Z, der ein einfaches Array von Polygonen speichert. Das folgende Beispiel zeigt, wie ein Einheitswürfel bestehend aus sechs Polygonen als POLYHEDRALSURFACE Z repräsentiert wird. Die äquivalente Solid-Geometrie in CityGML wird in einem zweiten Tab gegenübergestellt.

  • POLYHEDRALSURFACE Z

  • CityGML Solid

POLYHEDRALSURFACE Z (
  ((0 0 0, 0 1 0, 1 1 0, 1 0 0, 0 0 0)),
  ((0 0 0, 0 1 0, 0 1 1, 0 0 1, 0 0 0)),
  ((0 0 0, 1 0 0, 1 0 1, 0 0 1, 0 0 0)),
  ((1 1 1, 1 0 1, 0 0 1, 0 1 1, 1 1 1)),
  ((1 1 1, 1 0 1, 1 0 0, 1 1 0, 1 1 1)),
  ((1 1 1, 1 1 0, 0 1 0, 0 1 1, 1 1 1))
)
<gml:Solid gml:id="mySolid">
  <gml:exterior>
    <gml:Shell gml:id="myOuterShell">
      <gml:surfaceMember>
        <gml:Polygon gml:id="first">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>0 0 0 0 1 0 1 1 0 1 0 0 0 0 0</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
      <gml:surfaceMember>
        <gml:Polygon gml:id="second">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>0 0 0 0 1 0 0 1 1 0 0 1 0 0 0</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
      <gml:surfaceMember>
        <gml:Polygon gml:id="third">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>0 0 0 1 0 0 1 0 1 0 0 1 0 0 0</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
      <gml:surfaceMember>
        <gml:Polygon gml:id="fourth">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>1 1 1 1 0 1 0 0 1 0 1 1 1 1 1</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
      <gml:surfaceMember>
        <gml:Polygon gml:id="fifth">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>1 1 1 1 0 1 1 0 0 1 1 0 1 1 1</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
      <gml:surfaceMember>
        <gml:Polygon gml:id="sixth">
          <gml:exterior>
            <gml:LinearRing>
              <gml:posList>1 1 1 1 1 0 0 1 0 0 1 1 1 1 1</gml:posList>
            </gml:LinearRing>
          </gml:exterior>
        </gml:Polygon>
      </gml:surfaceMember>
    </gml:Shell>
  </gml:exterior>
</gml:Solid>

Im Gegensatz zur POLYHEDRALSURFACE Z in PostGIS enthält die CityGML Solid-Geometrie eine zusätzliche Shell, die die aus den Polygonen gebildete äußere Hülle des Volumnes repräsentiert. Darüber hinaus verfügen sowohl der Solid, die Shell als auch jedes einzelne Poylgon über einen eigenen Identifier (gml:id), die eine Wiederverwendung der Bestandteile sowie die Zuweisung von Texturen und Farben ermöglichen. Das folgende JSON-Objekt kodiert diese zusätzlichen Metadaten und verknüpft sie mit der POLYHEDRALSURFACE Z Repräsentation:

{
  "type": 9, (1)
  "objectId": "mySolid",
  "children": [
    {
      "type": 6, (2)
      "objectId": "myOuterShell"
    },
    {
      "type": 5, (3)
      "objectId": "first",
      "parent": 0,
      "geometryIndex": 0
    },
    {
      "type": 5,
      "objectId": "second",
      "parent": 0,
      "geometryIndex": 1
    },
    {
      "type": 5,
      "objectId": "third",
      "parent": 0,
      "geometryIndex": 2
    },
    {
      "type": 5,
      "objectId": "fourth",
      "parent": 0,
      "geometryIndex": 3
    },
    {
      "type": 5,
      "objectId": "fifth",
      "parent": 0,
      "geometryIndex": 4
    },
    {
      "type": 5,
      "objectId": "sixth",
      "parent": 0,
      "geometryIndex": 5
    }
  ]
}
1 Ein Wert von 9 bedeutet Solid.
2 Ein Wert von 6 bedeutet CompositeSurface oder Shell.
3 Ein Wert von 5 bedeutet Polygon.

Die Metadaten werden wie folgt interpretiert: Die Eigenschaft "type" des JSON-Objekts klassifiziert die Geometrie als Solid (type = 9), mit einer eindeutigen "objectId" von "mySolid". Das "children" Array listet alle Bestandteile des Solid auf und stellt eine hierarchische Beziehung zwischen ihnen her. Das erste Element im "children" Array repräsentiert die äußere Hülle der Volumengeometrie (type = 6) und hat den Identifier "myOuterShell". Gemäß der Definition in ISO 19107 fungiert die äußere Hülle als Container, verweist jedoch nicht direkt auf eine bestimmte Geometrie innerhalb der POLYHEDRALSURFACE Z.

Die weiteren sechs Einträge im "children" Array repräsentieren die einzelnen Polygone (type = 5), aus denen die äußere Hülle besteht. Jedes Polygon besitzt eine eigene eindeutige "objectId". Das "parent" Attribut enthält einen 0-basierten Verweis auf einen Eintrag im "children" Array und definiert darüber das übergeordnete Element des jeweiligen Kindelements. In diesem Beispiel bedeutet der Wert 0, dass alle Polygone zur äußeren Hülle gehören. Der "geometryIndex" ist ein 0-basierter Index, der das Kindelement mit einem bestimmten Polygon innerhalb der POLYHEDRALSURFACE Z verknüpft, die in der geometry Spalte gespeichert ist.

Diese einfache JSON-Struktur eignet sich zur Abbildung der CityGML-Geometrietypen auf einen räumlichen Datentyp. Zusammengefasst besteht die Grundidee darin, dass die in einem räumlichen Datentyp enthaltenen Primitive (Punkte, Linien, Polygone) über den geometryIndex referenziert werden, während die children und parent Struktur die Einbettung dieser Primitive in eine CityGML-Geometriehierarchie ermöglicht. Die objectId stellt einen eindeutigen Identifier für jeden Bestandteil bereit und gewährleistet so, dass die Geometrie und ihre Bestandteile einzelnen referenziert und in der Datenbank unterschieden werden können.

Die folgende Tabelle listet alle Geometrietypen auf, die über die JSON-Metadaten unterstützt und beschrieben werden können. Für jeden Typ sind der entsprechende Wert des "type" Attributs sowie die zuläassigen Kindelemente angegeben:

Geometrietyp "type" Zulässige Kindelemente

Point

1

-

MultiPoint

2

Eine oder mehrere Point Geometrien

LineString

3

-

MultiLineString

4

Eine oder mehrere LineString Geometrien

Polygon

5

-

CompositeSurface

6

Eine oder mehrere Polygon Geometrien

TriangulatedSurface

7

Eine oder mehrere Polygon Geometrien

MultiSurface

8

Eine oder mehrere Polygon Geometrien

Solid

9

Genau eine CompositeSurface Geometrie zur Beschreibung der äußeren Hülle (Innenhüllen werden nicht unterstützt)

CompositeSolid

10

Eine oder mehrere Solid Geometrien

MultiSolid

11

Eine oder mehrere Solid Geometrien

Im Vergleich zur ISO 19107 und deren Umsetzung in GML wurde die Auswahl der unterstützten Geometrietypen sowie deren zulässiger Kindelemente bewusst vereinfacht, um die Komplexität der JSON-Metadaten zu reduzieren und deren Verarbeitung zu erleichtern.

Zusätzlich zu den zuvor beschriebenen Eigenschaften "objectId", "type" und "children" kann das JSON-Metadatenobjekt auch die "is2D" Eigenschaft enthalten. Wenn "is2D" auf true gesetzt ist, muss die Geometrie als zweidimensional interpretiert werden. Dennoch muss sie weiterhin mit 3D-Koordinaten in der geometry Spalte gespeichert werden (z.B. mit einem Höhenwert von 0). Werkzeuge, die die Geometrie verarbeiten, können die Höhenkoordinaten ignorieren, wenn "is2D" gesetzt ist.

Darüber hinaus kann jedes Element im "children" Array eine "isReversed" Eigenschaft besitzen. Dieses Flag zeigt an, ob die Koordinaten des Elements beim Import umgekehrt wurden, um die Orientierung zu invertieren. Dies kann beispielsweise beim Import von CityGML-Daten auftreten, die orientierbare Primitive wie gml:OrientableSurface enthalten, deren orientation Attribut auf "-" gesetzt ist. Anhand der "isReversed" Eigenschaft können solche (Teil-)Geometrien wieder als orientierbares Primitiv exportiert werden.

Das VCDB-Softwarepaket enthält eine JSON Schema-Spezifikation, die die zulässige Struktur des JSON-Metadatenobjekts definiert. Diese Schema-Datei mit dem Namen geometry-properties.schema.json befindet sich im Ordner json-schema des Softwarepakets.

IMPLICIT_GEOMETRY Tabelle

Die IMPLICIT_GEOMETRY Tabelle implementiert das Konzept der impliziten Geometrien in CityGML. Eine implizite Geometrie ist eine Vorlage (Template), die nur einmal in der VCDB gespeichert wird, aber von mehreren Stadtobjekten wiederverwendet werden kann. Typische Beispiele für implizite Geometrien sind 3D-Baummodelle, bei denen verschiedene Baumarten und -höhen durch unterschiedliche Template-Geometrien repräsentiert werden. Diese Baummodelle können dann für einzelne Baum-Objekte an verschiedenen Positionen instanziiert werden, je nach Art und Standort des Baums.

Jedes Feature kann dabei einen Referenzpunkt angeben, an dem die Template-Geometrie platziert werden soll, sowie eine individuelle 3x4-Transformationsmatrix, mit der Skalierung, Rotation und Translation auf die Vorlage angewendet werden. Die Verknüpfung zwischen einem Feature aus der FEATURE Tabelle und einer impliziten Geometrie in der IMPLICIT_GEOMETRY Tabelle erfolgt über einen entsprechenden Eintrag in der PROPERTY Tabelle. Der feature-spezifische Referenzpunkt sowie die Transformationsmatrix werden ebenfalls mit in der PROPERTY Tabelle gespeichert (siehe hier).

Die IMPLICIT_GEOMETRY Tabelle unterstützt drei Methoden zur Speicherung von Template-Geometrien:

  1. Speicherung als Geometrie mit lokalen Koordinaten: Die Geometrie wird in der Spalte implicit_geometry der GEOMETRY_DATA Tabelle gespeichert (wie oben beschrieben) und über den relative_geometry_id Fremdschlüssel referenziert.

  2. Speicherung als binärer Blob: Das 3D-Modell liegt in einem spezifischen Datenformat vor und wird als Binärobjekt in der library_object Spalte gespeichert.

  3. Sepicherung als Verweis auf ein externes 3D-Modell: In diesem Fall wird das 3D-Modell über eine URI in der Spalte reference_to_library referenziert, die auf eine externe Datei oder ein externes System verweist.

Für die Methoden 2 und 3 muss in der Spalte mime_type der MIME-Typ des binären 3D-Modells bzw. der externen Datei angeben werden, um eine korrekte Verarbeitung zu gewährleisten (z.B. model/gltf+json für ein glTF-Modell oder application/vnd.collada+xml für ein COLLADA-Modell). Optional kann die mime_type_codespace Spalte einen Code-Space zur weiteren Klassifizierung oder weiteren Kontext für den MIME-Type enthalten.

Die Spalte objectid schließlich stellt einen eindeutigen Identifier für die implizite Geometrie bereit, der idealerweise global eindeutig sein sollte.

Die empfohlene Methode zur Verwaltung impliziter Geometrien ist die Speicherung in der GEOMETRY_DATA Tabelle mit lokalen Koordinaten. Die Speicherung beliebiger binärer 3D-Modelle birgt das Risiko, dass Anwendungen diese möglicherweise nicht korrekt verarbeiten können.