3D

Beschreibung

Die Visualisierung von 3D-Daten bietet eine niederschwellige Übersicht von Gegebenheiten in der realen Welt, ohne vor Ort zu sein. Der Kartendienst basemap.de 3D stellt dafür LoD2-Gebäude und Geländeinformationen bereit.

Bereitstellung

Die 3D-Gebäude (LoD2) werden als 3D-Tiles mit einer Standardfärbung (Dächer in Rot, Wände in Grau, Brücken in Schwarz) im JSON-Format bereitgestellt.
• LoD2, EPSG:4978 (WGS84) - Höhe Null:
https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/lod2_4978_null.json
• LoD2, EPSG:4978 (WGS84) - Höhe DGM5:
https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/lod2_4978_dgm5.json
• LoD2, EPSG:3857 (WGS84, Pseudo-Mercator) - Höhe Null:
https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/lod2_3857_null.json

Die Geländedaten (Terrain) stehen als quantized Mesh und als kodierte RGB-Bilder bereit. Diese können dann mit beliebigen Karten kombiniert werden.
• DGM5, EPSG:4978 (WGS84)
https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_4326_mesh (Achtung! Dieser Link ist nicht direkt erreichbar, sondern dient als Eintrag für Cesium)
• DGM5, EPSG:3857 (WGS84, Pseudo-Mercator):
https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_3857_rgb.json

Aktualität, Datenmodell

Die LoD2-Gebäude werden jährlich zum 1. März veröffentlicht. Bei den Geländedaten geschieht dies unregelmäßig in einem mehrjährigen Intervall.
Datenaktualität basemap.de 3D

Eine Anpassung des Visualisierungs-Stiles kann bei den Gebäuden anhand der zugrundeliegenden Datenattribute erfolgen. Die Darstellung des Geländes wird durch die verwendete Karte definiert.
Datenmodell basemap.de 3D

Nutzung

LoD2-MapLibre
LoD2-Cesium
Terrain-MapLibre
Terrain-Cesium
MapLibreGL JS ist eine Open-Source Weiterentwicklung von MapboxGL JS, da Mapbox mit der Veröffentlichung der Version 2.0 zu einer proprietären Lizenz gewechselt ist.
Im Smart-Mapping Projekt wird MapLibreGL JS für die Kartendarstellung im Webbrowser und für weitere Funktionen genutzt. Darauf aufbauend erfolgt die Visualisierung der Gebäude über eine externe Javascript-Datei mittels ThreeJS.
 <html lang="en">
  <head>
   <meta charset="utf-8">
   <!-- Laden der benötigen Javascript uns CSS-Datei von Maplibre -->
   <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css' />
   <script src='https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js'></script>
   <script src="https://sg.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/Maplibre3DTiles.js"></script>   
   <style>
       body { margin:0; padding:0; }
       #map { position:absolute; top:0; bottom:0; width:100%; }
       .container {
          position: absolute;
          left: 5px;
          padding: 5px;
          border: 1px solid gray;
          border-radius: 2px;
          background-color: black;
          color: white;
          min-width: 200px;
       }

       #controls { position:absolute; top:0; left:0; }
       #info {
           top:120px;
           min-height: 75px;
       }
   </style>
 </head>
 <body>
    <div id="map"></div>
    <div id="info" class="container"></div>
    <script>
         let infoElement = document.querySelector('#info');
         infoElement.innerHTML = "Klicken Sie auf ein Gebaeude, <br>um sich dessen Attribute anzuzeigen.";

        <!-- Initialisiern des Viewer mit der definierten Hintergrundkarte -->
        var map = new maplibregl.Map({
          container: 'map',
          style:'https://sgx.geodatenzentrum.de/gdz_basemapde_vektor/styles/bm_web_col.json',
          center: [6.959092,50.941485],
          zoom: 16.3,
          bearing: -20,
          pitch: 40,
          hash: true
        });

        map.addControl(new maplibregl.NavigationControl(),'top-left');

        <!-- Holen der Gebaeude und hinzufuegen als eigenen Layer-->
        map.on('style.load', function() {
          let lod2_layer = new Mapbox3DTiles.Mapbox3DTilesLayer( {
              id: 'lod2_building',
              url: 'https://sg.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/lod2_3857_null.json',
              colorWall: '#c2c2c2',
              colorRoof: '#ff5c4d',
              colorBridge: '#999999'
          } );
          map.addLayer(lod2_layer, 'Gebaeude3D_nicht_oeffentlich');
          map.setLayoutProperty('Gebaeude3D_oeffentlich', 'visibility', 'none');
          map.setLayoutProperty('Gebaeude3D_nicht_oeffentlich', 'visibility', 'none');
          map.setLayoutProperty('Hauskoordinate', 'visibility', 'none');
        });

<!-- Gebaeude erst ab Zoomstufe 16 darstellen, fuer eine schnellere Darstellung--> map.on('zoom', () => { var zoom=map.getZoom(); if (zoom<16) { map.setLayoutProperty('lod2_building', 'visibility', 'none'); } else { map.setLayoutProperty('lod2_building', 'visibility', 'visible'); } }); <!-- Anzeigen der Gebaeude-Features in der Info-Box --> map.on('click', (event)=>{ let infoElement = document.querySelector('#info'); let features = map.queryRenderedFeatures(event.point, {outline: true, outlineColor: 0xff0000}); let tileset='false' for (let i = 0; i < features.length; i++) { source = features[i].source; if(source.includes('root.json')) {tileset='true'} } if (tileset === "true" ) { console.log(features) infoElement.innerHTML = features.filter(feature=> feature.layer.id == 'lod2_building') .map(feature=>`Layer: ${feature.layer.id}<br> ${Object.entries(feature.properties) .map(entry=>`<b>${entry[0]}:</b>${entry[1]}`) .join('<br>\n')} `).join('<hr>\n') } else { infoElement.innerHTML = "Klicken Sie auf ein Gebaeude, <br>um sich dessen Attribute anzuzeigen."; } })
</script> </body> </html>
CesiumJS ist eine JavaScript Bibliothek zum Erstellen von 3D-Globen und 2D-Karten im Browser, welche als Open-Source Software zur Verfügung steht. Es wird aber auch ein kostenpflichtiger Dienst angeboten, um u.a. spezifische Hintergrundkarten zu nutzen. In dem folgenden Beispiel werden nur kostenfreie Dienste verwendet.
<html lang="en">
    <head>
     <meta charset="utf-8">
     <title> LoD2 Gebaeude </title>
     <!-- Laden der benötigen Javascript und CSS-Datei von Cesium -->
     <script script src="https://cesium.com/downloads/cesiumjs/releases/1.125/Build/Cesium/Cesium.js"></script>
     <link href="https://cesium.com/downloads/cesiumjs/releases/1.125/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
     <style>
         html, body, #cesiumContainer {
             width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
         }
     </style>
   </head>
   <body>
      <div id="cesiumContainer"></div>
      <script>
	  <!-- optional: Cesium.Ion.defaultAccessToken = 'XXXX'; -->

          <!-- Initialisiern des Cesium-Viewer-->
	  var viewer = new Cesium.Viewer('cesiumContainer',{
             shadows: false,
             geocoder: false,
             baseLayerPicker: false
          });

          <!-- Hintergrundkarte für die Gebiete außerhalb von Deutschland-->
          var osm= new Cesium.OpenStreetMapImageryProvider({
              url : '//a.tile.openstreetmap.org/',
              credit: new Cesium.Credit("\u003ca href=\"https://www.openstreetmap.org/copyright\""+
                                         "target=\"_blank\"\u003e\u0026copy; OpenStreetMap contributors\u003c/a\u003e", true)
         });
         viewer.imageryLayers.addImageryProvider(osm);

         <!-- Hintergrundkarte festlegen - WMS der SmartMapping Karte. Leider unterstützt Cesium keine Vector-Tiles.-->
         const provider = new Cesium.WebMapServiceImageryProvider({
            url : 'https://sgx.geodatenzentrum.de/wms_basemapde?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities',
            layers: "de_basemapde_web_raster_farbe",
            parameters: {
              transparent: true,
              format: "image/png",
            }
        });
        viewer.imageryLayers.addImageryProvider(provider);

        <!-- Kamera auf uebergebenen Punkt zentrieren in einer bestimmten Hoehe-->
        viewer.camera.flyTo({destination:Cesium.Cartesian3.fromDegrees(6.958215,50.932767, 1500.0),
                              orientation:{
                                    heading: Cesium.Math.toRadians(0.0),
                                    pitch : Cesium.Math.toRadians(-50.0),
                                    roll : 0.0}
                            });

  
        <!-- 3D-Tileset ergaenzen, welches die LoD2-Gebaeude von der Smart-Mapping Seite laedt --> 
        window.startup = async function (Cesium) {
           'use strict';
           try {
              const tileset = await Cesium.Cesium3DTileset.fromUrl(
     				"https://sg.geodatenzentrum.de/gdz_basemapde_3d_gebaeude/lod2_4978_null.json",
		                { showOutline: false }
                              );

               viewer.scene.primitives.add(tileset);

               <!-- Die definierten Flächen können individuell eingefärbt werden.--> 
               var cityStyle = new Cesium.Cesium3DTileStyle({
                  color : {
                   conditions : [
                    ["${surface} === 'wall'", "color('#f2f2f2')"],
                    ["${surface} === 'roof'", "color('#ff5c4d')"],
                    ["${surface} === 'bridge'", "color('#999999')"]
                   ]
                  },
                });
              tileset.style = cityStyle
          } catch (error) {
               console.error(`Error creating tileset: ${error}`);
          }
       };

<!-- Beim Aufruf der Anwendung die Gebaeude laden-->
if (typeof Cesium !== 'undefined') {
    window.startupCalled = true;
    window.startup(Cesium).catch((error) => {
      "use strict";
      console.error(error);
    });
}
      </script>
   </body>
  </html>  
MaplibreGL JS ist eine Open-Source Weiterentwicklung von MapboxGL JS, da Mapbox mit der Veröffentlichung der Version 2.0 zu einer proprietären Lizenz gewechselt ist.
Im Smart-Mapping Projekt wird MaplibreGL JS für die Kartendarstellung im Web-Browser und für weitere Funktionen genutzt.
 <html>
  <head>
   <meta charset="utf-8"/>
   <title> 3D Gelaende </title>
   <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
   <!-- Laden der benötigen Javascript und CSS-Datei von Maplibre -->
   <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.6.0/dist/maplibre-gl.css' />
   <script src='https://unpkg.com/maplibre-gl@5.6.0/dist/maplibre-gl.js'></script>
   <style>
       body { margin:0; padding:0; }
       #map { position:absolute; top:0; bottom:0; width:100%; }
   </style>
 </head>
 <body>
    <div id="map"></div> 
    <script>
        <!-- Initialisiern des Viewer mit der definierten Hintergrundkarte -->  
        var map = (window.map = new maplibregl.Map({
          container: 'map',
          zoom: 13.3,
          center: [10.8859,47.64851],
          pitch: 54,
          hash: true,
          style: 'https://sgx.geodatenzentrum.de/gdz_basemapde_vektor/styles/bm_web_col.json',
          maxZoom: 18,
          maxPitch: 85
       }));

       <!-- Beim Starten fuege das Gelaende und den Hillshade hinzu -->
       map.on('load', () => {
         <!-- Gelaendearchiv holen und als Gelaende setzen --> 
  	 map.addSource("terrainSource", {
	    "type": "raster-dem",
	    "url": "https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_3857_rgb.json",
	    "tileSize": "256"
	 });
	 map.setTerrain({
	    source: "terrainSource"
	 });

	<!-- Hillshade-Layer aus dem Gelaende definieren und als Layer hinzufuegen -->
	map.addSource("hillshadeSource",{
	    "type": "raster-dem",
	    "url": "https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_3857_rgb.json",
	    "tileSize": "256"
	});
	map.addLayer({
	   "id": "hills",
	   "type": "hillshade",
	   "source": "hillshadeSource",
	   "layout": {visibility: "visible"},
	   "paint":  {"hillshade-shadow-color": "#473B24"}
  	});
      });          
      map.addControl(
             new maplibregl.NavigationControl({
                visualizePitch: true,
                showZoom: true,
                showCompass: true
             })
      );
      map.addControl(
             new maplibregl.TerrainControl({
                source: 'terrainSource',
                exaggeration: 1
             })
      );
    </script>
 </body>
</html>
CesiumJS ist eine JavaScript Bibliothek zum Erstellen von 3D-Globen und 2D-Karten im Browser, welche als Open-Source Software zur Verfügung steht. Es wird aber auch ein kostenpflichtiger Dienst angeboten, um u.a. spezifische Hintergrundkarten zu nutzen. In dem folgenden Beispiel werden nur kostenfreie Dienste verwendet.
<html lang="en">
<head>
  <meta charset="utf-8">
  <title> Gelande </title>
  <!-- Laden der benötigen Javascript und CSS-Datei von Cesium -->
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.130/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.130/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
  <style>
      html, body, #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
  </style>
</head>
<body>
  <div id="cesiumContainer"></div>
  <script>
    <!-- optional: Cesium.Ion.defaultAccessToken = 'XXXX'; -->

    <!-- Initialisiern des Cesium-Viewer-->
    var viewer = new Cesium.Viewer('cesiumContainer',{
          shadows: false,
          geocoder: false,
          baseLayerPicker: false
    });

    <!-- Hintergrundkarte für die Gebiete außerhalb von Deutschland-->
    var osm= new Cesium.OpenStreetMapImageryProvider({
        url : '//a.tile.openstreetmap.org/',
             credit: new Cesium.Credit("\u003ca href=\"https://www.openstreetmap.org/copyright\""+
                                         "target=\"_blank\"\u003e\u0026copy; OpenStreetMap contributors\u003c/a\u003e", true)
    });
    viewer.imageryLayers.addImageryProvider(osm);

    <!-- Hintergrundkarte festlegen - WMS der SmartMapping Karte. Leider unterstützt Cesium keine Vector-Tiles.-->
    const provider = new Cesium.WebMapServiceImageryProvider({
        url : 'https://sgx.geodatenzentrum.de/wms_basemapde?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetCapabilities',
        layers: "de_basemapde_web_raster_farbe",
        parameters: {
              transparent: true,
              format: "image/png",
            }
        });
    viewer.imageryLayers.addImageryProvider(provider);

     <!-- Kamera auf uebergebenen Punkt zentrieren in einer bestimmten Hoehe-->
     viewer.camera.flyTo({destination:Cesium.Cartesian3.fromDegrees(10.277367,47.415311, 3500.0), 
                             orientation:{ 
                                  heading: Cesium.Math.toRadians(50.0), 
                                  pitch : Cesium.Math.toRadians(-40.0), 
                                  roll : 0.0}
                            });

     <!--Gelaende ergaenzen --> 
     window.startup = async function (Cesium) {
           'use strict';
           try {
                 const terr = await Cesium.CesiumTerrainProvider.fromUrl("https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_4326_mesh/")
		 viewer.terrainProvider=terr;
               }
           catch (error) {
                console.error(`Error creating tileset: ${error}`);
              }
     };

     <!-- Beim Aufruf der Anwendung das Gelaende laden-->
     if (typeof Cesium !== 'undefined') {
        window.startupCalled = true;
        window.startup(Cesium).catch((error) => {
           "use strict";
           console.error(error);
        });
     }
  </script>
</body>
</html>

Weiterführende Informationen

Derzeit ist eine kurze zusammenfassende Dokumentation verfügbar:
• Dokumentation basemap.de 3D

Lizenz- und Nutzungsbedingungen

Es gelten folgende Lizenz- und Nutzungsbedingungen:
PDF Datei