背景
????????眾所周知,在GIS的世界里,圖例和地圖永遠(yuǎn)是一對(duì)一起出現(xiàn)的對(duì)象。在地圖上表示地理環(huán)境各要素,比如山脈、河流、城市、鐵路等所用的符號(hào)叫做圖例。這些符號(hào)所表示的意義,常注明在地圖的邊角上。圖例是表達(dá)地圖內(nèi)容的基本形式和方法,是現(xiàn)代地圖的語(yǔ)言,是讀圖和用讀所借助的工具。地圖符號(hào)一般包括各種大小、粗細(xì)、顏色不同的點(diǎn)、線、圖形等。符號(hào)的設(shè)計(jì)要能表達(dá)地面景物的形狀、大小和位置,而且還能反映出各種景物的質(zhì)和量的特征,以及相互關(guān)系。因此圖例常設(shè)計(jì)成與實(shí)地景物輪廓相似的幾何圖形。
?????????還有一些地圖,專門表示各種自然條件、工業(yè)分布等。在這些圖上,也必然有相應(yīng)的圖例,說明某種符號(hào)代表某種森林,某種符號(hào)代表某種礦產(chǎn),某種符號(hào)代表某種工業(yè),等等。讀圖之前,先把圖例中的地圖符號(hào)和注記的意義弄清楚,對(duì)于正確理解地圖內(nèi)容就方便多了??梢赃@樣說,圖例是讀圖的“線索”,方便用戶按圖索驥。
?????????在之前的博文中,介紹了很多Leaflet的內(nèi)容,關(guān)于圖例的展示一直沒有涉及。本文簡(jiǎn)單講講在Leaflet中如何進(jìn)行圖例的展示,基于Leaflet.Legend進(jìn)行圖例的展示。通過講解Leaflet.Legend得集成,核心API的講解,讓您對(duì)Leaflet.Legend有一個(gè)基本的認(rèn)識(shí)和了解。
一、Leaflet.Legend簡(jiǎn)介
????????Leaflet本身是一個(gè)非常輕量級(jí)的前端組件,基于Leaflet有很多的擴(kuò)展插件,圍繞Leaflet的生態(tài)非常豐富。在Leaflet中的插件中,可以找到下面的插件列表內(nèi)容。
?1、Legend的開源協(xié)議
????????Leaflet.Legend是一個(gè)MIT協(xié)議,非常寬松的協(xié)議??煞判脑陧?xiàng)目中使用。Leaflet.Legend 是一個(gè) Leaflet 插件, 用于顯示圖例符號(hào)和切換相應(yīng)的疊加層的顯示.開源地址:Legend。
MIT License
Copyright (c) 2020 ptma@163.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
?2、Legend API介紹
????????打開src目錄下的leaflet.legend.js文件,這里是整個(gè)圖例類的源碼文件,如上圖所示的各個(gè)Symbol類都定義在這里。下面就這些類進(jìn)行深入的講解。
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();
},
????????上述代碼定義了創(chuàng)建圖例對(duì)象的各個(gè)屬性,具體的參數(shù)說明如下:
參數(shù)名稱 | 類型 | 默認(rèn)值 | 描述? |
position | String | topleft | 圖例控件位置 |
title | String | Legend | 圖例控件的標(biāo)題 |
opacity | Number | 1.0 | 圖例面板的透明度 |
legends | LegendSymbol[] | [] | [LegendSymbol](#legendsymbol) 圖例符號(hào)數(shù)組。 |
symbolWidth | Number | 24 | 圖例符號(hào)的寬度,以像素為單位 |
symbolHeight | Number | 24 | 圖例符號(hào)的高度,以像素為單位 |
column | Number | 1 | 圖例符號(hào)排列的列數(shù) |
collapsed | Boolean | false | 圖例面板是否默認(rèn)展開 |
????????LegendSymbol對(duì)象的定義如下:
參數(shù)名稱 | 類型 | 默認(rèn)值 | 描述 |
label | String | undefined | 圖例符號(hào)的文本標(biāo)簽。 |
type | String | undefined | 圖例符號(hào)的類型. 可以是image','circle','rectangle','polygon' 或 'polyline'。 |
url | String | undefined | 圖里圖片的 URL,僅用于 type 為 'image' 時(shí) |
radius | Number | undefined | 圓形圖例的半徑,以像素為單位,僅用于 type 為 'circle' 時(shí) |
sides | Number | undefined | 正多邊形的邊數(shù),僅用于 type 為 'polygon' 時(shí)。 |
layers | Layer | Layer[] | undefined,圖例符號(hào)關(guān)聯(lián)的疊加層. 關(guān)聯(lián)疊加層后可通過點(diǎn)擊圖例來(lái)切換相應(yīng)疊加層的可見性。 |
inactive | Boolean | undefined | 圖例符號(hào)是否為非激活的, 非激活的圖例會(huì)減淡顯示 |
stroke | Boolean | true | 是否繪制邊框 |
color | String | #3388ff | 邊框顏色 |
weight | Number | 3? | 邊框?qū)挾?/td> |
opacity | Number | 1.0 | 邊框透明度 |
lineCap | String | round | 指定如何繪制每一條線段末端的屬性。有 3 個(gè)可能的值,分別是:'butt','round' 或 ’square‘ |
lineJoin | String | round | 用來(lái)設(shè)置2個(gè)長(zhǎng)度不為0的相連部分(線段,圓弧,曲線)如何連接在一起的屬性(長(zhǎng)度為0的變形部分,其指定的末端和控制點(diǎn)在同一位置,會(huì)被忽略) |
dashArray | String | null | 控制用來(lái)描邊的點(diǎn)劃線的圖案范式 |
dashOffset | String | null | dash模式到路徑開始的距離 |
fill | Boolean | depends | 是否用顏色填充 |
fillColor | String | * | 填充色,默認(rèn)與邊框顏色相同 |
fillOpacity | Number | 0.2? | 填充透明度 |
fillRule | String | evenodd | 填充規(guī)則 |
二、Legend實(shí)例開發(fā)
????????有了上面對(duì)圖例API的基礎(chǔ)認(rèn)知之后,我們便可以進(jìn)行相應(yīng)的實(shí)例開發(fā)。下面將使用一個(gè)詳細(xì)的案例講解,來(lái)詳細(xì)說明Legend如何進(jìn)行深入開發(fā)。
1、新建html頁(yè)面
<!DOCTYPE html>
<html>
<head>
<title>Leaflet legend control</title>
<meta charset="utf-8" />
<style type="text/css">
body {
padding: 0;
margin: 0;
}
html,
body,
#map {
height: 100%;
}
</style>
<link rel="stylesheet" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<link rel="stylesheet" href="../src/leaflet.legend.css" />
<script type="text/javascript" src="../src/leaflet.legend.js"></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
2、創(chuàng)建Leaflet對(duì)象引用
var map = L.map("map", {
center: [29.797751134173065, 120.7012939453125],
zoom: 5
});
L.tileLayer('file:///D%3A/wzh_test/q0403/{z}/{x}/{y}.png', {
minZoom: 0,
maxZoom: 7,
tms: false,
attribution: '圖例功能測(cè)試-夜郎king'
}).addTo(map);
3、圖例定義
var marker = L.circleMarker(L.latLng(29.702368038541767, 120.47607421874999), {
radius: 6,
fillColor: "#ff0000",
color: "blue",
weight: 2,
opacity: 1,
fillOpacity: 0.6,
});
var latlngs = [
[
29.204918463909035,
119.6246337890625,
],
[
29.79358002272772,
120.27008056640624,
],
[
29.70087695780884,
120.2984046936035,
]
];
var polyline = L.polyline(latlngs, {
color: 'red'
}).addTo(map);
const legend = L.control.Legend({
position: "bottomleft",
collapsed: false,
symbolWidth: 24,
opacity: 1,
title:"圖例",
column: 2,
legends: [{
label: "位置",
type: "image",
url: "marker/marker-red.png",
}, {
label: "Marker2",
type: "image",
url: "marker/purple.png"
}, {
label: "Circle",
type: "circle",
radius: 6,
color: "blue",
fillColor: "#FF0000",
fillOpacity: 0.6,
weight: 2,
layers: [marker],
inactive: true,
}, {
label: "Real line",
type: "polyline",
color: "#FF0000",
fillColor: "#FF0000",
weight: 2,
layers: polyline
}, {
label: "Dotted line",
type: "polyline",
color: "#0000FF",
fillColor: "#0000FF",
dashArray: [5, 5],
weight: 2
}, {
label: "Rectangle",
type: "rectangle",
color: "#FF0000",
fillColor: "#FF0000",
weight: 2
}, {
label: "Square",
type: "polygon",
sides: 4,
color: "#FF0000",
fillColor: "#FF0000",
weight: 2
}, {
label: "Regular triangle",
type: "polygon",
sides: 3,
color: "#FF0000",
fillColor: "#FF0000",
weight: 2
}, {
label: "Regular polygon",
type: "polygon",
sides: 5,
color: "#FF0000",
fillColor: "#FF0000",
weight: 2
}]
})
.addTo(map);
4、展示效果
?????????點(diǎn)擊Circle圖例還可以進(jìn)行圖層的切換,默認(rèn)情況下,地圖上不展示這些信息,點(diǎn)擊之后會(huì)在地圖上添加相應(yīng)的圖層對(duì)象。
5、圖例調(diào)用過程
????????在源碼中進(jìn)行debug調(diào)試,觀察相應(yīng)的代碼如何執(zhí)行的。首先進(jìn)行Legend初始化,調(diào)用initialize方法,在這個(gè)方法中會(huì)將出入的參數(shù)進(jìn)行解析,然后再創(chuàng)建元素對(duì)象。
_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);
}
},
?????????在上面的代碼執(zhí)行過程中定義相應(yīng)的圖例對(duì)象,同時(shí)將對(duì)象放置到頁(yè)面元素中。下面重點(diǎn)看一下各個(gè)圖例對(duì)象是怎么進(jìn)行初始化的。
_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
);
}
},
?以上就是Legend圖例對(duì)象的主要執(zhí)行過程,有興趣的朋友可以把源碼clone到本地進(jìn)行深入研究。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-426821.html
總結(jié)
????????以上就是本文的主要內(nèi)容,本文簡(jiǎn)單講解在Leaflet中如何進(jìn)行圖例的展示。通過講解Leaflet.Legend的集成,核心API的講解,讓您對(duì)Leaflet.Legend有一個(gè)基本的認(rèn)識(shí)和了解。本文行文倉(cāng)促,難免有誤,歡迎批評(píng)指正。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-426821.html
到了這里,關(guān)于LeafLet加載自定義Legend的設(shè)計(jì)與實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!