微信公众号,JS-SDK获取位置信息,并调起第三方地图App导航

孔运良
2023-12-01

微信公众号关联网页获取位置信息,可以参照《微信公众平台技术文档-> 微信JS-SDK说明文档,官方链接地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115

步骤一:绑定域名

先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。注:该域名不包括端口号,并且必须是备案过的域名。

备注:登录后可在“开发者中心”查看对应的接口权限。

步骤二:引入JS文件

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

备注:支持使用 AMD/CMD 标准模块加载方法加载

步骤三:通过config接口注入权限验证配置

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。签名算法见文末的附录1,所有JS接口列表见文末的附录2

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

步骤四:通过ready接口处理成功验证

[html]  view plain  copy
  1. wx.ready(function(){  
  2.     // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。  
  3. });  

步骤五:通过error接口处理失败验证

[html]  view plain  copy
  1. wx.error(function(res){  
  2.     // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。  
  3. });  

地理位置

使用微信内置地图查看位置接口

wx.openLocation({
latitude: 0, // 纬度,浮点数,范围为90 ~ -90
longitude: 0, // 经度,浮点数,范围为180 ~ -180。
name: '', // 位置名
address: '', // 地址详情说明
scale: 1, // 地图缩放级别,整形值,范围从1~28。默认为最大
infoUrl: '' // 在查看位置界面底部显示的超链接,可点击跳转
});

获取地理位置接口

wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res) {
var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res.speed; // 速度,以米/每秒计
var accuracy = res.accuracy; // 位置精度
}
});

代码示例:

nav.js

//获取浏览器信息
var browser = {
	ua : function() {
		var u = navigator.userAgent;
		var isChrome = u.match(/Chrome\/([\d.]+)/)
				|| u.match(/CriOS\/([\d.]+)/);
		var isAndroid = u.match(/(Android);?[\s\/]+([\d.]+)?/);
		var iosVersion = function() {
			if (/iP(hone|od|ad)/.test(navigator.platform)) {
				var v = (navigator.appVersion).match(/OS (\d+)_(\d+)_?(\d+)?/);
				return [ parseInt(v[1], 10), parseInt(v[2], 10),
						parseInt(v[3] || 0, 10) ];
			}
		}();
		var chromeVersion = function() {
			var chrome = navigator.userAgent.match(/Chrome\/(\d+)\./);
			if (chrome) {
				return parseInt(chrome[1], 10);
			}
		}();
		var ios9 = iosVersion && iosVersion[0] >= 9;
		var chrome18 = isChrome && isAndroid && chromeVersion
				&& chromeVersion > 18;
		return { // 移动终端浏览器版本信息
			trident : u.indexOf('Trident') > -1, // IE内核
			presto : u.indexOf('Presto') > -1, // opera内核
			webKit : u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核
			gecko : u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, // 火狐内核
			mobile : !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端
			iOS : !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端
			android : u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, // android终端或uc浏览器
			iPhone : u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器
			iPad : u.indexOf('iPad') > -1, // 是否iPad
			webApp : u.indexOf('Safari') == -1, // 是否web应该程序,没有头部与底部
			weChat : u.indexOf('MicroMessenger') > -1,
			UC : u.indexOf('UCBrowser') > -1,
			u3 : u.indexOf('U3') > -1,
			chrome : u.indexOf('Chrome') > -1,
			windowsPhone : u.indexOf("Windows Phone") > -1,
			samsung : u.indexOf("Samsung") > -1,
			QQ : (u.match(/\sQQ/i) != null ? u.match(/\sQQ/i).toLowerCase() == " qq"
					: false),
			isChrome : isChrome,
			isAndroid : isAndroid,
			iosVersion : iosVersion,
			chromeVersion : chromeVersion,
			ios9 : ios9,
			chrome18 : chrome18
		};
	}()
}
var ua = browser.ua;

// 打开地图App,开始导航
function openMapApp(lat, lng, addr) {
	// 地图uri api数组
	var uri = new Array();
	if (ua.android) {
		// 百度地图uri api
		uri[0] = "bdapp://map/navi?location=" + lat + "," + lng + "&query="
				+ addr;
		// 高德地图uri api
		uri[1] = "androidamap://navi?sourceApplication=xlwx&poiname=" + addr
				+ "&lat=" + lat + "&lon=" + lng + "&dev=1&style=2";
		// 腾讯地图uri api
		uri[2] = "qqmap://map/marker?marker=coord:" + lat + "," + lng
				+ ";title:" + addr + "&referer=xlwx";
	} else if (ua.iOS) {
		// 百度地图uri api
		uri[0] = "baidumap://map/navi?location=" + lat + "," + lng + "&query="
				+ addr;
		// 高德地图uri api
		uri[1] = "iosamap://navi?sourceApplication=xlwx&poiname=" + addr
				+ "&lat=" + lat + "&lon=" + lng + "&dev=1&style=2";
		// 腾讯地图uri api
		uri[2] = "qqmap://map/marker?marker=coord:" + lat + "," + lng
				+ ";title:" + addr + "&referer=xlwx";
		// 苹果地图uri api
		uri[3] = "http://maps.apple.com/?sll=" + lat + "," + lng + "&address="
				+ addr;
	}
	//调用uri	
	if(uri.length == 0){
		return;
	}
	window.location.href = uri[0];
	//启动定时器time1
	var time1 = setTimeout(function() {
		// 若启动应用,则js会被中断较长时间,超出此范围
		window.location.href = uri[1];
	}, 2000);
	//启动定时器time2
	var time2 = setTimeout(function() {
		// 若启动应用,则js会被中断较长时间,超出此范围
		window.location.href = uri[2];
	}, 4000);
	//清除定时器
	window.beforeunload = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}		
	}
	window.pagehide = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}
	}
	window.onblur = function() {
		if(time1 != null){
			clearTimeout(time1);
		}
		if(time2 != null){
			clearTimeout(time2);
		}
	}
}
map.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*,com.wx.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<title>获取位置信息</title>
<link href="${pageContext.request.contextPath }/css/app_comm.css" rel="stylesheet" type="text/css" />
<link href="${pageContext.request.contextPath }/css/app_style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery.min.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/app_comm.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/common.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/navigation/nav.js"></script>
<script charset="utf-8" src="http://map.qq.com/api/js?v=2.exp&libraries=convertor"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

<%  
Map<String, String> ret = new HashMap<String, String>();  
String url = request.getScheme() + "://" + request.getServerName() + "/map";
ret = JsSignUtil.sign(url);
%>

<script type="text/javascript">
//全局变量
var map = null;
//驾驶服务
var drivingService = null;
//信息窗口
var infoWindow = null;
//驾驶策略
var policys = ["LEAST_TIME","LEAST_DISTANCE","AVOID_HIGHWAYS","REAL_TRAFFIC"];
//当前位置的marker
var curr_marker = null;
//当前位置坐标
var curr = null;

//就绪时执行
$(function(){
	//初始化地图
	init();
});

//初始化
function init(){
	//初始化导航窗口
    initNavWindow();
	//加载腾讯地图
    initMap();
    //获取用户当前状态
    getUserChargeStatus(); 
    //初始化导航按钮
    initNavClick();
    //初始化微信定位接口
    initWxLocation();
}

//初始化微信定位接口
function initWxLocation(){
	//配置微信定位功能 start
	wx.config({  
	    debug: false,  
	    appId: '<%=ret.get("appId")%>',  
	    timestamp:'<%=ret.get("timestamp")%>',  
	    nonceStr:'<%=ret.get("nonceStr")%>',  
	    signature:'<%=ret.get("signature")%>',  
	    jsApiList : [ 'checkJsApi', 'openLocation', 'getLocation' ]  
	});//end_config  
	  
	wx.error(function(res) {  
	    alert("出错了:" + res.errMsg);  
	});  
	  
	wx.ready(function() { 
	    //判断当前客户端版本是否支持指定JS接口 
	    wx.checkJsApi({  
	        jsApiList : ['getLocation'],  
	        success : function(res) {  
	        }  
	    }); 
	        
	    //获取位置信息        
	    wx.getLocation({
	    	type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
	        success: function (res) {
	            var latitude = res.latitude; // 纬度,浮点数,范围为90 ~ -90
	            var longitude = res.longitude; // 经度,浮点数,范围为180 ~ -180。
	            var speed = res.speed; // 速度,以米/每秒计
	            var accuracy = res.accuracy; // 位置精度
	            //alert("纬度:" + latitude + ", 经度:" + longitude);
	            //循环定位,每隔一段时间会自动定位一次
	            //转换gps坐标为腾讯坐标
	            //curr = new qq.maps.LatLng(latitude, longitude);
		        qq.maps.convertor.translate(new qq.maps.LatLng(latitude, longitude), 1, function(res){
		        	curr = res[0];
		        	if(curr_marker == null){
		            	panPointAndGetPlants();
		            }else{
		            	curr_marker.setPosition(curr);
		            }
			    });	            
	        },
	        cancel: function (res) {
	            alert('用户拒绝授权,获取地理位置失败');
	        },
	        fail: function(error) {
	            alert('获取地理位置失败,请确保开启GPS且允许微信获取您的地理位置!');
	        }
	    });    
	}); //配置微信定位功能 end
}

//平移中心点,获取列表
function panPointAndGetPlants(){
	//平移中心点到定位位置
    panToPoint(curr);      
    //获取附近的列表
    getPlants();
}

//初始化地图
function initMap(){
	//设置c_map高度
	$("#c_map").height($(window).height() - 55);
	//初始位置天安门
	var center = new qq.maps.LatLng(39.908860, 116.397390);
    map = new qq.maps.Map(document.getElementById("c_map"), {
        center: center,
        zoom: 10,
      	//启用比例尺
        scaleControl: true,
        scaleControlOptions: {
            //设置控件位置相对右下角对齐,向左排列
            position: qq.maps.ControlPosition.BOTTOM_RIGHT
        },
        //启用缩放控件
        zoomControl: true,
        //设置缩放控件的位置和样式
        zoomControlOptions: {
            //设置缩放控件的位置为相对左方中间位置对齐.
            position: qq.maps.ControlPosition.LEFT_TOP,
            //设置缩放控件样式为仅包含放大缩小两个按钮
            style: qq.maps.ZoomControlStyle.SMALL
        }
    });
}

//平移地图中心点,定位位置
function panToPoint(point){
	if(map != null){
		//panTo()将地图中心移动到指定的经纬度坐标。
        map.panTo(point);
        //zoomTo()将地图缩放到指定的级别。
        map.zoomTo(13);
        //绘制当前位置marker
        curr_marker = new qq.maps.Marker({
            //设置Marker的位置坐标
            position: point,
            //设置Marker被添加到Map上时的动画效果为落下
            animation: qq.maps.MarkerAnimation.DOWN,
            //设置显示Marker的地图
            map: map,
            //自定义Marker图标为大头针样式
            icon: new qq.maps.MarkerImage("images/zb_curr.png")
        });
	}
}

function getPlants(){
	if(curr == null){
		return;
	}
	ajaxSyncRequest('${pageContext.request.contextPath}/wx/pileList',{"latitude":curr.getLat(),"longitude":curr.getLng()},function(res){
	       if(res.success){
	    	   //将JSON字符串转换为JavaScript对象	    	   
	    	   drawerMarker($.parseJSON(res.datas));
	       }else{
	    	   alert(res.msg);
	       }
	});
}

//获取用户当前状态
function getUserChargeStatus(){
    ajaxSyncRequest('${pageContext.request.contextPath}/wx/getUserInfo',{},function(data){
       if(data.success){
           if(data.user.useStatus == 1){
               window.location.href="show";
               return;
           }	      
           if(data.user.billNotified == 1){
               //notifybill接口被调用,数据没复位
               window.location.href="show";
               return;
           }     	
       }
    });
}

//绘制附近的marker
//[{"id":1,"plantName":demo,"address":"深圳","distance":800,"num":2,"driver":10}]
function drawerMarker(datas){	
	$.each(datas, function(i, data){		
		//转换百度坐标为腾讯坐标
		qq.maps.convertor.translate(new qq.maps.LatLng(data.latitude, data.longitude), 3, function(res){
			var point = res[0];
			//创建一个Marker
	    	var marker = new qq.maps.Marker({
		        //设置Marker的位置坐标
		        position: point,
		        //设置Marker被添加到Map上时的动画效果为从天而降
		        animation:qq.maps.MarkerAnimation.DROP,
		        //设置显示Marker的地图
		        map: map,
		        //自定义Marker图标为大头针样式
		        icon: new qq.maps.MarkerImage("images/zb.png")
	    	});	
	    	//添加信息窗口
	    	getInfoWindow();
			//info窗口内容
			var html = '<div class="app_infowindow">';
			html = html + '<ul><li>';
			html = html + '<p><font class="app_infowindow_name">';
			html = html + data.plantName;
			html = html + '</font><i><font class="col_or">';
			html = html + data.num;
			html = html + '</font>可用</i></p><p>';			
			html = html + data.address;
	        html = html + '</p></li></ul></div>';
	        html = html + '<div class="app_infoicon" οnclick="routeplan(';
	        html = html + point.getLat() + "," + point.getLng() + ",'" + data.address + '\')">';
	        html = html + '<img src="images/arrow.png"><br/>';
	        html = html + '<a href="#">去这里<a/>';
	        html = html + '</div>';
	        //标记Marker点击事件
	        qq.maps.event.addListener(marker, 'click', function(){
	        	infoWindow.open();		            
	        	infoWindow.setContent(html);
	        	infoWindow.setPosition(marker.getPosition());	        	
	        });	
		});
	});
}

//路线规划
function routeplan(lat, lng, addr){
	//保存数据,切换策略时用
	$("#to_lat").val(lat);
	$("#to_lng").val(lng);
	$("#to_addr").val(addr);
	//起始位置
	var from = curr;
	//目的地
	var to = new qq.maps.LatLng(lat, lng);
	//驾驶策略
	var policy = policys[parseInt($("#to_policy").val())];	
	//设置获取驾车线路方案的服务
    getDrivingService();
	//清空当前结果在map和panel中的展现。
    drivingService.clear();
    //设置驾车方案
    drivingService.setPolicy(qq.maps.DrivingPolicy[policy]);
    //设置驾车的区域范围
    //drivingService.setLocation("北京");
    //设置回调函数
    drivingService.setComplete(function(result) {
        if (result.type == qq.maps.ServiceResultType.MULTI_DESTINATION) {
            //起终点不唯一
            var d = result.detail;
            drivingService.search(d.start[0], d.end[0]);
        }else{
        	$(".tab_title").text(addr);
        	var dis = parseFloat(result.detail.distance) / 1000;
        	$("#dist").text(dis.toFixed(1));
        	$("#dur").text(result.detail.duration);
        }
    });
    //设置检索失败回调函数
    drivingService.setError(function(data) {
        alert(data);
    });
    //设置驾驶路线的起点和终点
    drivingService.search(from, to);
    //关闭infowindow
    infoWindow.close();
    //弹出导航窗口
    if($("#info").is(":hidden")){
    	$("#info").slideToggle(300);   	
    }	
}

//获取驾驶服务
function getDrivingService(){
	if(drivingService == null){
		drivingService = new qq.maps.DrivingService({
	        map: map,
	        //展现结果,自定义
	        //panel: document.getElementById('info')
	    });
	}
}

//获取info window
function getInfoWindow(){
	if(infoWindow == null){
		infoWindow = new qq.maps.InfoWindow({
	        map: map
	    });
	}
}

//初始化导航窗口
function initNavWindow(){
	//初始化导航窗口为隐藏状态
	$("#info").hide();
	//初始化导航tab
	$(".tab_bar ul li").click(function(){
		$(".tab_bar ul li").removeClass("tab_bar_curr");
		$(this).addClass("tab_bar_curr");
		$("#to_policy").val($(this).index());
		var lat = $("#to_lat").val();
		var lng = $("#to_lng").val();
		var addr = $("#to_addr").val();
		routeplan(lat, lng, addr);
	});
}

//初始化导航按钮
function initNavClick(){
	$(".tab_right").click(function(){
		var lat = $("#to_lat").val();
		var lng = $("#to_lng").val();
	    var addr = $("#to_addr").val();	
		openMapApp(lat, lng, addr);
	});
}

</script>
<style type="text/css">
	.app_infowindow{ float:left; margin:0px 10px 0px 0px}
	.app_infowindow li p{ line-height:16px; font-size:8px; color:#999;}
	.app_infowindow li p i{ padding:0 5px; border-radius:5px; background:#eee;}
	.app_infowindow_name{ font-weight:bold; font-size:12px; color:#333;}
	.app_infoicon{ float:left; padding:0px 0px 0px 10px; height:100%; border-left:1px #eee solid }
	.app_infoicon img{ width:28px; height:28px;}
	.app_infoicon a{font-size:12px; color:#67bcf2;}
	.app_panel{width:100%; height:100px; background:#edebe8; bottom:55px; position:fixed;}
	.tab_bar{width:100%; height:30px; background:#fff; bottom:135px; position:fixed;}
	.tab_bar ul{padding-top:6px;}	
	.tab_bar_li{width:25%; float:left; text-align:center; font-size:12px; position:relative; color:#b5b5b5}
	.tab_bar_curr{color:#068cfb;}
	.tab_context{width:100%; height:70px; bottom:55px; position:fixed; padding:0px 0px 0px 10px;}
	.tab_context .tab_left{width:80%; float:left; position:relative;}
	.tab_context .tab_right{width:20%; float:left; position:relative;}
	.tab_left p{line-height:28px;}
	.tab_title{ font-weight:bold; font-size:16px; color:#333;}
	.tab_text{ font-size:14px; color:#999;}
	.ico_nav{ width:32px; height:32px; text-align:center;}
	.nav_text{ font-size:14px; color:#068cfb;}
	.app_map{height:650px}
</style>
</head>

<body>

<div class="w_all app_main">
    <!-- 存储数据 -->
	<input type="hidden" id="to_lat" value=""/>
    <input type="hidden" id="to_lng" value=""/>	
    <input type="hidden" id="to_addr" value=""/>
    <input type="hidden" id="to_policy" value="0"/>
    <!-- map -->	
	<div class="app_map" id="c_map"></div>
	<div class="app_panel" id="info">
		<div class="tab_bar">
		    <ul> 
		        <li class="tab_bar_li tab_bar_curr">最少时间</li>
		        <li class="tab_bar_li">最短距离</li>
		        <li class="tab_bar_li">不走高速</li>
		        <li class="tab_bar_li">躲避拥堵</li>	        
		    </ul>
		</div>
		<div class="tab_context">
			<div class="tab_left">
				<p class="tab_title">北京</p>
				<p class="tab_text"><span id="dist">2.0</span>公里 | <span id="dur">12</span>分钟</p>
			</div>
			<div class="tab_right">
			    <img src="images/navigation.png" class="ico_nav"/>
			    <p class="nav_text">导航</p>
			</div>
		</div>
	</div>	
    <div class="app_menu">
    </div>
</div>

</body>
</html>

完!!!

 类似资料: