mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-04 09:14:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// Leaflet.PixiOverlay
 | 
						|
// version: 1.8.1
 | 
						|
// author: Manuel Baclet <mbaclet@gmail.com>
 | 
						|
// license: MIT
 | 
						|
 | 
						|
(function (factory) {
 | 
						|
	if (typeof define === 'function' && define.amd) {
 | 
						|
		// AMD
 | 
						|
		define(['leaflet', 'pixi.js'], factory);
 | 
						|
	} else if (typeof module !== 'undefined') {
 | 
						|
		// Node/CommonJS
 | 
						|
		module.exports = factory(require('leaflet'), require('pixi.js'));
 | 
						|
	} else {
 | 
						|
		// Browser globals
 | 
						|
		if (typeof window.L === 'undefined') {
 | 
						|
			throw new Error('Leaflet must be loaded first');
 | 
						|
		}
 | 
						|
		if (typeof window.PIXI === 'undefined') {
 | 
						|
			throw new Error('Pixi.js must be loaded first');
 | 
						|
		}
 | 
						|
		factory(window.L, window.PIXI);
 | 
						|
	}
 | 
						|
}(function (L, PIXI) {
 | 
						|
 | 
						|
	var round = L.Point.prototype._round;
 | 
						|
	var no_round = function () {return this;};
 | 
						|
 | 
						|
	function setInteractionManager(interactionManager, destroyInteractionManager, autoPreventDefault) {
 | 
						|
		if (destroyInteractionManager) {
 | 
						|
			interactionManager.destroy();
 | 
						|
		} else if (!autoPreventDefault) {
 | 
						|
			interactionManager.autoPreventDefault = false;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	var pixiOverlayClass = {
 | 
						|
 | 
						|
		options: {
 | 
						|
			// @option padding: Number = 0.1
 | 
						|
			// How much to extend the clip area around the map view (relative to its size)
 | 
						|
			// e.g. 0.1 would be 10% of map view in each direction
 | 
						|
			padding: 0.1,
 | 
						|
			// @option forceCanvas: Boolean = false
 | 
						|
			// Force use of a 2d-canvas
 | 
						|
			forceCanvas: false,
 | 
						|
			// @option doubleBuffering: Boolean = false
 | 
						|
			// Help to prevent flicker when refreshing display on some devices (e.g. iOS devices)
 | 
						|
			// It is ignored if rendering is done with 2d-canvas
 | 
						|
			doubleBuffering: false,
 | 
						|
			// @option resolution: Number = 1
 | 
						|
			// Resolution of the renderer canvas
 | 
						|
			resolution: L.Browser.retina ? 2 : 1,
 | 
						|
			// @option projectionZoom(map: map): Number
 | 
						|
			// return the layer projection zoom level
 | 
						|
			projectionZoom: function (map) {return (map.getMaxZoom() + map.getMinZoom()) / 2;},
 | 
						|
			// @option destroyInteractionManager:  Boolean = false
 | 
						|
			// Destroy PIXI Interaction Manager
 | 
						|
			destroyInteractionManager: false,
 | 
						|
			// @option
 | 
						|
			// Customize PIXI Interaction Manager autoPreventDefault property
 | 
						|
			// This option is ignored if destroyInteractionManager is set
 | 
						|
			autoPreventDefault: true,
 | 
						|
			// @option resolution: Boolean = false
 | 
						|
			// Enables drawing buffer preservation
 | 
						|
			preserveDrawingBuffer: false,
 | 
						|
			// @option resolution: Boolean = true
 | 
						|
			// Clear the canvas before the new render pass
 | 
						|
			clearBeforeRender: true,
 | 
						|
			// @option shouldRedrawOnMove(e: moveEvent): Boolean
 | 
						|
			// filter move events that should trigger a layer redraw
 | 
						|
			shouldRedrawOnMove: function () {return false;},
 | 
						|
		},
 | 
						|
 | 
						|
		initialize: function (drawCallback, pixiContainer, options) {
 | 
						|
			L.setOptions(this, options);
 | 
						|
			L.stamp(this);
 | 
						|
			this._drawCallback = drawCallback;
 | 
						|
			this._pixiContainer = pixiContainer;
 | 
						|
			this._rendererOptions = {
 | 
						|
				transparent: true,
 | 
						|
				resolution: this.options.resolution,
 | 
						|
				antialias: true,
 | 
						|
				forceCanvas: this.options.forceCanvas,
 | 
						|
				preserveDrawingBuffer: this.options.preserveDrawingBuffer,
 | 
						|
				clearBeforeRender: this.options.clearBeforeRender
 | 
						|
			};
 | 
						|
			this._doubleBuffering = PIXI.utils.isWebGLSupported() && !this.options.forceCanvas &&
 | 
						|
				this.options.doubleBuffering;
 | 
						|
		},
 | 
						|
 | 
						|
		_setMap: function () {},
 | 
						|
 | 
						|
		_setContainerStyle: function () {},
 | 
						|
 | 
						|
		_addContainer: function () {
 | 
						|
			this.getPane().appendChild(this._container);
 | 
						|
		},
 | 
						|
 | 
						|
		_setEvents: function () {},
 | 
						|
 | 
						|
		onAdd: function (targetMap) {
 | 
						|
			this._setMap(targetMap);
 | 
						|
			if (!this._container) {
 | 
						|
				var container = this._container = L.DomUtil.create('div', 'leaflet-pixi-overlay');
 | 
						|
				container.style.position = 'absolute';
 | 
						|
				this._renderer = PIXI.autoDetectRenderer(this._rendererOptions);
 | 
						|
				setInteractionManager(
 | 
						|
					this._renderer.plugins.interaction,
 | 
						|
					this.options.destroyInteractionManager,
 | 
						|
					this.options.autoPreventDefault
 | 
						|
				);
 | 
						|
				container.appendChild(this._renderer.view);
 | 
						|
				if (this._zoomAnimated) {
 | 
						|
					L.DomUtil.addClass(container, 'leaflet-zoom-animated');
 | 
						|
					this._setContainerStyle();
 | 
						|
				}
 | 
						|
				if (this._doubleBuffering) {
 | 
						|
					this._auxRenderer = PIXI.autoDetectRenderer(this._rendererOptions);
 | 
						|
					setInteractionManager(
 | 
						|
						this._auxRenderer.plugins.interaction,
 | 
						|
						this.options.destroyInteractionManager,
 | 
						|
						this.options.autoPreventDefault
 | 
						|
					);
 | 
						|
					container.appendChild(this._auxRenderer.view);
 | 
						|
					this._renderer.view.style.position = 'absolute';
 | 
						|
					this._auxRenderer.view.style.position = 'absolute';
 | 
						|
				}
 | 
						|
			}
 | 
						|
			this._addContainer();
 | 
						|
			this._setEvents();
 | 
						|
 | 
						|
			var map = this._map;
 | 
						|
			this._initialZoom = this.options.projectionZoom(map);
 | 
						|
			this._wgsOrigin = L.latLng([0, 0]);
 | 
						|
			this._wgsInitialShift = map.project(this._wgsOrigin, this._initialZoom);
 | 
						|
			this._mapInitialZoom = map.getZoom();
 | 
						|
			var _layer = this;
 | 
						|
 | 
						|
			this.utils = {
 | 
						|
				latLngToLayerPoint: function (latLng, zoom) {
 | 
						|
					zoom = (zoom === undefined) ? _layer._initialZoom : zoom;
 | 
						|
					var projectedPoint = map.project(L.latLng(latLng), zoom);
 | 
						|
					return projectedPoint;
 | 
						|
				},
 | 
						|
				layerPointToLatLng: function (point, zoom) {
 | 
						|
					zoom = (zoom === undefined) ? _layer._initialZoom : zoom;
 | 
						|
					var projectedPoint = L.point(point);
 | 
						|
					return map.unproject(projectedPoint, zoom);
 | 
						|
				},
 | 
						|
				getScale: function (zoom) {
 | 
						|
					if (zoom === undefined) return map.getZoomScale(map.getZoom(), _layer._initialZoom);
 | 
						|
					else return map.getZoomScale(zoom, _layer._initialZoom);
 | 
						|
				},
 | 
						|
				getRenderer: function () {
 | 
						|
					return _layer._renderer;
 | 
						|
				},
 | 
						|
				getContainer: function () {
 | 
						|
					return _layer._pixiContainer;
 | 
						|
				},
 | 
						|
				getMap: function () {
 | 
						|
					return _layer._map;
 | 
						|
				}
 | 
						|
			};
 | 
						|
			this._update({type: 'add'});
 | 
						|
		},
 | 
						|
 | 
						|
		onRemove: function () {
 | 
						|
			L.DomUtil.remove(this._container);
 | 
						|
		},
 | 
						|
 | 
						|
		getEvents: function () {
 | 
						|
			var events = {
 | 
						|
				zoom: this._onZoom,
 | 
						|
				move: this._onMove,
 | 
						|
				moveend: this._update
 | 
						|
			};
 | 
						|
			if (this._zoomAnimated) {
 | 
						|
				events.zoomanim = this._onAnimZoom;
 | 
						|
			}
 | 
						|
			return events;
 | 
						|
		},
 | 
						|
 | 
						|
		_onZoom: function () {
 | 
						|
			this._updateTransform(this._map.getCenter(), this._map.getZoom());
 | 
						|
		},
 | 
						|
 | 
						|
		_onAnimZoom: function (e) {
 | 
						|
			this._updateTransform(e.center, e.zoom);
 | 
						|
		},
 | 
						|
 | 
						|
		_onMove: function(e) {
 | 
						|
			if (this.options.shouldRedrawOnMove(e)) {
 | 
						|
				this._update(e);
 | 
						|
			}
 | 
						|
		},
 | 
						|
 | 
						|
		_updateTransform: function (center, zoom) {
 | 
						|
			var scale = this._map.getZoomScale(zoom, this._zoom),
 | 
						|
				viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding),
 | 
						|
				currentCenterPoint = this._map.project(this._center, zoom),
 | 
						|
 | 
						|
				topLeftOffset = viewHalf.multiplyBy(-scale).add(currentCenterPoint)
 | 
						|
					.subtract(this._map._getNewPixelOrigin(center, zoom));
 | 
						|
 | 
						|
			if (L.Browser.any3d) {
 | 
						|
				L.DomUtil.setTransform(this._container, topLeftOffset, scale);
 | 
						|
			} else {
 | 
						|
				L.DomUtil.setPosition(this._container, topLeftOffset);
 | 
						|
			}
 | 
						|
		},
 | 
						|
 | 
						|
		_redraw: function(offset, e) {
 | 
						|
			this._disableLeafletRounding();
 | 
						|
			var scale = this._map.getZoomScale(this._zoom, this._initialZoom),
 | 
						|
				shift = this._map.latLngToLayerPoint(this._wgsOrigin)
 | 
						|
				._subtract(this._wgsInitialShift.multiplyBy(scale))._subtract(offset);
 | 
						|
			this._pixiContainer.scale.set(scale);
 | 
						|
			this._pixiContainer.position.set(shift.x, shift.y);
 | 
						|
			this._drawCallback(this.utils, e);
 | 
						|
			this._enableLeafletRounding();
 | 
						|
		},
 | 
						|
 | 
						|
		_update: function (e) {
 | 
						|
			// is this really useful?
 | 
						|
			if (this._map._animatingZoom && this._bounds) {return;}
 | 
						|
 | 
						|
			// Update pixel bounds of renderer container
 | 
						|
			var p = this.options.padding,
 | 
						|
				mapSize = this._map.getSize(),
 | 
						|
				min = this._map.containerPointToLayerPoint(mapSize.multiplyBy(-p)).round();
 | 
						|
 | 
						|
			this._bounds = new L.Bounds(min, min.add(mapSize.multiplyBy(1 + p * 2)).round());
 | 
						|
			this._center = this._map.getCenter();
 | 
						|
			this._zoom = this._map.getZoom();
 | 
						|
 | 
						|
			if (this._doubleBuffering) {
 | 
						|
				var currentRenderer = this._renderer;
 | 
						|
				this._renderer = this._auxRenderer;
 | 
						|
				this._auxRenderer = currentRenderer;
 | 
						|
			}
 | 
						|
 | 
						|
			var view = this._renderer.view;
 | 
						|
			var b = this._bounds,
 | 
						|
				container = this._container,
 | 
						|
				size = b.getSize();
 | 
						|
 | 
						|
			if (!this._renderer.size || this._renderer.size.x !== size.x || this._renderer.size.y !== size.y) {
 | 
						|
				if (this._renderer.gl) {
 | 
						|
					this._renderer.resolution = this.options.resolution;
 | 
						|
					if (this._renderer.rootRenderTarget) {
 | 
						|
						this._renderer.rootRenderTarget.resolution = this.options.resolution;
 | 
						|
					}
 | 
						|
				}
 | 
						|
				this._renderer.resize(size.x, size.y);
 | 
						|
				view.style.width = size.x + 'px';
 | 
						|
				view.style.height = size.y + 'px';
 | 
						|
				if (this._renderer.gl) {
 | 
						|
					var gl = this._renderer.gl;
 | 
						|
					if (gl.drawingBufferWidth !== this._renderer.width) {
 | 
						|
						var resolution = this.options.resolution * gl.drawingBufferWidth / this._renderer.width;
 | 
						|
						this._renderer.resolution = resolution;
 | 
						|
						if (this._renderer.rootRenderTarget) {
 | 
						|
							this._renderer.rootRenderTarget.resolution = resolution;
 | 
						|
						}
 | 
						|
						this._renderer.resize(size.x, size.y);
 | 
						|
					}
 | 
						|
				}
 | 
						|
				this._renderer.size = size;
 | 
						|
			}
 | 
						|
 | 
						|
			if (this._doubleBuffering) {
 | 
						|
				var self = this;
 | 
						|
				requestAnimationFrame(function() {
 | 
						|
					self._redraw(b.min, e);
 | 
						|
					self._renderer.gl.finish();
 | 
						|
					view.style.visibility = 'visible';
 | 
						|
					self._auxRenderer.view.style.visibility = 'hidden';
 | 
						|
					L.DomUtil.setPosition(container, b.min);
 | 
						|
				});
 | 
						|
			} else {
 | 
						|
				this._redraw(b.min, e);
 | 
						|
				L.DomUtil.setPosition(container, b.min);
 | 
						|
			}
 | 
						|
		},
 | 
						|
 | 
						|
		_disableLeafletRounding: function () {
 | 
						|
			L.Point.prototype._round = no_round;
 | 
						|
		},
 | 
						|
 | 
						|
		_enableLeafletRounding: function () {
 | 
						|
			L.Point.prototype._round = round;
 | 
						|
		},
 | 
						|
 | 
						|
		redraw: function (data) {
 | 
						|
			if (this._map) {
 | 
						|
				this._disableLeafletRounding();
 | 
						|
				this._drawCallback(this.utils, data);
 | 
						|
				this._enableLeafletRounding();
 | 
						|
			}
 | 
						|
			return this;
 | 
						|
		}
 | 
						|
 | 
						|
	};
 | 
						|
 | 
						|
	if (L.version >= "1") {
 | 
						|
 | 
						|
		L.PixiOverlay = L.Layer.extend(pixiOverlayClass);
 | 
						|
 | 
						|
	} else {
 | 
						|
 | 
						|
		// backport some leaflet@1.0.0 methods
 | 
						|
		L.Map.prototype.getZoomScale = function (toZoom, fromZoom) {
 | 
						|
			var crs = this.options.crs;
 | 
						|
			fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
 | 
						|
			return crs.scale(toZoom) / crs.scale(fromZoom);
 | 
						|
		};
 | 
						|
 | 
						|
		L.DomUtil.setTransform = function (el, offset, scale) {
 | 
						|
			var pos = offset || new L.Point(0, 0);
 | 
						|
 | 
						|
			el.style[L.DomUtil.TRANSFORM] =
 | 
						|
				(L.Browser.ie3d ?
 | 
						|
					'translate(' + pos.x + 'px,' + pos.y + 'px)' :
 | 
						|
					'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') +
 | 
						|
				(scale ? ' scale(' + scale + ')' : '');
 | 
						|
		};
 | 
						|
 | 
						|
		// patch pixiOverlayClass for leaflet@0.7.7
 | 
						|
		pixiOverlayClass.includes = L.Mixin.Events;
 | 
						|
 | 
						|
		pixiOverlayClass.addTo = function (map) {
 | 
						|
			map.addLayer(this);
 | 
						|
			return this;
 | 
						|
		};
 | 
						|
 | 
						|
		pixiOverlayClass._setMap = function (map) {
 | 
						|
			this._map = map;
 | 
						|
			this._zoomAnimated = map._zoomAnimated;
 | 
						|
		};
 | 
						|
 | 
						|
		pixiOverlayClass._setContainerStyle = function () {
 | 
						|
			var self = this;
 | 
						|
			[
 | 
						|
				'-webkit-transform-origin',
 | 
						|
				'-ms-transform-origin',
 | 
						|
				'transform-origin'
 | 
						|
			].forEach(function (property) {
 | 
						|
				self._container.style[property] = '0 0';
 | 
						|
			});
 | 
						|
		};
 | 
						|
 | 
						|
		pixiOverlayClass._addContainer = function () {
 | 
						|
			this._map.getPanes()[this.options.pane || 'overlayPane']
 | 
						|
				.appendChild(this._container);
 | 
						|
		};
 | 
						|
 | 
						|
		pixiOverlayClass._setEvents = function () {
 | 
						|
			var events = this.getEvents();
 | 
						|
			for (var evt in events) {
 | 
						|
				this._map.on(evt, events[evt], this);
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		pixiOverlayClass.onRemove = function () {
 | 
						|
			this._map.getPanes()[this.options.pane || 'overlayPane']
 | 
						|
				.removeChild(this._container);
 | 
						|
			var events = this.getEvents();
 | 
						|
			for (var evt in events) {
 | 
						|
				this._map.off(evt, events[evt], this);
 | 
						|
			}
 | 
						|
		};
 | 
						|
 | 
						|
		L.PixiOverlay = L.Class.extend(pixiOverlayClass);
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
	// @factory L.pixiOverlay(drawCallback: function, pixiContainer: PIXI.Container, options?: L.PixiOverlay options)
 | 
						|
	// Creates a PixiOverlay with the given arguments.
 | 
						|
	L.pixiOverlay = function (drawCallback, pixiContainer, options) {
 | 
						|
		return L.Browser.canvas ? new L.PixiOverlay(drawCallback, pixiContainer, options) : null;
 | 
						|
	};
 | 
						|
 | 
						|
})); |