L.Control.Layers.Minimap.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Leaflet.layerscontrol-minimap
  3. *
  4. * Layers control with synced minimaps for Leaflet.
  5. *
  6. * Jan Pieter Waagmeester <jieter@jieter.nl>
  7. */
  8. (function () {
  9. 'use strict';
  10. var cloneLayer = function (layer) {
  11. var options = layer.options;
  12. if (layer instanceof L.TileLayer) {
  13. return L.tileLayer(layer._url, options);
  14. }
  15. if (layer instanceof L.ImageOverlay) {
  16. return L.imageOverlay(layer._url, layer._bounds, options);
  17. }
  18. if (layer instanceof L.Polygon || layer instanceof L.Rectangle) {
  19. return L.polygon(layer.getLatLngs(), options);
  20. }
  21. if (layer instanceof L.Marker) {
  22. return L.marker(layer.getLatLng(), options);
  23. }
  24. if (layer instanceof L.circleMarker) {
  25. return L.circleMarker(layer.getLatLng(), options);
  26. }
  27. if (layer instanceof L.Polyline) {
  28. return L.polyline(layer.getLatLngs(), options);
  29. }
  30. if (layer instanceof L.MultiPolyline) {
  31. return L.polyline(layer.getLatLngs(), options);
  32. }
  33. if (layer instanceof L.MultiPolygon) {
  34. return L.MultiPolygon(layer.getLatLngs(), options);
  35. }
  36. if (layer instanceof L.Circle) {
  37. return L.circle(layer.getLatLng(), layer.getRadius(), options);
  38. }
  39. if (layer instanceof L.GeoJSON) {
  40. return L.geoJson(layer.toGeoJSON(), options);
  41. }
  42. // no interaction on minimaps, add FeatureGroup as LayerGroup
  43. if (layer instanceof L.LayerGroup || layer instanceof L.FeatureGroup) {
  44. var layergroup = L.layerGroup();
  45. layer.eachLayer(function (inner) {
  46. layergroup.addLayer(cloneLayer(inner));
  47. });
  48. return layergroup;
  49. }
  50. };
  51. L.Control.Layers.Minimap = L.Control.Layers.extend({
  52. options: {
  53. position: 'topright',
  54. topPadding: 10,
  55. bottomPadding: 40,
  56. overlayBackgroundLayer: L.tileLayer('http://a{s}.acetate.geoiq.com/tiles/acetate-base/{z}/{x}/{y}.png', {
  57. attribution: '&copy;2012 Esri & Stamen, Data from OSM and Natural Earth',
  58. subdomains: '0123',
  59. minZoom: 2,
  60. maxZoom: 18
  61. })
  62. },
  63. isCollapsed: function () {
  64. return !L.DomUtil.hasClass(this._container, 'leaflet-control-layers-expanded');
  65. },
  66. _expand: function () {
  67. L.Control.Layers.prototype._expand.call(this);
  68. this._onListScroll();
  69. },
  70. _initLayout: function () {
  71. L.Control.Layers.prototype._initLayout.call(this);
  72. L.DomUtil.addClass(this._container, 'leaflet-control-layers-minimap');
  73. L.DomEvent.on(this._container, 'scroll', this._onListScroll, this);
  74. },
  75. _update: function () {
  76. L.Control.Layers.prototype._update.call(this);
  77. this._map.on('resize', this._onResize, this);
  78. this._onResize();
  79. this._map.whenReady(this._onListScroll, this);
  80. },
  81. _addItem: function (obj) {
  82. var container = obj.overlay ? this._overlaysList : this._baseLayersList;
  83. var label = L.DomUtil.create('label', 'leaflet-minimap-container', container);
  84. var checked = this._map.hasLayer(obj.layer);
  85. this._createMinimap(
  86. L.DomUtil.create('div', 'leaflet-minimap', label),
  87. obj.layer,
  88. obj.overlay
  89. );
  90. var span = L.DomUtil.create('span', 'leaflet-minimap-label', label);
  91. var input;
  92. if (obj.overlay) {
  93. input = document.createElement('input');
  94. input.type = 'checkbox';
  95. input.className = 'leaflet-control-layers-selector';
  96. input.defaultChecked = checked;
  97. } else {
  98. input = this._createRadioElement('leaflet-base-layers', checked);
  99. }
  100. input.layerId = L.stamp(obj.layer);
  101. span.appendChild(input);
  102. L.DomEvent.on(label, 'click', this._onInputClick, this);
  103. var name = L.DomUtil.create('span', '', span);
  104. name.innerHTML = ' ' + obj.name;
  105. return label;
  106. },
  107. _onResize: function () {
  108. var mapHeight = this._map.getContainer().clientHeight;
  109. var controlHeight = this._container.clientHeight;
  110. if (controlHeight > mapHeight - this.options.bottomPadding) {
  111. this._container.style.overflowY = 'scroll';
  112. }
  113. this._container.style.maxHeight = (mapHeight - this.options.bottomPadding - this.options.topPadding) + 'px';
  114. },
  115. _onListScroll: function () {
  116. var minimaps = document.getElementsByClassName('leaflet-minimap-container');
  117. if (minimaps.length === 0) {
  118. return;
  119. }
  120. var first, last;
  121. if (this.isCollapsed()) {
  122. first = last = -1;
  123. } else {
  124. var minimapHeight = minimaps.item(0).clientHeight;
  125. var container = this._container;
  126. var listHeight = container.clientHeight;
  127. var scrollTop = container.scrollTop;
  128. first = Math.floor(scrollTop / minimapHeight);
  129. last = Math.ceil((scrollTop + listHeight) / minimapHeight);
  130. }
  131. for (var i = 0; i < minimaps.length; ++i) {
  132. var minimap = minimaps[i].childNodes.item(0);
  133. var map = minimap._miniMap;
  134. var layer = map._layer;
  135. if (!layer) {
  136. continue;
  137. }
  138. if (i >= first && i <= last) {
  139. if (!map.hasLayer(layer)) {
  140. layer.addTo(map);
  141. }
  142. map.invalidateSize();
  143. } else {
  144. if (map.hasLayer(layer)) {
  145. map.removeLayer(layer);
  146. }
  147. }
  148. }
  149. },
  150. _createMinimap: function (mapContainer, originalLayer, isOverlay) {
  151. var minimap = mapContainer._miniMap = L.map(mapContainer, {
  152. attributionControl: false,
  153. zoomControl: false
  154. });
  155. // disable interaction.
  156. minimap.dragging.disable();
  157. minimap.touchZoom.disable();
  158. minimap.doubleClickZoom.disable();
  159. minimap.scrollWheelZoom.disable();
  160. // create tilelayer, but do not add it to the map yet.
  161. if (isOverlay) {
  162. minimap._layer = L.layerGroup([
  163. cloneLayer(this.options.overlayBackgroundLayer),
  164. cloneLayer(originalLayer)
  165. ]);
  166. } else {
  167. minimap._layer = cloneLayer(originalLayer);
  168. }
  169. var map = this._map;
  170. map.whenReady(function () {
  171. minimap.setView(map.getCenter(), map.getZoom());
  172. map.sync(minimap);
  173. });
  174. }
  175. });
  176. L.control.layers.minimap = function (baseLayers, overlays, options) {
  177. return new L.Control.Layers.Minimap(baseLayers, overlays, options);
  178. };
  179. })();