Fullstack Portal Created by the HCMR for the Marine Strategy Framework Directive Program in order to cover demands and aspects considering extendability and maintainability
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.

355 lines
13 KiB

2 years ago
(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);