1. 程式人生 > >微信公眾號開發《三》微信JS-SDK之地理位置的獲取,整合百度地圖實現線上地圖搜尋

微信公眾號開發《三》微信JS-SDK之地理位置的獲取,整合百度地圖實現線上地圖搜尋

本次講解微信開發第三篇:獲取使用者地址位置資訊,是非常常用的功能,特別是服務行業公眾號,尤為需要該功能,本次講解的就是如何呼叫微信JS-SDK介面,獲取使用者位置資訊,並結合百度地鐵,實現線上地圖搜尋,與線上導航。


在這貼上上二篇博文連結,方便大家訪問:

1.何為JS-SDK:微信JS-SDK是微信公眾平臺面向網頁開發者提供的基於微信內的網頁開發工具包。網頁開發者可藉助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信使用者提供更優質的網頁體驗。簡單來說:就是在自己公眾平臺後臺配置後,可直接呼叫的功能介面。

那如何配置呢?下面講解下配置步驟:示例講解是基於測試公眾號

,如何使用測試公眾號,可以參考第一篇文章

1.在公眾號後臺繫結域名:測試公眾號登入就可看見如下圖。正式公眾號配置位置:“公眾號設定”的“功能設定”裡填寫“JS介面安全域名”


3.獲取必須引數:

wx.config({
    debug: true, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
    appId: '', // 必填,公眾號的唯一標識
    timestamp: , // 必填,生成簽名的時間戳
    nonceStr: '', // 必填,生成簽名的隨機串
    signature: '',// 必填,簽名
    jsApiList: [
		'openLocation',
		'getLocation'
	] // 必填,需要使用的JS介面列表,更多介面可看官方文件
});

看呼叫介面,可知,現在缺timestamp,signature,nonceStr。不用想的太複雜,還是那個原則,沒什麼獲取什麼,

獲取signature簽名,生成簽名之前必須先了解一下jsapi_ticket,jsapi_ticket是公眾號用於呼叫微信JS介面的臨時票據。正常情況下,jsapi_ticket的有效期為7200秒,通過access_token來獲取。由於獲取jsapi_ticket的api呼叫次數非常有限,頻繁重新整理jsapi_ticket會導致api呼叫受限,影響自身業務,開發者必須在自己的服務全域性快取jsapi_ticket。

寫個工具類封裝獲取方法

public class SHA1 { //sha演算法
    private final int[] abcde = { 
            0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 
        }; 
    // 摘要資料儲存陣列 
    private int[] digestInt = new int[5]; 
    // 計算過程中的臨時資料儲存陣列 
    private int[] tmpData = new int[80]; 
    // 計算sha-1摘要 
    private int process_input_bytes(byte[] bytedata) { 
        // 初試化常量 
        System.arraycopy(abcde, 0, digestInt, 0, abcde.length); 
        // 格式化輸入位元組陣列,補10及長度資料 
        byte[] newbyte = byteArrayFormatData(bytedata); 
        // 獲取資料摘要計算的資料單元個數 
        int MCount = newbyte.length / 64; 
        // 迴圈對每個資料單元進行摘要計算 
        for (int pos = 0; pos < MCount; pos++) { 
            // 將每個單元的資料轉換成16個整型資料,並儲存到tmpData的前16個數組元素中 
            for (int j = 0; j < 16; j++) { 
                tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4)); 
            } 
            // 摘要計算函式 
            encrypt(); 
        } 
        return 20; 
    } 
    // 格式化輸入位元組陣列格式 
    private byte[] byteArrayFormatData(byte[] bytedata) { 
        // 補0數量 
        int zeros = 0; 
        // 補位後總位數 
        int size = 0; 
        // 原始資料長度 
        int n = bytedata.length; 
        // 模64後的剩餘位數 
        int m = n % 64; 
        // 計算新增0的個數以及新增10後的總長度 
        if (m < 56) { 
            zeros = 55 - m; 
            size = n - m + 64; 
        } else if (m == 56) { 
            zeros = 63; 
            size = n + 8 + 64; 
        } else { 
            zeros = 63 - m + 56; 
            size = (n + 64) - m + 64; 
        } 
        // 補位後生成的新陣列內容 
        byte[] newbyte = new byte[size]; 
        // 複製陣列的前面部分 
        System.arraycopy(bytedata, 0, newbyte, 0, n); 
        // 獲得陣列Append資料元素的位置 
        int l = n; 
        // 補1操作 
        newbyte[l++] = (byte) 0x80; 
        // 補0操作 
        for (int i = 0; i < zeros; i++) { 
            newbyte[l++] = (byte) 0x00; 
        } 
        // 計算資料長度,補資料長度位共8位元組,長整型 
        long N = (long) n * 8; 
        byte h8 = (byte) (N & 0xFF); 
        byte h7 = (byte) ((N >> 8) & 0xFF); 
        byte h6 = (byte) ((N >> 16) & 0xFF); 
        byte h5 = (byte) ((N >> 24) & 0xFF); 
        byte h4 = (byte) ((N >> 32) & 0xFF); 
        byte h3 = (byte) ((N >> 40) & 0xFF); 
        byte h2 = (byte) ((N >> 48) & 0xFF); 
        byte h1 = (byte) (N >> 56); 
        newbyte[l++] = h1; 
        newbyte[l++] = h2; 
        newbyte[l++] = h3; 
        newbyte[l++] = h4; 
        newbyte[l++] = h5; 
        newbyte[l++] = h6; 
        newbyte[l++] = h7; 
        newbyte[l++] = h8; 
        return newbyte; 
    } 
    private int f1(int x, int y, int z) { 
        return (x & y) | (~x & z); 
    } 
    private int f2(int x, int y, int z) { 
        return x ^ y ^ z; 
    } 
    private int f3(int x, int y, int z) { 
        return (x & y) | (x & z) | (y & z); 
    } 
    private int f4(int x, int y) { 
        return (x << y) | x >>> (32 - y); 
    } 
    // 單元摘要計算函式 
    private void encrypt() { 
        for (int i = 16; i <= 79; i++) { 
            tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^ 
                    tmpData[i - 16], 1); 
        } 
        int[] tmpabcde = new int[5]; 
        for (int i1 = 0; i1 < tmpabcde.length; i1++) { 
            tmpabcde[i1] = digestInt[i1]; 
        } 
        for (int j = 0; j <= 19; j++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[j] + 0x5a827999; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int k = 20; k <= 39; k++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[k] + 0x6ed9eba1; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int l = 40; l <= 59; l++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[l] + 0x8f1bbcdc; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int m = 60; m <= 79; m++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[m] + 0xca62c1d6; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int i2 = 0; i2 < tmpabcde.length; i2++) { 
            digestInt[i2] = digestInt[i2] + tmpabcde[i2]; 
        } 
        for (int n = 0; n < tmpData.length; n++) { 
            tmpData[n] = 0; 
        } 
    } 
    // 4位元組陣列轉換為整數 
    private int byteArrayToInt(byte[] bytedata, int i) { 
        return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) | 
        ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff); 
    } 
    // 整數轉換為4位元組陣列 
    private void intToByteArray(int intValue, byte[] byteData, int i) { 
        byteData[i] = (byte) (intValue >>> 24); 
        byteData[i + 1] = (byte) (intValue >>> 16); 
        byteData[i + 2] = (byte) (intValue >>> 8); 
        byteData[i + 3] = (byte) intValue; 
    } 
    // 將位元組轉換為十六進位制字串 
    private static String byteToHexString(byte ib) { 
        char[] Digit = { 
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 
                'D', 'E', 'F' 
            }; 
        char[] ob = new char[2]; 
        ob[0] = Digit[(ib >>> 4) & 0X0F]; 
        ob[1] = Digit[ib & 0X0F]; 
        String s = new String(ob); 
        return s; 
    } 
    // 將位元組陣列轉換為十六進位制字串 
    private static String byteArrayToHexString(byte[] bytearray) { 
        String strDigest = ""; 
        for (int i = 0; i < bytearray.length; i++) { 
            strDigest += byteToHexString(bytearray[i]); 
        } 
        return strDigest; 
    } 
    // 計算sha-1摘要,返回相應的位元組陣列 
    public byte[] getDigestOfBytes(byte[] byteData) { 
        process_input_bytes(byteData); 
        byte[] digest = new byte[20]; 
        for (int i = 0; i < digestInt.length; i++) { 
            intToByteArray(digestInt[i], digest, i * 4); 
        } 
        return digest; 
    } 
    // 計算sha-1摘要,返回相應的十六進位制字串 
    public String getDigestOfString(byte[] byteData) { 
        return byteArrayToHexString(getDigestOfBytes(byteData)); 
    } 
    public static void main(String[] args) { 
        String data = "123456"; 
        System.out.println(data); 
        String digest = new SHA1().getDigestOfString(data.getBytes()); 
        System.out.println(digest);
       
       // System.out.println( ToMD5.convertSHA1(data).toUpperCase());
    } 
} 
/**
 * Ticket封裝類
 * @author lh
 */
public class Ticket {
	private String errcode;
	private String errmsg;
	private String ticket;
	private String expires_in;
	//省略get,set方法
}
/**
 * Signature封裝類
 * @author lh
 */
public class SignatureInfo {
	private String signature;
	private String timestamp;
	private String noncestr;
	private String url;
	//省略get,set方法
}

獲取ticket

/**
 * 獲取ticket
 * @param accessToken
 * @return
 */
public static Ticket getTicket(String accessToken){
	Ticket ticket = new Ticket();
	String getTicket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
	String url = getTicket.replace("ACCESS_TOKEN",accessToken);
	JSONObject jsonObject = httpRequest(url, "POST", null);
	if (null != jsonObject) {
		if (0 != jsonObject.getInt("errcode")) {
			log.error("獲取ticket失敗 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
		}else{
			ticket.setErrcode(jsonObject.getString("errcode"));
			ticket.setErrmsg(jsonObject.getString("errmsg"));
			ticket.setExpires_in(jsonObject.getString("expires_in"));
			ticket.setTicket(jsonObject.getString("ticket"));
		}
	}
	return ticket;
}

獲取Signature方法

/**
 * 簽名演算法
 * @param ticket
 * @return
 */
public static SignatureInfo getSignature(SignatureInfo sign,Ticket ticket){
	String data = "jsapi_ticket="+ticket.getTicket()+"&noncestr="+sign.getNoncestr()+"×tamp="+sign.getTimestamp()+"&url="+sign.getUrl();
	String signature =  new SHA1().getDigestOfString(data.getBytes()); 
	sign.setSignature(signature);
	log.info("signature="+sign.getSignature());
	return sign;
}

最後綜合上面方法,封裝主函式

public String jssdk_demo(HttpServletRequest request,HttpServletResponse response){
	String param = request.getQueryString();//獲取請求引數
	String url = request.getServletPath();//獲取請求路徑(不帶引數)
	if(param!=null){
		url = url+"?"+param;//組合成完整請求URL
	}
	String projectnameP = request.getContextPath();
    String projectName = projectnameP.substring(projectnameP.lastIndexOf('/')+1,projectnameP.length());  //獲取工程名,如testW
	if(!"".equals(projectName)){
		projectName ="/"+projectName;
	}
	String port = String.valueOf(request.getServerPort());//獲取埠號
	if(!"80".equals(port)){//不是80埠時需加埠號
		port = ":"+port;
	}else{
		port = "";
	}
	String strBackUrl = "http://" + request.getServerName()+port+projectName+url;//完整的請求路徑http://192.168.1.117/testW/+路徑
	AccessToken token = null;
	if(TimedTask.accessToken==null || TimedTask.accessToken.getToken()==""){//token失效,重新獲取,獲取方法參考第二篇博文,在這由於篇幅問題暫不列出
		token = WeixinUtil.getAccessToken(TimedTask.appid, TimedTask.appsecret);/
	}else{
		token = TimedTask.accessToken;
	}
	Ticket ticket = null;
	if(TimedTask.ticket ==null || TimedTask.ticket.getTicket()==""){
		ticket = WeixinUtil.getTicket(token.getToken());//獲取ticket
	}else{
		ticket = TimedTask.ticket;
	}
	SignatureInfo siInfo = new SignatureInfo();
	siInfo.setNoncestr(RandomStringUtils.randomAlphanumeric(20));//隨機字串
	siInfo.setTimestamp(String.valueOf(System.currentTimeMillis()));//隨機時間截
	siInfo.setUrl(strBackUrl);
	siInfo = WeixinUtil.getSignature(siInfo, ticket);
	request.setAttribute("siInfo",siInfo);
	return "weixin/jssdk_demo";
}

到此需要準備的資料就已經全部完成了,現在我們看看前臺jssdk_demo.jsp頁面是如何呼叫的

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<c:set var="BS" value="${pageContext.request.contextPath}"></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>jssdk_demo</title>
<script type="text/javascript" src="${BS}/js/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="${BS}/js/weixin/jweixin-1.2.0.js"></script>
<link href="${BS}/css/weixin/weixinStyle.css" type="text/css" rel="stylesheet" />
<link href="${BS}/css/weixin/weixinmain.css" type="text/css" rel="stylesheet"/>
//百度地圖沒有密匙的可以去官網申請
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=密匙"></script>
<script type="text/javascript" src="http://developer.baidu.com/map/jsdemo/demo/convertor.js"></script> 
<script type="text/javascript" src="https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js"></script>
</head>
<input type="hidden" id="timestamp" value="${siInfo.timestamp}">
<input type="hidden" id="nonceStr" value="${siInfo.noncestr}">
<input type="hidden" id="signature" value="${siInfo.signature}">
<input type="hidden" id="longitude" value="">
<input type="hidden" id="latitude" value="">
<input type="hidden" id="weixinOperId" value="微信appid">
<script type="text/javascript">
var phoneWidth = parseInt(window.screen.width);
var phoneScale = phoneWidth/640;
var ua = navigator.userAgent;
if (/Android (\d+\.\d+)/.test(ua)){
    var version = parseFloat(RegExp.$1);
    if(version>2.3){
        document.write("<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0, minimum-scale = 1.0, maximum-scale = "+phoneScale+", target-densitydpi=device-dpi\">");
    }else{
        document.write("<meta name=\"viewport\" content=\"width=device-width, target-densitydpi=device-dpi\">");
    }
}else{
    document.write("<meta name=\"viewport\" content=\"width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,target-densitydpi=device-dpi\">");
}
$(function(){
	$(".nav a").click(function(){
		$('.nav a').removeClass('active');
		$(this).addClass('active');
		var nav = $(this).attr("nav");
		$("section div[class='desc']").each(function(i,val){
			if($(this).attr("nav")==nav){
				$(this).show();
			}else{
				$(this).hide();
			}
		});
	});
});
var signature = $("#signature").val();
var nonceStr = $("#nonceStr").val();
var timestamp = $("#timestamp").val();
var weixinOperId = $("#weixinOperId").val();
wx.config({
    debug: false, // 開啟除錯模式,呼叫的所有api的返回值會在客戶端alert出來,若要檢視傳入的引數,可以在pc端開啟,引數資訊會通過log打出,僅在pc端時才會列印。
    appId: weixinOperId, // 必填,公眾號的唯一標識
    timestamp:timestamp, // 必填,生成簽名的時間戳
    nonceStr: nonceStr, // 必填,生成簽名的隨機串
    signature:signature,// 必填,簽名
    jsApiList: [ 
        'openLocation',
		'getLocation'
    ] // 必填,需要使用的JS介面列表,所有JS介面列表見官方文件附錄2
});
wx.ready(function(){
	getLocation();
});
wx.error(function(res){
	//alert("error");
});
</script>
<script type="text/javascript">
$(function () {
	$("#wdialogTitle2").text("資訊提示");
    $("#wdialogConfirm2").click(function(i,val){
    	$("#wdialog2").hide();
    });
    $(".warn_message").text("");
    //重新整理定位
    $(".SelectCityWrap .cityTit .r").click(function () {
        $(this).addClass("hover");
        getLocation();
    });
    $("b.search").click(function () {
        searchMap($("#indexSearchBox").val());
        return false;
    });
});

var latitude,longitude;
//獲取當前地址
function getLocation(){
	wx.getLocation({
	    type: 'gcj02', // 預設為wgs84的gps座標,如果要返回直接給openLocation用的火星座標,可傳入'gcj02'
	    success: function (res) {
	        latitude = res.latitude; // 緯度,浮點數,範圍為90 ~ -90
	        longitude = res.longitude; // 經度,浮點數,範圍為180 ~ -180。
	        var speed = res.speed; // 速度,以米/每秒計
	        var accuracy = res.accuracy; // 位置精度
	        getAddressInfo2(longitude,latitude);
	    },cancel: function (res){
	        $("#wdialogContent2").text("使用者拒絕授權獲取地理位置");
        	$("#wdialog2").show();
	    }
	});
}

var addId = "choseAdd";
var longiText = "longitude";
var latiText = "latitude";
//開啟百度地圖並標記當前定位地址
function showMapArea(){
	var myGeo = new BMap.Geocoder();
	var pt = new BMap.Point(longitude,latitude);
 	translateCallback2 = function (point){
 		createBaiduMap(point.lng,point.lat,1);
	};
    setTimeout(function(){
    	BMap.Convertor.translate(pt,2,translateCallback2);     //火星經緯度轉成百度座標,2變成0時,則是預設的wgs84的gps座標轉換成百度座標
	}, 100);
}
//呼叫百度地圖API,經緯度轉化成實際地址
function getAddressInfo2(lon,lat) {
	var myGeo = new BMap.Geocoder();
	var pt = new BMap.Point(lon,lat);
 	translateCallback2 = function (point){
		myGeo.getLocation(point, function(rs) {
			var addComp = rs.addressComponents;
			var addr = addComp.province+ addComp.city + addComp.district+ addComp.street+ addComp.streetNumber;
			$("#nowAdd").text(addr);
		});
	};
    setTimeout(function(){
    	BMap.Convertor.translate(pt,2,translateCallback2);     //火星經緯度轉成百度座標
	}, 100);
}
function returnAdd(){
	$("#addressArea").show();
	$("#mapArea").hide();
}
function confirmC(){
	var address = $("#choseAdd").text();
	var longiText = $("#longitude").val();
	var latiText = $("#latitude").val();
	if(latiText=="" || longitude==""){
		$("#wdialogContent2").text("請先選擇您當前位置");
     	$("#wdialog2").show();
	}
}
function getNavi(){
	wx.openLocation({
	    latitude: latitude, // 緯度,浮點數,範圍為90 ~ -90
	    longitude: longitude, // 經度,浮點數,範圍為180 ~ -180。
	    name: '我現在在這裡', // 位置名
	    address: $("#nowAdd").text(), // 地址詳情說明
	    scale: 20, // 地圖縮放級別,整形值,範圍從1~28。預設為最大
	    infoUrl: 'https://www.baidu.com/' // 在檢視位置介面底部顯示的超連結,可點選跳轉
	});
}
</script>
<body>
	<div  id="addressArea" style="min-height:526px;">
		<section class="SelectCityWrap" style="width:98%;">
		    <h3 class="cityTit" style="width:100%;background:#DDDDDD;">
		        <span class="l left" style="max-width:80%;height:45px;overflow:hidden;">當前地址:<span class="val" style="height:45px;max-height:45px;overflow:hidden;" id="nowAdd">${nowAdd}</span></span>
		        <span class="r right"></span>
		    </h3>
		    <section class="content">
				<div class="nav">
			    	<a class=""  nav="nav_1" onclick="getNavi()">當前地址導航</a>
			    	<a nav="nav_2" onclick="showMapArea()">地圖選擇</a>
			    </div>
				<div class="desc" nav="nav_1">
			    </div>
				<div class="desc" nav="nav_2" style="display:none;width:100%;">
					<section  class="SelectCityWrap" style="width:100%;">
						<h3 class="cityTit" style="text-align:left;width:100%;background:#DDDDDD;">
							<span class="" style="padding-left:5px;">已選地址:<span class="val" id="choseAdd">點選地圖可選擇地址</span></span>
						</h3>
						<!-- 搜尋 -->
						<div style="height:auto;" class="indexSearch">
							<div class="content search">
								<input type="search" id="indexSearchBox" placeholder="點選地圖可選擇地址"  style="height: 38px;line-height:35px;width:100%;max-width:570px;padding-left:10px;font-size: 16px;" class="left">
								<span></span>
								<b class="search"></b>
							</div>
						</div>
						<!-- 搜尋 end-->
						<div id="container" style="width:100%;height:300px;"></div >
						<section id="r_content" style="margin-bottom:55px;">
							<div class="r_shadow">
								<div class="r_searchlist positiolist" id="search-result"></div>
							</div>
						</section>
					</section> 	          
			    </div>
			</section>
		</section>
	</div>
	<div  id="mapArea" style="min-height:526px;display:none;">
		<header id="r_header" class="r_title">
		    <a class="r_returnbk" onclick="returnAdd()">
		        <img src="${BS}/images/weixin/r_icon7.png" alt="">
		    </a>
		    <a style="float:right;padding-right:12px;" onclick="confirmC()">確定</a>
		</header>
		<section  class="SelectCityWrap">
			<!-- 搜尋 -->
		    <div style="height:auto;" class="indexSearch">
		        <div class="content search">
		        	<input type="search" id="indexSearchBox" placeholder="點選地圖可選擇地址"  style="height: 38px;line-height:35px;width:100%;max-width:570px;padding-left:10px;font-size: 16px;" class="left">
		            <span></span>
		            <b class="search"></b>
		        </div>
		    </div>
		    <!-- 搜尋 end-->
			<div id="container" style="width:100%;height:300px;"></div >
			<section id="r_content">
		        <div class="r_shadow">
		            <div class="r_searchlist positiolist" id="search-result">
		            </div>
		        </div>
		    </section>
		</section>
	</div>
	<script type="text/javascript" src="${BS}/js/weixin/mapLocation.js"></script>
</body>
</html>
mapLocation.js,為封裝好的百度地圖的方法,具體看各自需求可進行修改:
function getHtml5Location() {
	if(navigator.geolocation) {
		// navigator.geolocation.watchPosition(updateLocation, handleLocationError, {
		navigator.geolocation.getCurrentPosition(updateLocation, handleLocationError,{
	        // 指示瀏覽器獲取高精度的位置,預設為false
	        enableHighAcuracy: true,
	        // 指定獲取地理位置的超時時間,預設不限時,單位為毫秒
	        //timeout: 5000,
	        // 最長有效期,在重複獲取地理位置時,此引數指定多久再次獲取位置。
	        maximumAge: 20000
   		});
	}else{
		$("#wdialogContent2").text("無法獲取您當前地理位置");
     	$("#wdialog2").show();
	}
}
function updateLocation(position) {
	var latitude = position.coords.latitude;
	var longitude = position.coords.longitude;
	var accuracy = position.coords.accuracy;
	// 如果accuracy的值太大,我們認為它不準確,不用它計算距離
	if (accuracy >= 1000) {
		return;
	}
	var pt = new BMap.Point(longitude,latitude);
	setTimeout(function(){
		BMap.Convertor.translate(pt,0,translateCallback);     //真實經緯度轉成百度座標
	}, 100);
	translateCallback = function (point){
		createBaiduMap(point.lat,point.lng,1);
	};
}

function handleLocationError(error) {
	switch (error.code) {
		case 0:
			$("#wdialogContent2").text("嘗試獲取您的位置資訊時發生錯誤:"+ error.message);
     		$("#wdialog2").show();
			break;
		case 1:
			$("#wdialogContent2").text("使用者拒絕了獲取位置資訊請求");
     		$("#wdialog2").show();
			break;
		case 2:
			$("#wdialogContent2").text("瀏覽器無法獲取您的位置資訊:"+ error.message);
     		$("#wdialog2").show();
			break;
		case 3:
			$("#wdialogContent2").text("獲取您位置資訊超時");
     		$("#wdialog2").show();
			break;
	}
}
/**
 * 傳人座標獲得詳細地址
 * @param lat
 * @param lon
 */
function getAddressInfo(lon,lat,type) {
	var myGeo = new BMap.Geocoder();
	var pt = new BMap.Point(lon,lat);
 	translateCallback2 = function (point){
		myGeo.getLocation(point, function(rs) {
			var addComp = rs.addressComponents;
			//rs.surroundingPois;//附近地址
			var addr = addComp.province+ addComp.city + addComp.district+ addComp.street+ addComp.streetNumber;
			searchMap(addr);
		});
	};
    setTimeout(function(){
    	if(type==1){
    		BMap.Convertor.translate(pt,0,translateCallback2);     //真實經緯度轉成百度座標
    	}else{
    		translateCallback2(pt);
    	}
	}, 100);
}
var map = null;
function setMapEvent(){
    map.enableDragging();//啟用地圖拖拽事件,預設啟用(可不寫)
    map.enableScrollWheelZoom();//啟用地圖滾輪放大縮小
    map.enableDoubleClickZoom();//啟用滑鼠雙擊放大,預設啟用(可不寫)
    map.enableKeyboard();//啟用鍵盤上下左右鍵移動地圖
}
var marker = null;
function createBaiduMap(longitude, latitude,type) { 
	if(map==null){
		map =new BMap.Map("container"); 
	}
	setMapEvent();
	mSearchManager.clear();
	var	pt= new BMap.Point(longitude,latitude);  
	translateCallback = function (point){
		var	point= new BMap.Point(point.lng, point.lat);  
		map.setCenter(point);
	    map.centerAndZoom(point, 16);  
	    // 新增帶有定位的導航控制元件
	    var navigationControl = new BMap.NavigationControl({
	       // 靠左上角位置
	       anchor: BMAP_ANCHOR_TOP_LEFT,
	       // LARGE型別
	       type: BMAP_NAVIGATION_CONTROL_LARGE,
	       // 啟用顯示定位
	       enableGeolocation: true
	    });
	    map.addControl(navigationControl);  
	    marker = new BMap.Marker(point); //標註  
	    marker.enableDragging();
	    marker.addEventListener("dragend",getAttr);
		function getAttr(){
			var p = marker.getPosition();       //獲取marker的位置
			getAddressInfo(p.lng,p.lat);
		}
	    map.clearOverlays();
	    map.addOverlay(marker);
	    map.addEventListener("click", function(e){ 
	    	var gc = new BMap.Geocoder(); 
	    	var pt = new BMap.Point(e.point.lng,e.point.lat); 
	    	document.getElementById(longiText).value = e.point.lng;
	    	document.getElementById(latiText).value = e.point.lat;
	    	window.map.removeOverlay(marker);
    	    marker = new BMap.Marker(e.point);//建立一個覆蓋物  
	        map.addOverlay(marker);//增加一個標示到地圖上  
	    	var dress = gc.getLocation(pt, function(rs){
	    		var addComp = rs.addressComponents;
    			var address = addComp.province+addComp.city+addComp.district+addComp.street+addComp.streetNumber;
    			if(typeof(addId)!="undefined" && addId !=null){
    				$("#"+addId).text(address);
    			}
    			searchMap(address);
    		});
	    });
	    // 新增定位控制元件
//	    var geolocationControl = new BMap.GeolocationControl();
//	    geolocationControl.addEventListener("locationSuccess", function(e){
//	    	  window.map.removeOverlay(marker);
//	    	  marker = new BMap.Marker(e.point);//建立一個覆蓋物  
//	          map.addOverlay(marker);//增加一個標示到地圖上  
//	          map.panTo(e.point); 
		      // 定位成功事件
//		      var address = '';
//		      address += e.addressComponent.province;
//		      address += e.addressComponent.city;
//		      address += e.addressComponent.district;
//		      address += e.addressComponent.street;
//		      address += e.addressComponent.streetNumber;
//		      searchMap(address);
	    	 //getLocation();
//	    });
//	    geolocationControl.addEventListener("locationError",function(e){
//	        // 定位失敗事件
//	        alert(e.message);
//	    });
	    //地圖拖動事件
	    /*map.addEventListener("dragging", function(evt){
	       var offsetPoint = new BMap.Pixel(evt.offsetX, evt.offsetY); 
	    });*/
//	    map.addControl(geolocationControl);
	    // 新增帶有定位的導航控制元件
	};
    setTimeout(function(){
    	if(type==1){
    		translateCallback(pt);
    	}else{
    		BMap.Convertor.translate(pt,0,translateCallback);     //真實經緯度轉成百度座標
    	}
	}, 100);
} 
var mSearchManager = new SearchManager();
var isR = false;
function SearchManager(){
	this.SearchResultList = new Array();
	this.showSearchResult = function(poi){
		var index = this.SearchResultList.length;
		var marker = new BMap.Marker(poi.point);
        var a=document.createElement("a");  
        var p=document.createElement("P");
        this.SearchResultList[index] = new KzSearchResult( marker , poi , a , p);
        var address = "";
		if(this.SearchResultList[index].poi.province!=undefined && this.SearchResultList[index].poi.province!=null
				&& this.SearchResultList[index].poi.province !=""){
			address = this.SearchResultList[index].poi.province;
		}
		if(this.SearchResultList[index].poi.city!=undefined && this.SearchResultList[index].poi.city!=null
				&& this.SearchResultList[index].poi.city !=""){
			address +=this.SearchResultList[index].poi.city;
		}
    	var div = document.getElementById("search-result");
        a.href="javascript:mSearchManager.zoomto("+index+")";
        var $a = $("<a style=\"padding-left:10px;\" href=\"javascript:mSearchManager.zoomto("+index+")\"></a>");
        var section = $("<section class=\"listbox nobg list\" style=\"height:60px;\"></section>");
        var div1 = $("<div class=\"jobname\" style=\"height:25px;line-height:25px;\">"+poi.title+"</div>");
        var div2 = $("<div class=\"time\" style=\"height:25px;line-height:25px;color:#026AFF;\"></div>");
        var div3 = $("<div class=\"box1\" style=\"height:35px;line-height:35px;\">"+address+poi.address+"</div>");
        $a.append(div1).append(div2).append(div3);
        section.append($a);
        $("#search-result").append(section);
	};
	this.clear = function(){
		var div = $("#search-result section");
		div.remove();
		window.map.removeOverlay(marker);
		this.SearchResultList.length = 0;
	};
	this.clear2 = function(){
		var div = $("#search-result section");
		div.remove();
		this.SearchResultList.length = 0;
	};
	this.zoomto = function (index){
		$(".time").each(function(i,val){
			if(i==index){
				$(this).text("當前位置");
			}else{
				$(this).text("");
			}
		});
		window.map.removeOverlay(marker);
		marker = new BMap.Marker(this.SearchResultList[index].poi.point);
		window.map.addOverlay(marker);
		window.map.centerAndZoom(this.SearchResultList[index].poi.point, 16);
		document.getElementById(longiText).value = this.SearchResultList[index].poi.point.lng;
		document.getElementById(latiText).value = this.SearchResultList[index].poi.point.lat;
		if(typeof(addId)!="undefined" && addId !=null){
			document.getElementById(addId).innerHTML = this.SearchResultList[index].poi.title;
		}
	};	
}
function KzSearchResult(m , b ,a , p){
	this.marker = m;
	this.poi = b;
	this.a = a;
	this.p = p;
}
function searchMap(area) {
   if(map==null){
		map =new BMap.Map("container"); 
   }
   var ls = new BMap.LocalSearch(map);
   ls.setSearchCompleteCallback(function(rs) {
	  mSearchManager.clear2();
      if(ls.getStatus() == BMAP_STATUS_SUCCESS) {
    	for(var index=0;index<rs.getCurrentNumPois();index++){
	        var poi = rs.getPoi(index);
	        if (poi) {
	        	mSearchManager.showSearchResult(poi);
	        }
      	}
      }
   });
   ls.search(area);
}

到此該篇博文已經講解完畢,如有問題,歡迎大家指出,一起探討

相關推薦

php公眾開發公牛牛房卡平臺搭建使用php7要註意的地方

mar shadow 公眾號開發 jpg oss 文檔 微信公眾號開發 dem proc 開啟微信公眾號開發三公牛牛房卡平臺搭建網站(h5.fanshubbs.com聯系Q1687054422),從微信開發文檔中下載demo 如下載php示例代碼 示例代碼中是使用“$GL

java的公眾開發支付)

步驟一:我們需要將微信支付所需要的引數組裝好,然後傳送請求。 所需要的引數在微信支付開發文件中就可以找到我們所必須的11個引數。 步驟二:然後在回撥函式中處理我們支付後的業務邏輯。 /** * * 獲得威微信支付的相關引數

公眾開發JS-SDK地理位置獲取整合地圖實現線上地圖搜尋

本次講解微信開發第三篇:獲取使用者地址位置資訊,是非常常用的功能,特別是服務行業公眾號,尤為需要該功能,本次講解的就是如何呼叫微信JS-SDK介面,獲取使用者位置資訊,並結合百度地鐵,實現線上地圖搜尋,與線上導航。 在這貼上上二篇博文連結,方便大家訪問: 1.何為J

公眾開發教程 小程序

微信開發 微信小程序PHP微信公眾平臺開發高級篇http://www.imooc.com/u/197650/courses?sort=publish微信小程序教程 。鏈接:http://pan.baidu.com/s/1slmAwDf 密碼:ciry微信公眾號開發教程 微信小程序

公眾開發《一》OAuth2.0網頁授權認證獲取使用者的詳細資訊實現自動登陸

從接觸公眾號到現在,通過不斷積累學習,對如何呼叫微信提供介面有了一定的見解。當然在開發過程中遇到很多問題,現在把部分模組功能在這備案一下,做個總結也希望能給其他人幫助 工欲善其事,必先利其器,先看看開發公眾號需要準備或瞭解什麼 web開發工具:官方提供的開發工具,使用自己

公眾開發__網頁授權並獲取使用者基本資訊(是否關注公眾、頭像、暱稱等)

        本人最近要做微信公眾號網頁開發的專案,其中有個需求是判斷使用者是否關注公眾號,由於之前沒有接觸過微信授權的東西,所以提前開始做調研。在度娘上看了好多部落格、百度知道、百度經驗、知乎問答等,還仔細閱讀了微信公眾平臺開發文件,大致瞭解到:        微信網頁授

公眾開發002-網頁授權

閱讀完的我們就知道在獲取使用者授權資訊的時候需要設定回撥域名:(1)、在微信公眾號請求使用者網頁授權之前,開發者需要先到公眾平臺官網中的“開發 - 介面許可權 - 網頁服務 - 網頁帳號 - 網頁授權獲取使用者基本資訊”的配置選項中,修改授權回撥域名。請注意,這裡填寫的是域名

C#公眾開發 -- ()使用者關注之後自動回覆

通過了上一篇文章之後的微信開發者驗證之後,我們就可以做微信公眾號的程式碼開發了。 當我們點選關注某個公眾號的時候,有時候會發現他會自動給我們回覆一條訊息,比如歡迎關注XXX公眾號。這個功能其實是在點選關注的時候,使用者觸發了微信定義的事件,同時微信會返回給我們一個XML資料包,微信官方的解釋如下: 推送X

公眾開發) -- 生成臨時二維碼

1.臨時二維碼和長期二維碼是由 scene_id 的值區分的 scene_id=1是長期 2.通過掃描二維碼關注的使用者 使用者資訊場景值(qr_scene) 為scene_id的值 3.此處只做臨時二維碼的說明 //生成臨時二維碼 function getTimeQrCode(){

公眾開發中遇到的問題——支付回撥分享獲取openId(

微信的統一下單介面(https://api.mch.weixin.qq.com/pay/unifiedorder)中,下單時,有這樣一個引數:notify_url,該引數是為接收微信支付非同步通知回撥的地址,通知url必須為直接可訪問的url,不能攜帶引數。之前我做回撥的時

基於springboot+mybatis的公眾開發篇-訊息的接收與回覆

1、在寫處理訊息的方法前,我們得把相關的model類寫好。 在model包下建立message(req與resp),具體建立如圖所示: BaseMessage類 /** * 訊息基類(普通使用者 -> 公眾帳號) * */ public

公眾開發系列:響應關注和取關事件

一、實際需求              當我們關注某些微信公眾號的時候,有的公眾號會給我們回覆一條文字資訊。本節內容,我們就來實現如何在使用者關注公眾號後,由公眾號給使用者回覆一條文字資訊。同樣在使

公眾開發筆記1(nodejs開發的)

.post err log 加密 課堂 是我 targe 分享 gty 本篇記錄了微信公眾號開發的一些筆記 一、微信服務器與我們服務器的交流 微信開發者擁有自己的服務器,在我們服務器上可以與微信服務器進行交流。既然可以交流,那就必定需要前提條件(微信認證),也就是說,只有自

公眾開發

weixin 後來 方式 發送請求 菜單 ml2 發現 格式 ejs 一、微信服務器與我們服務器的交流 微信開發者擁有自己的服務器,在我們服務器上可以與微信服務器進行交流。既然可以交流,那就必定需要前提條件(微信認證),也就是說,只有自己的服務器與微信服務器進行認證通過後,

公眾開發--獲取用戶息中文亂碼的解決方案

其中 utf-8 == font zzu 解決 col class api 在微信開發中我們會經常需要獲取用戶的信息。 微信給我們提供了獲取用戶信息的api, 地址為 https://api.weixin.qq.com/cgi-bin/user/info?access_t

公眾開發80端口映射解決方案

解決方案 微信開發 80端口映射 說明最近公司要搞微信公眾號開發,需要解決80端口映射的問題,看了網上好多老司機的方法,最終選擇ngrok比較符合公司的情況。微信公眾平臺開發,可參考:https://mp.weixin.qq.com/wiki 。微信公眾號接口只支持80接口。測試環境: wind

公眾開發系列-啟用開發模式

sum oca 使用 popu 接口交互 開發模式 signature 微信公眾 local 微信公眾平臺分為兩種模式:編輯模式與開發模式; 微信公眾帳號申請成功後,要想用程序接收處理用戶的請求,就必需要在“高級功能”裏進行配置。點擊“高級功能”。 從微信開發平臺開發人

公眾開發(一)

jpg 解壓 china arc 公眾平臺 開發 技術分享 更換 微信公眾號 4.1 示例代碼設置 首先下載此處的php接入代碼 ,在公眾號中 配置 url 地址指向 文件 代碼 只需更換 自定義的token 即可 這樣就完成最初的接入 微信公眾平臺提供了一個php示例

公眾開發】根據openId群發消息

tostring put spa rep tpc shm 發送 ring private 根據開發文檔可知,只要使用POST方式提交固定格式的json字符串到那個地址即可。這裏我寫的是最簡單的文本 第一步:建立對應的實體類。 1 package cn.sp.bean;

公眾開發網頁授權(獲取用戶息)

還需要 開發文檔 app err 通過 casb ddt 省份 sse   這次暑假留在學校參與工作室的項目,對微信公眾號比較感興趣,所以參與這方面的學習研究。 昨天完成了關於網頁授權,獲取用戶信息方面的功能,所以乘熱打鐵,寫上一篇。實現本篇涉及的 功能,還需要完成一些基礎