微信公衆號開發《三》微信JS-SDK之地理位置的獲取與在線導航,集成百度地圖實如今線地圖搜索

本次講解微信開發第三篇:獲取用戶地址位置信息,是很是經常使用的功能,特別是服務行業公衆號,尤其須要該功能,本次講解的就是如何調用微信JS-SDK接口,獲取用戶位置信息,並結合百度地鐵,實如今線地圖搜索,與在線導航。javascript


官方文檔地址:https://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html css

在這粘貼上二篇博文連接,方便你們訪問: html

微信公衆號開發《一》OAuth2.0網頁受權認證獲取用戶的詳細信息,實現自動登錄 java

微信公衆號開發《二》發送模板消息實現消息業務實時通知
jquery

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

那如何配置呢?下面講解下配置步驟:示例講解是基於測試公衆號,如何使用測試公衆號,能夠參考第一篇文章 算法

 

1.在公衆號後臺綁定域名:測試公衆號登陸就可看見以下圖。正式公衆號配置位置:「公衆號設置」的「功能設置」裏填寫「JS接口安全域名」json


2.頁面中引入接口JS文件,下載地址:http://res.wx.qq.com/open/js/jweixin-1.2.0.js api

注意:JS最新版本爲1.2.0,爲了適配IOS開發,最好使用最新版本號JS,1.1.0版本可能會形成有些功能調用失敗,有興趣的能夠看看官方文檔:https://mp.weixin.qq.com/advanced/wiki?t=t=resource/res_main&id=mp1483682025_enmey 數組

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);
}

本文也發佈到另一個網站,若是隻有那邊纔有賬號的,有須要的能夠收藏一下微信JS-SDK之地理位置的獲取,集成百度地圖實如今線地圖搜索

到此該篇博文已經講解完畢,若有問題,歡迎你們指出,一塊兒探討

相關文章
相關標籤/搜索