1、基于uniapp搭建的微信小程序,效果图:
2、参考文档:
map | 微信开放文档、MapContext.initMarkerCluster(Object object) | 微信开放文档、MapContext.includePoints(Object object) | 微信开放文档、MapContext.on(string event, function callback) | 微信开放文档
3、实现关键点:
a.实现点聚合需要在添加点标记的时候设置joinCluster参数为true(map | 微信开放文档)微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/component/map.html#marker
b.map属性include-points缩放视野以包含所有给定的坐标点,仅限于地图初始化之前,地图初始化之后就不实现,需要调用MapContext.includePoints实现缩放视野以包含所有给定坐标点,代码在下方展示(MapContext.includePoints(Object object) | 微信开放文档)微信开发者平台文档https://developers.weixin.qq.com/miniprogram/dev/api/media/map/MapContext.includePoints.html
c.标记点marker必须包含id、longitude、latitude字段,并且生成点聚合的时候一定要把id数组也就是clusterId传过去
d.点位如果需要请求获取的话要在获取到数据再去调用点聚合新增标记点这些,不然初始页面是空数据
4、实现代码:
<template>
<view>
<map id="myMap" style="width: 100%; height: 100vh;" :latitude="latitude" :longitude="longitude" enable-zoom
enable-scroll @markertap="markertap"></map>
<view class="flex_c screenBox">
<image src="https://mp100.fengo.vip/fengo100/2024-07-23/1834c060-95e4-4b43-85c7-51bc08b14383.png"
mode="aspectFit" class="imgs"></image>
<view class="font_size32">筛选</view>
</view>
<view class="pointBox">
<view class="list" v-for="(item,index) in pointList" :key="index">
<image :src="item.url" mode="aspectFit" class="imgs"></image>
<view class="">{{item.name}}</view>
</view>
</view>
</view>
</template>
<script>
import {
getAllOnLineWorkerList
} from '@/api/worker.js'
export default {
data() {
return {
_mapContext: null,
pointList: [{
url: 'https://mp100.fengo.vip/fengo100/2024-07-11/53c3fc2f-e3a9-43b9-96d0-183a90818a49.png',
name: '编内',
}, {
url: 'https://mp100.fengo.vip/fengo100/2024-07-11/c4560ce5-a20f-461c-8784-46f8868cb6cd.png',
name: '编外',
}, {
url: 'https://mp100.fengo.vip/fengo100/2024-07-11/01c22de8-57fa-4a07-bf58-b86bd2391585.png',
name: '外籍',
}, {
url: 'https://mp100.fengo.vip/fengo100/2024-07-12/8b061a36-61d0-4c2e-8f62-538d12e46bc4.png',
name: '上线',
}, {
url: 'https://mp100.fengo.vip/fengo100/2024-07-12/3278ad24-ad42-497f-ad9e-dd8619f8c4d3.png',
name: '下线',
}],
latitude: 39.904989,
longitude: 116.405285,
organizationalStructureId: 0, //组织架构id 填0 代表不根据组织架构搜索
providerId: '', //服务商id
rootOperatorId: 1, //根节点操作员id 默认选中 缝歌100 值为1 默认值合伙人后台也相同,不影响逻辑
rootType: 1, //根节点类型 1 服务商根节点 2 合伙人根节点 默认选中 缝歌100 值为1 默认值合伙人后台也相同,不影响逻辑
workerType: 0, //员工类型 0 全部 1 编内 2 编外 3 编内和编外 4 外籍
workerList: [], //师傅列表
positions: [],
}
},
onLoad() {
},
onReady() {
// 创建map对象
this._mapContext = uni.createMapContext("myMap", this);
const userInfo = this.$store.state.release ? this.$store.state.userInfo : this.$store.state.testUserInfo
this.providerId = userInfo.serviceProviderId
this.getAllOnLineWorkerList()
},
methods: {
// 获取区域内所有师傅列表
async getAllOnLineWorkerList() {
let that = this,
data = {
orderId: -1,
organizationalStructureId: 0, //组织架构id 填0 代表不根据组织架构搜索
providerId: that.providerId, //服务商id
rootOperatorId: that.rootOperatorId, //根节点操作员id 默认选中 缝歌100 值为1 默认值合伙人后台也相同,不影响逻辑
rootType: that.rootType, //根节点类型 1 服务商根节点 2 合伙人根节点 默认选中 缝歌100 值为1 默认值合伙人后台也相同,不影响逻辑
workerType: that.workerType, //员工类型 0 全部 1 编内 2 编外 3 编内和编外 4 外籍
}
const info = await getAllOnLineWorkerList(data)
if (info && info.status == '200') {
console.log(info.data, 'info');
that.workerList = info.data
that.workerList.forEach(item => {
item.lnglat = item.location.split(',')
item.longitude = item.lnglat[0]
item.latitude = item.lnglat[1]
})
if (that.workerList.length <= 0) {
that.latitude = 39.904989
that.longitude = 116.405285
}
that.cluster();
} else {
that.$refs.uToast.show({
type: 'error',
message: info.message || '获取师傅失败,请重试~',
})
}
},
// 点击标记点
markertap(value) {
console.log(value, '点击标记点');
},
// 点聚合
cluster() {
// 仅调用初始化,才会触发 on.("markerClusterCreate", (e) => {})
this._mapContext.initMarkerCluster({
enableDefaultStyle: false, // 是否使用默认样式
zoomOnClick: true, // 点击聚合的点,是否改变地图的缩放级别
gridSize: 60, // 聚合计算时网格的像素大小,默认60
complete(res) {
console.log('initMarkerCluster', res)
}
});
// 缩放视野展示所有经纬度
this._mapContext.includePoints({
points: this.workerList,
padding: [20, 60, 20, 20],
complete(res) {
// console.log('includePoints', res)
}
});
// 缩放或拖动导致新的聚合簇产生时触发,仅返回新创建的聚合簇信息。
this._mapContext.on("markerClusterCreate", (res) => {
console.log("markerClusterCreate", res);
const clusters = res.clusters
const markers = clusters.map(cluster => {
const {
center,
clusterId,
markerIds
} = cluster
let iconPath = 'https://mp100.fengo.vip/fengo100/2024-07-11/53c3fc2f-e3a9-43b9-96d0-183a90818a49.png'
return {
...center,
width: 0,
height: 0,
clusterId, // 必须
iconPath: iconPath,
width: 24,
height: 36,
label: {
content: markerIds.length + '',
fontSize: 16,
color: '#ffffff',
width: 20,
height: 20,
lineHeight: 20,
bgColor: '#E90000',
borderRadius: 10,
textAlign: 'center',
anchorX: 12,
anchorY: -46,
}
}
})
this._mapContext.addMarkers({
markers,
clear: false,
complete(res) {
console.log('clusterCreate addMarkers', res)
}
})
});
// 聚合簇的点击事件
this._mapContext.on("markerClusterClick",(res)=>{
console.log('markerClusterClick', res)
})
this.addMarkers();
},
// 添加标记点
addMarkers() {
const markers = []
this.workerList.forEach((item) => {
let iconPath = 'https://mp100.fengo.vip/fengo100/2024-07-11/53c3fc2f-e3a9-43b9-96d0-183a90818a49.png'
if (item.workerType == 1) {
iconPath =
'https://mp100.fengo.vip/fengo100/2024-07-11/53c3fc2f-e3a9-43b9-96d0-183a90818a49.png'
} else if (item.workerType == 2) {
iconPath =
'https://mp100.fengo.vip/fengo100/2024-07-11/c4560ce5-a20f-461c-8784-46f8868cb6cd.png'
} else {
iconPath =
'https://mp100.fengo.vip/fengo100/2024-07-11/01c22de8-57fa-4a07-bf58-b86bd2391585.png'
}
markers.push(
Object.assign({}, {
id: item.id,
iconPath: iconPath,
width: 24,
height: 36,
joinCluster: true, // 指定了该参数才会参与聚合
}, item)
)
})
this._mapContext.addMarkers({
markers,
clear: false, //是否先清空地图上所有 marker
complete(res) {
console.log('addMarkers', res)
}
})
},
}
}
</script>
<style scoped lang="scss">
.screenBox {
position: fixed;
top: 12rpx;
right: 20rpx;
padding: 28rpx;
box-sizing: border-box;
background: #FFFFFF;
box-shadow: 0rpx 2rpx 6rpx 0rpx rgba(57, 57, 57, 0.26);
border-radius: 13rpx;
.imgs {
width: 43rpx;
height: 38rpx;
margin-right: 14rpx;
}
}
.pointBox {
position: fixed;
bottom: 176rpx;
right: 20rpx;
padding: 18rpx 12rpx;
box-sizing: border-box;
background: #FFFFFF;
box-shadow: -9rpx 7rpx 13rpx 0rpx rgba(203, 204, 212, 0.6);
border-radius: 13rpx;
.list {
padding: 10rpx 0;
box-sizing: border-box;
text-align: center;
border-bottom: 2rpx solid #DADADA;
.imgs {
width: 27rpx;
height: 40rpx;
margin-bottom: 12rpx;
}
}
.list:nth-last-child(1) {
border-bottom: none;
}
}
</style>