Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

leaflet-mapbox-gl.js 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. L.MapboxGL = L.Layer.extend({
  2. options: {
  3. updateInterval: 32
  4. },
  5. initialize: function (options) {
  6. L.setOptions(this, options);
  7. if (options.accessToken) {
  8. mapboxgl.accessToken = options.accessToken;
  9. } else {
  10. throw new Error('You should provide a Mapbox GL access token as a token option.');
  11. }
  12. /**
  13. * Create a version of `fn` that only fires once every `time` millseconds.
  14. *
  15. * @param {Function} fn the function to be throttled
  16. * @param {number} time millseconds required between function calls
  17. * @param {*} context the value of `this` with which the function is called
  18. * @returns {Function} debounced function
  19. * @private
  20. */
  21. var throttle = function (fn, time, context) {
  22. var lock, args, wrapperFn, later;
  23. later = function () {
  24. // reset lock and call if queued
  25. lock = false;
  26. if (args) {
  27. wrapperFn.apply(context, args);
  28. args = false;
  29. }
  30. };
  31. wrapperFn = function () {
  32. if (lock) {
  33. // called too soon, queue to call later
  34. args = arguments;
  35. } else {
  36. // call and lock until later
  37. fn.apply(context, arguments);
  38. setTimeout(later, time);
  39. lock = true;
  40. }
  41. };
  42. return wrapperFn;
  43. };
  44. // setup throttling the update event when panning
  45. this._throttledUpdate = throttle(L.Util.bind(this._update, this), this.options.updateInterval);
  46. },
  47. onAdd: function (map) {
  48. if (!this._glContainer) {
  49. this._initContainer();
  50. }
  51. map._panes.tilePane.appendChild(this._glContainer);
  52. this._initGL();
  53. this._offset = this._map.containerPointToLayerPoint([0, 0]);
  54. // work around https://github.com/mapbox/mapbox-gl-leaflet/issues/47
  55. if (map.options.zoomAnimation) {
  56. L.DomEvent.on(map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
  57. }
  58. },
  59. onRemove: function (map) {
  60. if (this._map.options.zoomAnimation) {
  61. L.DomEvent.off(this._map._proxy, L.DomUtil.TRANSITION_END, this._transitionEnd, this);
  62. }
  63. map.getPanes().tilePane.removeChild(this._glContainer);
  64. this._glMap.remove();
  65. this._glMap = null;
  66. },
  67. getEvents: function () {
  68. return {
  69. move: this._throttledUpdate, // sensibly throttle updating while panning
  70. zoomanim: this._animateZoom, // applys the zoom animation to the <canvas>
  71. zoom: this._pinchZoom, // animate every zoom event for smoother pinch-zooming
  72. zoomstart: this._zoomStart, // flag starting a zoom to disable panning
  73. zoomend: this._zoomEnd
  74. };
  75. },
  76. _initContainer: function () {
  77. var container = this._glContainer = L.DomUtil.create('div', 'leaflet-gl-layer');
  78. var size = this._map.getSize();
  79. container.style.width = size.x + 'px';
  80. container.style.height = size.y + 'px';
  81. },
  82. _initGL: function () {
  83. var center = this._map.getCenter();
  84. var options = L.extend({}, this.options, {
  85. container: this._glContainer,
  86. interactive: false,
  87. center: [center.lng, center.lat],
  88. zoom: this._map.getZoom() - 1,
  89. attributionControl: false
  90. });
  91. this._glMap = new mapboxgl.Map(options);
  92. // allow GL base map to pan beyond min/max latitudes
  93. this._glMap.transform.latRange = null;
  94. // treat child <canvas> element like L.ImageOverlay
  95. L.DomUtil.addClass(this._glMap._canvas, 'leaflet-image-layer');
  96. L.DomUtil.addClass(this._glMap._canvas, 'leaflet-zoom-animated');
  97. },
  98. _update: function (e) {
  99. // update the offset so we can correct for it later when we zoom
  100. this._offset = this._map.containerPointToLayerPoint([0, 0]);
  101. if (this._zooming) {
  102. return;
  103. }
  104. var size = this._map.getSize(),
  105. container = this._glContainer,
  106. gl = this._glMap,
  107. topLeft = this._map.containerPointToLayerPoint([0, 0]);
  108. L.DomUtil.setPosition(container, topLeft);
  109. var center = this._map.getCenter();
  110. // gl.setView([center.lat, center.lng], this._map.getZoom() - 1, 0);
  111. // calling setView directly causes sync issues because it uses requestAnimFrame
  112. var tr = gl.transform;
  113. tr.center = mapboxgl.LngLat.convert([center.lng, center.lat]);
  114. tr.zoom = this._map.getZoom() - 1;
  115. if (gl.transform.width !== size.x || gl.transform.height !== size.y) {
  116. container.style.width = size.x + 'px';
  117. container.style.height = size.y + 'px';
  118. if (gl._resize !== null && gl._resize !== undefined){
  119. gl._resize();
  120. } else {
  121. gl.resize();
  122. }
  123. } else {
  124. gl._update();
  125. }
  126. },
  127. // update the map constantly during a pinch zoom
  128. _pinchZoom: function (e) {
  129. this._glMap.jumpTo({
  130. zoom: this._map.getZoom() - 1,
  131. center: this._map.getCenter()
  132. });
  133. },
  134. // borrowed from L.ImageOverlay https://github.com/Leaflet/Leaflet/blob/master/src/layer/ImageOverlay.js#L139-L144
  135. _animateZoom: function (e) {
  136. var scale = this._map.getZoomScale(e.zoom),
  137. offset = this._map._latLngToNewLayerPoint(this._map.getBounds().getNorthWest(), e.zoom, e.center);
  138. L.DomUtil.setTransform(this._glMap._canvas, offset.subtract(this._offset), scale);
  139. },
  140. _zoomStart: function (e) {
  141. this._zooming = true;
  142. },
  143. _zoomEnd: function () {
  144. var scale = this._map.getZoomScale(this._map.getZoom()),
  145. offset = this._map._latLngToNewLayerPoint(this._map.getBounds().getNorthWest(), this._map.getZoom(), this._map.getCenter());
  146. L.DomUtil.setTransform(this._glMap._canvas, offset.subtract(this._offset), scale);
  147. this._zooming = false;
  148. },
  149. _transitionEnd: function (e) {
  150. L.Util.requestAnimFrame(function () {
  151. var zoom = this._map.getZoom(),
  152. center = this._map.getCenter(),
  153. offset = this._map.latLngToContainerPoint(this._map.getBounds().getNorthWest());
  154. // reset the scale and offset
  155. L.DomUtil.setTransform(this._glMap._canvas, offset, 1);
  156. // enable panning once the gl map is ready again
  157. this._glMap.once('moveend', L.Util.bind(function () {
  158. this._zoomEnd();
  159. }, this));
  160. // update the map position
  161. this._glMap.jumpTo({
  162. center: center,
  163. zoom: zoom - 1
  164. });
  165. }, this);
  166. }
  167. });
  168. L.mapboxGL = function (options) {
  169. return new L.MapboxGL(options);
  170. };