海量地图数据处理
大约 5 分钟
海量地图数据处理
需求
上万条监测点数据显示在地图上,层级到达14级时,切换成灾害类型图标。
解决方案
由于数据过多直接添加marker数据的方式,会造成浏览器卡死的情况。经研究我们采用方案是小于14级时用天地图海量数据显示,,层级大于14级时,切换成灾害类型图标。
1.创建地图
初始化地图
initMap() {
// 创建地图实例
// map:用于显示地图的DIV对象。
// {},地图属性对象
this.Map = new T.Map("map", {
//projection:"EPSG:4326",
enableAutoResize: true,
});
// this.Map.centerAndZoom() 对地图进行初始化。未进行初始化的地图将不能进行任何操作。
var center = this.getCenter();
var point = new T.LngLat(center[0], center[1]);
this.Map.centerAndZoom(point, this.mapZoom || this.mapLevel); // 地图全局事件监听
this.mapEventListen(); // 设置地图区域
this.getProjectList(); // 获取项目列表
},
mapEventListen() {
let that = this;
var zoom;
// 监听地图事件缩放事件
this.Map.addEventListener("zoomend", function (e) {
zoom = this.getZoom();
if (zoom >= 14) {
that.isIconShow = true;
that.parseProjectListForMap(that.initProjectList, zoom);
} else if (that.isIconShow && zoom < 14) {
that.parseProjectListForMap(that.initProjectList, zoom);
}
});
// 监听地图移动事件
this.Map.addEventListener("moveend", function (e) {
if (zoom >= 14) {
that.isIconShow = true;
that.parseProjectListForMap(that.initProjectList, zoom);
}
});
},
},
};
2.地图数据显示
采用天地图地图组件,添加海量密集点解决3万多监测点显示问题
let lnglats = [];
var _CloudCollection;
for (var i = 0; i < projectList.length; i++) {
var ll = new T.LngLat(projectList[i].lon, projectList[i].lat);
lnglats.push(ll);
}
if (document.createElement("canvas").getContext) {
// 判断当前浏览器是否支持绘制海量点
_CloudCollection = new T.CloudMarkerCollection(lnglats, {
color: "blue",
SizeType: TDT_POINT_SIZE_SMALLER
});
this.Map.addOverLay(_CloudCollection);
} else {
alert("此示例目前只有在IE9及以上浏览器打开");
}
3.储存监测数据在本地,用于层级大于14时,只在当前可视区域显示图标。
采用RBush RBush-一个基于javascriptr-tree的高性能二维点和矩形空间索引
https://www.5axxw.com/wiki/content/7wjc4t
RBush安装rbush npm install rbush
引入RBush import RBush from "rbush";
创建树 const tree = new RBush();
存储监测数据到RBush
for (var i = 0; i < projectList.length; i++) {
var ll = new T.LngLat(projectList[i].lon, projectList[i].lat);
lnglats.push(ll);
let temp = {
minX: Number(projectList[i].lon),
minY: Number(projectList[i].lat),
maxX: Number(projectList[i].lon),
maxY: Number(projectList[i].lat),
foo: projectList[i]
};
treeList.push(temp);
}
tree.load(treeList);
if (document.createElement("canvas").getContext) {
// 判断当前浏览器是否支持绘制海量点
_CloudCollection = new T.CloudMarkerCollection(lnglats, {
color: "blue",
SizeType: TDT_POINT_SIZE_SMALLER
});
this.Map.addOverLay(_CloudCollection);
} else {
alert("此示例目前只有在IE9及以上浏览器打开");
}
this.isIconShow = false;
层级大于14时,先隐藏海量监测点
if (window._CloudCollection) {
window._CloudCollection.getPane().style.visibility = "hidden";
}
获取当前可视区域下的可视区域左下角 右上角,找出当前可视区域下的监测点,显示在地图上
var bs = this.Map.getBounds(); //获取可视区域
var bssw = bs.getSouthWest(); //可视区域左下角
var bsne = bs.getNorthEast(); //可视区域右上角
const result = tree.search({
minX: bssw.getLng(),
minY: bssw.getLat(),
maxX: bsne.getLng(),
maxY: bsne.getLat()
});
console.log(result,"当前可视区域下的监测点")
完整逻辑代码
var locations = [];
if (currentZoom >= 14) {
if (window._CloudCollection) {
window._CloudCollection.getPane().style.visibility = "hidden";
}
var bs = this.Map.getBounds(); //获取可视区域
var bssw = bs.getSouthWest(); //可视区域左下角
var bsne = bs.getNorthEast(); //可视区域右上角
const result = tree.search({
minX: bssw.getLng(),
minY: bssw.getLat(),
maxX: bsne.getLng(),
maxY: bsne.getLat()
});
let _this = this;
this.projectMarker.map(item => {
item._cache = false;
});
for (var i = 0; i < result.length; i++) {
let point = new T.LngLat(result[i].foo.lon, result[i].foo.lat);
let modeName = "";
let normalName = result[i].foo.extAttr3 || 5;
modeName = this.getProjectListType(result[i].foo.monitorObject);
let myIcon = new T.Icon({
iconUrl:
"/images/real-time/" + modeName + "-" + normalName + ".png",
iconSize: new T.Point(this.iconX, this.iconY),
iconAnchor: new T.Point(this.iconX / 2, this.iconY / 2)
});
// 创建标注对象并添加到地图
let marker = new T.Marker(point, {
icon: myIcon
});
locations.push(marker.getLngLat());
// 添加标注
marker._cache = true;
this.Map.addOverLay(marker);
// 为当前点添加事件
marker.addEventListener("click", function(data) {});
this.projectMarker.push(marker);
}
this.projectMarker.forEach(item => {
if (!item._cache) {
this.Map.removeOverLay(item);
}
});
} else {
// 清空14级以上marker
this.projectMarker.forEach(item => {
this.Map.removeOverLay(item);
});
if (!window._CloudCollection) {
let treeList = [];
let levels = [];
for (var i = 0; i < projectList.length; i++) {
var ll = new T.LngLat(projectList[i].lon, projectList[i].lat);
locations.push(ll);
levels.push(projectList[i].extAttr3 || "0");
let temp = {
minX: Number(projectList[i].lon),
minY: Number(projectList[i].lat),
maxX: Number(projectList[i].lon),
maxY: Number(projectList[i].lat),
foo: projectList[i]
};
treeList.push(temp);
}
tree.load(treeList);
if (document.createElement("canvas").getContext) {
// 判断当前浏览器是否支持绘制海量点
// 根据类型更改海量点颜色
// overTdt();
window._CloudCollection = new T.CloudMarkerCollection(locations, {
levels: levels,
color: "blue",
SizeType: TDT_POINT_SIZE_SMALLER
});
this.Map.addOverLay(window._CloudCollection);
} else {
this.$Message.warning("此示例目前只有在IE9及以上浏览器打开");
}
} else {
window._CloudCollection.getPane().style.visibility = "inherit";
}
this.isIconShow = false;
}