433 lines
12 KiB
Vue
433 lines
12 KiB
Vue
<template>
|
||
<view class="tm-mapSelectedPoint" :class="[black_tmeme?'grey-darken-5':'']">
|
||
<map :scale="mapscale" id="MapTm" ref="MapTm" @regionchange="moveMapChange" :markers="markers" :latitude="mapCenter.lat" :longitude="mapCenter.lng" :style="{width:`${width}rpx`,height:`400rpx`}"></map>
|
||
<view class=" pa-32 ">
|
||
<view class="tm-mapSelectedPoint-contr">
|
||
<view class="pb-32"><text class=" text-size-n fulled text-overflow-1">当前:{{adress.adress||"获取失败,请移动地图选择"}}</text></view>
|
||
<view class="flex-between pb-10">
|
||
<tm-button @click="confirm" block height="80" style="width:60%">确认位置</tm-button>
|
||
<view style="width:35%" class="flex-shrink">
|
||
<tm-button :black="black_tmeme" :fllowTheme="fllowTheme" :theme="color_tmeme" @click="getLocation" text block height="80" icon="icon-position-fill">定位当前</tm-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-if="adressList.length>0" class="grey-lighten-5 px-24 round-6 mt-32" :class="[black_tmeme?'bk grey-darken-4':'']">
|
||
<scroll-view scroll-y :style="{height: scrollHeight+'px'}">
|
||
<view @click="selecListitem(item)" v-for="(item,index) in adressList" :key="index" :class="[black_tmeme?'bk':'']" class="py-24 border-b-1 flex-between">
|
||
<view class="mr-32">
|
||
<view class="pb-12"> {{item.name}}</view>
|
||
<view class="text-size-s text-grey">{{item.address}}</view>
|
||
</view>
|
||
<view class="flex-shrink">
|
||
<tm-icons :black="black_tmeme" :fllowTheme="fllowTheme" :color="color_tmeme" size="40" v-if="activeId == item.id" name="icon-check-circle"></tm-icons>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
/**
|
||
* 地图选点
|
||
* @property {Boolean|String} black = [true|false] 默认null,是否开启暗黑模式
|
||
* @property {String} color = [] 主题默认:primary,提供是请写主题色名称
|
||
* @property {String} map-key = [] 地图key:默认为作者测试的,用户不要使用我的,否则会被限制,key作废。
|
||
* @property {String} map-type = [] 地图类型:qq,qq,baidu,amp高德。
|
||
* @property {Number} scale = [] 默认:14,地图绽放级别5-18
|
||
* @property {Number} width = [] 默认:700,组件的宽度。
|
||
* @property {Number} height = [] 默认:1200,组件的高度。
|
||
* @property {Object} location = [] 默认:{latitude:39.908823,longitude:116.39747},默认的定位点,北京。
|
||
* @property {Function} confirm 点击确认位置按钮时返回当前定位资料信息。
|
||
* @property {Function} change 当移动地图时的位置信息,返回的结构同confirm
|
||
*/
|
||
import tmButton from '@/tm-vuetify/components/tm-button/tm-button.vue';
|
||
import tmIcons from '@/tm-vuetify/components/tm-icons/tm-icons.vue';
|
||
export default {
|
||
name:"tm-mapSelectedPoint",
|
||
components:{tmButton,tmIcons},
|
||
props:{
|
||
width:{
|
||
type:Number|String,
|
||
default:700
|
||
},
|
||
height:{
|
||
type:Number|String,
|
||
default:1200
|
||
},
|
||
location:{
|
||
type:Object,
|
||
default:()=>{
|
||
return {
|
||
latitude:0,
|
||
longitude:0
|
||
}
|
||
}
|
||
},
|
||
scale:{
|
||
type:Number,
|
||
default:14
|
||
},
|
||
// 是否开启暗黑模式
|
||
black: {
|
||
type: String | Boolean,
|
||
default: null
|
||
},
|
||
color: {
|
||
type: String | Array,
|
||
default: 'primary'
|
||
},
|
||
// 跟随主题色的改变而改变。
|
||
fllowTheme: {
|
||
type: Boolean | String,
|
||
default: true
|
||
},
|
||
mapKey:{
|
||
type:String,
|
||
default:'U3QBZ-3YIKI-YBEGX-5WURG-5ZQE6-ZGFME'
|
||
},
|
||
mapType:{
|
||
type:String,
|
||
default:'qq' //qq,baidu,amp
|
||
}
|
||
},
|
||
watch: {
|
||
location:{
|
||
deep:true,
|
||
async handler(newValue, oldValue) {
|
||
this.moveMap(newValue.latitude,newValue.longitude)
|
||
await this.moveMarkes(newValue.latitude,newValue.longitude)
|
||
}
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
now_latitude:0,
|
||
now_longitude:0,
|
||
mapCenter:{
|
||
lat:0,
|
||
lng:0
|
||
},
|
||
markers:[],
|
||
timeid:9566555566,
|
||
adressList:[],
|
||
adress:{
|
||
adress:'',
|
||
city:[]
|
||
},
|
||
scrollHeight:0,
|
||
activeId:'',
|
||
map:null,
|
||
};
|
||
},
|
||
|
||
computed:{
|
||
black_tmeme: function() {
|
||
if (this.black !== null) return this.black;
|
||
return this.$tm.vx.state().tmVuetify.black;
|
||
},
|
||
color_tmeme: function() {
|
||
if (this.$tm.vx.state().tmVuetify.color !== null && this.$tm.vx.state().tmVuetify.color && this
|
||
.fllowTheme) {
|
||
return this.$tm.vx.state().tmVuetify.color;
|
||
}
|
||
return this.color;
|
||
},
|
||
mapscale:function(){
|
||
return this.scale;
|
||
}
|
||
},
|
||
created() {
|
||
this.now_latitude = this.location.latitude;
|
||
this.now_longitude = this.location.longitude;
|
||
this.mapCenter = {
|
||
lat:this.location.latitude,
|
||
lng:this.location.longitude
|
||
}
|
||
},
|
||
async mounted() {
|
||
let t = this;
|
||
this.map = uni.createMapContext("MapTm", this)
|
||
let q = await this.$Querey('.tm-mapSelectedPoint-contr',this).catch(e=>{});
|
||
let h = q[0].height||80;
|
||
this.scrollHeight = uni.upx2px(this.height) - uni.upx2px(400) - h;
|
||
// #ifdef MP
|
||
uni.authorize({
|
||
scope: 'scope.userLocation',
|
||
success() {
|
||
t.mapready();
|
||
}
|
||
})
|
||
// #endif
|
||
// #ifndef MP
|
||
this.$nextTick(async function(){
|
||
await uni.$tm.sleep(200)
|
||
await this.mapready();
|
||
})
|
||
// #endif
|
||
},
|
||
methods: {
|
||
moveMap(latitude,longitude){
|
||
this.map.moveToLocation({
|
||
latitude:latitude,
|
||
longitude:longitude
|
||
})
|
||
},
|
||
async mapready(){
|
||
|
||
let t = this;
|
||
// #ifndef H5
|
||
uni.getSetting({
|
||
success: async (res) => {
|
||
if(!res.authSetting['scope.userLocation']){
|
||
uni.showModal({
|
||
title:"权限受限",
|
||
content:"你禁止了位置受限,请打开设置,允许访问地址!否则功能无法使用。",
|
||
cancelText:"我已允许",
|
||
confirmText:"前往设置",
|
||
success: async (rks) => {
|
||
if(rks.cancel==true){
|
||
await t.getLocation();
|
||
return
|
||
}
|
||
uni.openSetting({})
|
||
}
|
||
})
|
||
return;
|
||
}
|
||
if(t.mapCenter.lat !==0 && t.mapCenter.lng!==0){
|
||
t.markers = [t.createMarker( t.mapCenter.lat ,t.mapCenter.lng)]
|
||
await t.poiSidel_byTencentMap(t.mapCenter.lat ,t.mapCenter.lng)
|
||
return;
|
||
}
|
||
await t.getLocation();
|
||
},
|
||
fail: (res) => {
|
||
uni.$tm.toast("系统错误")
|
||
}
|
||
})
|
||
// #endif
|
||
|
||
// #ifdef H5
|
||
if(t.mapCenter.lat !==0 && t.mapCenter.lng!==0){
|
||
t.markers = [t.createMarker( t.mapCenter.lat ,t.mapCenter.lng)]
|
||
await t.poiSidel_byTencentMap(t.mapCenter.lat ,t.mapCenter.lng)
|
||
return;
|
||
}
|
||
await this.getLocation();
|
||
// #endif
|
||
},
|
||
confirm(){
|
||
this.$emit('confirm',{...this.adress,latitude:this.now_latitude,longitude:this.now_longitude})
|
||
},
|
||
async getLocation() {
|
||
let t = this;
|
||
|
||
//非h5通过GPS定位 。
|
||
|
||
// #ifndef H5
|
||
uni.getSetting({
|
||
success: async (res) => {
|
||
if(!res.authSetting['scope.userLocation']){
|
||
uni.showModal({
|
||
title:"权限受限",
|
||
content:"你禁止了位置受限,请打开设置,允许访问地址!否则功能无法使用。",
|
||
cancelText:"我已允许",
|
||
confirmText:"前往设置",
|
||
success: async (rks) => {
|
||
if(rks.cancel==true){
|
||
await t.getLocation();
|
||
return
|
||
}
|
||
uni.openSetting({})
|
||
}
|
||
})
|
||
return;
|
||
}
|
||
|
||
uni.getLocation({
|
||
type: 'gcj02', //返回可以用于uni.openLocation的经纬度
|
||
success:async function (res) {
|
||
const latitude = res.latitude;
|
||
const longitude = res.longitude;
|
||
t.now_latitude = latitude;
|
||
t.now_longitude = longitude;
|
||
t.mapCenter = {
|
||
lat:latitude,
|
||
lng:longitude
|
||
}
|
||
|
||
t.moveMap(t.mapCenter.lat,t.mapCenter.lng)
|
||
await t.moveMarkes(latitude,longitude)
|
||
//缓存定位点。否则失败,间隔15s小于15秒。不允许调用。
|
||
uni.setStorageSync('tmvue_map_selectePoint',{latitude:latitude,longitude:longitude})
|
||
},
|
||
fail: async (err) => {
|
||
let p = uni.getStorageSync('tmvue_map_selectePoint');
|
||
|
||
try{
|
||
|
||
if(typeof p == 'object'){
|
||
const latitude = p .latitude;
|
||
const longitude = p .longitude;
|
||
t.now_latitude = latitude;
|
||
t.now_longitude = longitude;
|
||
t.mapCenter = {
|
||
lat:latitude,
|
||
lng:longitude
|
||
}
|
||
t.moveMap(t.mapCenter.lat,t.mapCenter.lng)
|
||
await t.moveMarkes(latitude,longitude)
|
||
}
|
||
}catch(e){
|
||
uni.$tm.toast('请间隙至少15s调用,不可频繁定位。')
|
||
}
|
||
|
||
}
|
||
});
|
||
|
||
},
|
||
fail: (res) => {
|
||
uni.$tm.toast("系统错误")
|
||
}
|
||
})
|
||
// #endif
|
||
|
||
|
||
//h5通过ip定位
|
||
// #ifdef H5
|
||
|
||
uni.showLoading({
|
||
mask:true,title:'...'
|
||
})
|
||
|
||
//没有获取到地址资料。通过Ip尝试定位 。
|
||
let adressPoiObj = await uni.$tm.request.get("https://apis.map.qq.com/ws/location/v1/ip?key="+this.mapKey).catch(e=>{
|
||
uni.hideLoading();
|
||
uni.$tm.toast("地址解析错误")
|
||
})
|
||
|
||
if(adressPoiObj['status']==0){
|
||
t.now_latitude = adressPoiObj.result.location.lat;
|
||
t.now_longitude = adressPoiObj.result.location.lng;
|
||
t.map.moveToLocation({
|
||
latitude:t.now_latitude,
|
||
longitude:t.now_longitude
|
||
})
|
||
t.moveMap(t.mapCenter.lat,t.mapCenter.lng)
|
||
t.markers = [t.createMarker( adressPoiObj.result.location.lat,adressPoiObj.result.location.lng)]
|
||
await t.poiSidel_byTencentMap(adressPoiObj.result.location.lat,adressPoiObj.result.location.lng)
|
||
}
|
||
|
||
// #endif
|
||
},
|
||
createMarker(latitude,longitude){
|
||
|
||
let id = 636598;
|
||
let label = {
|
||
content:'',
|
||
color:'#000000',
|
||
fontSize:12,
|
||
bgColor:'red',
|
||
padding:5,
|
||
textAlign:'center',
|
||
|
||
}
|
||
return {
|
||
id:id,
|
||
iconPath:'/static/posiimg.png',
|
||
width:45,
|
||
height:45,
|
||
latitude:latitude,
|
||
longitude:longitude,
|
||
label:label,
|
||
|
||
}
|
||
},
|
||
moveMapChange(e){
|
||
var etype = ''
|
||
// #ifdef APP-PLUS
|
||
etype = 'end'
|
||
// #endif
|
||
// #ifdef MP-WEIXIN
|
||
etype = e.type
|
||
// #endif
|
||
clearTimeout(this.timeid);
|
||
if(etype ==='end'){
|
||
|
||
let t = this;
|
||
this.timeid = setTimeout(function() {
|
||
|
||
t.map.getCenterLocation({
|
||
success:async (res)=>{
|
||
await t.moveMarkes(res.latitude,res.longitude)
|
||
}
|
||
})
|
||
}, 350);
|
||
}
|
||
|
||
|
||
},
|
||
async selecListitem(item){
|
||
let t = this;
|
||
this.$set(this.adress,'adress',item.address)
|
||
await this.moveMarkes(item.location.latitude,item.location.longitude)
|
||
this.activeId = item.id;
|
||
},
|
||
async moveMarkes(latitude,longitude,callback){
|
||
let t = this;
|
||
t.markers = []
|
||
await uni.$tm.sleep(50)
|
||
if(t.markers.length==0){
|
||
t.markers = [t.createMarker( latitude,longitude)]
|
||
}
|
||
t.now_latitude = latitude;
|
||
t.now_longitude = longitude;
|
||
t.poiSidel_byTencentMap(latitude,longitude)
|
||
},
|
||
//mp腾讯地址获取当前地址资料。
|
||
async poiSidel_byTencentMap(latitude,longitude){
|
||
let t = this;
|
||
uni.showLoading({
|
||
mask:true,title:'...'
|
||
})
|
||
let lot=`location=${latitude},${longitude}&get_poi=1&key=${this.mapKey}`
|
||
let adressPoiObj = await uni.$tm.request.get("https://apis.map.qq.com/ws/geocoder/v1/?"+lot).catch(e=>{
|
||
uni.hideLoading();
|
||
uni.$tm.toast("地址解析错误")
|
||
})
|
||
uni.hideLoading();
|
||
if(adressPoiObj.status!==0){
|
||
uni.$tm.toast(adressPoiObj.message)
|
||
return;
|
||
}
|
||
let adress = adressPoiObj.result;
|
||
this.$set(this.adress,'adress',adress.address)
|
||
this.$set(this.adress,'city',[adress.address_component.province,adress.address_component.city,adress.address_component.district]);
|
||
this.$emit('change',{...this.adress,latitude:this.now_latitude,longitude:this.now_longitude})
|
||
let pos = adress.pois;
|
||
if(pos.length==0) return;
|
||
let list = [];
|
||
for(let i=0;i<pos.length;i++){
|
||
list.push({
|
||
address:pos[i].address,
|
||
name:pos[i].title,
|
||
id:pos[i].id,
|
||
location:{
|
||
latitude:pos[i].location.lat,
|
||
longitude:pos[i].location.lng
|
||
}
|
||
})
|
||
}
|
||
|
||
this.adressList = list;
|
||
}
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
|
||
</style>
|