uni-app 微信小程序地图增加标记点,并实现点击弹窗

项目需求,在微信小程序的地图中,实现打点,然后点击某个点要能弹出关于这个点的某些信息,同时在当前点跳到其他点时,对应信息也要替换,点击空白处要关闭弹窗,在此做个记录

最终实现效果如图 (展示用的是小程序模拟器,有点小问题,真机调试是正常的,点击某个点时会把这个点设置为中心点,而不是像GIF一样,一直往定位点跳)


废话不多说,直接上代码

<template>
	<view>
		<map 
			id="map" 
			style="width: 100%; height: 100vh;" 
			:show-location="true"
			:latitude="map.latitude" 
			:longitude="map.longitude" 
			:scale="map.scale" 
			:markers="map.markers" 
			:circles="map.circles" 
			@markertap="markertap"
			@tap="tap"
		>
			<cover-image class="location" src="/static/img/map/location.png" @click="getLocation"></cover-image>
			<cover-image class="record" src="/static/img/map/record.png" @click="shouSleet"></cover-image>
			<cover-image class="refresh" src="/static/img/map/refresh.png" @click="loadData"></cover-image>
			
			<lv-select
				showValue="name"
				uniShadow="true"
				@handleSearch="searchHandle"
				@change="searchChange"
				:infoList="select.infoList"
				v-model="select.searchValue"
				:loading="select.loading"
				:isShowSelect="isShowSelect"
				>
			</lv-select>
			
			<view v-if="viewshow" class="uni-row-show">
				<view class="uni-flex uni-row">
					<text>标题:</text>
					<view style="-webkit-flex: 1;flex: 1;">
						<text style="color: gray;">{{map.marker.customData.localAccentTitle}}</text>
					</view>
					<cover-image class="close" src="/static/img/map/cha.png" @click="closeshow"></cover-image>
				</view>
				<view class="uni-flex uni-row" style="-webkit-flex: 1;flex: 1;">
					<text>描述:</text>
					<text>{{map.marker.customData.localAccentDescribe}}</text>
				</view>
				<view class="uni-flex uni-row" style="-webkit-flex: 1;flex: 1;">
					<text>时间:</text>
					<text>{{map.marker.customData.createTime}}</text>
				</view>
				<view class="uni-flex uni-row" style="-webkit-flex: 1;flex: 1;">
					<text>作者:</text>
					<text>{{map.marker.customData.createPeople}}</text>
				</view>
				
				<view class="audio" v-if="audioShow">
					<imt-audio :src="map.marker.customData.path"></imt-audio>
				</view>
			</view>
		</map>
	</view>
</template>

<script>
	import lvSelect from 'components/lv-select/lv-select'	//搜索组件
	import imtAudio from 'components/imt-audio/imt-audio';	//音频播放组件
	import { mapState, mapMutations } from 'vuex'
	
	export default {
		components: {imtAudio, lvSelect},
	    data() {
			return {
				viewshow: false,
				audioShow: false,
				isShowSelect: true,
				map: {
					mapObj: {},
					latitude: 23.140996, // 默认定在广州
					longitude: 113.362993,
					scale: 13, // 默认16
					markers: [],
					marker: {},
					lastMarker: {}
				},
				select: {
					loading: false,
					searchValue: '',
					infoList: []
				},
			};
		},
		onLoad() {
			this.map.mapObj = uni.createMapContext("map", this);   // 得到map对象
			this.getLocation();
			this.loadData(); 
		},
		computed: mapState(['userInfo']),
		methods: {
			...mapMutations(['checkLoginTo']),
			tap(){//地图空白处点击事件
				this.viewshow = false;
				this.isShowSelect = false;
				this.markerChangeColour();
			},
			searchHandle() {//搜索事件
				this.select.infoList = [];
				this.viewshow = false;
				this.isShowSelect = true;
				this.select.loading = true;
				this.map.markers.forEach((item, index) => {
					if(item.hasOwnProperty("customData")){
						if (item.customData.localAccentTitle.indexOf(this.select.searchValue) >= 0) {
							let data = {
								"item" : item,
								"name": item.customData.localAccentTitle
							}
							this.select.infoList.push(data);
						}
					}
					if(this.map.markers.length == index+1) {
						this.select.loading = false;
					}
				});
			},
			searchChange(data) {	//搜索框点击事件
				this.map.lastMarker = this.map.marker;
				let marker = this.map.markers.find(item => {return item.id == data.item.id});
				
				if(!marker) {
					this.viewshow = false;
					uni.showToast({
						title: '数据加载失败',
						icon:'none',
						duration: 3000
					});
				} else {
					this.map.lastMarker = this.map.marker;
					this.map.marker = marker;
					this.viewshow = true;
					this.audioShow = true;
					
					this.map.mapObj.moveToLocation({
						latitude: this.map.marker.latitude,
						longitude: this.map.marker.longitude
					});
				};
				
				this.markerChangeColour();
			},
			closeshow() {
				this.viewshow = !this.viewshow;
				this.markerChangeColour();
			},
			markertap(e) {//标记点点击事件
				if(this.map.marker.id == e.detail.markerId) {
					this.isShowSelect = false;
					this.viewshow = !this.viewshow;
				} else {
					let marker = this.map.markers.find(item => {return item.id == e.detail.markerId});
					if(!marker) {
						this.viewshow = false;
						uni.showToast({
							title: '数据加载失败',
							icon:'none',
							duration: 3000
						});
					} else {
						if(marker.LanguageNews == 1) {
							this.viewshow = false;
							this.isShowSelect = false;
							this.$utils.showLoading('加载中');
							uni.navigateTo({
								url: '/pages/index/languageNews/languageNews?id=' + marker.LanguageNewsId
							});
							this.$utils.hideLoading();
						} else {
							this.map.lastMarker = this.map.marker;
							this.map.marker = marker;
							this.viewshow = true;
							this.isShowSelect = false;
							this.audioShow = false;
							this.$nextTick(function(){
								this.audioShow = true;
							})//重载音频组件--否则音频会自动播放
							this.map.mapObj.moveToLocation({
								latitude: marker.latitude,
								longitude: marker.longitude
							});	//移动到当前定位地点
						}
					};
				}
				
				this.markerChangeColour();
			},
			markerChangeColour() {//更改图标颜色
				if(this.viewshow) {
					this.map.marker.iconPath = '/static/img/map/lan-point.png';
					
					if(this.map.lastMarker) {
						this.map.markers.find(item => {
							if(item.id == this.map.lastMarker.id) {
								item.iconPath = '/static/img/map/hong-point.png';
							}
						});
					}
				} else {
					this.map.marker.iconPath = '/static/img/map/hong-point.png';
				}
			},
			loadData() {//获取地图显示的数据
				this.$utils.showLoading();
				let url = this.$service.getServiceUrl() + this.$service.url.getloadMapDataUrl;
				//获取地图显示的数据
				this.$utils.postData(url).then(res => {
					this.map.markers = [];
					res.forEach((item, index) => {
						let marker = {
							"id": index,
							"latitude": item.latitude,
							"longitude": item.longitude,
							"width": '50rpx',
							"height": '50rpx',
							"iconPath": '/static/img/map/hong-point.png',
							"customData": {
								"localAccentTitle": item.localAccentTitle,
								"localAccentDescribe": item.localAccentDescribe,
								"createTime": item.createTime,
								"createPeople": item.createPeople,
								"path": this.$service.getServiceUrl() + item.attachment.path
							}
						};
						this.map.markers.push(marker);
					});
					this.getLanguageNewsList();
				});
			},
			getLanguageNewsList(){
				let length = this.map.markers.length;
				let LanguageNewsUrl = this.$service.getServiceUrl() + this.$service.url.getlanguageNewsUrl;
				this.$utils.postData(LanguageNewsUrl).then(res => {
					res.data.forEach((item, index) => {
						let marker = {
							"id": index + 1 + length,
							"width": '50rpx',
							"height": '50rpx',
							"iconPath": '/static/img/map/hei-point.png',
							"LanguageNews": 1,
							"LanguageNewsId": item.id
						};
						let mars_point = this.baiduTomars(item);
						marker.latitude = mars_point.latitude;
						marker.longitude = mars_point.longitude;
						this.map.markers.push(marker);
					});
					
				});
				this.$utils.hideLoading();
			},
			// 获取地理位置
			getLocation() {
				var that = this;
				uni.getLocation({
					type: 'gcj02',
					success(res) {
						that.map.latitude = res.latitude;
						that.map.longitude = res.longitude;
						that.map.scale = 13;
					},
					fail: function () {
						uni.showToast({
							title: '获取定位失败,请检查是否开启位置信息权限',
							icon:'none',
							duration: 4000
						});
					}
				});
				this.map.mapObj.moveToLocation();	//移动到当前定位地点
			},
			shouSleet() {
				let that = this;
				that.checkLoginTo(function() {
					//跳转到录音页面
					if(that.map.latitude == '23.140996' || that.map.longitude == '113.362993') {
						uni.showToast({
							title: '请先定位,再进行录音!',
							icon:'none',
							duration: 3000
						});
					} else {
						that.$utils.showLoading('加载中');
						uni.navigateTo({
							url: '/pages/map/voice/voice?latitude=' + that.map.latitude + '&longitude=' + that.map.longitude
						});
						that.$utils.hideLoading();
					}
				});
			},
			//百度地图bd09II坐标转国测局火星GCJ02坐标
			baiduTomars(item) {
				let x_pi=3.14159265358979324 * 3000.0 / 180.0;
				let mars_point={
					"latitude": 0,
					"longitude": 0
				};
				let x=item.longitude - 0.0065;
				let y=item.latitude - 0.006;
				let z=Math.sqrt(x*x+y*y)- 0.00002 * Math.sin(y * x_pi);
				let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
				mars_point.longitude=z * Math.cos(theta);
				mars_point.latitude=z * Math.sin(theta);
				return mars_point;
			}
		}
	}
</script>

<style lang="scss">
	@charset "UTF-8";
	
	/* 头条小程序组件内不能引入字体 */
	/* #ifdef MP-TOUTIAO */
	@font-face {
		font-family: uniicons;
		font-weight: normal;
		font-style: normal;
		src: url("~@/static/uni.ttf") format("truetype");
	}
	
	/* #endif */
	/* #ifndef APP-NVUE */
	page {
		display: flex;
		flex-direction: column;
		box-sizing: border-box;
		background-color: #efeff4;
		min-height: 100%;
		height: auto;
	}
	view {
		font-size: 14px;
		line-height: inherit;
	}
	/* #endif */
	
	.location {
		position: fixed;
		right: 30rpx;
		bottom:100rpx;
		width: 60rpx;
		height: 60rpx;
	}
	.record {
		position: fixed;
		right: 27rpx;
		bottom: 170rpx;
		width: 70rpx;
		height: 70rpx;
	}
	.refresh {
		position: fixed;
		right: 30rpx;
		bottom: 255rpx;
		width: 60rpx;
		height: 60rpx;
	}
	.uni-row-show {
		margin: upx;
		border-radius : 25rpx;
		position: absolute;
		left: 70rpx;
		width: 600rpx;
		color: #000000;
		background-color: #ffffff;
	}
	.uni-row{
		width: 90%;
		margin: 5px auto!important;
		line-height:20px
	}
	.uni-row > text:last-child {
		color: gray;
		width: 67%;
	}
	.close{
		width: 15px;
		height:15px;
		margin-top: -10rpx;
		margin-right:-30rpx;
	}
	.audio {
		padding: 20upx;
	}
</style>

你可能感兴趣的:(信创,小程序)