uniapp小程序自定义聚合点

发布于:2024-10-18 ⋅ 阅读:(16) ⋅ 点赞:(0)

注:

1.默认的聚合点可以点击自动展示子级点位,但是自定义的聚合点在ios上无法触发markerClusterClick的监听,至今未解决,不知啥原因

2.ios和安卓展示的点位样式还有有差别

源码附上

<template>
	<view class="marker-map">
		<map id="mapId" style="width: 100%; height:1342rpx ;" :latitude="latitude" :longitude="longitude"
			show-location show-scale :scale="zoom" @regionchange="regionchange" @updated="update" @callouttap='callouttap'>
		</map>
		<view class="layer flex-column align-end">
			<view class="cur-location justify-center align-center" @click="backCenter">
				<image :src="imgConf.position" mode="" style="width:60%;height: 60%;"></image>
			</view>
			<view class="list">
				<u-transition :show="showMarkerListPop" mode="fade-up">
					<mapMarkerList @onclose="showMarkerListPop=false" />
				</u-transition>
			</view>
		</view>
	</view>
</template>

<script>
	import mapMarkerList from './components/mapMarkerList.vue'
	import imgConf from '@/utils/imgConf.js'
	export default {
		components: {
			mapMarkerList
		},
		data() {
			return {
				imgConf,
				longitude: 104.04311,
				latitude: 30.64242,
				markers: [], // 使用 marker点击事件 需要填写id
				fixedHeight: 60,
				zoom: 16,
				showMarkerListPop: false
			}
		},
		created() {
			this.mapContext = uni.createMapContext("mapId", this);


			console.log("this.mapContext", this.mapContext);
			// 使用默认聚合效果时可注释下一句
			this.bindEvent()
			this.getDotList();
		},

		methods: {
			bindEvent() {
				this.mapContext.initMarkerCluster({
					enableDefaultStyle: false,
					zoomOnClick: true,
					gridSize: 100,
					complete(res) {
						console.log('initMarkerCluster', res)
					}
				});

				// enableDefaultStyle 为 true 时不会触发该事件
				this.mapContext.on('markerClusterCreate', res => {
					const clusters = res.clusters
					const markers = clusters.map(cluster => {
						const {
							center,
							clusterId,
							markerIds
						} = cluster
						return {
							...center,
							width: 1,
							height: 1,
							clusterId, // 必须
							iconPath: '',
							label: {
								content: '盛世年华' + "(" + "2" + "套)" + '\n' + '12' + '元起',
								color: "#ffffff",
								fontSize: 11,
								borderRadius: 8,
								bgColor: "#0090FF",
								padding: 10,
								textAlign: 'center',
								anchorX: 0,
								anchorY: -56,
							}
							// callout: {
							// 	content: '盛世年华' + "(" + "2" + "套)" + '\n' + '12' + '元起',
							// 	color: "#ffffff",
							// 	fontSize: 11,
							// 	borderRadius: 8,
							// 	bgColor: "#0090FF",
							// 	padding: 10,
							// 	textAlign: 'center',
							// 	display: 'ALWAYS',
							// },
						}
					})
					this.mapContext.addMarkers({
						markers,
						clear: false,
						complete(res) {
							console.log('clusterCreate addMarkers', res)
						}
					})
				})

				this.mapContext.on("markerClusterClick", (ClusterInfo) => {
					console.log("点击聚合点", ClusterInfo); //[id1,id2]
				});
			},
			// 获取所有点位/
			async getDotList(params) {
				// const res = await getDot(params)
				const resPosition = [{
						longitude: 113.324520,
						latitude: 23.099994,
						title: '盛世年华1',
						num: 1,
						price: 35500
					},
					{
						longitude: 102.04320,
						latitude: 31.64242,
						title: '盛世年华2',
						num: 1,
						price: 35500
					},
					{
						longitude: 102.04313,
						latitude: 30.64242,
						title: '盛世年华3',
						num: 1,
						price: 15500
					},
					{
						longitude: 113.326520,
						latitude: 31.64242,
						title: '盛世年华4',
						num: 3,
						price: 25500
					},
				]
				const markers = []
				resPosition.forEach((p, i) => {
					markers.push(
						Object.assign({}, {
							id: i + 1,
							iconPath: '',
							joinCluster: true,
							width: 2,
							height: 2,
							callout: {
								content: p.title + "(" + p.num + "套)" + '\n' + p.price + '元起',
								color: "#ffffff",
								fontSize: 11,
								borderRadius: 8,
								bgColor: "#0090FF",
								padding: 10,
								textAlign: 'center',
								display: 'ALWAYS',
							},
						}, p)
					)
				})
				this.markers = JSON.parse(JSON.stringify(markers))
				this.mapContext.addMarkers({
					markers: this.markers,
					clear: false,
					complete(res) {
						console.log('addMarkers', res)
					}
				})
				// .map((item, index) => {
				// 	if (item.lnglat === '') {
				// 		return undefined
				// 	}
				// 	var location = item.x.split(",");
				// 	let iconPath = ''

				// 	let label = item.name.length > 20 ? item.name.substr(0, 18) + '...' : item.name;
				// 	label = label.length > 10 ? label.substr(0, 10) + '\n' + label.substr(10) : label;
				// 	return {
				// 		id: index,
				// 		longitude: Number(location[0]),
				// 		latitude: Number(location[1]),
				// 		iconPath,
				// 		joinCluster: this.zoom > 18 ? false : true,
				// 		width: 50,
				// 		height: 60,
				// 		name: item.name,
				// 		label: {
				// 			content: label,
				// 			anchorX: 20,
				// 			anchorY: -45,
				// 			color: '#333',
				// 			fontSize: 14
				// 		}
				// 	}
				// }).filter(i => i !== undefined)
				console.log('markers', this.markers)
				if (this.markers.length === 0) {
					uni.showToast({
						title: '暂无相关点位信息',
						icon: "none"
					})
					this.longitude = 92.066757
					this.latitude = 31.473608
					this.zoom = 16
					return
				}
				// })
			},
			// 点击标记点
			callouttap(e) {
				this.showMarkerListPop = true
				// 根据markerid查找
				console.log('点击标记点E', e) //e.markerId
			},

			regionchange() {
				// this.mapContext.getScale({
				// 	success: (res) => {
				// 		this.zoom = res.scale
				// 	}
				// })
			},
			update() {

				console.log('渲染更新完成') //e.markerId
			},
			// 定位到当前位置
			backCenter() {
				uni.getLocation({
					type: 'gcj02',
					success: (res) => {
						if (res.longitude && res.latitude) {
							this.latitude = Number(res.latitude)
							this.longitude = Number(res.longitude)
							this.zoom = 16.01 // 必须要有层级的变化,下面的方法才能生效
							this.mapContext.moveToLocation({
								longitude: this.longitude,
								latitude: this.latitude,
								success: (res) => {
									this.zoom = 16.03
								},
								fail: (info) => {
									console.log(info)
								}
							})
						} else {
							uni.showToast({
								title: '无法获取当前定位'
							})
						}
					},
					fail(err) {
						uni.showToast({
							title: '无法获取当前定位'
						})
					}
				});
			},
		}
	}
</script>

<style lang="scss" scoped>
	.marker-map {
		.layer {
			position: fixed;
			z-index: 999;
			width: 100%;
			right: 0;
			bottom: 0;
		}

		.cur-location {
			width: 86rpx;
			height: 86rpx;
			background: #FFFFFF;
			box-shadow: 0rpx 0rpx 8rpx 1rpx rgba(0, 144, 255, 0.15);
			border-radius: 20rpx 20rpx 20rpx 20rpx;
			margin-right: 30rpx;
			margin-bottom: 50rpx;
		}

		.list {
			width: 100%;
			height: 100%;
		}
	}
</style>