terrestris GmbH & Co. KG

Einstieg in die WebGIS-3D Welt

Inhalt

Vorheriges Thema

1.1.2. GPX-Tracks in das Portal laden

Nächstes Thema

2. Ein hochauflösendes Geländemodell in X3DOM

1.1.3. Code-Snippets im Detail

Nachdem wir die Anwendung in ihren Funktionen getestet haben, wollen wir im nächsten Schritt an zentralen Stellen der Anwenung den Code inspizieren und geringfügige Änderungen vornehmen. Der Fokus soll hierbei auf den Cesium-spezifischen Passagen im Code liegen. Erweiterte Programmierkenntnisse sind hierfür nicht notwendig!

1.1.3.1. Dateistruktur der Anwendung

Wenn Sie die Anwendung in Ihrem Dateibrowser öffnen, werden Sie unterhalb des Ordners cesium_client/ die folgende Ordnerstruktur vorfinden (bis zur dritten Ordnerebene angezeigt):

cesium_client/
  geodjango/
    cesium/
      [...]
    geodjango/
      [...]
    terretris_auth/
      [...]
  statics/
    client/
      app/
        [...]
      libs/
        [...]
      resources/
        [...]

Die Struktur folgt der typischen Struktur eines Django-Projekts und gliedert sich wie folgt:

  • cesium_client/: Der übergeordnete Anwendungsordner.
  • geodjango/: Alle Backend-Dateien für Django. In diesem Ordner liegen ausschließlich die serverseitig auszuführende Python-Skripte, wie z.B. Einstellungen für die Datenbankanbindung, Model-Defintionen, Benutzerverwaltung und der Projektcode, der die Applikationslogik der Schnittstellen beinhaltet.
  • statics/: Alle Client-Dateien. In diesem Ordner liegen alle clientseitig auszuführende JavaScript-Dateien.
  • app/: Der Clientcode, weiter unterteilt nach Klassen. Innerhalb dieses Ordners liegen alle ExtJS und Cesium Klassen und Methoden, die das Frontend steuern. Hierzu gehören z.B. die sichtbaren Panels, das Höhenprofil und der 3D-Viewer selbst.
  • lib/: Alle JavaScript Bibliotheken für den Client (ExtJS, Cesium). Änderungen in diesem Ordner sind i.a.R nicht notwendig.
  • resources/: Alle Stildateien für den Client (CSS, Bilder etc.).

Wir werden uns für die folgenden Code-Beispiele weitestgehend auf den Client beschränken und Änderungen in der Cesium-Konfiguration vornehmen.

1.1.3.2. Der Cesium-Viewer

Die Anwendung wurde so konzipiert, dass sie durch eine zentrale Konfigurationsdatei aufgebaut wird. Diese Datei wird beim initialen Aufruf über eine Django-Schnittstelle geladen und vom Client ausgewertet. Konkret geschieht dies in der statics/client/app-dev.js über die Schnittstelle /django/auth/init/, die ein JSON in folgender Form ausgibt:

{
    "user": {
        "id": 1,
        "name": "terrestris"
    },
    "layers": [
        {
            "fileExtension": null,
            "name": "Bing",
            "extent": null,
            "credit": "terrestris",
            "url": null,
            "imageryProvider": "BingMaps",
            "maximumLevel": 18,
            "proxy": null
        }
    ],
    "viewer": {
        "animation": true,
        "baseLayerPicker": false,
        "containerId": "cesiumContainer",
        "fullscreenButton": false,
        "homeButton": true,
        "sceneMode": "3D",
        "sceneModePicker": false,
        "showRenderLoopErrors": true,
        "timeline": true,
        "useDefaultRenderLoop": true
    }
}

Innerhalb dieser Konfiguration sind die Objekte user, layers und viewer vorhanden, wobei layers den verwendeten Hintergrunddienst und viewer die Konfigurationsparameter für den Cesium-Viewer beinhalten. Der Client wertet dieses JSON mit einem eigenen Parser (statics/client/app/parser/Config.js) aus und übersetzt die Angaben in valide JavaScript Objekte. Vernachlässigen wir für diesen Workshop den über ExtJS realisierten Viewport (für Details siehe statics/client/app/view/Viewport.js), ist für Cesium einzig der folgende Codeblock für den Cesium-Viewer relevant (in der Config.js):

var viewer = new Cesium.Viewer(viewerConf.containerId, {
    animation: viewerConf.animation,
    baseLayerPicker: viewerConf.baseLayerPicker,
    fullscreenButton: viewerConf.fullscreenButton,
    homeButton: viewerConf.homeButton,
    geocoder: false,
    imageryProvider: false,
    sceneMode: me.getSceneMode(viewerConf.sceneMode),
    sceneModePicker: viewerConf.sceneModePicker,
    showRenderLoopErrors: viewerConf.showRenderLoopErrors,
    timeline: viewerConf.timeline,
    terrainProvider: new Cesium.VRTheWorldTerrainProvider({
        url : 'http://www.vr-theworld.com/vr-theworld/tiles1.0.0/73/',
        credit : 'Terrain data courtesy VT MÄK'
    }),
    useDefaultRenderLoop: viewerConf.useDefaultRenderLoop
});

Der Viewer wird mit new Cesium.Viewer(<div>, {options}) instanziiert. Hierbei ist {options} ein Objekt von gültigen Eigenschaften dieser Klasse. Eine Übersicht dieser inlusive einer erweiterten Dokumentation finden Sie unter http://cesiumjs.org/Cesium/Build/Documentation/Viewer.html.

1.1.3.3. Manipulation der Viewer-Eigenschaften

  1. Wir wollen die Konfiguration nun so ändern, dass der Client mit einem zusätzlichen Button aufgerufen wird, der es ALLEN Nutzern, unabhängig von dem jeweiligen Status erlaubt, den Viewer in den Vollbildmodus zu setzen. Nutzen Sie hierzu ggf. die o.g. Cesium-Doku.

  2. Da wir in unserer Anwenung eine Nutzerverwaltung einsetzen, ist es möglich, jedem Nutzer spezifische zusätzlich Clienteigenschaften, d.h. nicht statische Inhalte zuzuordnen. Dies ist z.B. für die Hintergrundkarte möglich, die aktuell jedem User (ob anonym oder angemeldet) den Bing Luftbilddienst zuweist. Im nächsten Schritt werden wir die Schnittstelle in Django so ändern, dass jeder eingeloggte User einen WMS als Hintergrundkarte erhält. Hierzu muss die Antwort der o.g. init Schnittstelle angepasst werden. Öffnen Sie daher die Datei views.py im Ordner cesium_client/geodjango/cesium und ändern Sie innerhalb der der Methode (init_view) den folgenden Block:

    return render_to_response('login.json', {
        "userid": id,
        "username": username,
        'attributes': {
            'imageryProvider': '"WebMapService"',
            'name': '"OSM terrestris"',
            'url': '"http://ows.terrestris.de/osm/service"',
            'layers': '"OSM-WMS"',
            'parameters': {
                'transparent': 'true',
                'singleTile': 'true',
                'format': 'image/jpeg'
            },
            'extent': 'null',
            'maximumLevel': 18,
            'credit': '"terrestris"',
            'proxy': '"/django/proxy?url="'
        }
    })
    

    Die Änderung bewirkt, dass in der gegebene Inhalt in die Konfigurationsdatei geschrieben wird und die Methode createImageryProvider() in der Config.js ein Objekt für einen WMS an den Viewer zurückgibt und somit der WMS auf dem Globus dargestellt wird. Selbstverständlich können Sie an dieser Stelle jeden beliebigen WMS einfügen! Cesium besitzt neben den hier gezeigten Layertypen (Bing und WMS) eine Unterstützung für weitere Provider (z.B. OpenStreetMap). Für eine Übersicht aller möglichen ImageryProvider sei an dieser Stelle auf die offizielle Dokumentation verwiesen (http://cesiumjs.org/Cesium/Build/Documentation/ImageryProvider.html?classFilter=imagery&show=all)

  3. Bonusaufgabe: Ändern Sie mit Hilfe der Beispiele im Cesium Sandcastle die initiale Zentrums-Koordinate des Globus, sodass dieser z.B. auf die Beuth Hochschule in einer Höhe von 3000m zoomt.

Wir haben in diesem Modul die 3D-Bibliothek Cesium kennengelernt und am Beispiel eines einfachen Clients erste Einblicke in diese erhalten. Im nächsten Modul werden wir eine weitere Bibliothek - X3DOM - in unser Repertoire aufnehmen und uns der Modellierung von 3D-Modellen widmen. Weiter zu Modul 2.