• 基于Leaflet的leaflet-sidebar侧边栏组件集成


    如果你需要在Leaflet地图中增加一个侧边栏,以此来做一个额外的数据处理,那么您可以使用现成的leaflet-sidebar组件来帮助您加快开发速度,同时,该组件基于leaflet进行了扩展,更加灵活。

    言归正传,本文开始重点阐述如何进行组件的引入和集成。

    第一步、在github上想在组件。

    相应的github地址为:https://github.com/Turbo87/sidebar-v2.git,下载后得到的目录结构大致如下:

    第二步、打开其示例程序

    目录在examples,里面有例子。

    我们可以看到,这个控件不仅支持leaflet,同时支持openlayers。所以非常好用。

    第三步、可以打开position-right.html,这个是官方提供的示例,用于演示侧边栏摆放在右边。使用浏览器打开可以看到如下页面:

    这是官方提供的基于osm底图的演示页面,那么怎么在本地进行集成开发呢?

    第三步、使用本地影像服务进行开发

    复制position-right2.html文件,使用熟悉的方式将底图替换为本地。关键代码如下:

    1. L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
    2. code: 'EPSG:4326',
    3. projection: L.Projection.LonLat,
    4. transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
    5. scale: function (zoom) {
    6. return 256 * Math.pow(2, zoom - 1);
    7. }
    8. });
    9. var mymap = L.map('map',{crs:L.CRS.CustomEPSG4326,attributionControl: false}).setView([28.250248, 112.896366], 10);
    10. function onMapClick(e) {
    11. L.popup().setLatLng(e.latlng)
    12. .setContent("坐标为:" + e.latlng.toString())
    13. .openOn(mymap);
    14. }
    15. $(document).ready(function(){
    16. $("#mapid").height(window.screen.height-76 - 65 - 20);
    17. mymap.invalidateSize(true);//地图重绘
    18. //底图
    19. L.tileLayer('http://localhost:8086/data/basemap_nowater/1_10_tms/{z}/{x}/{y}.jpg', {
    20. maxZoom: 20,
    21. minZoom:3,
    22. attribution: 'diy Map data © yelangking contributors, ',
    23. id: 'mapbox/streets-v11',
    24. tileSize: 256,
    25. zoomOffset: -1
    26. }).addTo(mymap);
    27. //标签
    28. L.tileLayer('http://localhost:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png', {maxZoom: 10,minZoom:3,
    29. id: 'mapbox/label',tileSize: 256,zoomOffset: -1
    30. }).addTo(mymap);
    31. mymap.on('click', onMapClick);
    32. // add a polygon
    33. var polygon = L.polygon([
    34. [28.31177, 112.80762],
    35. [28.31451, 113.1633],
    36. [28.00415, 113.17566],
    37. [28.00278, 112.81174]
    38. ],{
    39. color: 'green',
    40. fillColor: '#f03',
    41. fillOpacity: 0.5
    42. }).addTo(mymap);
    43. initLayerArray();//初始化地图图层
    44. });

    第四步、引入sidebar的css和js文件

    <link rel="stylesheet" href="../css/leaflet-sidebar.css" />
     <script src="../js/leaflet-sidebar.js"></script>

    第五步、在dom中绑定sidebar到map中

    var sidebar = L.control.sidebar('sidebar', {position: 'right'}).addTo(mymap);

    打开浏览器访问这个地址,可以看到以下的页面:

    经过上述的步骤,就完成了sidebar的继承。完整代码如下:

    1. html>
    2. <html lang="en">
    3. <head>
    4. <title>sidebar-v2 exampletitle>
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    6. <meta charset="utf-8">
    7. <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
    8. <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.1/dist/leaflet.css" />
    9. <link rel="stylesheet" href="../css/leaflet-sidebar.css" />
    10. <style>
    11. body {
    12. padding: 0;
    13. margin: 0;
    14. }
    15. html, body, #map {
    16. height: 100%;
    17. font: 10pt "Helvetica Neue", Arial, Helvetica, sans-serif;
    18. }
    19. .lorem {
    20. font-style: italic;
    21. color: #AAA;
    22. }
    23. style>
    24. head>
    25. <body>
    26. <div id="sidebar" class="sidebar collapsed">
    27. <div class="sidebar-tabs">
    28. <ul role="tablist">
    29. <li><a href="#home" role="tab" id="xz_info"><i class="fa fa-bars">i>a>li>
    30. <li><a href="#profile" role="tab"><i class="fa fa-user">i>a>li>
    31. <li class="disabled"><a href="#messages" role="tab"><i class="fa fa-envelope">i>a>li>
    32. <li><a href="https://github.com/Turbo87/sidebar-v2" role="tab" target="_blank"><i class="fa fa-github">i>a>li>
    33. ul>
    34. <ul role="tablist">
    35. <li><a href="#settings" role="tab"><i class="fa fa-gear">i>a>li>
    36. ul>
    37. div>
    38. <div class="sidebar-content">
    39. <div class="sidebar-pane" id="home">
    40. <h1 class="sidebar-header">
    41. sidebar-v2
    42. <span class="sidebar-close"><i class="fa fa-caret-right">i>span>
    43. h1>
    44. <p>A responsive sidebar for mapping libraries like <a href="http://leafletjs.com/">Leafleta> or <a href="http://openlayers.org/">OpenLayersa>.p>
    45. <p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.p>
    46. <p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.p>
    47. <p class="lorem">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.p>
    48. div>
    49. <div class="sidebar-pane" id="profile">
    50. <h1 class="sidebar-header">Profile<span class="sidebar-close"><i class="fa fa-caret-right">i>span>h1>
    51. div>
    52. <div class="sidebar-pane" id="messages">
    53. <h1 class="sidebar-header">Messages<span class="sidebar-close"><i class="fa fa-caret-right">i>span>h1>
    54. div>
    55. <div class="sidebar-pane" id="settings">
    56. <h1 class="sidebar-header">Settings<span class="sidebar-close"><i class="fa fa-caret-right">i>span>h1>
    57. div>
    58. div>
    59. div>
    60. <div id="map" class="sidebar-map">div>
    61. <a href="https://github.com/Turbo87/sidebar-v2/"><img style="position: fixed; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub">a>
    62. <script src="https://unpkg.com/leaflet@1.0.1/dist/leaflet.js">script>
    63. <script src="../js/leaflet-sidebar.js">script>
    64. <script src="../../jquery/jquery.js">script>
    65. <script>
    66. L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
    67. code: 'EPSG:4326',
    68. projection: L.Projection.LonLat,
    69. transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
    70. scale: function (zoom) {
    71. return 256 * Math.pow(2, zoom - 1);
    72. }
    73. });
    74. var mymap = L.map('map',{crs:L.CRS.CustomEPSG4326,attributionControl: false}).setView([28.250248, 112.896366], 10);
    75. function onMapClick(e) {
    76. L.popup().setLatLng(e.latlng)
    77. .setContent("坐标为:" + e.latlng.toString())
    78. .openOn(mymap);
    79. }
    80. $(document).ready(function(){
    81. $("#mapid").height(window.screen.height-76 - 65 - 20);
    82. mymap.invalidateSize(true);//地图重绘
    83. //底图
    84. L.tileLayer('http://localhost:8086/data/basemap_nowater/1_10_tms/{z}/{x}/{y}.jpg', {
    85. maxZoom: 20,
    86. minZoom:3,
    87. attribution: 'diy Map data © yelangking contributors, ',
    88. id: 'mapbox/streets-v11',
    89. tileSize: 256,
    90. zoomOffset: -1
    91. }).addTo(mymap);
    92. //标签
    93. L.tileLayer('http://localhost:8086/data/basemap_nowater/1-10label/{z}/{x}/{y}.png', {maxZoom: 10,minZoom:3,
    94. id: 'mapbox/label',tileSize: 256,zoomOffset: -1
    95. }).addTo(mymap);
    96. mymap.on('click', onMapClick);
    97. // add a polygon
    98. var polygon = L.polygon([
    99. [28.31177, 112.80762],
    100. [28.31451, 113.1633],
    101. [28.00415, 113.17566],
    102. [28.00278, 112.81174]
    103. ],{
    104. color: 'green',
    105. fillColor: '#f03',
    106. fillOpacity: 0.5
    107. }).addTo(mymap);
    108. initLayerArray();//初始化地图图层
    109. });
    110. var sidebar = L.control.sidebar('sidebar', {position: 'right'}).addTo(mymap);
    111. script>
    112. body>
    113. html>

    有兴趣的朋友可以看一下sidebar.js这个文件,他提供了以下内置的函数,可以方便调用。sidebar.js的源码如下:

    1. /* global L */
    2. /**
    3. * @name Sidebar
    4. * @class L.Control.Sidebar
    5. * @extends L.Control
    6. * @param {string} id - The id of the sidebar element (without the # character)
    7. * @param {Object} [options] - Optional options object
    8. * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
    9. * @see L.control.sidebar
    10. */
    11. L.Control.Sidebar = L.Control.extend(/** @lends L.Control.Sidebar.prototype */ {
    12. includes: (L.Evented.prototype || L.Mixin.Events),
    13. options: {
    14. position: 'left'
    15. },
    16. initialize: function (id, options) {
    17. var i, child;
    18. L.setOptions(this, options);
    19. // Find sidebar HTMLElement
    20. this._sidebar = L.DomUtil.get(id);
    21. // Attach .sidebar-left/right class
    22. L.DomUtil.addClass(this._sidebar, 'sidebar-' + this.options.position);
    23. // Attach touch styling if necessary
    24. if (L.Browser.touch)
    25. L.DomUtil.addClass(this._sidebar, 'leaflet-touch');
    26. // Find sidebar > div.sidebar-content
    27. for (i = this._sidebar.children.length - 1; i >= 0; i--) {
    28. child = this._sidebar.children[i];
    29. if (child.tagName == 'DIV' &&
    30. L.DomUtil.hasClass(child, 'sidebar-content'))
    31. this._container = child;
    32. }
    33. // Find sidebar ul.sidebar-tabs > li, sidebar .sidebar-tabs > ul > li
    34. this._tabitems = this._sidebar.querySelectorAll('ul.sidebar-tabs > li, .sidebar-tabs > ul > li');
    35. for (i = this._tabitems.length - 1; i >= 0; i--) {
    36. this._tabitems[i]._sidebar = this;
    37. }
    38. // Find sidebar > div.sidebar-content > div.sidebar-pane
    39. this._panes = [];
    40. this._closeButtons = [];
    41. for (i = this._container.children.length - 1; i >= 0; i--) {
    42. child = this._container.children[i];
    43. if (child.tagName == 'DIV' &&
    44. L.DomUtil.hasClass(child, 'sidebar-pane')) {
    45. this._panes.push(child);
    46. var closeButtons = child.querySelectorAll('.sidebar-close');
    47. for (var j = 0, len = closeButtons.length; j < len; j++)
    48. this._closeButtons.push(closeButtons[j]);
    49. }
    50. }
    51. },
    52. /**
    53. * Add this sidebar to the specified map.
    54. *
    55. * @param {L.Map} map
    56. * @returns {Sidebar}
    57. */
    58. addTo: function (map) {
    59. var i, child;
    60. this._map = map;
    61. for (i = this._tabitems.length - 1; i >= 0; i--) {
    62. child = this._tabitems[i];
    63. var sub = child.querySelector('a');
    64. if (sub.hasAttribute('href') && sub.getAttribute('href').slice(0,1) == '#') {
    65. L.DomEvent
    66. .on(sub, 'click', L.DomEvent.preventDefault )
    67. .on(sub, 'click', this._onClick, child);
    68. }
    69. }
    70. for (i = this._closeButtons.length - 1; i >= 0; i--) {
    71. child = this._closeButtons[i];
    72. L.DomEvent.on(child, 'click', this._onCloseClick, this);
    73. }
    74. return this;
    75. },
    76. /**
    77. * @deprecated - Please use remove() instead of removeFrom(), as of Leaflet 0.8-dev, the removeFrom() has been replaced with remove()
    78. * Removes this sidebar from the map.
    79. * @param {L.Map} map
    80. * @returns {Sidebar}
    81. */
    82. removeFrom: function(map) {
    83. console.log('removeFrom() has been deprecated, please use remove() instead as support for this function will be ending soon.');
    84. this.remove(map);
    85. },
    86. /**
    87. * Remove this sidebar from the map.
    88. *
    89. * @param {L.Map} map
    90. * @returns {Sidebar}
    91. */
    92. remove: function (map) {
    93. var i, child;
    94. this._map = null;
    95. for (i = this._tabitems.length - 1; i >= 0; i--) {
    96. child = this._tabitems[i];
    97. L.DomEvent.off(child.querySelector('a'), 'click', this._onClick);
    98. }
    99. for (i = this._closeButtons.length - 1; i >= 0; i--) {
    100. child = this._closeButtons[i];
    101. L.DomEvent.off(child, 'click', this._onCloseClick, this);
    102. }
    103. return this;
    104. },
    105. /**
    106. * Open sidebar (if necessary) and show the specified tab.
    107. *
    108. * @param {string} id - The id of the tab to show (without the # character)
    109. */
    110. open: function(id) {
    111. var i, child;
    112. // hide old active contents and show new content
    113. for (i = this._panes.length - 1; i >= 0; i--) {
    114. child = this._panes[i];
    115. if (child.id == id)
    116. L.DomUtil.addClass(child, 'active');
    117. else if (L.DomUtil.hasClass(child, 'active'))
    118. L.DomUtil.removeClass(child, 'active');
    119. }
    120. // remove old active highlights and set new highlight
    121. for (i = this._tabitems.length - 1; i >= 0; i--) {
    122. child = this._tabitems[i];
    123. if (child.querySelector('a').hash == '#' + id)
    124. L.DomUtil.addClass(child, 'active');
    125. else if (L.DomUtil.hasClass(child, 'active'))
    126. L.DomUtil.removeClass(child, 'active');
    127. }
    128. this.fire('content', { id: id });
    129. // open sidebar (if necessary)
    130. if (L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
    131. this.fire('opening');
    132. L.DomUtil.removeClass(this._sidebar, 'collapsed');
    133. }
    134. return this;
    135. },
    136. /**
    137. * Close the sidebar (if necessary).
    138. */
    139. close: function() {
    140. // remove old active highlights
    141. for (var i = this._tabitems.length - 1; i >= 0; i--) {
    142. var child = this._tabitems[i];
    143. if (L.DomUtil.hasClass(child, 'active'))
    144. L.DomUtil.removeClass(child, 'active');
    145. }
    146. // close sidebar
    147. if (!L.DomUtil.hasClass(this._sidebar, 'collapsed')) {
    148. this.fire('closing');
    149. L.DomUtil.addClass(this._sidebar, 'collapsed');
    150. }
    151. return this;
    152. },
    153. /**
    154. * @private
    155. */
    156. _onClick: function() {
    157. if (L.DomUtil.hasClass(this, 'active'))
    158. this._sidebar.close();
    159. else if (!L.DomUtil.hasClass(this, 'disabled'))
    160. this._sidebar.open(this.querySelector('a').hash.slice(1));
    161. },
    162. /**
    163. * @private
    164. */
    165. _onCloseClick: function () {
    166. this.close();
    167. }
    168. });
    169. /**
    170. * Creates a new sidebar.
    171. *
    172. * @example
    173. * var sidebar = L.control.sidebar('sidebar').addTo(map);
    174. *
    175. * @param {string} id - The id of the sidebar element (without the # character)
    176. * @param {Object} [options] - Optional options object
    177. * @param {string} [options.position=left] - Position of the sidebar: 'left' or 'right'
    178. * @returns {Sidebar} A new sidebar instance
    179. */
    180. L.control.sidebar = function (id, options) {
    181. return new L.Control.Sidebar(id, options);
    182. };

    总结:本文介绍了leaflet的侧边栏控制组件sidebar,同时详细说明了如何将sidebar集成到leaflet中。如果有什么疑问,欢迎交流。

  • 相关阅读:
    html截取最后几个字符
    Spirng Cloud Gateway详解
    3.1、数据链路层概述
    [LeetCode]数组相关试题
    【论文笔记】Perception, Planning, Control, and Coordination for Autonomous Vehicles
    SVM介绍
    kotlin 注解 @Parcelize 使用
    [jmx]zookeeper/kafka/hive/hadoop/presto/presto等组件的jmx监控汇集
    PaadleInference源码编译操作流程
    【Java SE】抽象类和接口
  • 原文地址:https://blog.csdn.net/yelangkingwuzuhu/article/details/126514927