Wie die 3D Funktionalität verwendet wird, möchte ich in mehreren Blog-Postings anhand des Aufbaus von 3D Stadtmodellen erläutern.
Im heutigen Posting soll es zunächst um die Konstruktion von LOD1 gehen. Die Abkürzung LOD steht für Level of Detail, Level 1 für die Konstruktion von Gebäudeblöcken aus in die Höhe gezogenen Grundflächen, auch Klötzchenmodell genannt.
Was wird benötigt?
- Gebäudehöhe
- Höhe über Grund
Genausogut können Hausumringe z.B. aus ALK-Daten verwendet werden, sofern Höhenangaben beigegeben sind.
Wie geht man vor?
- Liegen die Daten nicht direkt als SDO_GEOMETRY vor, müssen sie mit einem Werkzeug zuvor konvertiert werden.
- Für die zu erzeugenden 3D-Geometrien wird eine neue Tabelle angelegt.
create table buildings_lod1 ( building_id number primary key, gmlid varchar2(30), height number, ground_height number, geom sdo_geometry );
- Mit der Funktion SDO_UTIL.EXTRUDE werden aus den 2D-Geometrien (Flächen) unter Verwendung der Höhenangaben HEIGHT und GROUND_HEIGHT 3D-Geometrien (Körper) erzeugt.
-- Vorgehen für Version 11.2 insert into buildings_lod1 ( building_id, gmlid, height, ground_height, geom) select building_id, gmlid, height, ground_height, sdo_util.extrude ( geom, sdo_number_array (ground_height), sdo_number_array (height), 0.005, 7405 -- Compound CRS aus EPSG:27700 + EPSG:5701 ) from building_footprints; commit;
Für die 567 Gebäudesätze braucht es wenige Sekunden und die neue Tabelle ist befüllt.
Neues Koordinatensystem ist jetzt EPSG:7405, also OSGB 1936 + ODN height. - Zwecks Überprüfung werden die Daten nun noch nach KML konvertiert, in einem Ordner im XMLDB Repository als Resource abgelegt und mit Google Earth zur Anzeige gebracht.
-- PL/SQL Prozedur: Export SDO_GEOMETRY als KML declare result boolean; kmldoc xmltype; begin SELECT -- Anm.: Ein bisschen SQL/XML in der Datenbank kann nicht schaden xmlelement ( "kml", xmlattributes ('http://www.opengis.net/kml/2.2' as "xmlns"), xmlelement ( "Document", xmlelement ( "Style", xmlattributes('BuildingStyle' as "id"), xmlelement ("LineStyle", xmlelement ("width", '1'), xmlelement ("color", 'ffffffff') ), xmlelement ( "PolyStyle", xmlelement ("color", 'bfc0c0c0') ), xmlelement ( "BalloonStyle", xmlelement ("text", '$[name]') ) ), xmlagg ( xmlelement ( "Placemark", xmlelement ("name", 'Building '|| gmlid), xmlelement ("styleUrl", '#BuildingStyle'), xmltype ( sdo_util.to_kmlgeometry ( snap_to_ground ( sdo_cs.transform(geom,4327), 0 ) ) ) ) ) ) ) INTO kmldoc FROM buildings_lod1; -- Wenn KML-Datei schon in Repository vorhanden ist, dann löschen if dbms_xdb.existsresource ('/public/Buildings/buildings_lod1.kml') then dbms_xdb.deleteresource('/public/Buildings/buildings_lod1.kml'); end if; -- KML-Datei ins Repository schreiben result := dbms_xdb.createResource ('/public/Buildings/buildings_lod1.kml', kmldoc); if not result then raise_application_error (-20000, 'Failed to create resource'); end if; end; / commit;
Die Hilfsfunktion SNAP_TO_GROUND ist übrigens wie folgt definiert:
-- "Alles auf Grund" create or replace function snap_to_ground ( geom sdo_geometry, ground_height number) return sdo_geometry deterministic is i number; g sdo_geometry; current_ground_height number; offset number; begin g := geom; current_ground_height := sdo_geom.sdo_min_mbr_ordinate(g,3); offset := current_ground_height - ground_height; i := 0; while i < g.sdo_ordinates.count loop g.sdo_ordinates(i+3) := g.sdo_ordinates(i+3) - offset; i := i + 3; end loop; return g; end; /
Die ausserdem verwendeten Funktionen SDO_UTIL.TO_KMLGEOMETRY und SDO_CS.TRANSFORM sind Bestandteil der Oracle DB Spatial Features.
Alternativ kann der Export natürlich auch als GML (CityGML-konform) erfolgen. Dann läßt sich das Ergebnis, wie in der nachfolgenden Abbildung, z.B. mit dem LandExplorer CityGML Viewer darstellen.