1.大量点标记的处理(点聚合||海量点)
普通点标记 Marker 是一个个 dom,当 Marker 太多时内存占用过高,页面会卡顿,可采用两种优化方案:
示例:点聚合-点标记-示例中心-JS API 示例 | 高德地图API
// 聚合渲染
? ?renderCluster() {
? ? ?this.curVisibleType.map(type => {
? ? ? ?this.dataMap[type].map(item => {
? ? ? ? ?const marker = new AMap.Marker({
? ? ? ? ? ?offset: new AMap.Pixel(this.markerOffset.x, this.markerOffset.y),
? ? ? ? ? ?extData: { ...item, type },
? ? ? ? ? ?position: item.position,
? ? ? ? ? ?content: this.setCabinet(this.typeMap[type], item.hasCount)
? ? ? ? });
? ? ? ? ?marker.on("click", this.handleMarkerClick);
? ? ? ? ?this[`markers${type}`].push(marker);
? ? ? });
?
? ? ? ?this[`cluster${type}`] = new AMap.MarkerClusterer(
? ? ? ? ?this.mapInst,
? ? ? ? ?this[`markers${type}`],
? ? ? ? {
? ? ? ? ? ?gridSize: 80,
? ? ? ? ? ?maxZoom: 18,
? ? ? ? ? ?renderClusterMarker: ({ count, marker, markers }) => {
? ? ? ? ? ? ?this.customClusterMarker({ count, marker, markers }, type);
? ? ? ? ? }
? ? ? ? }
? ? ? );
? ? });
? }
注意 :海量点图层的创建、显隐、事件、自定义样式是否能达到需求效果
//创建海量点柜机图层
? ?createMassMarks(index, data, type) {
? ? ?let styleObjectArr = [
? ? ? {
? ? ? ? ?size: new AMap.Size(24, 24), // 图标大小
? ? ? ? ?anchor: new AMap.Pixel(12, 12), // 图标显示位置偏移量,基准点为图标中心
? ? ? ? ?url: require('@/assets/img/siteSel/usual-cabinet.svg')
? ? ? }, //不动
? ? ? {
? ? ? ? ?size: new AMap.Size(24, 24),
? ? ? ? ?anchor: new AMap.Pixel(12, 12),
? ? ? ? ?url: require('@/assets/img/siteSel/add-cabinet.svg')
? ? ? }, //扩容
? ? ? {
? ? ? ? ?size: new AMap.Size(24, 24),
? ? ? ? ?anchor: new AMap.Pixel(12, 12),
? ? ? ? ?url: require('@/assets/img/siteSel/sub-cabinet.svg')
? ? ? }, //缩容
? ? ? {
? ? ? ? ?size: new AMap.Size(24, 24),
? ? ? ? ?anchor: new AMap.Pixel(12, 12),
? ? ? ? ?url: require('@/assets/img/siteSel/zero-cabinet.svg')
? ? ? }, //0周转
? ? ? {
? ? ? ? ?size: new AMap.Size(20, 20),
? ? ? ? ?anchor: new AMap.Pixel(10, 10),
? ? ? ? ?url: require('@/assets/img/siteSel/nerveCabinet.svg')
? ? ? } //最优普通||图神经普通
? ? ];
? ? ?let massMarksList = new AMap.MassMarks(data, {
? ? ? ?cursor: 'pointer',
? ? ? ?style: styleObjectArr,
? ? ? ?zIndex: index, // 海量点图层叠加的顺序
? ? ? ?zooms: [3, 19] // 在指定地图缩放级别范围内展示海量点图层
? ? });
? }
效果图:
2.大量 polyline 时的处理
当地图内的 polyline 太多时,内存占用过高,页面会卡顿
解决思路:三重过滤数据:只加载可视区内的边->过滤太短的边->根据缩放等级确定加载量 缩放等级太低时加载少量边
let tmapBounds = this.mapInst.getBounds();
let southWest = new AMap.LngLat(
?tmapBounds.southwest.lng,
?tmapBounds.southwest.lat
);
let northEast = new AMap.LngLat(
?tmapBounds.northeast.lng,
?tmapBounds.northeast.lat
);
?
//绘制地图可视区域
let bounds = new AMap.Bounds(southWest, northEast);
this.rectangle = new AMap.Rectangle({
?bounds: bounds,
?strokeColor: "red",
?strokeWeight: 6,
?strokeOpacity: 0,
?strokeStyle: "dashed",
?fillColor: "blue",
?fillOpacity: 0,
?cursor: "pointer",
?zIndex: 50,
?bubble: true,
});
this.rectangle.setMap(this.mapInst);
?
type == 0 &&
(ary = ary.filter(
? (item) =>
? ? ?this.rectangle.contains(item.originPosition) ||
? ? ?this.rectangle.contains(item.endPosition)
)); //短物理边 两个端点在可视区内即加载
?
type == 1 &&
(ary = ary.filter(
? (item) =>
? ? ?this.rectangle.contains(item.originPosition) ||
? ? ?this.rectangle.contains(item.endPosition) ||
? ? ?AMap.GeometryUtil.doesSegmentRingIntersect(
? ? ? ?item.originPosition,
? ? ? ?item.endPosition,
? ? ? [
? ? ? ? ?southWest,
? ? ? ? ?northEast,
? ? ? ? [southWest.lng, northEast.lat],
? ? ? ? [northEast.lat, southWest.lng],
? ? ? ]
? ? )
)); //长频次边 两个端点在可视区内 或者 边与可视区交叉即加载
ary = ary.filter(item => this.calculateSideLength(item.originPosition, item.endPosition) > filterLength)
?
calculateSideLength(originPosition, endPosition) {
//计算边长度
? ? ?let originLnglat = new AMap.LngLat(originPosition[0], originPosition[1]);
? ? ?let originPixel = this.mapInst.lngLatToContainer(originLnglat);
?
? ? ?let endLnglat = new AMap.LngLat(endPosition[0], endPosition[1]);
? ? ?let endPixel = this.mapInst.lngLatToContainer(endLnglat);
?
? ? ?let length = Math.sqrt(Math.pow(originPixel.x - endPixel.x, 2) + Math.pow(originPixel.y - endPixel.y, 2));
?
? ? ?return length;
}
let num = zoom >= 17 ? ary.length : ary.length > baseNum ? baseNum : ary.length;
?
[type == 0 || (type == 1 && zoom <= 13)] && (ary = ary.splice(0, num));
效果图:
3.地理围栏为环多边形或多多边形时的处理
问题:某个区域有多个多边形块时,只有第一个块可点击 hover;
解决思路:
1.对于多个多边形块应循环数组直接绘制,对于环多边形,应建立二维数组
2.区分多多边形和环多边形:
效果图:
?
//地理围栏绘制和清除
? ?gridShow() {
? ? ?this.polygonList.length !== 0 && this.mapInst.remove(this.polygonList);
? ? ?if (this.gridActive) {
? ? ? ?this.polygonList = [];
? ? ? ?this.edList.map(item => {
? ? ? ? ?if (item.polygonNum == 1) {
? ? ? ? ? ?const polygon = this.createPolygon(item, item.polygonList);
? ? ? ? ? ?this.handlePolygon(polygon);
? ? ? ? } else {
? ? ? ? ? ?//某个区域有多个多边形块时 (解决多个多边形块只有第一个块可点击 hover的问题)
? ? ? ? ? ?let lengthAry = [];
? ? ? ? ? ?item.polygonList.map(item => {
? ? ? ? ? ? ?lengthAry.push(item.length);
? ? ? ? ? });
? ? ? ? ? ?let maxLength = Math.max(...lengthAry);
? ? ? ? ? ?let maxPolygonAry = item.polygonList.filter(item => item.length == maxLength); //最大多边形块的path数组
? ? ? ? ? ?let otherPolygonAry = item.polygonList.filter(item => item.length !== maxLength); //除最大多边形块的其他多边形块path数组
?
? ? ? ? ? ?const maxPolygon = this.createPolygon(item, maxPolygonAry); //最大多边形块
?
? ? ? ? ? ?otherPolygonAry.map(items => {
? ? ? ? ? ? ?if (maxPolygon.contains(items[0])) {
? ? ? ? ? ? ? ?//如果其他多边形块的点包含在最大多边形块里,说明 为环多边形 建立二维数组
? ? ? ? ? ? ? ?maxPolygonAry[maxPolygonAry.length] = items;
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ?//如果其他多边形块的点不包含在最大多边形块里,则直接绘制多边形块
? ? ? ? ? ? ? ?const polygon = this.createPolygon(item, items);
? ? ? ? ? ? ? ?this.handlePolygon(polygon);
? ? ? ? ? ? }
? ? ? ? ? });
? ? ? ? ? ?//绘制最终的最大多边形块 清除初始最大多边形块
? ? ? ? ? ?const maxPolygonEnd = this.createPolygon(item, maxPolygonAry);
? ? ? ? ? ?this.mapInst.remove(maxPolygon);
? ? ? ? ? ?this.handlePolygon(maxPolygonEnd);
? ? ? ? }
? ? ? });
? ? } else {
? ? ? ?this.polygonList.length !== 0 && this.mapInst.remove(this.polygonList);
? ? }
? }
|