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.
		
		
		
		
		
			
		
			
				
					
					
						
							354 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
	
	
							354 lines
						
					
					
						
							13 KiB
						
					
					
				(function (factory, window) { | 
						|
    // define an AMD module that relies on 'leaflet' | 
						|
    if (typeof define === "function" && define.amd) { | 
						|
        define(["leaflet"], factory); | 
						|
 | 
						|
        // define a Common JS module that relies on 'leaflet' | 
						|
    } else if (typeof exports === "object") { | 
						|
        module.exports = factory(require("leaflet")); | 
						|
    } | 
						|
 | 
						|
    // attach your plugin to the global 'L' variable | 
						|
    if (typeof window !== "undefined" && window.L) { | 
						|
        factory(L); | 
						|
    } | 
						|
})(function (L) { | 
						|
    class LegendSymbol { | 
						|
        constructor(control, container, legend) { | 
						|
            this._control = control; | 
						|
            this._container = container; | 
						|
            this._legend = legend; | 
						|
            this._width = this._control.options.symbolWidth; | 
						|
            this._height = this._control.options.symbolHeight; | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    class GeometricSymbol extends LegendSymbol { | 
						|
        constructor(control, container, legend) { | 
						|
            super(control, container, legend); | 
						|
 | 
						|
            this._canvas = this._buildCanvas(); | 
						|
            if (this._drawSymbol) { | 
						|
                this._drawSymbol(); | 
						|
            } | 
						|
            this._style(); | 
						|
        } | 
						|
 | 
						|
        _buildCanvas() { | 
						|
            var canvas = L.DomUtil.create("canvas", null, this._container); | 
						|
            canvas.height = this._control.options.symbolHeight; | 
						|
            canvas.width = this._control.options.symbolWidth; | 
						|
            return canvas; | 
						|
        } | 
						|
 | 
						|
        _drawSymbol() {} | 
						|
 | 
						|
        _style() { | 
						|
            var ctx = (this._ctx = this._canvas.getContext("2d")); | 
						|
            if (this._legend.fill || this._legend.fillColor) { | 
						|
                ctx.globalAlpha = this._legend.fillOpacity || 1; | 
						|
                ctx.fillStyle = this._legend.fillColor || this._legend.color; | 
						|
                ctx.fill(this._legend.fillRule || "evenodd"); | 
						|
            } | 
						|
 | 
						|
            if (this._legend.stroke || this._legend.color) { | 
						|
                if (this._legend.dashArray) { | 
						|
                    ctx.setLineDash(this._legend.dashArray || []); | 
						|
                } | 
						|
                ctx.globalAlpha = this._legend.opacity || 1.0; | 
						|
                ctx.lineWidth = this._legend.weight || 2; | 
						|
                ctx.strokeStyle = this._legend.color || "#3388ff"; | 
						|
                ctx.lineCap = this._legend.lineCap || "round"; | 
						|
                ctx.lineJoin = this._legend.lineJoin || "round"; | 
						|
                ctx.stroke(); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        rescale() {} | 
						|
 | 
						|
        center() {} | 
						|
    } | 
						|
 | 
						|
    class CircleSymbol extends GeometricSymbol { | 
						|
        _drawSymbol() { | 
						|
            var ctx = (this._ctx = this._canvas.getContext("2d")); | 
						|
 | 
						|
            var legend = this._legend; | 
						|
            var linelWeight = legend.weight || 3; | 
						|
 | 
						|
            var centerX = this._control.options.symbolWidth / 2; | 
						|
            var centerY = this._control.options.symbolHeight / 2; | 
						|
            var maxRadius = Math.min(centerX, centerY) - linelWeight; | 
						|
            var radius = maxRadius; | 
						|
            if (legend.radius) { | 
						|
                radius = Math.min(legend.radius, maxRadius); | 
						|
            } | 
						|
 | 
						|
            ctx.arc(centerX, centerY, radius, 0, Math.PI * 2, false); | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    class PolylineSymbol extends GeometricSymbol { | 
						|
        _drawSymbol() { | 
						|
            var ctx = (this._ctx = this._canvas.getContext("2d")); | 
						|
 | 
						|
            var x1 = 0; | 
						|
            var x2 = this._control.options.symbolWidth; | 
						|
            var y = this._control.options.symbolHeight / 2; | 
						|
 | 
						|
            ctx.beginPath(); | 
						|
            ctx.moveTo(x1, y); | 
						|
            ctx.lineTo(x2, y); | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    class RectangleSymbol extends GeometricSymbol { | 
						|
        _drawSymbol() { | 
						|
            var ctx = (this._ctx = this._canvas.getContext("2d")); | 
						|
            var linelWeight = this._legend.weight || 3; | 
						|
 | 
						|
            var x0 = this._control.options.symbolWidth / 2; | 
						|
            var y0 = this._control.options.symbolHeight / 2; | 
						|
 | 
						|
            var rx = x0 - linelWeight; | 
						|
            var ry = y0 - linelWeight; | 
						|
            if (rx == ry) { | 
						|
                ry = ry / 2; | 
						|
            } | 
						|
            ctx.rect(x0 - rx, y0 - ry, rx * 2, ry * 2); | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    /** | 
						|
     * 圆心坐标:(x0,y0) 半径:r 角度(X轴顺时针旋转):a | 
						|
     * 弧度 = 角度 * Math.PI / 180 | 
						|
     * 则圆上任一点为:(x1,y1) | 
						|
     * x1   =   x0   +   r   *   Math.cos( a  * Math.PI / 180) | 
						|
     * y1   =   y0   +   r   *   Math.sin( a  * Math.PI / 180) | 
						|
     */ | 
						|
    class PolygonSymbol extends GeometricSymbol { | 
						|
        _drawSymbol() { | 
						|
            var ctx = (this._ctx = this._canvas.getContext("2d")); | 
						|
 | 
						|
            var linelWeight = this._legend.weight || 3; | 
						|
            var x0 = this._control.options.symbolWidth / 2; | 
						|
            var y0 = this._control.options.symbolHeight / 2; | 
						|
            var r = Math.min(x0, y0) - linelWeight; | 
						|
            var a = 360 / this._legend.sides; | 
						|
            ctx.beginPath(); | 
						|
            for (var i = 0; i <= this._legend.sides; i++) { | 
						|
                var x1 = x0 + r * Math.cos(((a * i + (90 - a / 2)) * Math.PI) / 180); | 
						|
                var y1 = y0 + r * Math.sin(((a * i + (90 - a / 2)) * Math.PI) / 180); | 
						|
                if (i == 0) { | 
						|
                    ctx.moveTo(x1, y1); | 
						|
                } else { | 
						|
                    ctx.lineTo(x1, y1); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    class ImageSymbol extends LegendSymbol { | 
						|
        constructor(control, container, legend) { | 
						|
            super(control, container, legend); | 
						|
            this._img = null; | 
						|
            this._loadImages(); | 
						|
        } | 
						|
 | 
						|
        _loadImages() { | 
						|
            var imageLoaded = () => { | 
						|
                this.rescale(); | 
						|
            }; | 
						|
            var img = L.DomUtil.create("img", null, this._container); | 
						|
            this._img = img; | 
						|
            img.onload = imageLoaded; | 
						|
            img.src = this._legend.url; | 
						|
        } | 
						|
 | 
						|
        rescale() { | 
						|
            if (this._img) { | 
						|
                var _options = this._control.options; | 
						|
                if (this._img.width > _options.symbolWidth || this._img.height > _options.symbolHeight) { | 
						|
                    var imgW = this._img.width; | 
						|
                    var imgH = this._img.height; | 
						|
                    var scaleW = _options.symbolWidth / imgW; | 
						|
                    var scaleH = _options.symbolHeight / imgH; | 
						|
                    var scale = Math.min(scaleW, scaleH); | 
						|
                    this._img.width = imgW * scale; | 
						|
                    this._img.height = imgH * scale; | 
						|
                } | 
						|
                this.center(); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        center() { | 
						|
            var containerCenterX = this._container.offsetWidth / 2; | 
						|
            var containerCenterY = this._container.offsetHeight / 2; | 
						|
            var imageCenterX = parseInt(this._img.width) / 2; | 
						|
            var imageCenterY = parseInt(this._img.height) / 2; | 
						|
 | 
						|
            var shiftX = containerCenterX - imageCenterX; | 
						|
            var shiftY = containerCenterY - imageCenterY; | 
						|
 | 
						|
            this._img.style.left = shiftX.toString() + "px"; | 
						|
            this._img.style.top = shiftY.toString() + "px"; | 
						|
        } | 
						|
    } | 
						|
 | 
						|
    L.Control.Legend = L.Control.extend({ | 
						|
        options: { | 
						|
            position: "topleft", | 
						|
            title: "Legend", | 
						|
            legends: [], | 
						|
            symbolWidth: 24, | 
						|
            symbolHeight: 24, | 
						|
            opacity: 1.0, | 
						|
            column: 1, | 
						|
            collapsed: false, | 
						|
        }, | 
						|
 | 
						|
        initialize: function (options) { | 
						|
            L.Util.setOptions(this, options); | 
						|
            this._legendSymbols = []; | 
						|
            this._buildContainer(); | 
						|
        }, | 
						|
 | 
						|
        onAdd: function (map) { | 
						|
            this._map = map; | 
						|
            this._initLayout(); | 
						|
            return this._container; | 
						|
        }, | 
						|
 | 
						|
        _buildContainer: function () { | 
						|
            this._container = L.DomUtil.create("div", "leaflet-legend leaflet-bar leaflet-control"); | 
						|
            this._container.style.backgroundColor = "rgba(255,255,255, " + this.options.opacity + ")"; | 
						|
 | 
						|
            this._contents = L.DomUtil.create("section", "leaflet-legend-contents", this._container); | 
						|
            this._link = L.DomUtil.create("a", "leaflet-legend-toggle", this._container); | 
						|
            this._link.title = "Legend"; | 
						|
            this._link.href = "#"; | 
						|
 | 
						|
            var title = L.DomUtil.create("h3", "leaflet-legend-title", this._contents); | 
						|
            title.innerText = this.options.title || "Legend"; | 
						|
 | 
						|
            var len = this.options.legends.length; | 
						|
            var colSize = Math.ceil(len / this.options.column); | 
						|
            var legendContainer = this._contents; | 
						|
            for (var i = 0; i < len; i++) { | 
						|
                if (i % colSize == 0) { | 
						|
                    legendContainer = L.DomUtil.create("div", "leaflet-legend-column", this._contents); | 
						|
                } | 
						|
                var legend = this.options.legends[i]; | 
						|
                this._buildLegendItems(legendContainer, legend); | 
						|
            } | 
						|
        }, | 
						|
 | 
						|
        _buildLegendItems: function (legendContainer, legend) { | 
						|
            var legendItemDiv = L.DomUtil.create("div", "leaflet-legend-item", legendContainer); | 
						|
            if (legend.inactive) { | 
						|
                L.DomUtil.addClass(legendItemDiv, "leaflet-legend-item-inactive"); | 
						|
            } | 
						|
            var symbolContainer = L.DomUtil.create("i", null, legendItemDiv); | 
						|
 | 
						|
            var legendSymbol; | 
						|
            if (legend.type === "image") { | 
						|
                legendSymbol = new ImageSymbol(this, symbolContainer, legend); | 
						|
            } else if (legend.type === "circle") { | 
						|
                legendSymbol = new CircleSymbol(this, symbolContainer, legend); | 
						|
            } else if (legend.type === "rectangle") { | 
						|
                legendSymbol = new RectangleSymbol(this, symbolContainer, legend); | 
						|
            } else if (legend.type === "polygon") { | 
						|
                legendSymbol = new PolygonSymbol(this, symbolContainer, legend); | 
						|
            } else if (legend.type === "polyline") { | 
						|
                legendSymbol = new PolylineSymbol(this, symbolContainer, legend); | 
						|
            } else { | 
						|
                L.DomUtil.remove(legendItemDiv); | 
						|
                return; | 
						|
            } | 
						|
            this._legendSymbols.push(legendSymbol); | 
						|
 | 
						|
            symbolContainer.style.width = this.options.symbolWidth + "px"; | 
						|
            symbolContainer.style.height = this.options.symbolHeight + "px"; | 
						|
 | 
						|
            var legendLabel = L.DomUtil.create("span", null, legendItemDiv); | 
						|
            legendLabel.innerText = legend.label; | 
						|
            if (legend.layers) { | 
						|
                L.DomUtil.addClass(legendItemDiv, "leaflet-legend-item-clickable"); | 
						|
                L.DomEvent.on( | 
						|
                    legendItemDiv, | 
						|
                    "click", | 
						|
                    function () { | 
						|
                        this._toggleLegend.call(this, legendItemDiv, legend.layers); | 
						|
                    }, | 
						|
                    this | 
						|
                ); | 
						|
            } | 
						|
        }, | 
						|
 | 
						|
        _initLayout: function () { | 
						|
            L.DomEvent.disableClickPropagation(this._container); | 
						|
            L.DomEvent.disableScrollPropagation(this._container); | 
						|
 | 
						|
            if (this.options.collapsed) { | 
						|
                this._map.on("click", this.collapse, this); | 
						|
 | 
						|
                L.DomEvent.on( | 
						|
                    this._container, | 
						|
                    { | 
						|
                        mouseenter: this.expand, | 
						|
                        mouseleave: this.collapse, | 
						|
                    }, | 
						|
                    this | 
						|
                ); | 
						|
            } else { | 
						|
                this.expand(); | 
						|
            } | 
						|
        }, | 
						|
 | 
						|
        _toggleLegend: function (legendDiv, layers) { | 
						|
            if (L.DomUtil.hasClass(legendDiv, "leaflet-legend-item-inactive")) { | 
						|
                L.DomUtil.removeClass(legendDiv, "leaflet-legend-item-inactive"); | 
						|
                if (L.Util.isArray(layers)) { | 
						|
                    for (var i = 0, len = layers.length; i < len; i++) { | 
						|
                        this._map.addLayer(layers[i]); | 
						|
                    } | 
						|
                } else { | 
						|
                    this._map.addLayer(layers); | 
						|
                } | 
						|
            } else { | 
						|
                L.DomUtil.addClass(legendDiv, "leaflet-legend-item-inactive"); | 
						|
                if (L.Util.isArray(layers)) { | 
						|
                    for (var i = 0, len = layers.length; i < len; i++) { | 
						|
                        this._map.removeLayer(layers[i]); | 
						|
                    } | 
						|
                } else { | 
						|
                    this._map.removeLayer(layers); | 
						|
                } | 
						|
            } | 
						|
        }, | 
						|
 | 
						|
        expand: function () { | 
						|
            this._link.style.display = "none"; | 
						|
            L.DomUtil.addClass(this._container, "leaflet-legend-expanded"); | 
						|
            for (var legendSymbol of this._legendSymbols) { | 
						|
                legendSymbol.rescale(); | 
						|
            } | 
						|
            return this; | 
						|
        }, | 
						|
 | 
						|
        collapse: function () { | 
						|
            this._link.style.display = "block"; | 
						|
            L.DomUtil.removeClass(this._container, "leaflet-legend-expanded"); | 
						|
            return this; | 
						|
        }, | 
						|
 | 
						|
        redraw: function () { | 
						|
            L.DomUtil.empty(this._contents); | 
						|
            this._buildLegendItems(); | 
						|
        }, | 
						|
    }); | 
						|
 | 
						|
    L.control.legend = L.control.Legend = function (options) { | 
						|
        return new L.Control.Legend(options); | 
						|
    }; | 
						|
}, window);
 | 
						|
 |