terrestris GmbH & Co. KG

GeoExt 2.0

Inhalt

Vorheriges Thema

2. WMS und der GeoExt LayerStore

Nächstes Thema

2.2. Eine Legende hinzufügen

2.1. Der Karte einen TreeView hinzufügen um die Layer zu managen

Mit dem Ext.tree.Panel und seinen Treenodes bietet Ext JS ein leistungstarkes Tool, um mit hierarchische Informationen zu arbeiten.

Seit Version 4 von Ext JS können Trees aus Stores erstellt werden. Unsere Layer sind ein Beispiel für hierarchische Daten. Hierfür können wir einen Ext.data.TreeStore benutzen, den wir mit einem GeoExt.data.LayerTreeModel konfigurieren.

Die Knoten des Trees verwalten dabei die Layer der Karte; mit checkboxen konfiguriert, können diese Layer an- und ausgeschalten. Zusätzlich und dank der drag&drop-Unterstützung von Ext JS trees, können die Layer einfach neu geordnet werden.

Bemerkung

Vergessen Sie nicht die benötigten Klassen hinzuzuüfgen. Gehen Sie zur Ext.require-Definition des Grundbeispiels und fügen Sie die folgenden Klassen hinzu:

  • ‘Ext.grid.Panel’,
  • ‘GeoExt.data.WmsCapabilitiesLayerStore’,
  • ‘GeoExt.tree.Panel’,
  • ‘Ext.tree.plugin.TreeViewDragDrop’,
  • ‘Ext.util.Point’,
  • ‘GeoExt.tree.OverlayLayerContainer’,
  • ‘GeoExt.tree.BaseLayerContainer’,
  • ‘GeoExt.data.LayerTreeModel’,
  • ‘GeoExt.tree.View’,
  • ‘GeoExt.tree.Column’

2.1.1. Layer Management mit dem Treepanel

Lassen Sie uns nun einen Tree zum letzten Beispiel hinzufügen. (Legen Sie sich vorher eine Kopie an, falls Sie das Basisbeispiel behalten wollen.) Dafür erstellen wir ein Tree-Panel mit einem GeoExt.tree.LayerContainer und fügen es als neues Item unserem Hauptpanel hinzu.

Tasks

  1. Falls Sie map.html nicht bereits im Editor geöffnet haben, tun Sie dies nun. Fügen Sie die folgende Tree-Definition am Ende des Applikations-Skriptes hinzu:

    var store = Ext.create('Ext.data.TreeStore', {
        model: 'GeoExt.data.LayerTreeModel',
        root: {
            expanded: true,
            children: [
                {
                    plugins: [{
                        ptype: 'gx_layercontainer'
                    }],
                    expanded: true,
                    text: 'Layers'
                }
            ]
        },
        autoLoad: true
    });
    
    items.push(Ext.create('Ext.tree.Panel', {
        ref: "tree",
        region: "west",
        store: store,
        width: 200,
        rootVisible: false,
        viewConfig: {
            plugins: { ptype: 'treeviewdragdrop' }
        },
        bbar: [{
            text: "Remove from Map",
            handler: function() {
                var tree = Ext.ComponentQuery.query('treepanel[ref="tree"]')[0],
                    node = tree.getSelectionModel().getSelection()[0],
                    mapPanel = Ext.ComponentQuery.query('gx_mappanel')[0];
                if (node && node.get('layer') instanceof OpenLayers.Layer.WMS) {
                    mapPanel.map.removeLayer(node.get('layer'));
                }
            }
        }]
    }));
    

    Laden Sie map.html in ihrem Browser neu, um die Veränderungen zu sehen. Auf der linken Seite der Karte haben wir nun den Tree. Wie Sie sehen, befindet sich der von uns hinzugefügt Layer “OWS-WMS” im Tree.

  2. Um die Funktionalität des Tree komplett zu nutzen, benötigen wir natürlich weitere Layer. Fügen Sie ihrer Karte weitere Layer hinzu. Zum Beispiel die Layer “OSM-Bushaltestellen” und “OSM-Strassenbahnhaltestellen”, von http://ows.terrestris.de/dienste.html. Sie können nun die Reihenfolge der Layer ändern und einzelne Layer an- und ausschalten.

../_images/tree.png

Applikation mit Tree-Panel

2.1.2. Der neue Code im Detail

Schauen wir uns zuerst einmal die Tree-Konfiguration an, um zu sehen, was die Bestandteile sind.

Wie wir bereits gesehen haben, können wir die Knoten per drag&drop neu ordnen. Dies wird durch ein spezielles Plugin ermöglicht, dass wir dem Tree-View mitgeben.

viewConfig: {
    plugins: { ptype: 'treeviewdragdrop' }
},

Das TreeViewDragDrop-Plugin bietet eine drag&drop Funktionalität für den TreeView, der aus dem TreeGrid erstellt wird.

Noch interessanter ist das root-Element.

root: {
    expanded: true,
    children: [
        {
            plugins: [{
                ptype: 'gx_layercontainer'
            }],
            expanded: true,
            text: 'Layers'
        }
    ]
}

Jeder Tree benötigt einen root-Knoten. GeoExt bietet ein gx_layercontainer-Plugin für Treenodes. Konfiguriert man nun den Store des Trees mit dem Layerstore der Karte, wird für jeden Layer in der Karte ein Knoten im Tree angelegt.

Die Knoten mit denen der Layercontainer gefüttert wird, sind Instanzen von GeoExt.tree.LayerNode. Der Container stellt dabei sicher, dass die Liste der Layer immer mit der Lister der Karte synchronisiert wird. Die Checkbox kontrolliert dabei die Sichtbarkeit des Layers.

Erstaunlicherweise erfordert der Root-Knoten mit allen Kartenlayern weniger Code, als ein Button um Layer zu löschen:

bbar: [{
    text: "Remove from Map",
    handler: function() {
        var tree = Ext.ComponentQuery.query('treepanel[ref="tree"]')[0],
            node = tree.getSelectionModel().getSelection()[0],
            mapPanel = Ext.ComponentQuery.query('gx_mappanel')[0];
        if (node && node.get('layer') instanceof OpenLayers.Layer.WMS) {
            mapPanel.map.removeLayer(node.get('layer'));
        }
    }
}]

Wir fügen diesen Button einer sogenannten Bottom-Toolbar zu. Diese taucht als “bbar”-Element im Treepanel auf. Der Kern des Buttons ist sein handler. Im handler definieren wir eine Funktion, die beschreibt, was bei auslösen des Buttons passieren soll. Der Tree verfügt über ein Ext.selection.Model. Dieses Model liefert ein Array aller ausgewählten Datensätze - in unserem Fall Nodes. Das Standard-Selection-Model des trees erlaubt nur die Selektion eines einzelnen Knoten. Mit der Methode getSelection() bekommen wir die aktuelle Auswahl. Anschließend prüfen wir, ob der ausgewählte Knoten sich auf einen WMS-Layer bezieht (wir wollen verhindern, dass Vektorlayer oder andere Layer, die wir manuell hinzugefügt haben, gelöscht werden) und löschen mit der Methode removeLayer() des OpenLayers.Map-Objekts, den Layer aus der Karte.

2.1.3. Die nächsten Schritte

Jetzt wo wir den Inhalt unsere Karte mit Hilfe eines Trees kontrollieren, möchten Wir eine Legende anzeigen lassen, die die Karte erklärt.