import EventDispatcher from './../../utils/EventDispatcher.js';
import { convertBoolean } from './../utils/Converters.js';
import { ExternalMapItemState, ExternalMapGroupState, OlMapLayerState } from './ExternalMapLayer.js';
import { LayerTreeGroupState } from './LayerTree.js';
/**
* Class representing an external layer tree item
* @class
* @augments EventDispatcher
*/
export class ExternalLayerTreeItemState extends EventDispatcher {
/**
* Instantiate an external layer tree item
* @param {ExternalMapItemState} mapItemState - the external map item state
*/
constructor(mapItemState) {
if (!(mapItemState instanceof ExternalMapItemState)) {
throw TypeError('The map item state has to be an external map item state!');
}
super();
this._mapItemState = mapItemState;
mapItemState.addListener(this.dispatch.bind(this), mapItemState.type+'.wmsTitle.changed');
}
/**
* Map item name
* @type {string}
*/
get name() {
return this._mapItemState.name;
}
/**
* Map item type
* @type {string}
*/
get type() {
return this._mapItemState.type;
}
/**
* Map item level
* @type {number}
*/
get level() {
return this._mapItemState.level;
}
/**
* WMS item name
* @type {?string}
*/
get wmsName() {
return this._mapItemState.wmsName;
}
/**
* WMS item title
* @type {string}
*/
get wmsTitle() {
return this._mapItemState.wmsTitle;
}
/**
* WMS item title
* @type {string}
*/
set wmsTitle(title) {
this._mapItemState.wmsTitle = title;
}
/**
* WMS layer Geographic Bounding Box
* @type {null}
*/
get wmsGeographicBoundingBox() {
return this._mapItemState.wmsGeographicBoundingBox;
}
/**
* WMS layer Bounding Boxes
* @type {Array}
*/
get wmsBoundingBoxes() {
return this._mapItemState.wmsBoundingBoxes;
}
/**
* WMS Minimum scale denominator
* If the minimum scale denominator is not defined: -1 is returned
* If the WMS layer is a group, the minimum scale denominator is -1 if only one layer
* minimum scale denominator is not defined else the smallest layer minimum scale denominator
* in the group
* @type {number}
*/
get wmsMinScaleDenominator() {
return this._mapItemState.wmsMinScaleDenominator;
}
/**
* WMS layer maximum scale denominator
* If the maximum scale denominator is not defined: -1 is returned
* If the WMS layer is a group, the maximum scale denominator is the largest of the layers in the group
* @type {number}
*/
get wmsMaxScaleDenominator() {
return this._mapItemState.wmsMaxScaleDenominator;
}
/**
* Map item is checked
* @type {boolean}
*/
get checked() {
return this._mapItemState.checked;
}
/**
* Set map item is checked
* @type {boolean}
*/
set checked(val) {
this._mapItemState.checked = val;
}
/**
* Map item is visible
* It depends on the parent visibility
* @type {boolean}
*/
get visibility() {
return this._mapItemState.visibility;
}
/**
* Map item opacity
* @type {number}
*/
get opacity() {
return this._mapItemState.opacity;
}
/**
* Set map item opacity
* @type {number}
*/
set opacity(val) {
this._mapItemState.opacity = val;
}
/**
* Lizmap layer config
* @type {null}
*/
get layerConfig() {
return this._mapItemState.layerConfig;
}
/**
* External map item state
* @type {?ExternalMapItemState}
*/
get mapItemState() {
return this._mapItemState;
}
/**
* Layer tree item is expanded
* @type {boolean}
*/
get expanded() {
return this._expanded;
}
/**
* Set layer tree item is expanded
* @type {boolean}
*/
set expanded(val) {
const newVal = convertBoolean(val);
if(this._expanded === newVal){
return;
}
this._expanded = newVal;
this.dispatch({
type: this.type + '.expanded.changed',
name: this.name
});
}
/**
* Calculate and save visibility
* @returns {boolean} the calculated visibility
*/
calculateVisibility() {
return this._mapItemState.calculateVisibility();
}
/**
* Get item visibility taking care of this.visibility and scale
* @param {number} scaleDenominator the scale denominator for which the visibility has to be evaluated
* @returns {boolean} the item visibility
*/
isVisible(scaleDenominator) {
if (this.type === 'group') {
return this.visibility;
}
if(this._mapItemState.wmsMinScaleDenominator !== undefined && this._mapItemState.wmsMaxScaleDenominator !== undefined){
return this.visibility && this._mapItemState.wmsMinScaleDenominator < scaleDenominator
&& scaleDenominator < this._mapItemState.wmsMaxScaleDenominator;
}
return this.visibility;
}
}
/**
* Class representing an external layer tree group
* @class
* @augments ExternalLayerTreeItemState
*/
export class ExternalLayerTreeGroupState extends ExternalLayerTreeItemState {
/**
* Instantiate an external layer tree group
* @param {ExternalMapGroupState} mapGroupState - the external map group state
* @param {LayerTreeGroupState} [parentGroupState] - the parent layer tree group
*/
constructor(mapGroupState, parentGroupState) {
if (!(mapGroupState instanceof ExternalMapGroupState)) {
throw TypeError('The map group state has to be an external map group state!');
}
super(mapGroupState);
this._parentGroupState = null;
this._expanded = true;
if (parentGroupState instanceof LayerTreeGroupState
&& parentGroupState.type == 'group') {
this._parentGroupState = parentGroupState;
}
this._items = [];
mapGroupState.addListener(
evtLayer => {
const extLayer = mapGroupState.children[0];
if (evtLayer.childName != extLayer.name)
return;
const extTreeLayer = new OlTreeLayerState(extLayer, this);
extTreeLayer.addListener(this.dispatch.bind(this), extTreeLayer.type+'.visibility.changed');
extTreeLayer.addListener(this.dispatch.bind(this), extTreeLayer.type+'.opacity.changed');
extTreeLayer.addListener(this.dispatch.bind(this), extTreeLayer.type+'.wmsTitle.changed');
extTreeLayer.addListener(this.dispatch.bind(this), extTreeLayer.type+'.icon.changed');
this._items.unshift(extTreeLayer);
}, ['ol-layer.added']
);
mapGroupState.addListener(
evtLayer => {
const layers = this._items
.map((item, index) => {return {'name': item.name,'index':index}})
.filter((item) => item.name == evtLayer.childName);
if (layers.length == 0) {
return;
}
const extTreeLayer = this._items.at(layers[0].index);
extTreeLayer.removeListener(this.dispatch.bind(this), extTreeLayer.type+'.visibility.changed');
extTreeLayer.removeListener(this.dispatch.bind(this), extTreeLayer.type+'.opacity.changed');
extTreeLayer.removeListener(this.dispatch.bind(this), extTreeLayer.type+'.wmsTitle.changed');
extTreeLayer.removeListener(this.dispatch.bind(this), extTreeLayer.type+'.icon.changed');
this._items.splice(layers[0].index, 1);
}, ['ol-layer.removed']
);
mapGroupState.addListener(this.dispatch.bind(this), 'ol-layer.added');
mapGroupState.addListener(this.dispatch.bind(this), 'ol-layer.removed');
}
/**
* Children items count
* @type {number}
*/
get childrenCount() {
return this._items.length;
}
/**
* Children items
* @type {OlTreeLayerState[]}
*/
get children() {
return [...this._items];
}
/**
* Iterate through children items
* @generator
* @yields {OlTreeLayerState} The next child item
*/
*getChildren() {
for (const item of this._items) {
yield item;
}
}
}
/**
* Class representing an OpenLayers tree layer state
* @class
* @augments ExternalLayerTreeItemState
*/
export class OlTreeLayerState extends ExternalLayerTreeItemState {
/**
* Instantiate an OpenLayers tree layer
* @param {OlMapLayerState} mapLayerState - the OpenLayers map layer state
* @param {ExternalLayerTreeGroupState} [parentGroupState] - the parent layer tree group
*/
constructor(mapLayerState, parentGroupState) {
if (!(mapLayerState instanceof OlMapLayerState)) {
throw TypeError('The map layer state has to be an OpenLayers map layer state!');
}
if (!(parentGroupState instanceof ExternalLayerTreeGroupState)) {
throw TypeError('The parent layer tree group has to be an external layer tree group state!');
}
super(mapLayerState);
mapLayerState.addListener(this.dispatch.bind(this), this.type+'.visibility.changed');
mapLayerState.addListener(this.dispatch.bind(this), this.type+'.opacity.changed');
mapLayerState.addListener(this.dispatch.bind(this), this.type+'.wmsTitle.changed');
mapLayerState.addListener(this.dispatch.bind(this), this.type+'.icon.changed');
this._parentGroupState = parentGroupState;
this._expanded = true;
}
/**
* layer icon
* @type {string}
*/
get icon() {
return this._mapItemState.icon;
}
/**
* layer icon
* @type {string}
*/
set icon(base64icon) {
this._mapItemState.icon = base64icon;
}
}