使用vue和高德地图,仿58地图找房pc端,且解决marker过多卡顿
使用vue和高德地图,仿58地图找房pc端,且解决marker过多卡顿1.在index.html引入高德地图链接https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Geocoder,AMap.Autocomplete,AMap.PlaceSearch,AMap.InfoWindow2.https://webapi.
使用vue和高德地图,仿58地图找房pc端,且解决marker过多卡顿
1.在index.html引入高德地图链接
https://webapi.amap.com/maps?v=1.4.15&key=你的key&plugin=AMap.Geocoder,AMap.Autocomplete,AMap.PlaceSearch,AMap.InfoWindow
2.https://webapi.amap.com/demos/js/liteToolbar.js 工具栏
3.本来用vue3.0,写的,改成了html,可根据自己需求修改
源码地址 下载
最开始的思路:最开始是想用 高德地图点聚合来写(官网点聚合),但是点聚合聚合区域计算方式不适用省市区,或者是行政区划聚合(官网行政区划聚合),奈何小弟能力有限,很多事件都想控制,但是找不到。。。
最后思路:后来想到,可以搞个假的聚合,像聚合就行啊。
- 在地图当前zoom层级小于8的时候 ,显示省级的marker标记点。
- 地图 8<=zoom<=10 的时候,清空地图上的marker标记,显示市级的标记点
- 地图 10<zoom<14 的时候,清空地图上的marker标记,显示区级的标记点
- 地图 zoom>=14 的时候,清空地图上的marker标记,显示门店的标记点
- 当门店数据过多,一次性加载在地图上,肯定会卡顿很长时间,那我们就利用地区的可视区域AMap.GeometryUtil.isPointInRing()方法,如果门店经纬度在可视区域,才在地图上加载marker.
先上效果图
好了现在根据思路来一步步实现
- 首先先实现清除地图上的所有marker方法和判断经纬度是否在可视区域的方法
//清除marker标记
function clearMarker() {
map.clearMap()
}
/**规划处地图的可视范围,且判断经纬度是否在当前可视区域
* @param {string} center
* @returns {Boolean}
*/
function logMapBounds(center) { center是经纬度字符串,用","拼接
var point= center.split(',')
var bounds = map.getBounds();
const NorthEast = bounds.getNorthEast();
const SouthWest = bounds.getSouthWest();
const SouthEast = [NorthEast.lng, SouthWest.lat];
const NorthWest = [SouthWest.lng, NorthEast.lat];
const path = [[NorthEast.lng, NorthEast.lat], SouthEast, [SouthWest.lng, SouthWest.lat], NorthWest]
return AMap.GeometryUtil.isPointInRing(point,path);
}
2.点击省市区marker转到相应层级和显示对应marker
//点击省,到市级,点击市到区级,点击区到门店
function showInfoM (e){
let level=map.getZoom()
let zooms,centers;
if(level<8){
zooms=8
}else if(level>=8&&level<11){
zooms=11
}else if(level>=11&&level<15){
zooms=15
}
centers=[e.target.Ce.position.lng,e.target.Ce.position.lat]
map.setCenter(centers)
map.setZoom(zooms)
}
3.由于省市区的marker一样,所以创建省市区的marker
creatMarker(data) 里面的data是请求后台接口返回的数据
数据格式 data:[{
baseAreaCenter: "116.405285,39.904989",
baseAreaCode: "11",
baseAreaName: "北京市", //省code
count: 5
}]
//添加省级或市级或区级marker
function creatMarker(data){ //data数据格式见上面代码块
clearMarker()
for(let i=0;i<data.length;i++){
var div=`<div class="circle" center=${data[i].baseAreaCenter}>
<div>
<div>${data[i].baseAreaName} </div><div>${data[i].count}</div>
</div>
</div>`
if(logMapBounds(data[i].baseAreaCenter)){
markers = new AMap.Marker({
content:div,
areaCode:data[i].baseAreaCode,
position:data[i].baseAreaCenter.split(","),
offset: new AMap.Pixel(-24, 5),
zIndex: data[i].count,
map:map
});
markers.on('click', showInfoM); //省市区marker点击事件 见代码快2的showInfoM方法
}
}
}
4.增加门店的marker
//创建门店marker
function creatShopMarker(data){
clearMarker()
for (var i = 0; i < data.length; i++) {
if(logMapBounds(data[i].baseAreaCenter)){
var marker = new AMap.Marker({
position: data[i].baseAreaCenter.split(','),
icon: require('@/assets/marker.svg'),
size:[32,43],
imageSize: new AMap.Size(32,43),
map: map
});
marker.content =`<div><span style="color:#31C0FD">${data[i].brandName}</span> ${data[i].storesAreaName}</div>`;
marker.on('click', markerClick);
}
}
}
//点击门店marker时触发的事件
function markerClick(e){
infoWindow.setContent(e.target.content);
infoWindow.open(map, e.target.getPosition());
}
5.当地图缩放和左右平移的时候 都要重新渲染地图上的marker
const init = () => {
//初始化地图容器
marker, map = new AMap.Map("container", {
resizeEnable: true,
zoom: 5,
zooms: [5, 18],
center: [106.49, 34.6],
});
AMap.plugin(['AMap.ToolBar','AMap.Scale','AMap.ControlBar'],function(){
//创建放大缩小控件
map.addControl(new AMap.ToolBar({
position:'RB', //定位在地图右下角
locate:false, //不显示定位按钮
ruler:true,//显示定位按钮标尺
direction:false, //不显示移动按钮
offset:new AMap.Pixel(59,24)
}));
//比例尺控件
map.addControl(new AMap.Scale());
// 添加 3D 罗盘控制
map.addControl(new AMap.ControlBar({
showZoomBar:false,//不显示缩放按钮
showControlButton:false //不显示显示倾斜、旋转按钮
}));
})
//创建信息窗体
infoWindow = new AMap.InfoWindow({offset: new AMap.Pixel(0, -30)});
//map绑定滚动结束事件
map.on('zoomend', mapZoomend);
//map拖拽结束事件
map.on('moveend', mapMoveEnd);
//首次加载省的marker
creatMarker(state.provinces)
};
6.地图缩放对应事件和地图平移缩放事件
//地图层级放大缩小的事件
function mapZoomend(){
let level=map.getZoom()
state.level=level
if(level<8){
getCurrentProMap().then(res=>{
if(res.code==200){
clearMarker()
creatMarker(state.provinces)
}
})
}else if(level>=8&&level<=10){
getCurrentCityMap().then(res=>{
if(res.code==200){
clearMarker()
creatMarker(state.citys)
}
})
}else if(level>10&&level<14){
getCurrentAreaMap().then(res=>{
if(res.code==200){
clearMarker()
creatMarker(state.areas)
}
})
}else if(level>=14){
getCurrentStoreMap().then(res=>{
if(res.code==200){
clearMarker()
creatShopMarker(state.shop)
}
})
}
}
//地图拖动结束时的事件
function mapMoveEnd(){
let level=map.getZoom()
state.level=level
clearMarker()
if(level<8){
creatMarker(state.provinces)
}else if(level>=8&&level<=10){
creatMarker(state.citys)
}else if(level>10&&level<14){
creatMarker(state.areas)
}else if(level>=14){
creatShopMarker(state.shop)
}
}
7.接下来是请求省市区门店四个接口,可根据自己的 公司需求修改
//获取省的数据
const getCurrentProMap=()=>{
return new Promise((resolve,reject)=>{
let params={
enterpriseCode:state.enterpriseCode
}
getProvinceMap(params).then(res=>{
if(res.code==200){
state.provinces=res.data
}
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
//获取市的数据
const getCurrentCityMap=()=>{
return new Promise((resolve,reject)=>{
let params={
enterpriseCode:state.enterpriseCode
}
getCityMap(params).then(res=>{
state.citys=res.data
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
//获取区的数据
const getCurrentAreaMap=()=>{
return new Promise((resolve,reject)=>{
let params={
enterpriseCode:state.enterpriseCode
}
getAreaMap(params).then(res=>{
state.areas=res.data
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
//获取品牌门店数据
const getCurrentStoreMap=(data)=>{
return new Promise((resolve,reject)=>{
let params={
enterpriseCode:state.enterpriseCode,
}
if(data)params.baseAreaCode=data
else delete params.baseAreaCode
getStoreMap(params).then(res=>{
state.shop=res.data
resolve(res)
}).catch(err=>{
reject(err)
})
})
}
更多推荐
所有评论(0)