在开发带有地图的项目中我使用到了百度地图、高德地图、还有谷歌地图、说起来真令人心酸.
最近开发项目因为需要使用到地图展示每个设备的具体位置,但是每个设备的点非常的密集,然后使用到了地图的点聚合,将地图上密集的点聚合成一个圆,并且移动到点上可以查看这个设备点的一些信息,点击点可以进入设备的详细信息中.
- 一开始我使用的是项目之前使用的百度地图,以前的老项目是使用jq写的,后面我使用vue重构,使用到了vue百度地图插件,一开始还好好的,但是发布到生产环境的时候却出现了问题,大概设备的点达到了3000左右的时候,网页会出现非常明显的卡顿与未响应.
后来我前往github上查找原因,原来出现这个问题的不止我一个人,有人推荐海量点,但是海量点并不符合我的业务要求,查看百度地图文档,发现官方的点聚合例子在点超过千位也会出现卡死的状态,遂放弃百度地图.
正好高德地图也有点聚合的例子,高德地图也封装了vue的地图插件,这次我小心了起来,先去文档中查看例子,发现大概超过3000点也会出现卡死的状态.
然后去高度地图官方文档查看,几万点加载完全无压力,然后我开始使用了高德地图.
好了,我分享我的使用方法:
- 首先在我们的index.html中引入高德地图cdn js文件
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.14&key=你申请的key"></script>
- 将高德地图写成一个组件,创建一个
.vue
文件<div class="map" id="container"></div> //记得给map高度哦 .map { width: 100%; margin: 0.2rem auto 0 auto; display: inline-block; height: 88vh; }
//创建点 mapObj=new AMap.Map('container', {//'map-location'是对应页面盒子的id resizeEnable: true, center: [105, 34], zoom: 4, zooms:[3,20], expandZoomRange:true, //添加下面这行代码能缩小到10米哦 viewMode:'3D' })
//创建信息窗体实例 infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -10)});
//获取到所有的点 getDeviceAddressList(this.offset,this.limit) .then((res)=>{ res.data.data.list.forEach(element => { marker=new AMap.Marker({ position: [element.deviceLongitude,element.deviceLatitude],//每个点的经纬度 //自定义点的图标 content: '<img src="https://webapi.amap.com/theme/v1.3/markers/n/mark_bs.png" class="markericon" />', offset: new AMap.Pixel(-15, -15), //你如果需要在点里面添加其他信息 deviceId:element.deviceId, deviceSn:element.deviceSn, deviceName:element.deviceName, deviceAddress:element.deviceAddress })
//信息窗口需要显示的内容 marker.content=`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p> <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p> <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>` //动态添加移入移出事件 marker.on('mouseover', this.markeronmouseover) marker.on('mouseout',this.markeronmouseout) marker.on('click',this.routerpush) //添加到海量点聚合 markers.push(marker) });
//最后实例化点聚合 mapObj.plugin(["AMap.MarkerClusterer"],()=> { cluster = new AMap.MarkerClusterer( mapObj, // 地图实例 markers, // 海量点组成的数组 ) })
因为地图函数作用域的原因我们在在export default
外定义这些变量
let mapObj=null
let marker=null
let markers=[]
let cluster=null
let infoWindow=null
高德地图就这样完成了,你认为这就结束了?哈哈,如果是国外的用户使用我们的项目呢?高德地图能显示国外吗?答案是不能,国外黑乎乎的一片.
然后我使用了谷歌地图,你问我为什么不直接使用谷歌地图?虽然谷歌地图有国内的源,但是在国内谷歌地图不如高德地图,显示的详细位置没有谷歌地图准确,当然我们的用户也大多是国内的.
还是一样的,在index.html中引入谷歌地图(需要科学上网才能显示出来哦,并且谷歌地图并不是免费的哦,每月有200美元的免费使用,设置好上限即可)
- 还是先引入js文件.
<script src="https://maps.googleapis.com/maps/api/js?&key=你申请的key"></script> //谷歌地图点聚合插件 <script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
2.创建
.vue
文件
<div id="map"></div>
//记得加上宽度和高度
#map{
width: 100%;
margin: 0.2rem auto 0 auto;
display: inline-block;
height: 88vh;
}
- 还是在
export default
外定义好我们的变量.let map=null let markers=[] let marker=null let labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ' let markerCluster=null let contentString='' let infowindow=null
//创建地图函数 initMap() { //清空所有数据 map=null markers=[] marker=null labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ' markerCluster=null contentString='' infowindow=null //创建地图 var uluru = {lat: 1.3238320056192325, lng: 103.84289822703454}; var map = new google.maps.Map(document.getElementById('map'), { zoom: 12, center: uluru, scaleControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP }); //信息窗体 infowindow = new google.maps.InfoWindow({ content: '' }); //获取后端设备经纬度等信息 getDeviceAddressList(this.offset,this.limit) .then((res)=>{ res.data.data.list.forEach((element,index)=>{ //创建点 marker = new google.maps.Marker({ position: {lat: Number(element.deviceLatitude) , lng: Number(element.deviceLongitude)}, map: map, //添加点的信息 con:`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p> <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p> <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>` }) //鼠标移入事件 marker.addListener('mouseover', ()=> { //如果语言被切换,重新给点的内容赋值 markers[index].con=`<p style="margin: 10px 0px 0px 0px;">${this.$t('lang.dashboard.Serials')}:${element.deviceSn}</p> <p>${this.$t('lang.dashboard.name')}:${element.deviceName}</p> <p>${this.$t('lang.dashboard.ADDRESS')}:${element.deviceAddress}</p>` // 将点的信息添加至信息窗体 infowindow.setContent(markers[index].con) //打开点 infowindow.open(map,markers[index]) }) //鼠标移出事件 marker.addListener('mouseout', ()=> { //关闭信息窗体 infowindow.close() }) //点击事件,点击跳转设备详细信息页面 marker.addListener('click',()=>{ this.$router.push({ name: 'Particulars', params: {id: element.deviceId} }) }) //将点push到聚合数组 markers.push(marker) }) //创建点聚合 markerCluster = new MarkerClusterer(map, markers, {imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'} ) }) }
谷歌地图也介绍完了,你看懂了吗?
Comments | NOTHING