最终实现效果如图 (展示用的是小程序模拟器,有点小问题,真机调试是正常的,点击某个点时会把这个点设置为中心点,而不是像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>