1***@qq.com
1***@qq.com
  • 发布:2020-03-27 11:59
  • 更新:2024-04-24 11:20
  • 阅读:15627

uniapp h5 位置选择,微信定位+腾讯位置服务获取当前地址,逆地址解析

分类:uni-app

uniapp h5 位置选择,微信定位+腾讯位置服务获取当前地址,逆地址解析
https://wanghuohuo.blog.csdn.net/article/details/105137028
一、获取当前地理坐标
首先引入JSSDK

npm install jweixin-module --save
使用

var jweixin = require('jweixin-module')
jweixin.ready(function(){
// TODO
});
DCloud官网的论坛,有分享的例子http://ask.dcloud.net.cn/article/36007。

 

我这里做个定位接口例子。

首先要看微信的文档。清楚大致的流程。https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

1、common目录,创建文件,名称是wechat.js。内容如下:

   注意要点:

1、前端域名要放在微信公众平台js安全域名下。

2、 url:(window.location.href).split('#')[0]  当前页面url作为参数 进行数字签名。

// import request from './request';
var jweixin = require('jweixin-module');
import store from '@/store'
import api from '@/common/vmeitime-http/' //自己封装的网络请求类,也可以直接使用uni.request

export default {
//判断是否在微信中
isWechat: function() {
var ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/micromessenger/i) == 'micromessenger') {
// console.log('是微信客户端')
return true;
} else {
// console.log('不是微信客户端')
return false;
}
},
//初始化sdk配置
initJssdkShare: function(callback, url) {
//服务端进行签名 ,可使用uni.request替换。 签名算法请看文档
post(
'https://fbyc.microchainsoft.cn/index/wechat/getSignPackage',
{
url: url
},
function(res) {
// console.log(res)
if (res.data) {
jweixin.config({
debug: true,
appId: res.data.appId,
timestamp: res.data.timestamp,
nonceStr: res.data.nonceStr,
signature: res.data.signature,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage',
'getLocation'
]
});
//配置完成后,再执行分享等功能
if (callback) {
callback(res.data);
}
}
});
},
initJssdk:function(callback){

    api.getAddressCoordinate({  
            appId:uni.getStorageSync('hmAppId'),  
            url:(window.location.href).split('#')[0]  
        }).then((res)=>{  
            if(res.data){  
                console.log(".data===="+JSON.stringify(res.data))  
                console.log(".data.data===="+JSON.stringify(res.data.data))  
                jweixin.config({  
                    debug: false,  
                    appId: res.data.data.appId,  
                    timestamp: res.data.data.timestamp,  
                    nonceStr: res.data.data.nonceStr,  
                    signature: res.data.data.signature,  
                    jsApiList: [  
                        'checkJsApi',  
                        'getLocation'  
                    ]  
                });  
                //配置完成后,再执行分享等功能    
                if (callback) {  
                    callback(res.data);  
                }  
            }  
            }).catch((err) => {  
                    console.log("微信signature失败"+err)  
            })  
},  
//在需要自定义分享的页面中调用    
share: function(data, url) {  
    url = url ? url : window.location.href;  
    if (!this.isWechat()) {  
        return;  
    }  
    //每次都需要重新初始化配置,才可以进行分享    
    this.initJssdkShare(function(signData) {  
        jweixin.ready(function() {  
            var shareData = {  
                title: data && data.title ? data.title : signData.site_name,  
                desc: data && data.desc ? data.desc : signData.site_description,  
                link: url,  
                imgUrl: data && data.img ? data.img : signData.site_logo,  
                success: function(res) {  
                    //用户点击分享后的回调,这里可以进行统计,例如分享送金币之类的    
                    // post('/api/member/share');  
                },  
                cancel: function(res) {}  
            };  
            //分享给朋友接口    
            jweixin.onMenuShareAppMessage(shareData);  
            //分享到朋友圈接口    
            jweixin.onMenuShareTimeline(shareData);  
        });  
    }, url);  
},  
//在需要定位页面调用  
location: function(callback) {  
    if (!this.isWechat()) {  
        console.log('不是微信客户端')  
        return;  
    }  
    console.info('定位')  
    this.initJssdk(function(res) {  
        jweixin.ready(function() {  
            console.info('定位ready')  
            jweixin.getLocation({  
                type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'  
                success: function (res) {  
                    // console.log(res);  
                    callback(res)  
                },  
                fail:function(res){  
                    console.log(res)  
                },  
                // complete:function(res){  
                //     console.log(res)  
                // }  
            });  
        });  
    });  
}  

}
 2、main.js加载该文件

// #ifdef H5
import wechat from './common/util/wechat'
if(wechat.isWechat()){
Vue.prototype.$wechat =wechat;
}
// #endif
3、页面中使用 

// #ifdef H5
//获取定位经纬度
if (this.$wechat && this.$wechat.isWechat()) {
this.$wechat.location(function (res) {
console.log(res)
// let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
// let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
// todo
let latitude = 31.14979;
let longitude = 121.12426;

                //根据经纬度,解析区域,提示用户输入  
             });  
        }  
        // #endif  

 

 
二、逆地址解析
1、腾讯位置服务申请 服务调用前提 KEY

2、引入vue-jsonp 解决腾讯位置服务跨域请求问题

npm install vue-jsonp --save  

使用

import VueJsonp from 'vue-jsonp'

Vue.use(VueJsonp)

调用

this.$jsonp(url,{
                          key: this.publicKey,
                          location: locationObj
                        }).then(e => {
                            res(e.result);
                        })
                        .catch(err => {
                            res(err);
                        })

3、引入mimap组件 https://ext.dcloud.net.cn/plugin?id=1448

qqmap-wx-jssdk.min.js 可从微信下载

<template> <view class="server-place"> <map id='map' ref='map' v-bind:style="{height: mapH + 'px'}" style="width: 100%;" latitude="latitude" longitude="longitude"

controls='controls' @regionchange='mapChange'>
</map>

<view class="map-tools">  

    <view class="my-location" @click.stop="toMyLocation">  
        <image class="left" src="/static/img/areame.png" mode=""></image>  
        <view class="right">  
            <text class="title">我的位置</text>  
            <text class="text">{{myAddress}}</text>  
        </view>  
    </view>  

    <view class="start-place">  
        <view class="place">  
            <text class="title">{{tipText}}</text>  
            <text class="text">{{addressObj.address.formatted_addresses.recommend}}</text>  
        </view>  
        <view class="tip">{{descText}}</view>  
        <button @click.stop="submitAdress" class="sure" type="primary">确认选择</button>  
    </view>  
</view>  

</view>

</template>

<script>
var jweixin = require('jweixin-module');
const app = getApp()
var QQMapWX = require('./qqmap-wx-jssdk.min.js')
var qqmapsdk = new QQMapWX({
key: 'LXCBZ-NNIKD-UZ64F-H6AFI-UNJLH-OCFGE' //app的key
})
// 'YVEBZ-JS7LF-PK2JW-JJNFX-BITHO-ATB57'
export default {
props: {
tipText: {
type: String,
default: '选择位置'
},
descText: {
type: String,
default: '使用当前定位或在地图上标记位置'
},
},
data() {
return {
publicKey:'',// h5的key
mapH: 0, // 地图高度,可在initMapH()中设置高度
longitude: 0, // 初始经度
latitude: 0, // 初始纬度
myAddress: '', // 初始地址信息
addressObj: { // 地图选点信息
longitude: '',
latitude: '',
address: {
address:'',
formatted_addresses:{
recommend:'请选择位置'
}
}

            },  
            controls: [           // 地图中心点图标, 可更换iconPath, 详情见官方文档关于map组件的介绍  
                {  
                    iconPath: '/static/img/areacenter.png',  
                    position: {   
                        // left: 175,  
                        left: window.screen.width/2-20,  
                        top: 210,  
                        width: 40,   
                        height: 40,  
                    },  
                    clickable: false  
                }  
            ],  
        };  
    },  
    mounted() {  
        let _this = this  
        _this.$api.getAddressKey({  
            appId: uni.getStorageSync('hmAppId'),  
        }).then(res=>{  
            if(res.data.code == 10000){  
                _this.publicKey=res.data.data.key;  
                this.getLocation()  
                this.initMapH()  
            }  
        }).catch(res=>{  
            console.error("查询key失败: " + JSON.stringify(res));  
        })  
    },  
    methods:{  
        // 查询现在的位置  
        getLocation() {  
            let this_ = this  
             if (this.$wechat && this.$wechat.isWechat()) {  
                this.$wechat.location(function (res) {  
                    console.log(res)  
                    let latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90  
                    let longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。  
                    let res2={  
                            latitude: latitude ,  
                            longitude: longitude  
                        }  
                        this_.initMap(res2)  

                    //根据经纬度,解析区域,提示用户输入  
                });  
            }else{  
                console.error("不在微信环境中")  
            }  
        },  

        // 初始化我的位置  
        async initMap(res) {  
            this.longitude = res.longitude;  
            this.latitude = res.latitude;  

            this.addressObj = Object.assign({}, this.addressObj,{  
                longitude: res.longitude,  
                latitude: res.latitude,  
                address: await this.getAddressName(res)  
            })  
            this.myAddress = this.addressObj.address.formatted_addresses.recommend  
        },  

        // 地图选择位置后 查询地点名称  
        async checkMap(res) {  
            this.addressObj = Object.assign({}, this.addressObj,{  
                longitude: res.longitude,  
                latitude: res.latitude,  
                address: await this.getAddressName(res)  
            })  
            console.log('当前位置:' + res.latitude + '|' + res.longitude);  
        },  

        // 监听地图位置变化  
        mapChange(e) {  
            let that = this  
            clearTimeout(this.timer)  
            this.timer = setTimeout(() => {  
                if (e.type == 'end') {  
                    that.mapCtx = uni.createMapContext('map', this)  
                    that.mapCtx.getCenterLocation({  
                        success: res => {  
                            this.checkMap(res)  
                        },  
                        fail: err => {  
                            console.log(err);  
                        }  
                    })  
                }  
            }, 200)  
        },  
        // 查询地图中心点的名称  
        getAddressName(addressObj) {  

            return new Promise((res) => {  
                // #ifdef APP-PLUS  
                    qqmapsdk.reverseGeocoder({  
                        location: {  
                            latitude: addressObj.latitude,  
                            longitude: addressObj.longitude  
                        },  
                        get_poi: 1,  
                        poi_options: "page_size=1;page_index=1",  
                        output: 'jsonp',  
                        success: (e) => {  
                            res(e.result.formatted_addresses.recommend);  
                        },  
                        fail: err => {  
                            res(err);  
                        }  
                    })  
                // #endif  

                // #ifndef APP-PLUS  
                    // ======================== jsonp跨域 ========================   
                    let locationObj = addressObj.latitude+','+addressObj.longitude  
                    let url = 'https://apis.map.qq.com/ws/geocoder/v1?coord_type=5&get_poi=1&output=jsonp&poi_options=page_size=1;page_index=1';  
                    this.$jsonp(url,{  
                      key: this.publicKey,  
                      location: locationObj  
                    }).then(e => {  
                        res(e.result);  
                    })  
                    .catch(err => {  
                        res(err);  
                    })  
                // #endif  

            })  

        },  
        // 计算地图的高度  
        initMapH() {  
            // #ifdef APP-PLUS  
                this.mapH = uni.getSystemInfoSync().windowHeight - 210;  
            // #endif  
            // #ifndef APP-PLUS  
                this.mapH = uni.getSystemInfoSync().windowHeight - 170;  
            // #endif  
        },  
        // 移动到我的位置  
        toMyLocation() {  
            this.getLocation()  
        },  
        // 提交  
        submitAdress() {  
            this.controls = []  
            setTimeout(() => {  
                this.$emit('selectAddress', this.addressObj)  
            }, 100)  
        }  
    },  
}  

</script>

<style lang="scss" scoped>
.server-place{
position: fixed;
left: 0;
top: 0;
height: 100vh;
width: 100%;
background: #ffffff;
z-index: 999;
.icon-img{
width: 36px;
height: 36px;
display: block;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
margin-top: -70px;
}
.map-tools{
position: fixed;
width: 100%;
bottom: 0rem;
left: 0;
padding-bottom: .5rem;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.my-location{
width: 90%;
margin: 0 auto;
height: 2.5rem;
box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);
background: #fff;
border-radius: 0.5rem;
display: flex;
justify-content: flex-start;
align-items: center;
overflow: hidden;
.left{
background: #3384ff;
// flex: 20%;
width: 2.5rem;
height: 100%;
}
.right{
font-size: 0.57rem;
margin-left: .5rem;
color: #111;
// flex: 80%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
.text{
width: 12rem;
overflow: hidden;
white-space:nowrap;
text-overflow: ellipsis;
color: #3384FF;
margin-top: .3rem;
}
}
}

        .start-place{  
            width: 85%;  
            margin: 0 auto;  
            height: 5.5rem;  
            margin: 0 auto;  
            margin-top: .6rem;  
            box-shadow: 0px 3px 20px rgba(0, 0, 0, 0.2);  
            background: #fff;  
            border-radius: 0.5rem;  
            padding: .5rem;  
            .place{  
                .title{  
                    font-size: 0.67rem;  
                    font-weight: bold;  
                    color: #111;  
                }  
                .text{  
                    font-size: 0.76rem;  
                    color: #3384FF;  
                    font-weight: bold;  
                    width: 12rem;  
                    vertical-align: middle;  
                    display: inline-block;  
                    margin-left: .5rem;  
                    overflow: hidden;  
                    white-space:nowrap;  
                    text-overflow: ellipsis;  
                }  
            }  
            .tip{  
                font-size: 0.57rem;  
                color: #666;  
                margin-top: .5rem;  
            }  
            .sure{  
                margin-top: .5rem;  
                color: #FFFFFF;  
                background: #212121;  
                font-weight: 600;  
            }  

        }  
    }  
}  

</style>
4、相关图标

  https://share.weiyun.com/5aMXvh8

3 关注 分享
aliang888 无心之水 闫明

要回复文章请先登录注册

闫明

闫明

有用
2024-04-24 11:20
tpframe2020

tpframe2020

这发的什么鬼,复制粘贴也认真点吧
2020-12-16 17:23