• 基于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中。如果有什么疑问,欢迎交流。

  • 相关阅读:
    XV4001BD(数字输出陀螺传感器) 汽车级晶振
    系统架构设计师备考经验分享:如何有效备考
    速看 二建考生查分啦 安徽省2022年二建考试成绩、合格线公布
    Dubbo面试系列问题总结
    静态代理和动态代理
    Go开发IDE全览:GoLand vs VSCode全面解析
    如何解决“德语/文”等外文字符显示乱码问题
    UE 视差材质 学习笔记
    Java 基于 SpringBoot 的校园疫情防控系统
    React函数式组件渲染、useEffect顺序总结
  • 原文地址:https://blog.csdn.net/yelangkingwuzuhu/article/details/126514927