1 /* Copyright (c) 2011 by MapQuery Contributors (see AUTHORS for
2 * full list of contributors). Published under the MIT license.
3 * See https://github.com/mapquery/mapquery/blob/master/LICENSE for the
4 * full text of the license. */
7 #jquery.mapquery.mqLayerManager.js
8 The file containing the mqLayerManager Widget
10 ### *$('selector')*.`mqLayerManager([options])`
12 ####**Description**: create a widget to manage layers
15 - **map**: the mapquery instance
16 - **title**: Title that will be displayed at the top of the
17 layer manager (default: Layer Manager)
22 >Requires: jquery.mapquery.legend.js
25 The mqLayerManager allows us to control the order, opacity and visibility
26 of layers. We can also remove layers. It also shows the legend of the layer if
27 available and the error messages provided by the legend plugin. It listens to
28 layerchange event for order, transparancy and opacity changes. It listens to
29 addlayer and removelayer events to keep track which layers are on the map.
32 $('#layermanager').mqLayerManager({map:'#map'});
37 $.template('mqLayerManager',
38 '<div class="mq-layermanager ui-widget-content ">'+
41 $.template('mqLayerManagerElement',
42 '<div class="mq-layermanager-element ui-widget-content ui-corner-all" id="mq-layermanager-element-${id}">'+
43 '<div class="mq-layermanager-element-header ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">'+
44 '<span class="mq-layermanager-label ui-dialog-title">${label}</span>'+
45 '<a class="ui-dialog-titlebar-close ui-corner-all" href="#" role="button">'+
46 '<span class="ui-icon ui-icon-closethick">close</span></a></div>'+
47 '<div class="mq-layermanager-element-content">'+
48 '<div class="mq-layermanager-element-visibility">'+
49 '<input type="checkbox" class="mq-layermanager-element-vischeckbox" id="${id}-visibility" {{if visible}}checked="${visible}"{{/if}} />'+
50 '<div class="mq-layermanager-element-slider-container">'+
51 '<div class="mq-layermanager-element-slider"></div></div>'+
53 '<div class="mq-layermanager-element-legend">'+
55 '<img src="${imgUrl}" style="opacity:${opacity}"/>'+
64 $.widget("mapQuery.mqLayerManager", {
66 // The MapQuery instance
69 // Title that will be displayed at the top of the popup
70 title: "Layer Manager"
77 var element = this.element;
79 //get the mapquery object
80 map = $(this.options.map).data('mapQuery');
82 this.element.addClass('ui-widget ui-helper-clearfix ' +
85 var lmElement = $.tmpl('mqLayerManager').appendTo(element);
86 element.find('.ui-icon-closethick').button();
90 handle: '.mq-layermanager-element-header',
91 update: function(event, ui) {
92 var layerNodes = ui.item.siblings().andSelf();
93 var num = layerNodes.length-1;
94 layerNodes.each(function(i) {
95 var layer = $(this).data('layer');
97 self._position(layer, pos);
102 //these layers are already added to the map as such won't trigger
103 //and event, we call the draw function directly
104 $.each(map.layers().reverse(), function(){
105 self._layerAdded(lmElement, this);
108 element.delegate('.mq-layermanager-element-vischeckbox',
109 'change',function() {
110 var checkbox = $(this);
111 var element = checkbox.parents('.mq-layermanager-element');
112 var layer = element.data('layer');
113 var self = element.data('self');
114 self._visible(layer,checkbox.is(':checked'));
117 element.delegate('.ui-icon-closethick', 'click', function() {
118 var control = $(this).parents('.mq-layermanager-element');
119 self._remove(control.data('layer'));
124 {widget:self,control:lmElement},
127 map.bind("removelayer",
128 {widget:self,control:lmElement},
129 self._onLayerRemove);
131 map.bind("changelayer",
132 {widget:self,map:map,control:lmElement},
133 self._onLayerChange);
136 {widget:self,map:map,control:lmElement},
139 _destroy: function() {
140 this.element.removeClass(' ui-widget ui-helper-clearfix ' +
144 //functions that actually change things on the map
145 //call these from within the widget to do stuff on the map
146 //their actions will trigger events on the map and in return
147 //will trigger the _layer* functions
148 _add: function(map,layer) {
152 _remove: function(layer) {
156 _position: function(layer, pos) {
160 _visible: function(layer, vis) {
164 _opacity: function(layer,opac) {
168 //functions that change the widget
169 _layerAdded: function(widget, layer) {
171 var error = layer.legend().msg;
175 url =layer.legend().url;
176 if(url==''){error='No legend for this layer';}
179 error = 'Please zoom out to see this layer';
182 error = 'Please zoom in to see this layer';
185 error = 'This layer is outside the current view';
189 var layerElement = $.tmpl('mqLayerManagerElement',{
192 position: layer.position(),
193 visible: layer.visible(),
195 opacity: layer.visible()?layer.opacity():0,
198 // save layer layer in the DOM, so we can easily
199 // hide/show/delete the layer with live events
200 .data('layer', layer)
204 $(".mq-layermanager-element-slider", layerElement).slider({
207 value: layer.visible()?layer.opacity()*100:0,
208 slide: function(event, ui) {
209 var layer = layerElement.data('layer');
210 var self = layerElement.data('self');
211 self._opacity(layer,ui.value/100);
213 //using the slide event to check for the checkbox often gives errors.
214 change: function(event, ui) {
215 var layer = layerElement.data('layer');
216 var self = layerElement.data('self');
218 if(!layer.visible()){layer.visible(true);}
221 if(layer.visible()){layer.visible(false);}
227 _layerRemoved: function(widget, id) {
228 var control = $("#mq-layermanager-element-"+id);
229 control.fadeOut(function() {
234 _layerPosition: function(widget, layer) {
235 var layerNodes = widget.element.find('.mq-layermanager-element');
236 var num = layerNodes.length-1;
238 tmpNodes.length = layerNodes.length;
239 layerNodes.each(function() {
240 var layer = $(this).data('layer');
241 var pos = num-layer.position();
244 for (i=0;i<tmpNodes.length;i++) {
245 layerNodes.parent().append(tmpNodes[i]);
249 _layerVisible: function(widget, layer) {
251 widget.element.find('#mq-layermanager-element-'+layer.id);
253 layerElement.find('.mq-layermanager-element-vischeckbox');
254 checkbox[0].checked = layer.visible();
255 //update the opacity slider as well
256 var slider = layerElement.find('.mq-layermanager-element-slider');
257 var value = layer.visible()?layer.opacity()*100: 0;
258 slider.slider('value',value);
260 //update legend image
261 layerElement.find('.mq-layermanager-element-legend img').css(
262 {visibility:layer.visible()?true:'hidden'});
265 _layerOpacity: function(widget, layer) {
266 var layerElement = widget.element.find(
267 '#mq-layermanager-element-'+layer.id);
268 var slider = layerElement.find(
269 '.mq-layermanager-element-slider');
270 slider.slider('value',layer.opacity()*100);
271 //update legend image
273 '.mq-layermanager-element-legend img').css(
274 {opacity:layer.opacity()});
277 _moveEnd: function (widget,lmElement,map) {
279 $.each(map.layers().reverse(), function(){
280 widget._layerAdded(lmElement, this);
284 //functions bind to the map events
285 _onLayerAdd: function(evt, layer) {
286 evt.data.widget._layerAdded(evt.data.control,layer);
289 _onLayerRemove: function(evt, layer) {
290 evt.data.widget._layerRemoved(evt.data.control,layer.id);
293 _onLayerChange: function(evt, layer, property) {
296 evt.data.widget._layerOpacity(evt.data.widget,layer);
299 evt.data.widget._layerPosition(evt.data.widget,layer);
302 evt.data.widget._layerVisible(evt.data.widget,layer);
306 _onMoveEnd: function(evt) {
307 evt.data.widget._moveEnd(evt.data.widget,evt.data.control,evt.data.map);