IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 高德地图的开发实践 -> 正文阅读

[JavaScript知识库]高德地图的开发实践

1.大量点标记的处理(点聚合||海量点)

普通点标记 Marker 是一个个 dom,当 Marker 太多时内存占用过高,页面会卡顿,可采用两种优化方案:

  • 点聚合:设置 gridSize,相邻点进行聚合,减少 dom 数

示例:点聚合-点标记-示例中心-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);
 ? ? ? ? ?  }
 ? ? ? ?  }
 ? ? ?  );
 ? ?  });
 ?  }
  • 海量点:将同类点绘制到一个 canvas 图层里,提升性能,解决卡顿

注意 :海量点图层的创建、显隐、事件、自定义样式是否能达到需求效果

//创建海量点柜机图层
 ? ?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.区分多多边形和环多边形:

  • 获取最大多边形块的 path 数组和除最大多边形块的其他多边形块 path 数组;

  • 遍历除最大多边形块的其他多边形块 path 数组,包含在最大多边形块里则为环多边形, 否则为多多边形

效果图:

?

 //地理围栏绘制和清除
 ? ?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);
 ? ?  }
 ?  }

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:38:22  更:2022-02-07 13:39:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:14:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码