先看效果

地图中的标记点 可以动态变化自定义的图片与内容

在这里插入图片描述

原理

通过map组件中的 markers 属性 设置标记点 用于在地图上显示标记的位置

map组件所在uniapp官网位置:map-uni-app https://uniapp.dcloud.io/component/map

1、想要动态改变标记点图标 必须把默认的标记点覆盖,用到了markers参数下的 iconPath设置标记点的图标,如果需求只需要简单的动态改变标记点的图标到这一步就结束了,但是如果需要动态改变标记点图标及内容(动态显示文字)就需要看下一步!
2、把iconPath设置的图片改用一张1*1像素的透明背景图 png格式的。

3、markers 列表中的 customCallout 设置自定义气泡窗口 display: "ALWAYS"总数显示,并在标签内配置 slot="callout"这里注意的是 要比map组件层级高 必须使用 cover-view 或者 cover-image 标签;

<!-- 自定义窗口 -->
<cover-view slot="callout">
	<template v-for="(item,index) in markers">
		<cover-view :marker-id="item.id" :key='index'>
			<cover-view class="position-relative" style="width: 92rpx; height: 78rpx;">
				<cover-image class="position-absolute" style="width: 92rpx; height: 78rpx;" :src='item.options.iconPath'></cover-image>
				<cover-view style="top: 13rpx; left: 45rpx; width: 30rpx; height: 30rpx;"
					class="border bg-white rounded-circle flex align-center justify-center position-absolute">
					<cover-view>{{item.options.labelName}}</cover-view>
				</cover-view>
			</cover-view>
		</cover-view>
	</template>

</cover-view>

4、map标签上使用 @callouttap事件 点击标记点对应的气泡时触发,这样就可以动态获取标记点信息了。

<map id="map" ref="map" style="height: 870rpx; width: 750rpx;" :latitude="latitude" :longitude="longitude" :markers="markers" :enable-building='true'
:show-location='true' :circles='circles' @markertap='markertap' @callouttap='callouttap'></map>

其中、第二步中使用透明背景图把默认标记点隐藏,第三步把自定义气泡弹窗改为标记点,偏移量自行微调到原标记点上方,第四步,获取到点击标记点的回调。这样,就可以实现动态改变标记点图标及内容了。

附上代码(样式缺失,自行修改)

<template>
	<view>
<!-- 		<nav-bar bgColor="#4f8fef" fontColor="#fff" title="地图" :titleCenter='true'></nav-bar>
		<free-scroll-main :scrollView='false' :showTabber="false" scrollViewStyle="background-color: #fafaf9;">
		
		</free-scroll-main> -->

	<view class="bg-dark" style="height: 870rpx; width: 750rpx;">
				<map id="map" ref="map" style="height: 870rpx; width: 750rpx;" :latitude="latitude" :longitude="longitude" :markers="markers" :enable-building='true'
					:show-location='true' :circles='circles' @markertap='markertap' @callouttap='callouttap'>
					<!-- 自定义窗口 -->
					<cover-view slot="callout">
						<template v-for="(item,index) in markers">
							<cover-view :marker-id="item.id" :key='index'>
								<cover-view class="position-relative" style="width: 92rpx; height: 78rpx;">
									<cover-image class="position-absolute" style="width: 92rpx; height: 78rpx;" :src='item.options.iconPath'></cover-image>
									<cover-view style="top: 13rpx; left: 45rpx; width: 30rpx; height: 30rpx;"
										class="border bg-white rounded-circle flex align-center justify-center position-absolute">
										<cover-view>{{item.options.labelName}}</cover-view>
									</cover-view>
								</cover-view>
							</cover-view>
						</template>

					</cover-view>
				</map>
			</view>

			<view class="mt-5 flex align-center justify-center">

				<view class="position-relative border bg-white rounded-10" style=" width: 650rpx; height: 220rpx;">
					<view :style="getBgColor" class="position-absolute rounded-circle flex align-center justify-center"
						style="width: 60rpx; height: 60rpx; top: -30rpx; left: 30rpx;">
						<text class="text-white" style="font-size: 24rpx;">{{targetInfo.labelName}}</text>
					</view>
					<view class=" pt-3 px-3 flex align-center justify-between">
						<view class="flex flex-column">
							<text class="font-md font-weight-bolder">{{targetInfo.locationName}}</text>
							<text class="font-sm pt-1">{{targetInfo.address}}</text>
							<text class="font-sm py-1">{{targetInfo.city}}</text>
							<text class="font-sm">{{targetInfo.phoneNumber}}</text>
						</view>
						<view class="flex flex-column">
							<u-button class="btn mb-4" type="primary">预约</u-button>
							<u-button @click="openMap" class="btn" type="primary">导航</u-button>
						</view>
					</view>
				</view>
			</view>
	</view>
</template>

<script>
	import Map from '@/common/js/openMap.js'

	export default {
		components: {},
		data() {
			return {
				// 圆球颜色
				color: ['#0797e4', '#2be4ae'],
				// 定位维度
				latitude: 22.26666,
				// 定位经度
				longitude: 113.54342,
				// 点击选中id
				checkedId: 0,
				// 选中marker列表下标
				markerIndex: -1,
				// 点击获取到的标点信息
				targetInfo: {
					labelName: 'A',
					locationName: '嘉苑',
					address: '情侣路公交亭',
					city: '珠海',
					phoneNumber: '(0123)119119119',
					latitude: 22.26666,
					longitude: 113.54342,
				},

				// 标点列表
				markers: [
					// 	{
					// 	id: 1, //标记点id
					// 	clusterId: 1, //自定义点聚合簇效果时使用
					// 	title: '选中',
					// 	latitude: 22.26666, //维度
					// 	longitude: 113.54342, //经度
					// 	alpha: 1, //透明度 0-1
					// 	iconPath: '/static/images/map/none.png',
					// 	options: {
					// 		checked: true,
					// 		iconPath: '/static/images/map/select.png',
					// 		labelName: 'A',
					// 		locationName: '嘉苑',
					// 		address: '高新区大学路101号',
					// 		city: '珠海',
					// 		phoneNumber: '(0123)119119119'
					// 	},
					// 	// 自定义窗口
					// 	customCallout: {
					// 		anchorX: -1,
					// 		anchorY: 46,
					// 		display: "ALWAYS"
					// 	},

					// },
				],


				// 是否显示圆
				circles: [{
					latitude: 22.26666,
					longitude: 113.54342,
					color: '#2979ffcc',
					fillColor: '#2979ff61',
					strokeWidth: 1,
					radius: 500,
				}],

				// 控件
				controls: [

				]
			}
		},
		watch: {
			// 监听选中下标 改变图片 
			markerIndex(val, oldVal) {
				this.markers[val].options.iconPath = '/static/images/map/none.png'
				this.markers[val].options.iconPath = '/static/images/map/select.png';
				if (this.markers[oldVal]) {
					this.markers[oldVal].options.iconPath = '/static/images/map/noselect.png';
				}
				console.log(val, oldVal);
			}
		},
		computed: {
			getBgColor() {
				return `background-image: linear-gradient(90deg, ${this.color[0]}, ${this.color[1]});`
			}
		},
		created() {
			this.isGetLocation();
		},
		methods: {

			// 测试
			ceshi() {

				for (let i = 0; i < 5; i++) {
					let obj = {
						id: 1, //标记点id
						clusterId: 1, //自定义点聚合簇效果时使用
						title: '选中',
						latitude: 22.26666, //维度
						longitude: 113.54342, //经度
						alpha: 1, //透明度 0-1
						iconPath: '/static/images/map/none.png',
						options: {
							iconPath: '/static/images/map/noselect.png',
							labelName: 'A',
							locationName: '嘉苑',
							address: '高新区大学路101号',
							city: '珠海',
							phoneNumber: '(0123)119119119'
						},
						// 自定义窗口
						customCallout: {
							anchorX: -1,
							anchorY: 46,
							display: "ALWAYS"
						},

					}
					let start = this.markers.length;
					obj.id = start;
					obj.clusterId = start;
					obj.options.labelName = String.fromCharCode(65 + start) // A
					this.markers.push(obj);
				}

				this.markers.forEach((item, index) => {
					let timer = setTimeout(() => {
						let suiji = Math.round(Math.random() * 10) * 0.0003;
						if (Math.round(Math.random() * 5) > 2) {
							suiji = -suiji;
						}

						if (index % 2 != 0) {
							this.markers[index].longitude = this.longitude + suiji;
							this.markers[index].latitude = this.latitude + suiji;
						} else {
							this.markers[index].longitude = this.longitude + suiji;
							this.markers[index].latitude = this.latitude - suiji;
						}
						console.log(suiji);
						clearTimeout(timer);
						timer = null;
					}, 50 * index)

				})
				setTimeout(() => {
					this.getTargetInfo(this.markers[0]);
				}, 1500)

			},
			getTargetInfo(obj) {
				this.targetInfo.labelName = obj.options.labelName;
				this.targetInfo.locationName = obj.options.locationName;
				this.targetInfo.address = obj.options.address;
				this.targetInfo.phoneNumber = obj.options.phoneNumber;
				this.targetInfo.longitude = obj.longitude;
				this.targetInfo.latitude = obj.latitude;
			},
			// 点击标记点
			markertap(e) {
				console.log(e, '标记点e');
			},
			// 点击自定义气泡
			callouttap(e) {
				this.checkedId = e.detail.markerId;
				let markerId = e.detail.markerId;
				for (let i = 0; i < this.markers.length; i++) {
					if (this.markers[i].id == markerId) {
						this.markerIndex = i;
						break;
					}
				}
				if (this.markerIndex != -1) {
					this.getTargetInfo(this.markers[this.markerIndex]);

				} else {
					uni.showToast({
						title: '暂未该设备信息',
					})
				}

			},
			// 打开地图导航
			openMap() {
				console.log('uni.getSystemInfoSync().platform', uni.getSystemInfoSync().platform);
				console.log(this.targetInfo.latitude, this.targetInfo.longitude);
				// Map.openMap(this.targetInfo.latitude, this.targetInfo.longitude, this.targetInfo.locationName, 'wgs84')
				var options = {
					origin: { //导航起点坐标和名称,如果不传则起点为当前位置
						latitude: this.latitude,
						longitude: this.longitude,
						name: "起点"
					},

					destination: { //导航终点点坐标和名称
						latitude: this.targetInfo.latitude,
						longitude: this.targetInfo.longitude,
						name: this.targetInfo.locationName
					},
					// #ifdef MP-WEIXIN
					mapId: "map",
					// #endif
					mode: "drive" //导航方式 公交:bus驾车:drive(默认),步行:walk,骑行:bike;
				}
				//路线规划
				Map.routePlan(options, "gcj02")
				//驾车导航,打开地图直接开启导航,只需要传入options.destination终点信息
				Map.navigation(options, "gcj02")
			},
			// 获取定位信息
			getLocationInfo() {
				uni.getLocation({
					type: 'gcj02', //gcj02国测局坐标
					success: (res) => {
						console.log('当前位置的经度:' + res.longitude);
						console.log('当前位置的纬度:' + res.latitude);
						this.longitude = res.longitude;
						this.latitude = res.latitude;
						this.circles[0].longitude = res.longitude;
						this.circles[0].latitude = res.latitude;
						this.ceshi();
					}
				});
			},
			// 获取定位授权
			getAuthorizeInfo(a = "scope.userLocation") { //1. uniapp弹窗弹出获取授权(地理,个人微信信息等授权信息)弹窗
				var _this = this;
				uni.authorize({
					scope: a,
					success() { //1.1 允许授权
						_this.getLocationInfo();
					},
					fail() { //1.2 拒绝授权
						console.log("你拒绝了授权,无法获得周边信息")
					}
				})
			},
			// 查看是否已经授权定位
			isGetLocation(a = "scope.userLocation") { // 3. 检查当前是否已经授权访问scope属性,
				var _this = this;
				// #ifdef MP
				uni.getSetting({
					success(res) {
						if (!res.authSetting[a]) { //3.1 每次进入程序判断当前是否获得授权,如果没有就去获得授权,如果获得授权,就直接获取当前地理位置
							_this.getAuthorizeInfo()
						} else {
							_this.getLocationInfo()
						}
					}
				});
				// #endif

			},
		}
	}
</script>
<style scoped lang="scss">
	.btn {
		&/deep/.u-btn {
			width: 148rpx;
			height: 56rpx;
		}
	}
</style>

<style>
	@import '@/common/free.css';
	@import '@/common/common.css';
</style>

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐