一、封装leafletMap
import "leaflet.markercluster";
class LeafletMap {
constructor() {
const a = this;
a.config = {
domId: "container",
center: [33.25, 113.52],
zoom: 8,
zoomSnap: 8.5, //地图缩放级别,支持小数,但会影响地图缩放
zoomControl: false, //禁止缩放
touchZoom: false, //禁止触摸
scrollWheelZoom: false, //禁止鼠标滚轮
dragging: false, //禁止拖拽
};
}
init(config) {
const a = this;
a.config = { ...a.config, ...config,
renderer: L.canvas() // 或者 L.svg()
};
a.map = L.map(a.config.domId, a.config);
return a.map;
}
// 高德离线图层
addGDLayers(url) {
const a = this;
if (!configItem.tmsLayer) {
L.tileLayer(
"http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}" //在线高德地图
// "http://webst02.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8" //在线高德卫星图
).addTo(a.map);
} else {
L.tileLayer(
configItem.tmsLayer , {
/*minZoom: 1,
maxZoom: 14,*/
}
).addTo(a.map);
}
}
// 百度离线图层
addBDLayers(url) {
const a = this;
L.tileLayer(
url || "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" //在线百度地图
).addTo(a.map);
}
//标准tms图层
addTMSLayers(url, config = {}) {
const a = this;
const CRS_900913 = new L.Proj.CRS(
"EPSG:3395",
"+proj=merc +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs",
{
resolutions: [
156543.032, 78271.516, 39135.758, 19567.879, 9783.9395, 4891.96975,
2445.984875, 1222.9924375, 611.49621875, 305.748109375, 152.874054688,
76.437027344, 38.218513672, 19.109256836, 9.554628418, 4.777314209,
2.388657104, 1.194328552, 0.597164276, 0.298582138, 0.149291069,
0.074645535,
] /*(function () {
var level = 19;
var res = [];
res[0] = Math.pow(2, 18);
for (var i = 1; i < level; i++) {
res[i] = Math.pow(2, 18 - i);
}
console.log(res);
return res;
})()*/,
// origin: [0, 0],
// bounds: L.bounds([20037508.342789244, 0], [0, 20037508.342789244]),
origin: [7340032.00000000372529, -0.00000003068298],
bounds: L.bounds(
[7340032.00000000372529, -0.00000003068298],
[141.291239704979603, 7340032.089508121833205]
),
}
);
config.crs = CRS_900913;
console.log(url);
L.tileLayer(url, config).addTo(a.map);
}
//绘制行政边界(geojson)
addBounds(response, myStyle) {
const a = this;
!myStyle && (myStyle = { color: "#ff7800" });
// Add to layer
var layer = L.geoJSON(response, {
style: myStyle,
}).addTo(a.map);
return layer;
}
// 矢量图层(折线)
addPolylineLayers(latlngs, color, className = "") {
const a = this;
!latlngs &&
(latlngs = [
[45.51, -122.68],
[37.77, -122.43],
[34.04, -118.2],
]);
var polyline = L.polyline(latlngs, {
color: color || "red",
className: className, //类名
weight: 2, //线条宽度
}).addTo(a.map);
//将地图放大到折线
a.map.fitBounds(polyline.getBounds());
}
// 矢量图层(圆)
addCircleLayers(latins, className = "") {
const a = this;
latins = [33.25, 113.52];
L.circle(latins, {
radius: 200,
fillColor: "red", //填充色
fillOpacity: 0.5, //填充透明度 默认0.2
color: "yellow", //描边色
className: className, //类名
}).addTo(a.map);
}
//矢量图层(小图标)
addIconLayers(latlng, config = {}, data, className = "", callback) {
const a = this;
!latlng && (latlng = [33.5, 113.5]);
var obj = {
iconUrl: "../../assets/images/vertices.png",
iconSize: [30, 30],
// iconAnchor: [22, 94], //图标尖端坐标
// popupAnchor: [-3, -76], //弹出窗口“打开”的点相对于图标锚点的坐标
// shadowUrl: "my-icon-shadow.png", //阴影图像
// shadowSize: [68, 95], //阴影图像的大小
// shadowAnchor: [22, 94], //阴影“尖端”的坐标
className: className,
data: data,
};
obj = { ...obj, ...config };
var myIcon = L.icon(obj);
let marker = L.marker(latlng, { icon: myIcon }).on("click", function (e) {
callback(e);
}).addTo(a.map)
return marker;
// L.marker(latlng).addTo(a.map); //标记点
}
//矢量图层聚合
addClusterLayer() {
const a = this;
const markerClusterLayer = L.markerClusterGroup({
showCoverageOnHover: false, // 为true时,当鼠标悬停在点上时,它会显示它聚合的边界
zoomToBoundsOnClick: true, // 为true时,当鼠标点击某个点时,会缩放到它的边界范围
chunkedLoading: true,
maxClusterRadius: 50, // 聚类从中心标记覆盖的最大半径(以像素为单位),默认值 80
// disableClusteringAtZoom: 10 // 在缩放级别10及以下不进行聚合
}).addTo(a.map);
return markerClusterLayer;
}
//矢量图层(文本)同上,可以canvas绘制
addTextLayer(latlng, text, className = "my-div-icon", callback) {
const a = this;
!latlng && (latlng = [33.5, 113.5]);
// 创建自定义图标并添加文本
var customIcon = L.divIcon({className, html: '<span>'+text+'</span>'});
var marker = L.marker(latlng, {className,icon: customIcon})//.addTo(a.map);
return marker;
}
//添加大量的文本 使用canvas
addLayerUseCanvas (latlng, text) {
L.canvas().addLayer(L.marker(latlng).bindPopup(text));
}
//图像图层
ImageLayers(imageUrl, imageBounds, className = "") {
const a = this;
// var imageUrl = "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg",
// imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
var imageLayer = L.imageOverlay(imageUrl, imageBounds, {
opacity: 1, //图像透明度
interactive: true, //为true时
zIndex: 0, //显示层级
className: className, //类名
}).addTo(a.map);
return imageLayer;
}
//移除图层根据类名
removeLayersByAttr(className) {
var layers = this.getAllLayers(this.map);
for (var l in layers) {
if (layers[l].options.className == className) layers[l].remove();
}
}
//移除图层
removeLayers(layer) {
layer.remove();
}
//获取全部图层
getAllLayers(map) {
var allLayers = map._layers;
return allLayers;
}
//标记点绑定弹窗
markWithPopup(marker, popupContent) {
popupContent = "<p>Hello world!<br />This is a nice popup.</p>";
marker.bindPopup(popupContent).openPopup();
}
//弹窗
popupBox(latlng) {
const a = this;
latlng = [33.5, 113.5];
var popup = L.popup()
.setLatLng(latlng)
.setContent("<p>Hello world!<br />This is a nice popup.</p>")
.openOn(a.map);
return popup;
}
//关闭弹窗
closePopupBox(popup) {
popup.closePopup();
}
//交互事件
addMapEvent() {
const a = this;
a.map.on("click", function (e) {
var latlng = e.latlng, //经纬度
_taget = e.target, //target
pos = e.layerPoint || e.containerPoint; //屏幕位置
console.log(latlng, _taget, pos);
});
}
//移除交互事件
removeMapEvent() {
const a = this;
a.map.off("click", function (e) {
console.log(e);
});
}
}
export { LeafletMap };
二、vue引用
<template> <div class="index"> <div class="map" id="mapContainer"></div> </div> </template> <script> import { LeafletMap } from "@/utils/leafletMap.js"; export default { data() { return { areaCode:10, LMap: null, divMap: null, //地图map pointMarker: null, markClusterLayer: null, //聚合 allMarkers: [], //要聚合的点图层 }; }, mounted() { this.initMap(); }, // 方法集合 methods: { initMap() { let dom = document.getElementById("mapContainer"); dom.innerHTML = ""; this.LMap = new LeafletMap(); let Areacode = this.areaCode, { center, zoom, minZoom, maxZoom } = configItem.mapConfig[Areacode]; this.divMap = this.LMap.init({ domId: "mapContainer", center: [center[1], center[0]], zoom: zoom, minZoom, maxZoom, }); this.LMap.addGDLayers(); this.markClusterLayer = this.LMap.addClusterLayer(); this.mapClick(); this.mapZoomEnd(); this.areaBoundary(); }, //行政边界 areaBoundary() { const env = process.env.NODE_ENV; var str = env === "development" ? "/" : "../"; var jsonUrl = common.getStaticFile( str + "static/areaJson/" + this.areaCode + ".json" ); axios.get(jsonUrl).then((xcJson) => { var myStyle = { color: "#000", fillColor: "transparent", weight: 2, fillOpacity: 1, }; this.LMap.addBounds(xcJson.data, myStyle); }); }, //行政名称 addAreaName() { const env = process.env.NODE_ENV; var str = env === "development" ? "/" : "../"; var jsonUrl = common.getStaticFile( str + "static/areaPoint/" + this.areaCode + ".json" ); axios .get(jsonUrl) .then((res) => { res.data.forEach((item) => { var marker = this.LMap.addTextLayer( item.latlng, item.label, "areaName" ); this.divMap.addLayer(marker); this.areaNameLayers.push(marker); }); }) .catch((e) => console.log(e)); }, mapClick() { const env = process.env.NODE_ENV; var str = env === "development" ? "/" : "../"; var jsonUrl = common.getStaticFile( str + "static/areaPolygon/" + this.areaCode + ".json" ); axios.get(jsonUrl).then((jsonData) => { this.areaPolygon = jsonData.data; this.divMap.on("click", (event) => { this.removePoint(); let { lat, lng } = event.latlng; var pt = turf.point([lng, lat]); var poly = turf.polygon(this.areaPolygon); var isTrue = turf.booleanPointInPolygon(pt, poly); if (isTrue) { //添加点图层 this.pointMarker = this.LMap.addIconLayers([lat, lng], { iconUrl: common.getAssetsFile("pos.png"), }); this.$refs.ForecastBox.DialogVisible = true; this.$refs.ForecastBox.loadData(lng, lat); } }); }); }, mapZoomEnd() { // 监听地图缩放后重新聚合 this.divMap.on("zoomend", (e) => { // var zoom = this.divMap.getZoom(); if (this.allMarkers.length > 0 && this.markClusterLayer) { this.markClusterLayer.clearLayers(); // 清除所有标记后重新添加以触发重新聚合 this.markClusterLayer.addLayers(this.allMarkers); } }); }, //等值面图|格点值 changeShowWay(ybTime) { //清除图层 if (this.dztLayer) { this.LMap.removeLayers(this.dztLayer); this.dztLayer = null; } if (this.sztLayer) { this.LMap.removeLayers(this.sztLayer); this.sztLayer = null; } if (this.areaNameLayers.length > 0) { this.areaNameLayers.forEach((layer) => { this.LMap.removeLayers(layer); //移除图层 }); this.areaNameLayers = []; } this.legendData = []; //移除聚合点 this.markClusterLayer.clearLayers(); }, //加载格点数值 loadGridData(resData, unit) { let { Data: gridData, MaxLat, MaxLon, MinLat, MinLon, Width, Height, } = resData; var dx = (MaxLon - MinLon) / Width, dy = (MaxLat - MinLat) / Height; var numArray = []; const env = process.env.NODE_ENV; var str = env === "development" ? "/" : "../"; var jsonUrl = common.getStaticFile( str + "static/mapPoint/" + this.areaCode + ".json" ); axios.get(jsonUrl).then((jsonData) => { var mapData = jsonData.data, layers = []; for (var i = 0; i < gridData.length; i++) { var row = gridData[i]; for (var j = 0; j < row.length; j++) { var text = row[j], x = j, y = gridData.length - i - 1; if (text < 99999 && mapData[y][x] == 1) { var latlng = [MinLat + dy * i, MinLon + dx * j]; var layer = this.LMap.addTextLayer( latlng, text + unit, "divText" ); layers.push(layer); // numArray.push({ label: text, x, y }); } } } this.allMarkers = layers; this.markClusterLayer.addLayers(layers); if (numArray.length > 0) { var canvas = document.createElement("canvas"), ctx = canvas.getContext("2d"), textW = 70, textH = 50, sumW = Width * textW, sumH = Height * textH; canvas.width = sumW; canvas.height = sumH; for (var o of numArray) { ctx.fillStyle = "#000"; // 设置文本颜色为白色 ctx.font = "20px Arial"; // 设置字体大小和类型 ctx.textAlign = "center"; // 设置文本对齐方式为居中 ctx.textBaseline = "middle"; // 设置文本基线为中间 var value = o.label, text = value < 99999 ? value + unit : ""; text && ctx.fillText( text, (o.x - 0.5) * textW + textW / 2, (o.y + 1.2) * textH + textH / 2 ); // 在矩形中心绘制文本"Hello, Canvas!" } var imageUrl = canvas.toDataURL("image/png"); var imageBounds = [ [MinLat, MinLon], [MaxLat, MaxLon], ]; this.dztLayer = this.LMap.ImageLayers(imageUrl, imageBounds, "szt"); } }); }, //移除图标点 removePoint() { if (this.pointMarker) { this.LMap.removeLayers(this.pointMarker); this.pointMarker = null; } }, }, watch: {}, }; </script> <style rel="stylesheet/less" lang="less" scoped> .map{width:100%;height:100%;} </style>