/*
* Copyright (c) 2013 Bundesamt für Kartographie und Geodäsie.
* See license.txt in the BKG WebMap distribution or repository for the
* full text of the license.
*
* Author: Dirk Thalheim
*/
/**
* @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/BaseTypes/Element.js
* @requires OpenLayers/Util.js
* @requires BKGWebMap/Control/LayerSwitcher.js
* @requires BKGWebMap/Control/LayerSwitcher/LayerEntry.js
* @requires BKGWebMap/Util.js
*/
/**
* @classdesc Repräsemtationsklasse für einen simplen Layereintrag im Layerswitcher.
*
* @constructor BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
*/
BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry = OpenLayers.Class(BKGWebMap.Control.LayerSwitcher.LayerEntry, {
/**
* Schieberegler für Layertransparenz
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {BKGWebMap.Util.Slider}
*/
opacitySlider: null,
/**
* Listet die WMS-Ebenen auf, aus denen der Layer ggf. besteht. Wenn mehr als eine Ebene im WMS zur Verfügung
* stehen, werden zusätzlich Controls angezeigt, die diese Ebenen ein- bzw. ausschalten kann.
* Die verfügbaren Ebenen werden über die Methode getSubLayers ermittelt.
*
* Für jeden WMS-Layer wird in der Liste Name und Titel gespeichert
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {Array<object<string,string>>}
*/
subLayers: null,
/**
* CSS-Klasse für HTML-Element des Layereintrags
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {string}
*/
style: 'wmAdvancedLayerEntry',
/**
* Texte für Labels
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {object<string>}
*/
labels: {
opacity: 'Transparenz',
layers: 'Ebenen',
order: 'Reihenfolge'
},
/**
* <code>true</code> um Steuerelement für Layerreihenfolge anzuzeigen
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {boolean}
*/
drawOrder: true,
/**
* <code>true</code> um Steuerelement für Transparenz anzuzeigen
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {boolean}
*/
drawOpacity: true,
/**
* <code>true</code> um Steuerelement für WMS-Ebenen anzuzeigen
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @type {boolean}
*/
drawSubLayers: true,
initialize: function (layer, parent) {
BKGWebMap.Control.LayerSwitcher.LayerEntry.prototype.initialize.apply(this, [layer, parent]);
this.subLayers = this.getSubLayers(layer);
},
destroy: function () {
if (this.settingsToggler) {
this.settingsToggler.destroy();
this.settingsToggler = null;
}
if (this.opacitySlider) {
this.opacitySlider.destroy();
this.opacitySlider = null;
}
if (this.titleDiv) {
OpenLayers.Event.stopObserving(this.titleDiv, "click");
this.titleDiv = null;
}
if (this.prev) {
OpenLayers.Event.stopObserving(this.prev, "click");
this.prev = null;
}
if (this.next) {
OpenLayers.Event.stopObserving(this.next, "click");
this.prev = null;
}
this.toggleSettingsButton = null;
this.settingsDiv = null;
if (this.subLayers) {
BKGWebMap.Util.each(this.subLayers, function (index, subLayer) {
if (subLayer.div) OpenLayers.Event.stopObserving(subLayer.div, "click");
});
}
this.subLayers = null;
},
/**
* Ermittelt alle dem Layer zur Verfügung stehenden Unterlayer
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {OpenLayers.Layer.WMS} layer
* @returns {Array<object<string, string>>}
*/
getSubLayers: function (layer) {
/*
if (!layer instanceof OpenLayers.Layer.WMS) return [];
var curentLayers = layer.params.LAYERS.split(',');
var allLayers = layer.wmSubLayers || curentLayers;
layer.wmSubLayers = allLayers;
var layers = [];
BKGWebMap.Util.each(allLayers, function (index, name) {
layers.push({
id: name,
title: name,
active: curentLayers.indexOf(name) >= 0
});
});
return layers;
*/
if (!layer instanceof BKGWebMap.Layer.WMS) return [];
var layers = [];
BKGWebMap.Util.each(layer.layers, function (index, layer) {
layers.push({
id: layer.name,
title: layer.title,
active: layer.active
});
});
return layers;
},
/**
* Ermittelt die Sublayerparameter anhand einer ID.
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {string} id - die gesuchte Layer-ID
* @returns {Object} Parameter des Sublayers
*/
getSubLayer: function (id) {
for (var i = 0; i < this.subLayers.length; i++) {
if (this.subLayers[i].id == id) return this.subLayers[i];
}
return null;
},
/**
* Erzeugt die HTML-Darstellung für einen Layer-Eintrag
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
*/
draw: function () {
if (!this.layer.displayInLayerSwitcher) return null;
var baseLayer = this.layer.isBaseLayer;
var checked = (baseLayer) ? (this.layer == this.parent.map.baseLayer) : this.layer.getVisibility();
// create Wrapper element
this.div = document.createElement("div");
OpenLayers.Element.addClass(this.div, this.style);
if (checked) {
OpenLayers.Element.addClass(this.div, this.styleSelected);
}
if (!baseLayer && !this.layer.inRange) {
OpenLayers.Element.addClass(this.div, this.styleInactive);
}
// toggle Settings
this.toggleSettingsButton = document.createElement("div");
OpenLayers.Element.addClass(this.toggleSettingsButton, 'wmToggleSettingsButton');
this.div.appendChild(this.toggleSettingsButton);
// Layer title
this.titleDiv = document.createElement("div");
OpenLayers.Element.addClass(this.titleDiv, 'wmLayerTitle');
this.titleDiv.innerHTML = this.layer.name;
this.div.appendChild(this.titleDiv);
OpenLayers.Event.observe(this.titleDiv, "click", OpenLayers.Function.bindAsEventListener(this.toggleLayer, this));
// Layereinstellungen
this.settingsDiv = this.drawSettings();
// Einstellungen ein-/ausblenden
this.settingsToggler = new BKGWebMap.Util.Toggler(
this.toggleSettingsButton,
this.settingsDiv,
{closed: !this.layer._wmLayerSettingsVisible}
);
this.settingsToggler.events.on({
statechanged: this.onSettingsTogglerChange,
scope: this
});
return this.div;
},
/**
* Erstellt alle Steuerelemente für den Layer
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @returns {HTMLElement} Referenz auf HTML-Container für Steuerelemente
*/
drawSettings: function () {
var settingsDiv = document.createElement('div');
OpenLayers.Element.addClass(settingsDiv, 'wmLayerSettings');
this.div.appendChild(settingsDiv);
// Reihenfolge
if(this.drawOrder)
this.drawOrderControl(settingsDiv);
// opacity Slider
if(this.drawOpacity)
this.drawOpacityControl(settingsDiv);
// Layerauswahl für WMS
if(this.drawSubLayers)
this.drawSubLayerControl(settingsDiv);
return settingsDiv;
},
/**
* Erstellt die HTML-Elemente zur Steuerung der Layerreihenfolge.
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {HMTLElement} div - Der Parent für die Steuerelemente.
*/
drawOrderControl: function (div) {
var label = document.createElement('label');
label.innerHTML = this.labels.order;
div.appendChild(label);
/*
var orderDiv = document.createElement('div');
OpenLayers.Element.addClass(orderDiv, 'wmOrder');
div.appendChild(orderDiv);
*/
this.prev = document.createElement('div');
OpenLayers.Element.addClass(this.prev, 'wmOrderPrev');
this.next = document.createElement('div');
OpenLayers.Element.addClass(this.next, 'wmOrderNext');
label.appendChild(this.prev);
label.appendChild(this.next);
// Events registrieren
OpenLayers.Event.observe(this.prev, "click", OpenLayers.Function.bindAsEventListener(this.onPrevLayer, this));
OpenLayers.Event.observe(this.next, "click", OpenLayers.Function.bindAsEventListener(this.onNextLayer, this));
},
/**
* Erstellt die HTML-Elemente zur Steuerung der Layertransparenz.
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {HMTLElement} div - Der Parent für die Steuerelemente.
*/
drawOpacityControl: function (div) {
var opacityLabel = document.createElement('label');
opacityLabel.innerHTML = this.labels.opacity;
div.appendChild(opacityLabel);
this.opacitySlider = new BKGWebMap.Util.Slider({
scaleSize: 100, sliderSize: 10, value: this.layer.opacity * 100
});
div.appendChild(this.opacitySlider.div);
this.opacitySlider.events.on({ "valuechanged": OpenLayers.Function.bindAsEventListener(this.onOpacityChanged, this) });
},
/**
* Erstellt die HTML-Elemente zur Steuerung der Ebenen im WMS.
*
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {HMTLElement} div - Der Parent für die Steuerelemente.
*/
drawSubLayerControl: function (div) {
if (this.subLayers.length < 2) return;
var subLayersLabel = document.createElement('label');
subLayersLabel.innerHTML = this.labels.layers;
div.appendChild(subLayersLabel);
var layerList = document.createElement('ul');
OpenLayers.Element.addClass(layerList, 'wmSubLayers');
div.appendChild(layerList);
var layerEntry = this; // Referenz auf diese Instanz für funktionale Programmierung
BKGWebMap.Util.each(this.subLayers, function (index, subLayer) {
var item = document.createElement('li');
item.innerHTML = subLayer.title;
item.layerID = subLayer.id;
layerList.appendChild(item);
subLayer.div = item;
// an-/abwählen
OpenLayers.Event.observe(
item, "click",
OpenLayers.Function.bindAsEventListener(layerEntry.onSubLayerClick, layerEntry)
);
// Status per CSS
OpenLayers.Element.addClass(item, subLayer.active ? 'active' : 'inactive');
});
},
/**
* Aktiviert oder deaktiviert einen Sublayer im WMS.
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
* @param {Object} subLayer - die Sublayerdefinition mit id und aktuellem Status
* @param {string} subLayer.id - die ID/der Name des Sublayers im WMS
* @param {boolean} subLayer.active - der aktuelle Zustand des Sublayers
* @param {HTMLElement} subLayer.div - das HMTL-Element, welches den Sublayer repräsentiert
*/
toggleSubLayer: function (subLayer, item) {
var oldState = subLayer.active;
subLayer.active = !oldState;
// neuer Request-Parameter
var layers = [];
BKGWebMap.Util.each(this.subLayers, function (index, subLayer) {
if (subLayer.active) layers.push(subLayer.id);
});
// Mindestens ein Layer muss für WMS-Requests aktiv sein.
if (layers.length == 0) {
subLayer.active = oldState;
return;
}
// Status des Sublayers ändern
OpenLayers.Element.removeClass(subLayer.div, subLayer.active ? 'inactive' : 'active');
OpenLayers.Element.addClass(subLayer.div, subLayer.active ? 'active' : 'inactive');
this.layer.toggleLayer(subLayer.id);
//this.layer.mergeNewParams({LAYERS: layers.join(',')});
},
/**
* Eventhandler be Änderungen des Opacity-Sliders.
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
*/
onOpacityChanged: function (evt) {
this.layer.setOpacity(this.opacitySlider.value / 100);
},
/**
* Eventhandler für Clicks auf die Sublayer-Einträge zum Ein-/Ausschalten dieser.
* @memberOf BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry
*/
onSubLayerClick: function (evt) {
var item = BKGWebMap.Util.getEventTarget(evt);
var subLayer = this.getSubLayer(item.layerID);
this.toggleSubLayer(subLayer);
},
onPrevLayer: function (evt) {
this.layer.map.raiseLayer(this.layer, -1);
},
onNextLayer: function (evt) {
this.layer.map.raiseLayer(this.layer, 1);
},
onSettingsTogglerChange: function (evt) {
this.layer._wmLayerSettingsVisible = !this.settingsToggler.closed;
},
CLASS_NAME: "BKGWebMap.Control.LayerSwitcher.AdvancedLayerEntry"
});