海量标点,官方文档说,10万以下数据性能都可以很好。实际项目中,真实数据最多7千。自测5万左右的数据性能都是挺好的(坐标转换前)。
一、引入高德地图
通过vue-amap引入,npm安装:
import VueAMap from 'vue-amap';
Vue.use(VueAMap);
VueAMap.initAMapApiLoader({
key: 'YOUR_KEY',
plugin: ['AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType',...],
v: '1.4.15'//默认1.4.4,改为1.4.15,因为版本低会导致海量标点的rotation属性无效
});
二、兼容高德原生SDK
import VueAMap from 'vue-amap'
import { lazyAMapApiLoaderInstance } from 'vue-amap'
const amapManager = new VueAMap.AMapManager()
export default{
data(){
return{
massData:[],
massStyle:[],
mass:{},
amapManager,
events:{
init(o){
lazyAMapApiLoaderInstance.load().then(() => {
...
})
}
}
}
},
methods:{
...
}
}
三、创建MassMarks类
在地图加载完后创建MassMarks实例
lazyAMapApiLoaderInstance.load().then(() => {
//创建MassMarks类实例
const massMarks = new AMap.MassMarks([], {
zIndex: 1000,
zooms: [12, 18],
style: []
})
//将海量标点添加至地图实例
massMarks.setMap(o)
//添加点击事件
massMarks.on('click', (e) => {
console.log('e:',e)
})
// 将海量标点实例保存至全局
this.mass = massMarks
})
四、在websocket中接收数据
onMessage(e) { // 数据接收
const data = JSON.parse(e.data).data
if (!data) { // 没有数据
console.warn('websocket:', '未接收到小船数据')
this.$message.warning({
message: '未接收到小船数据',
center: true
})
return
}
this.getMassData(data)
}
五、处理数据(转换坐标)
调用高德API转换坐标,若需要转换的坐标太多(自测一次性转换1300左右个坐标就会不成功),需要先切割数组,分多次转换后再合并。
getMassData(data){
const dataArr = [] // 需转换的坐标数组
const initData = [] // 海量标点数据
const initStyle = [] // 海量标点样式
for (let i = 0; i < data.length; i++) {
dataArr.push([data[i].longitude, data[i].latitude])
initData.push({ lnglat: [], style: i, targetId: data[i].targetId })
initStyle.push({
url: require('@/assets/icon/boat2.svg'),
size: new AMap.Size(19, 19),
anchor: new AMap.Pixel(8, 8),
rotation: data[i].course
})
}
this.massData = initData
this.massStyle = initStyle
// 切割数组,每个1000
for (let i = 0; i < dataArr.length; i += 1000) {
path.push(dataArr.slice(i, i + 1000))
}
//发起转换坐标请求
const promises = path.map((item) => {
return this.convertFrom(item, 'gps')
})
Promise.all(promises).then((res) => {
const totalRes = res.reduce((total, item) => {
if (item.info === 'ok') {
return [...total, ...item.locations]
} else {
return total
}
}, [])
console.log('转换后的坐标:',totalRes)
...
this.creatMassMarkers(this.massData, this.massStyle)
})
},
convertFrom(path, type) {
return new Promise((resolve, reject) => {
AMap.convertFrom(path, type, function(status, result) {
if (result.info === 'ok') {
resolve(result)
}
})
})
}
六、给MassMarks类添加数据
methods:{
//向MassMarks类添加数据和样式
creatMassMarkers(data, style) {
this.mass.setData(data)
this.mass.setStyle(style)
}
}