300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 微信公众号h5实现高德/百度/腾讯地图导航

微信公众号h5实现高德/百度/腾讯地图导航

时间:2020-08-12 00:18:06

相关推荐

微信公众号h5实现高德/百度/腾讯地图导航

最近做了个微信公众号h5需求是这样的

1.点击地图进入地图详情

2.地图详情包括开始导航与地图(高德,百度,腾讯)选择,点击开始导航自动跳转该地图app

首先先理一下功能:

1:第一张图是直接显示坐标位置,除了点击进入地图,没有其他的交互,所以就只用了高德地图做的显示;

2:第二张图进入详情,显示坐标位置,点击下面按钮进行高德/百度/腾讯三种地图切换,并且可以进行导航,做导航的话需要进行当前地图定位(定位我用的是微信jssdk)。

说一下高德/百度/腾讯的三种坐标,在进行地图开发过程中,我们一般能接触到以下三种类型的地图坐标系:

1.WGS-84原始坐标系,一般用国际GPS纪录仪记录下来的经纬度,通过GPS定位拿到的原始经纬度,Google和高德地图定位的的经纬度(国外)都是基于WGS-84坐标系的;但是在国内是不允许直接用WGS84坐标系标注的,必须经过加密后才能使用;

2.GCJ-02坐标系,又名“火星坐标系”,是我国国测局独创的坐标体系,由WGS-84加密而成,在国内,必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,可以说,GCJ-02是国内最广泛使用的坐标系;

3.百度坐标系:bd-09,百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系,只适用于百度地图。(目前百度API提供了从其它坐标系转换为百度坐标系的API,但却没有从百度坐标系转为其他坐标系的API)

我拿到的后端的数据返回的是wgs-84坐标,在切换成高德/百度/腾讯地图时,我们要根据情况进行坐标转换,否则显示的坐标会有偏移

下面贴下几种坐标转换代码:

//GCJ-02 to WGS-84gcj_decrypt: function (gcjLat, gcjLon) {let PI = 3.14159265358979324;function outOfChina(lat, lon) {if (lon < 72.004 || lon > 137.8347)return true;if (lat < 0.8293 || lat > 55.8271)return true;return false;}function delta(lat, lon) {let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子let ee = 0.00669342162296594323; // ee: 椭球的偏心率let dLat = transformLat(lon - 105.0, lat - 35.0);let dLon = transformLon(lon - 105.0, lat - 35.0);let radLat = lat / 180.0 * PI;let magic = Math.sin(radLat);magic = 1 - ee * magic * magic;let sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);return {'lat': dLat, 'lon': dLon };}function transformLat(x, y) {let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;return ret;}function transformLon(x, y) {let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;return ret}if (outOfChina(gcjLat, gcjLon)) return [Number(gcjLon), Number(gcjLat)];let d = delta(gcjLat, gcjLon);return [Number(gcjLon) - d.lon, Number(gcjLat) - d.lat];},// WGS-84 to GCJ-02gcj_encrypt: function (wgsLat, wgsLon) {let PI = 3.14159265358979324;function outOfChina(lat, lon) {if (lon < 72.004 || lon > 137.8347)return true;if (lat < 0.8293 || lat > 55.8271)return true;return false;}function delta(lat, lon) {let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子let ee = 0.00669342162296594323; // ee: 椭球的偏心率let dLat = transformLat(lon - 105.0, lat - 35.0);let dLon = transformLon(lon - 105.0, lat - 35.0);let radLat = lat / 180.0 * PI;let magic = Math.sin(radLat);magic = 1 - ee * magic * magic;let sqrtMagic = Math.sqrt(magic);dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * PI);return {'lat': dLat, 'lon': dLon };}function transformLat(x, y) {let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;return ret;}function transformLon(x, y) {let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;return ret}if (outOfChina(wgsLat, wgsLon)) return [Number(wgsLon), Number(wgsLat)];let d = delta(wgsLat, wgsLon);return [Number(wgsLon) + d.lon, Number(wgsLat) + d.lat];},//百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换bd09toGCJ(bd_lon, bd_lat) {var x_pi = 3.14159265358979324 * 3000.0 / 180.0;var x = bd_lon - 0.0065;var y = bd_lat - 0.006;var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);var gg_lng = z * Math.cos(theta);var gg_lat = z * Math.sin(theta);return this.gcj_decrypt(gg_lat, gg_lng)},//火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换GCJtobd09(lng, lat) {var x_PI = 3.14159265358979324 * 3000.0 / 180.0;var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);var bd_lng = z * Math.cos(theta) + 0.0065;var bd_lat = z * Math.sin(theta) + 0.006;return [bd_lng, bd_lat]}

下面正式开始进入开发

高德地图定位

百度地图定位

由于调起导航是需要定位的,高德地图给出这样一段话:由于Chrome、IOS10等已不再支持非安全域的浏览器定位请求,为保证定位成功率和精度,请尽快升级您的站点到HTTPS。我们公司现在的域名还是http,所以高德地图定位获取不到。在做百度地图定位的时候,定位返回状态是BMAP_STATUS_SUCCESS成功的,但是定位距离我自己的准确位置相差了几十公里(暂时还没有找到原因),而后采用了微信jsjdk的定位

微信jssdk获取当前用户定位

贴下获取当前定位代码:

//从微信jssdk获取当前定位getConfig() {let that = this//从后端获取微信公众号参数this.$api.weixinjs().then(res => {wx.config({beta: true,debug: false,appId: res.data.appId, // 必填,公众号的唯一标识timestamp: res.data.timestamp, // 必填,生成签名的时间戳nonceStr: res.data.nonceStr, // 必填,生成签名的随机串signature: res.data.signature,// 必填,签名,见附录1jsApiList: ['checkJsApi', 'getLocation', 'openLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});wx.checkJsApi({jsApiList: ['getLocation'],success: function (res) {if (res.checkResult.getLocation == false) {that.$toast('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');return;}},fail: function (res) {console.log('checkJsApi fail=' + JSON.stringify(res))}});wx.ready(function () {wx.getLocation({type: "gcj02", //jssdk获取的坐标类型success: function (res) {console.log(res, 'success')that.GCJPosition.lat = res.latitude //纬度that.GCJPosition.lng = res.longitude //经度},cancel: function (res) {console.log(res, 'cancel')},fail: function (res) {console.log('fail', res)}});})})},

高德地图

// 初始化高德地图initAMap() {this.showmore = false// 实例化地图var mapObj = new AMap.Map('baidu-map', {resizeEnable: true,zoom: 17,zooms: [8, 17]});this.mapObj = mapObj;if (location.href.indexOf('&guide=1') !== -1) {mapObj.setStatus({scrollWheel: false })}this.addMark(this.position)},// 高德地图加点标记addMark(position) {var marker = new AMap.Marker({content: '<div class="marker-route marker-marker-bus-from locationMarker"></div>',offset: new AMap.Pixel(-13, -34),position: position});this.mapObj.setCenter(position);this.userLocation = marker;this.userLocation.setMap(this.mapObj);//点击标记点进行导航marker.on('click', function (e) {marker.markOnAMAP({position: marker.getPosition()})})},

百度地图

// 初始化百度地图initBMap() {this.showmore = falselet map = new BMap.Map('baidu-map');var point = new BMap.Point(168.95, 34.27);map.centerAndZoom(point, 18);let that = thisthis.bdPosition = this.$map.GCJtobd09(this.position[0], this.position[1]) //后端接口数据this.curP = this.$map.GCJtobd09(that.GCJPosition.lng, that.GCJPosition.lat) //当前坐标(gcj02)转成百度坐标let pt = new BMap.Point(this.bdPosition[0], this.bdPosition[1]);var mk = new BMap.Marker(pt);map.addOverlay(mk);//标出所在地map.panTo(pt);//地图中心移动var point = new BMap.Point(this.position[0], this.position[1]);//用所定位的经纬度查找所在地省市街道等信息mk.addEventListener("click", function (e) {window.location.href = `http://api./direction?origin=latlng:${this.curP[1]},${this.curP[0]}|name:我的位置&destination=${this.bdPosition[1]},${this.bdPosition[0]}&mode=driving&region=上海&output=html`;});},

腾讯地图

// 初始化腾讯地图initTMap() {console.log('初始化腾讯地图')this.showmore = falselet that = thisvar myLatlng = new qq.maps.LatLng(this.position[1], this.position[0]);//定义工厂模式函数var myOptions = {zoom: 17,//设置地图缩放级别center: myLatlng,//设置中心点样式mapTypeId: qq.maps.MapTypeId.ROADMAP //设置地图样式详情参见MapType}//获取dom元素添加地图信息var map = new qq.maps.Map(document.getElementById("baidu-map"), myOptions);var latlngs = [new qq.maps.LatLng(this.position[1], this.position[0])];for (var i = 0; i < latlngs.length; i++) {(function (n) {//实例标注var marker = new qq.maps.Marker({position: latlngs[n],map: map});//标注点击事件qq.maps.event.addListener(marker, 'click', function (e) {window.location.href = `https://apis./uri/v1/routeplan?type=bus&to=终点&tocoord=${that.position[1]},${that.position[0]}&referer=PGCBZ-7XVC3-XKO36-3CEGN-B2L63-XYBHT`;});})(i);}},

完整的页面功能实现代码

<template><div><div id="baidu-map" style="width: 100%;height: 100%;"></div><slot></slot><div class="map-btn"><div class="fix-btn" v-show="showmore"><div><span @click="initMap($event)">{{this.fixBtn[0]}}</span><span><img src="../assets/img/map/arrow_down_blue@2x.png" alt="" @click="showmore = !showmore" v-show="showmore"></span></div><div><span @click="initMap($event)">{{this.fixBtn[1]}}</span><span></span></div></div><div class="map-type"><span @click="initMap($event)">{{defaultBtn[0]}}</span><span><img src="../assets/img/map/arrow_up_blue@2x.png" alt="" @click="showmore = !showmore" v-show="!showmore"></span></div><div class="guide-btn" @click="beginGuide">开始导航</div></div></div></template><script>export default {name: "com-map",data() {return {btns: ['百度地图', '腾讯地图', '高德地图'],defaultBtn: ['高德地图'],fixBtn: [],showmore: false,position: [],mapObj: null, // 地图实例userLocation: null, // 用户位置 or 中心位置geolocation: null, // 定位geocoder: null, // 地理编码type: '高德地图',//百度地图参数center: {lng: 109.45744048529967, lat: 36.49771311230842 },zoom: 13,GCJPosition: {lat: 0,lng: 0},//微信获取的当前定位curP: [],bdPosition: []}},methods: {//点击切换地图initMap(e) {this.showmore = falsethis.defaultBtn[0] = e.target.innerHTMLthis.filterBtn()this.type = e.target.innerHTMLswitch (e.target.innerHTML) {case '百度地图': this.initBMap(); break;case '腾讯地图': this.initTMap(); break;case '高德地图': this.initAMap(); break;}},//开始导航beginGuide() {switch (this.type) {case '百度地图':window.location.href = `http://api./direction?origin=latlng:${this.curP[1]},${this.curP[0]}|name:我的位置&destination=${this.bdPosition[1]},${this.bdPosition[0]}&mode=driving&region=上海&output=html`;break;case '腾讯地图':window.location.href = `https://apis./uri/v1/routeplan?type=bus&to=终点&tocoord=${this.position[1]},${this.position[0]}&referer=PGCBZ-7XVC3-XKO36-3CEGN-B2L63-XYBHT`;break;case '高德地图':window.location.href = `/marker?position=${this.position[0]},${this.position[1]}&coordinate=gaode&callnative=1`break;}},//从微信jssdk获取当前定位getConfig() {let that = thisthis.$api.weixinjs().then(res => {wx.config({beta: true,debug: false,appId: res.data.appId, // 必填,公众号的唯一标识timestamp: res.data.timestamp, // 必填,生成签名的时间戳nonceStr: res.data.nonceStr, // 必填,生成签名的随机串signature: res.data.signature,// 必填,签名,见附录1jsApiList: ['checkJsApi', 'getLocation', 'openLocation'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2});wx.checkJsApi({jsApiList: ['getLocation'],success: function (res) {if (res.checkResult.getLocation == false) {that.$toast('你的微信版本太低,不支持微信JS接口,请升级到最新的微信版本!');return;}},fail: function (res) {console.log('checkJsApi fail=' + JSON.stringify(res))}});wx.ready(function () {wx.getLocation({type: "gcj02", //jssdk获取的坐标类型success: function (res) {console.log(res, 'success')that.GCJPosition.lat = res.latitude //纬度that.GCJPosition.lng = res.longitude //经度},cancel: function (res) {console.log(res, 'cancel')},fail: function (res) {console.log('fail', res)}});})})},// 初始化高德地图initAMap() {this.showmore = false// 实例化地图var mapObj = new AMap.Map('baidu-map', {resizeEnable: true,zoom: 17,zooms: [8, 17]});this.mapObj = mapObj;if (location.href.indexOf('&guide=1') !== -1) {mapObj.setStatus({scrollWheel: false })}// 加载定位插件this.addGeolocationPlugin();// 加载地理编码插件this.addGeocoderPlugin();// 绑定地图移动事件let that = this;setTimeout(function () {that.getLocation();}, 500)this.addMark(this.position)},// 初始化百度地图initBMap() {console.log('初始化百度地图', this.GCJPosition)this.showmore = falselet map = new BMap.Map('baidu-map');var point = new BMap.Point(168.95, 34.27);map.centerAndZoom(point, 18);let that = thisthis.bdPosition = this.$map.GCJtobd09(this.position[0], this.position[1])this.curP = this.$map.GCJtobd09(that.GCJPosition.lng, that.GCJPosition.lat) //当前坐标(gcj02)转成百度坐标let pt = new BMap.Point(this.bdPosition[0], this.bdPosition[1]);var mk = new BMap.Marker(pt);map.addOverlay(mk);//标出所在地map.panTo(pt);//地图中心移动var point = new BMap.Point(this.position[0], this.position[1]);//用所定位的经纬度查找所在地省市街道等信息console.log(this.GCJPosition, this.position)mk.addEventListener("click", function (e) {window.location.href = `http://api./direction?origin=latlng:${this.curP[1]},${this.curP[0]}|name:我的位置&destination=${this.bdPosition[1]},${this.bdPosition[0]}&mode=driving&region=上海&output=html`;});},// 初始化腾讯地图initTMap() {console.log('初始化腾讯地图')this.showmore = falselet that = thisvar myLatlng = new qq.maps.LatLng(this.position[1], this.position[0]);//定义工厂模式函数var myOptions = {zoom: 17,//设置地图缩放级别center: myLatlng,//设置中心点样式mapTypeId: qq.maps.MapTypeId.ROADMAP //设置地图样式详情参见MapType}//获取dom元素添加地图信息var map = new qq.maps.Map(document.getElementById("baidu-map"), myOptions);var latlngs = [new qq.maps.LatLng(this.position[1], this.position[0])];for (var i = 0; i < latlngs.length; i++) {(function (n) {//实例标注var marker = new qq.maps.Marker({position: latlngs[n],map: map});//标注点击事件qq.maps.event.addListener(marker, 'click', function (e) {window.location.href = `https://apis./uri/v1/routeplan?type=bus&to=终点&tocoord=${that.position[1]},${that.position[0]}&referer=PGCBZ-7XVC3-XKO36-3CEGN-B2L63-XYBHT`;});})(i);}},// 高德地图加标记addMark(position) {var marker = new AMap.Marker({content: '<div class="marker-route marker-marker-bus-from locationMarker"></div>',offset: new AMap.Pixel(-13, -34),position: position});this.mapObj.setCenter(position);this.userLocation = marker;this.userLocation.setMap(this.mapObj);marker.on('click', function (e) {marker.markOnAMAP({position: marker.getPosition()})})},getLocation() {this.geolocation.getCurrentPosition(); // 定位},addGeocoderPlugin: function () {this.mapObj.plugin(['AMap.Geocoder'], () => {this.geocoder = new AMap.Geocoder();});},addGeolocationPlugin: function () {this.mapObj.plugin(['AMap.Geolocation'], () => {this.geolocation = new AMap.Geolocation({enableHighAccuracy: true, //是否使用高精度定位,默认:truetimeout: 10000, //超过10秒后停止定位,默认:无穷大maximumAge: 0, //定位结果缓存0毫秒,默认:0showButton: false,convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:trueshowMarker: false, //定位成功后在定位到的位置显示点标记,默认:trueshowCircle: false, //定位成功后用圆圈表示定位精度范围,默认:truepanToLocation: false, //定位成功后将定位到的位置作为地图中心点,默认:truezoomToAccuracy: true //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false});this.mapObj.addControl(this.geolocation);AMap.event.addListener(this.geolocation, 'complete', (data) => {console.log('定位成功', data.position)this.GCJPosition.lat = data.position.latthis.GCJPosition.lng = data.position.lng});AMap.event.addListener(this.geolocation, 'error', (data) => {console.log('定位失败')});});},filterBtn() {this.fixBtn = this.btns.filter(item => this.defaultBtn.indexOf(item) < 0)}},created() {this.getConfig()this.filterBtn()}}</script><style lang="less">.smnoprint {display: none; //去掉腾讯地图放大缩小控件}.amap-info-content {font-size: 12px;}#myPageTop {position: absolute;top: 5px;right: 10px;background: #fff none repeat scroll 0 0;box-shadow: -1px -1px 10px rgba(0, 0, 0, 0.08);margin: 0.2rem auto;padding: 0.2rem;font-family: "Microsoft Yahei", "微软雅黑", "Pinghei";font-size: 14px;}#myPageTop label {margin: 0 20px 0 0;color: #666666;font-weight: normal;}#myPageTop input {width: 4rem;height: 0.5rem;border: 1px solid #c6c6c6;padding: 0 10px;}#myPageTop .column2 {padding-left: 25px;}.amap-sug-result {z-index: 99999;}.map-btn {display: flex;position: absolute;width: 100%;bottom: 0;left: 0;height: 100px;background-color: #fff;.map-type {width: 50%;text-align: center;background-color: #fff;line-height: 100px;font-size: 34px;color: #2c96f6;display: flex;justify-content: center;align-items: center;span:nth-child(1) {margin-right: 10px;}span:nth-child(2) {display: flex;align-items: center;width: 30px;img {width: 100%;}}}.guide-btn {width: 50%;text-align: center;background-color: #2c96f6;line-height: 100px;font-size: 34px;color: #fff;}.fix-btn {width: 50%;position: absolute;bottom: 100px;left: 0;text-align: center;div {height: 100px;line-height: 100px;background-color: #fff;font-size: 34px;color: #2c96f6;display: flex;justify-content: center;align-items: center;span:nth-child(1) {margin-right: 10px;}span:nth-child(2) {display: flex;align-items: center;width: 30px;img {width: 100%;}}}}}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。