如果你需要在Leaflet地图中增加一个侧边栏,以此来做一个额外的数据处理,那么您可以使用现成的leaflet-sidebar组件来帮助您加快开发速度,同时,该组件基于leaflet进行了扩展,更加灵活。
言归正传,本文开始重点阐述如何进行组件的引入和集成。
相应的github地址为:https://github.com/Turbo87/sidebar-v2.git,下载后得到的目录结构大致如下:
目录在examples,里面有例子。
我们可以看到,这个控件不仅支持leaflet,同时支持openlayers。所以非常好用。
第三步、可以打开position-right.html,这个是官方提供的示例,用于演示侧边栏摆放在右边。使用浏览器打开可以看到如下页面:
这是官方提供的基于osm底图的演示页面,那么怎么在本地进行集成开发呢?
第三步、使用本地影像服务进行开发
复制position-right2.html文件,使用熟悉的方式将底图替换为本地。关键代码如下:
L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
code: 'EPSG:4326',
projection: L.Projection.LonLat,
transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
scale: function (zoom) {
return 256 * Math.pow(2, zoom - 1);
}
});
var mymap = L.map('map',{crs:L.CRS.CustomEPSG4326,attributionControl: false}).setView([28.250248, 112.896366], 10);
function onMapClick(e) {
L.popup().setLatLng(e.latlng)
.setContent("坐标为:" + e.latlng.toString())
.openOn(mymap);
}
$(document).ready(function(){
$("#mapid").height(window.screen.height-76 - 65 - 20);
mymap.invalidateSize(true);//地图重绘
//底图
L.tileLayer('http://localhost:8086/data/basemap_nowater/1_10_tms/{z}/{x}/{y}.jpg', {
maxZoom: 20,
minZoom:3,
attribution: 'diy Map data © yelangking contributors, ',
id: 'mapbox/streets-v11',
tileSize: 256,
zoomOffset: -1
}).addTo(mymap);
//标签
L.tileLayer('http://localhost:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png', {maxZoom: 10,minZoom:3,
id: 'mapbox/label',tileSize: 256,zoomOffset: -1
}).addTo(mymap);
mymap.on('click', onMapClick);
// add a polygon
var polygon = L.polygon([
[28.31177, 112.80762],
[28.31451, 113.1633],
[28.00415, 113.17566],
[28.00278, 112.81174]
],{
color: 'green',
fillColor: '#f03',
fillOpacity: 0.5
}).addTo(mymap);
initLayerArray();//初始化地图图层
});
第四步、引入sidebar的css和js文件
第五步、在dom中绑定sidebar到map中
var sidebar = L.control.sidebar('sidebar', {position: 'right'}).addTo(mymap);
打开浏览器访问这个地址,可以看到以下的页面:
经过上述的步骤,就完成了sidebar的继承。完整代码如下:
sidebar-v2 example
有兴趣的朋友可以看一下sidebar.js这个文件,他提供了以下内置的函数,可以方便调用。sidebar.js的源码如下:
/* global L */
/**
* @name Sidebar
* @class L.Control.Sidebar
* @extends L.Control
* @param {string} id - The id of the sidebar element (without the # character)
* @param {Object} [options] - Optional options object
* @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
* @see L.control.sidebar
*/
L.Control.Sidebar = L.Control.extend(/** @lends L.Control.Sidebar.prototype */ {
includes: (L.Evented.prototype || L.Mixin.Events),
options: {
position: 'left'
},
initialize: function (id, options) {
var i, child;
L.setOptions(this, options);
// Find sidebar HTMLElement
this._sidebar = L.DomUtil.get(id);
// Attach .sidebar-left/right class
L.DomUtil.addClass(this._sidebar, 'sidebar-' + this.options.position);
// Attach touch styling if necessary
if (L.Browser.touch)
L.DomUtil.addClass(this._sidebar, 'leaflet-touch');
// Find sidebar > div.sidebar-content
for (i = this._sidebar.children.length - 1; i >= 0; i--) {
child = this._sidebar.children[i];
if (child.tagName == 'DIV' &&
L.DomUtil.hasClass(child, 'sidebar-content'))
this._container = child;
}
// Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
this._tabitems = this._sidebar.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
for (i = this._tabitems.length - 1; i >= 0; i--) {
this._tabitems[i]._sidebar = this;
}
// Find sidebar > div.sidebar-content > div.sidebar-pane
this._panes = [];
this._closeButtons = [];
for (i = this._container.children.length - 1; i >= 0; i--) {
child = this._container.children[i];
if (child.tagName == 'DIV' &&
L.DomUtil.hasClass(child, 'sidebar-pane')) {
this._panes.push(child);
var closeButtons = child.querySelectorAll('.sidebar-close');
for (var j = 0, len = closeButtons.length; j < len; j++)
this._closeButtons.push(closeButtons[j]);
}
}
},
/**
* Add this sidebar to the specified map.
*
* @param {L.Map} map
* @returns {Sidebar}
*/
addTo: function (map) {
var i, child;
this._map = map;
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
var sub = child.querySelector('a');
if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
L.DomEvent
.on(sub, 'click', L.DomEvent.preventDefault )
.on(sub, 'click', this._onClick, child);
}
}
for (i = this._closeButtons.length - 1; i >= 0; i--) {
child = this._closeButtons[i];
L.DomEvent.on(child, 'click', this._onCloseClick, this);
}
return this;
},
/**
* @deprecated - Please use remove() instead of removeFrom(), as of Leaflet 0.8-dev, the removeFrom() has been replaced with remove()
* Removes this sidebar from the map.
* @param {L.Map} map
* @returns {Sidebar}
*/
removeFrom: function(map) {
console.log('removeFrom() has been deprecated, please use remove() instead as support for this function will be ending soon.');
this.remove(map);
},
/**
* Remove this sidebar from the map.
*
* @param {L.Map} map
* @returns {Sidebar}
*/
remove: function (map) {
var i, child;
this._map = null;
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
L.DomEvent.off(child.querySelector('a'), 'click', this._onClick);
}
for (i = this._closeButtons.length - 1; i >= 0; i--) {
child = this._closeButtons[i];
L.DomEvent.off(child, 'click', this._onCloseClick, this);
}
return this;
},
/**
* Open sidebar (if necessary) and show the specified tab.
*
* @param {string} id - The id of the tab to show (without the # character)
*/
open: function(id) {
var i, child;
// hide old active contents and show new content
for (i = this._panes.length - 1; i >= 0; i--) {
child = this._panes[i];
if (child.id == id)
L.DomUtil.addClass(child, 'active');
else if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
// remove old active highlights and set new highlight
for (i = this._tabitems.length - 1; i >= 0; i--) {
child = this._tabitems[i];
if (child.querySelector('a').hash == '#' + id)
L.DomUtil.addClass(child, 'active');
else if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
this.fire('content', { id: id });
// open sidebar (if necessary)
if (L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
this.fire('opening');
L.DomUtil.removeClass(this._sidebar, 'collapsed');
}
return this;
},
/**
* Close the sidebar (if necessary).
*/
close: function() {
// remove old active highlights
for (var i = this._tabitems.length - 1; i >= 0; i--) {
var child = this._tabitems[i];
if (L.DomUtil.hasClass(child, 'active'))
L.DomUtil.removeClass(child, 'active');
}
// close sidebar
if (!L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
this.fire('closing');
L.DomUtil.addClass(this._sidebar, 'collapsed');
}
return this;
},
/**
* @private
*/
_onClick: function() {
if (L.DomUtil.hasClass(this, 'active'))
this._sidebar.close();
else if (!L.DomUtil.hasClass(this, 'disabled'))
this._sidebar.open(this.querySelector('a').hash.slice(1));
},
/**
* @private
*/
_onCloseClick: function () {
this.close();
}
});
/**
* Creates a new sidebar.
*
* @example
* var sidebar = L.control.sidebar('sidebar').addTo(map);
*
* @param {string} id - The id of the sidebar element (without the # character)
* @param {Object} [options] - Optional options object
* @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
* @returns {Sidebar} A new sidebar instance
*/
L.control.sidebar = function (id, options) {
return new L.Control.Sidebar(id, options);
};
总结:本文介绍了leaflet的侧边栏控制组件sidebar,同时详细说明了如何将sidebar集成到leaflet中。如果有什么疑问,欢迎交流。