/**
* @classdesc
*
* Control in the tools topbar where you can change the map type
* using a selector menu.<br/>
* <br/>
* You can also add additional layers not included by default, and with different projections.
* For adding a layer <a href="http://openlayers.org/en/v3.0.0/apidoc/ol.layer.Layer.html">`ol.layer.Layer`</a>
* or the own Cercalia API WMS class {@link cercalia.WMS}
*
* @constructor
* @param {cercaliax.Control.LayerSwitcherOptions} options
* @extends {ol.control.Control}
*/
cercalia.Control.LayerSwitcher = function(options){
/**
* @private
* @type {string}
*/
this.name_ = cercalia.MapControls.LayerSwitcher;
/**
* @private
* @type {String}
*/
this.topBarId_ = null;
/**
* Class name
* @private
* @type {string}
*/
this.CLASS_NAME_ = "cercalia.Control.LayerSwitcher";
/**
* @private
* @type {Array.<string>}
*/
this.listMapTypes_ = options.listMapTypes ? options.listMapTypes : [cercalia.MapTypes.CERCALIA,
cercalia.MapTypes.SATELLITE,
cercalia.MapTypes.HYBRID,
cercalia.MapTypes.OSM
];
/**
* Button
* @private
* @type {Object}
*/
this.element_ = null;
/**
* @private
* @type {Object}
*/
this.elementList_ = null;
//TODO: posar 'type:button' en els buttons.
this.element_ = document.createElement('button');
this.element_.className = 'layerswitcher';
this.element_.innerHTML = cercalia.i18n._('Map type');
cercalia.jQuery(this.element_).button({ icons: { primary: "cercalia-big-icon-map cercalia-big-icon", secondary: "ui-icon-triangle-1-s"} });
cercalia.jQuery(this.element_).removeClass("ui-button-text-icons").addClass("ui-button-text-icon-secondary cercalia-tool-button");
};
ol.inherits(cercalia.Control.LayerSwitcher, ol.control.Control);
/**
* @private
* @param {string} idTopBar
*/
cercalia.Control.LayerSwitcher.prototype.createMenuListMapTypes_ = function(target, idTopBar){
var self = this;
var layerswitcherList = document.createElement('div');
layerswitcherList.className = 'layerswitcherList';
var ulLayerswitcherList = document.createElement('ul');
ulLayerswitcherList.className = 'ui-corner-all ui-widget ui-state-default';
layerswitcherList.appendChild(ulLayerswitcherList);
target.appendChild(layerswitcherList);
this.elementList_ = layerswitcherList;
for(var i = 0; i < this.listMapTypes_.length; i++){
var nameMapType;
switch(this.listMapTypes_[i]){
case cercalia.MapTypes.CERCALIA:
nameMapType = cercalia.i18n._('Cercalia');
break;
case cercalia.MapTypes.OSM:
nameMapType = cercalia.i18n._('OSM');
break;
case cercalia.MapTypes.OPENSTREETMAP:
nameMapType = cercalia.i18n._('OpenStreetMap');
break;
case cercalia.MapTypes.SATELLITE:
nameMapType = cercalia.i18n._('Satellite');
break;
case cercalia.MapTypes.HYBRID:
nameMapType = cercalia.i18n._('Hybrid');
break;
default:
cercalia.Exception(cercalia.i18n._('Unknown map type "%"', [this.listMapTypes_[i]]));
break;
}
cercalia.jQuery('<li>')
.data('mapType',this.listMapTypes_[i])
.data('projectionCode', 'EPSG:3857')
.addClass(i == 0 ? "ui-corner-top ui-no-corner-bottom" : (i == this.listMapTypes_.length-1 ? "ui-corner-bottom ui-no-corner-top" : "ui-no-corner-all") )
.addClass("cercalia-box-sizing")
.addClass(this.listMapTypes_[i].replace(" ","_"))
.html(nameMapType)
.click(function(){
var cercaliaMap = self.getMap().getCercalia();
var center = cercaliaMap.getCenter();
var projectionCodeAct = cercaliaMap.getProjectionCode();
var projectionCodeDest = cercalia.jQuery(this).data('projectionCode');
cercaliaMap.setBaseLayer( cercalia.jQuery(this).data('mapType') );
if(projectionCodeAct!=projectionCodeDest){
cercaliaMap.setProjection(ol.proj.get(projectionCodeDest));
cercaliaMap.setCenter(center, null, false);
}
self.changeRadioBox_(this);
})
.appendTo( cercalia.jQuery(this.elementList_).find('ul') )
.button({icons: {primary:"", secondary: "cercalia-icon cercalia-icon-traffic-radio-disabled"}});
}
};
/**
* @param {string} name
* @param {cercalia.WMS|ol.layer.Layer} layer
* @param {string|undefined} projectionCode If you don't include a projection code, the API will use the default projection: EPSG:3857
* @param {string|undefined} logoUrl Map copyright image URL
*/
cercalia.Control.LayerSwitcher.prototype.addBaseLayer = function (name, layer, projectionCode, logoUrl) {
var self = this;
if(logoUrl){
layer.set('logo',logoUrl);
}
cercalia.jQuery('<li />')
.data('mapType', name)
.data('projectionCode', projectionCode ? projectionCode : 'EPSG:3857' )
.addClass("ui-corner-top ui-no-corner-bottom cercalia-box-sizing")
.addClass(name.replace(" ","_"))
.html(name)
.click(function(){
var cercaliaMap = self.getMap().getCercalia();
var center = cercaliaMap.getCenter();
var projectionCodeAct = cercaliaMap.getProjectionCode();
var projectionCodeDest = cercalia.jQuery(this).data('projectionCode');
cercaliaMap.setBaseLayer(layer);
if(projectionCodeAct != projectionCodeDest){
cercaliaMap.setProjection(ol.proj.get(projectionCodeDest));
cercaliaMap.setCenter(center, null, false);
}
self.changeRadioBox_(this);
})
.appendTo(cercalia.jQuery(this.elementList_).find('ul'))
.button({icons: {primary:"", secondary: "cercalia-icon cercalia-icon-traffic-radio-disabled"}});
};
/**
* Change base layer who has been added before in this control using `addBaseLayer` function.
* @param {string} name
*/
cercalia.Control.LayerSwitcher.prototype.setBaseLayer = function(name) {
cercalia.jQuery('.' + name).click();
};
/**
* Create the button in the tools topbar
* @private
* @param {string} idTopBar Div element ID where the control will be embedded
*/
cercalia.Control.LayerSwitcher.prototype.setTopBar = function (idTopBar) {
this.topBarId_ = idTopBar;
var self = this;
this.element_.addEventListener('click', function (event) {
if(cercalia.jQuery(self.element_).hasClass("cercalia-tool-button-open")) {
cercalia.jQuery(self.element_).removeClass("cercalia-tool-button-open");
cercalia.jQuery(".cercalia-tool-button.cercalia-tool-button-open").click().removeClass("cercalia-tool-button-open").button("refresh");
} else {
cercalia.jQuery(".cercalia-tool-button.cercalia-tool-button-open").click().removeClass("cercalia-tool-button-open").button("refresh");
cercalia.jQuery(self.element_).addClass("cercalia-tool-button-open");
}
//Obrim o tanquem segons com es trobi
cercalia.jQuery(self.elementList_).is(":visible") ? self.closeList_() : self.openList_();
});
var target = document.getElementById(idTopBar);
ol.control.Control.call(this, {
element: self.element_,
target: target
});
this.createMenuListMapTypes_(target, idTopBar);
setTimeout(function() {
self.changeRadioBox_()
}, 500);
};
/**
* @private
*/
cercalia.Control.LayerSwitcher.prototype.openList_ = function() {
//Siempre que abramos ajustamos la posición del list respecto el botón
var width = cercalia.jQuery(this.element_).width();
var rightPosition = cercalia.jQuery(this.element_).parent().width() - cercalia.jQuery(this.element_).position().left - width + 8;
cercalia.jQuery(this.elementList_).css('right', rightPosition);
cercalia.jQuery(this.elementList_).fadeIn();
cercalia.jQuery(this.element_).find('.ui-button-icon-secondary')
.addClass('ui-icon-triangle-1-n')
.removeClass('ui-icon-triangle-1-s');
};
/**
* @private
*/
cercalia.Control.LayerSwitcher.prototype.closeList_ = function() {
cercalia.jQuery(this.elementList_).fadeOut();
cercalia.jQuery(this.element_).find('.ui-button-icon-secondary')
.addClass('ui-icon-triangle-1-s')
.removeClass('ui-icon-triangle-1-n');
};
/**
* Returns the menú (list) HTML element
* @return {HTMLElement}
*/
cercalia.Control.LayerSwitcher.prototype.getElementList = function() {
return this.elementList_;
};
/**
* @private
* @param {Element|undefined} htmlElement
*/
cercalia.Control.LayerSwitcher.prototype.changeRadioBox_ = function(htmlElement) {
if(this.getMap() && !htmlElement) {
var map = this.getMap();
var cercaliaMap = map.getCercalia();
var baseLayer = cercaliaMap.getBaseLayer();
var layerName = baseLayer.get('name');
htmlElement = cercalia.jQuery('.' + layerName)[0];
}
cercalia.jQuery(htmlElement.parentNode.childNodes).find('.ui-button-icon-secondary').removeClass('cercalia-icon-traffic-radio-enabled');
cercalia.jQuery(htmlElement).find('.ui-button-icon-secondary').addClass('cercalia-icon-traffic-radio-enabled');
};