微信公众号h5界面获取展示微信内置地图与地图坐标间的转换 — 微信地图(gcj02)转为百度地图

此文章中实例用测试号进行演示 。getLocation openLocation

主要运用微信JS-SDK,微信JS-SDK是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
微信网页开发JS-SDK说明文档

使用

1、首先公众号中需要配置JS接口安全域名

注意:域名不能添加 httphttps
微信公众号h5界面获取展示微信内置地图与地图坐标间的转换 — 微信地图(gcj02)转为百度地图_第1张图片

2、配置支持环境

1)引入JS文件,在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js

如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)

2)或引入 weixin-jsapi'

import wx from 'weixin-jsapi'

3、设置 config 接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。通过 wx.config

wx.config({
  debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  appId: '', // 必填,公众号的唯一标识
  timestamp: , // 必填,生成签名的时间戳
  nonceStr: '', // 必填,生成签名的随机串
  signature: '',// 必填,签名
  jsApiList: [] // 必填,需要使用的JS接口列表
});

config 接口中所需参数,示例中是从后台获取的。

const url = window.location.href.split('#')[0] // 当前界面的地址,取#之前的;url域名必须与之前设置的JS接口安全域名一致
this.$http({
  url: this.$http.adornUrl(this.$store.state.urlCommon + '/createJsapiSignature'),
  method: 'get',
  params: this.$http.adornParams({url: url})
}).then(({data}) => {
  if (data.code !== 0) {
    return
  }
  wx.config({
    debug: false,
    appId: data.signature.appId,
    timestamp: data.signature.timestamp,
    nonceStr: data.signature.nonceStr,
    signature: data.signature.signature,
    jsApiList: ['getLocation'] // 获取定位地址
  })
})

4、通过 ready 接口处理成功验证

config 信息验证后会执行 ready 方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

wx.ready(function(){
	// xxx
});

通过error接口处理失败验证

config 信息验证失败会执行 error 函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

wx.error(function(res){
	// xxx
});

5、wx.getLocation 获取定位

let that = this // 为在getLLocation success 方法中使用外层this
wx.ready(() => {
  wx.getLocation({
    debug: false,
    type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
    success: function (res) {
    	that.latitude = parseFloat(res.latitude) // 纬度,浮点数,范围为90 ~ -90
        that.longitude = parseFloat(res.longitude) // 经度,浮点数,范围为180 ~ -180。
	},
    fail: function (err) { // 接口调用失败时执行的回调函数。
      console.log(err)
    }
})
接口调用说明

所有接口通过wx对象(也可使用jWeixin对象)来调用,参数是一个对象,除了每个接口本身需要传的参数之外,还有以下通用参数:

  • success:接口调用成功时执行的回调函数。
  • fail:接口调用失败时执行的回调函数。
  • complete:接口调用完成时执行的回调函数,无论成功或失败都会执行。
  • cancel:用户点击取消时的回调函数,仅部分有用户取消操作的api才会用到。
  • trigger: 监听Menu中的按钮点击时触发的方法,该方法仅支持Menu中的相关接口。

备注:不要尝试在trigger中使用ajax异步请求修改本次分享的内容,因为客户端分享操作是一个同步操作,这时候使用ajax的回包会还没有返回。

以上几个函数都带有一个参数,类型为对象,其中除了每个接口本身返回的数据之外,还有一个通用属性errMsg,其值格式如下:

调用成功时:"xxx:ok",其中xxx为调用的接口名

用户取消时:"xxx:cancel",其中xxx为调用的接口名

调用失败时:其值为具体错误信息

完整实例

获取当前用户定位

import wx from 'weixin-jsapi'
this.$http({
 url: this.$http.adornUrl(this.$store.state.urlCommon + '/createJsapiSignature'),
  method: 'get',
  params: this.$http.adornParams({url: url})
}).then(({data}) => {
  if (data.code !== 0) {
    return
  }
  wx.config({
    debug: false, 
    appId: data.signature.appId,
    timestamp: data.signature.timestamp,
    nonceStr: data.signature.nonceStr,
    signature: data.signature.signature,
    jsApiList: ['getLocation', 'openLocation']
  })
  wx.ready(() => {
    wx.getLocation({
      debug: false,
      type: 'gcj02', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
      success: function (res) {
        that.latitude = parseFloat(res.latitude) // 纬度,浮点数,范围为90 ~ -90
        that.longitude = parseFloat(res.longitude) // 经度,浮点数,范围为180 ~ -180。
        if (!that.longitude || !that.latitude) {
          that.loading = false
          that.$dialog.alert({
            message: `维修完成前,需要获取地理位置,请确认手机定位功能已开启`,
          })
          return false
        }
        wx.openLocation({
          latitude: that.latitude, // 纬度,浮点数,范围为90 ~ -90
          longitude: that.longitude, // 经度,浮点数,范围为180 ~ -180。
          name: '', // 位置名
          address: '', // 地址详情说明
          scale: 20, // 地图缩放级别,整形值,范围从1~28。默认为最大
          infoUrl: '' // 点位链接
         })
      },
      fail: function (err) {
        console.log(err)
      }
    })
  })
}).catch((err) => {
  console.log(err)
})

wx.getLocation 中的 type 默认为 wgs84的gps 坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'

经纬度转换

火星坐标(gcj02),腾讯、Google、高德通用,**百度地图(百度坐标BD-09)**有自己的坐标。若为 wgs84 ,位置回显会出现偏差。改为 gcj02 虽然微信端或者腾讯高德通用 gcj02 坐标的不会发生偏差,但是 pc 端若用百度地图,就会出现较大偏差。所以还需要解决经纬度转换。

gcj02 转为 百度地图

// 地图转换
// 参数形式为lng,lat
// 返回值:lng,lat
gcj2bdString (lng, lat) {
   const xpi = 3.14159265358979324 * 3000.0 / 180.0
   const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * xpi)
   const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * xpi)
   return {lng: z * Math.cos(theta) + 0.0065, lat: z * Math.sin(theta) + 0.006}
 }

微信地图(gcj02)转为百度地图

参考百度地图接口文档

http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=你的密钥 //GET请求

微信公众号h5界面获取展示微信内置地图与地图坐标间的转换 — 微信地图(gcj02)转为百度地图_第2张图片
所以此处我们用的是:

`http://api.map.baidu.com/geoconv/v1/?coords=${that.longitude},${that.latitude}&from=3&to=5&ak=yourAK`

跨域的解决

本地请求接口可通过设置代理处理跨域问题:
config/index.js
微信公众号h5界面获取展示微信内置地图与地图坐标间的转换 — 微信地图(gcj02)转为百度地图_第3张图片

线上此时需要配置ngix,设置线上代理;若不想要配置代理,可用 jsonp 解决跨域

使用 jsonp

一、安装 jsonp

npm install vue-jsonp --save

二、main.js 中引入

import {VueJsonp} from 'vue-jsonp'
Vue.use(VueJsonp)

三、组件中使用(this.$jsonp(url).then())

const url = `http://api.map.baidu.com/geoconv/v1/?coords=${that.longitude},${that.latitude}&from=3&to=5&ak=yourAk`                
this.$jsonp(url).then(res => {
  if (res.status === 0) {
   let params = {
     longitude: res.result[0].x,
     latitude: res.result[0].y
   }
})

你可能感兴趣的