您好,登錄后才能下訂單哦!
本文實例講述了C#實現微信結合百度api獲取當前用戶地理位置的方法。分享給大家供大家參考,具體如下:
操作步驟:
1. 先根據微信提供的接口文檔獲取到經緯度
參考文檔地址:http://mp.weixin.qq.com/wiki/8/1b86529d05db9f960e48c3c7ca5be288.html
2. 由于直接使用微信獲取到的經緯度,來使用百度地圖api獲取地址存在500~1000米的偏差,有時候定位不是很準確,所以需要轉換成百度的坐標
參考文檔地址:http://developer.baidu.com/map/index.php?title=webapi/guide/changeposition
3. 根據百度api實現逆地址解析,獲取當前位置
參考文檔地址:http://developer.baidu.com/map/index.php?title=webapi/guide/webservice-geocoding
具體實例:
該例子是mvc項目
1. WX_Location.cshtml頁面:
@using System.Web.Optimization; @{ Layout = "~/Views/Shared/Master/_App.cshtml"; } @section Head{ } <div data-role="page"> <div data-role="header" id="header" data-position="fixed"> <h2>微信定位頁面</h2> </div> <div data-role="content" class="ui-content"> <form id="add" method="post" onsubmit="return false"> <table border="0" cellpadding="0" cellspacing="0" class="register_table"> <tr class='tr_bg neiy'> <td class='tdl neiy'>定位:</td> <td class='tdr'><input id='txt_dw' name='dw' type='text' placeholder='正在定位' class='td_input' value='' /></td></tr> </table> <div data-role="footer" data-position="fixed" data-id="footernav"> <div data-role="navbar"> <ul> <li><a href="" external nofollow" font-size: 1em;">返回主頁</a></li> </ul> </div> </div> @Html.AntiForgeryToken() </form> </div> </div> @section scripts{ @*微信js-sdk*@ <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js" type="text/javascript"></script> <script type="text/javascript"> //微信jssdk配置 wx.config({ debug: false, appId: "", timestamp: "@Html.Raw(ViewData["timestamp"])", nonceStr: "@Html.Raw(ViewData["nonceStr"])", signature: "@Html.Raw(ViewData["signature"])", jsApiList: [ 'checkJsApi', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'hideMenuItems', 'showMenuItems', 'hideAllNonBaseMenuItem', 'showAllNonBaseMenuItem', 'translateVoice', 'startRecord', 'stopRecord', 'onRecordEnd', 'playVoice', 'pauseVoice', 'stopVoice', 'uploadVoice', 'downloadVoice', 'chooseImage', 'previewImage', 'uploadImage', 'downloadImage', 'getNetworkType', 'openLocation', 'getLocation', 'hideOptionMenu', 'showOptionMenu', 'closeWindow', 'scanQRCode', 'chooseWXPay', 'openProductSpecificView', 'addCard', 'chooseCard', 'openCard' ] }); //wx.error(function (res) { // alert("錯誤:" + res); //}); wx.checkJsApi({ jsApiList: [ 'getLocation', ], success: function (res) { if (res.checkResult.getLocation == false) { alert('你的微信版本太低,不支持微信JS接口,請升級到最新的微信版本!'); return; } } }); wx.ready(function () { 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); //獲取到經緯度之后,異步去后臺加載出來真實的地理位置 $.post("/App/Common/GetLocation", { lat: latitude, lon: longitude }, function (data) { //把返回回來的地理位置顯示在頁面的控件里面 $("#txt_dw").val(data); }, 'html'); }, cancel: function (res) { alert('用戶拒絕授權獲取地理位置'); } }); }); </script> }
2.
/// <summary> /// 微信定位 /// </summary> /// <returns></returns> public ActionResult WX_Location() { #region 獲取定位所需要的參數 //jssdk JS接口安全域名填寫, //access_token來獲取jsapi_ticket string ticket = GetTicket(); var timeStamp = TenpayUtil.getTimestamp(); var nonceStr = TenpayUtil.getNoncestr(); //設置參數 RequestHandler paySignReqHandler = new RequestHandler(System.Web.HttpContext.Current); //參數順序。 paySignReqHandler.setParameter("jsapi_ticket", ticket); paySignReqHandler.setParameter("noncestr", nonceStr); paySignReqHandler.setParameter("timestamp", timeStamp); paySignReqHandler.setParameter("url", Request.Url.AbsoluteUri);//Url#號后不要 // LogHelper.WriteInfoLog("noncestr:" + nonceStr + "。jsapi_ticked:" + ticket + "。timestamp:" + timeStamp + "。url:"+Request.Url.AbsoluteUri + "。"); ViewData["signature"] = paySignReqHandler.createSHA1Sign(); //LogHelper.WriteInfoLog("signature:" + paySignReqHandler.createSHA1Sign()); ViewData["timestamp"] = timeStamp; ViewData["nonceStr"] = nonceStr; #endregion return View(); }
3. 獲取地理位置方法
#region 獲取地理位置 public ActionResult GetLocation(string lat, string lon) { //23.1294。113.3761 LogHelper.WriteInfoLog(lat + "。" + lon); string x = string.Empty, y = string.Empty, strReturn = string.Empty; #region 先把微信經緯度(23.12536。113.36684 )轉換成百度坐標 string apiurl = "http://api.map.baidu.com/geoconv/v1/?coords=" + lon + "," + lat + "&from=1&to=5&ak=你的百度地圖api密鑰"; WebRequest request = WebRequest.Create(@apiurl); request.Method = "POST"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); Encoding encode = Encoding.UTF8; StreamReader reader = new StreamReader(stream, encode); string detail = reader.ReadToEnd(); var jd = JsonConvert.DeserializeObject<BaiDuCoordinates>(detail); List<bc_result> result = jd.result; foreach (var item in result) { x = item.x; y = item.y; } #endregion #region 通過得到的百度坐標進行逆地址解析獲取到真實的地理位置 apiurl = "http://api.map.baidu.com/geocoder/v2/?ak=8aoCgAGfz0r4MantipNitjI0&callback=renderReverse&location=" + y + "," + x + "&output=json&pois=1"; #region 通過傳入的參數得到url請求 request = WebRequest.Create(@apiurl); request.Method = "POST"; response = request.GetResponse(); stream = response.GetResponseStream(); encode = Encoding.UTF8; reader = new StreamReader(stream, encode); detail = reader.ReadToEnd(); //@"(?is)(?<=)(.∗)(?=)";//(?is) // string results = System.Text.RegularExpressions.Regex.Replace(detail, @"(?is)(?<=)(.∗)(?=)", "$2"); string results = Regex.Match(detail, @"(?is)(?<=)(.∗)(?=)").Result("$1"); JsonData jsondta = JsonMapper.ToObject(results); JsonData jdItems = jsondta["result"]; //獲取結構化地址信息 strReturn = (String)jdItems["formatted_address"]; LogHelper.WriteInfoLog(strReturn); #endregion #endregion return Content(strReturn); } #endregion
涉及到的相關方法以及類:
1. 獲取ticket
#region w微信JS-SDK權限簽名 public string GetTicket() { #region 通過 appid + appsecert 獲取公眾號的 access_token(不是用戶的 access_token) string apiurl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + TenpayUtil.appid + "&secret=" + TenpayUtil.appsecret; #region 通過傳入的參數得到url請求 WebRequest request = WebRequest.Create(@apiurl); request.Method = "POST"; WebResponse response = request.GetResponse(); Stream stream = response.GetResponseStream(); Encoding encode = Encoding.UTF8; StreamReader reader = new StreamReader(stream, encode); string detail = reader.ReadToEnd(); var jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail); String access_token = (String)jd.access_token; Session["access_token"] = access_token; #endregion #endregion #region 獲取ticket apiurl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token + "&type=jsapi"; request = WebRequest.Create(@apiurl); response = request.GetResponse(); stream = response.GetResponseStream(); encode = Encoding.UTF8; reader = new StreamReader(stream, encode); detail = reader.ReadToEnd(); jd = JsonConvert.DeserializeObject<WX_JSSDK>(detail); String ticket = jd.ticket; Session["ticket"] = ticket; #endregion return ticket; } #endregion
2. TenpayUtil類
/// <summary> /// TenpayUtil 的摘要說明。 /// 配置文件 /// </summary> public class TenpayUtil { public static string tenpay = "1"; //財付通商戶號 public static string partner = "";/ //財付通密鑰 public static string key = ""; //微信appsecret public static string appsecret = ""; //微信appid public static string appid = ""; //paysignkey(非appkey) public static string appkey = ""; //支付完成后的回調處理頁面,*替換成notify_url.asp所在路徑 public static string tenpay_notify = ""; public TenpayUtil() { } public static string getNoncestr() { Random random = new Random(); return MD5Util.GetMD5(random.Next(1000).ToString(), "GBK"); } public static string getTimestamp() { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0); return Convert.ToInt64(ts.TotalSeconds).ToString(); } /** 對字符串進行URL編碼 */ public static string UrlEncode(string instr, string charset) { //return instr; if (instr == null || instr.Trim() == "") return ""; else { string res; try { res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding(charset)); } catch (Exception ex) { res = HttpUtility.UrlEncode(instr, Encoding.GetEncoding("GB2312")); } return res; } } /** 對字符串進行URL解碼 */ public static string UrlDecode(string instr, string charset) { if (instr == null || instr.Trim() == "") return ""; else { string res; try { res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding(charset)); } catch (Exception ex) { res = HttpUtility.UrlDecode(instr, Encoding.GetEncoding("GB2312")); } return res; } } /** 取時間戳生成隨即數,替換交易單號中的后10位流水號 */ public static UInt32 UnixStamp() { TimeSpan ts = DateTime.Now - TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); return Convert.ToUInt32(ts.TotalSeconds); } /** 取隨機數 */ public static string BuildRandomStr(int length) { Random rand = new Random(); int num = rand.Next(); string str = num.ToString(); if (str.Length > length) { str = str.Substring(0, length); } else if (str.Length < length) { int n = length - str.Length; while (n > 0) { str.Insert(0, "0"); n--; } } return str; } }
3. RequestHandler類
/** '簽名工具類 ============================================================================/// <summary> 'api說明: 'init(); '初始化函數,默認給一些參數賦值。 'setKey(key_)'設置商戶密鑰 'createMd5Sign(signParams);字典生成Md5簽名 'genPackage(packageParams);獲取package包 'createSHA1Sign(signParams);創建簽名SHA1 'parseXML();輸出xml 'getDebugInfo(),獲取debug信息 * * ============================================================================ */ public class RequestHandler { public RequestHandler(HttpContext httpContext) { parameters = new Hashtable(); this.httpContext = httpContext; } /** 密鑰 */ private string key; protected HttpContext httpContext; /** 請求的參數 */ protected Hashtable parameters; /** debug信息 */ private string debugInfo; /** 初始化函數 */ public virtual void init() { } /** 獲取debug信息 */ public String getDebugInfo() { return debugInfo; } /** 獲取密鑰 */ public String getKey() { return key; } /** 設置密鑰 */ public void setKey(string key) { this.key = key; } /** 設置參數值 */ public void setParameter(string parameter, string parameterValue) { if (parameter != null && parameter != "") { if (parameters.Contains(parameter)) { parameters.Remove(parameter); } parameters.Add(parameter, parameterValue); } } //獲取package帶參數的簽名包 public string getRequestURL() { this.createSign(); StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "key".CompareTo(k) != 0) { sb.Append(k + "=" + TenpayUtil.UrlEncode(v, getCharset()) + "&"); } } //去掉最后一個& if (sb.Length > 0) { sb.Remove(sb.Length - 1, 1); } return sb.ToString(); } //創建md5摘要,規則是:按參數名稱a-z排序,遇到空值的參數不參加簽名。 protected virtual void createSign() { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { sb.Append(k + "=" + v + "&"); } } sb.Append("key=" + this.getKey()); string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); this.setParameter("sign", sign); //debug信息 this.setDebugInfo(sb.ToString() + " => sign:" + sign); } //創建package簽名 public virtual string CreateMd5Sign(string key, string value) { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { sb.Append(k + "=" + v + "&"); } } sb.Append(key + "=" + value); string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); return sign; } //創建sha1簽名 public string createSHA1Sign() { StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (null != v && "".CompareTo(v) != 0 && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0) { if (sb.Length == 0) { sb.Append(k + "=" + v); } else { sb.Append("&" + k + "=" + v); } } } string paySign = SHA1Util.getSha1(sb.ToString()).ToString().ToLower(); //debug信息 this.setDebugInfo(sb.ToString() + " => sign:" + paySign); return paySign; } public string GetBizSign() { Dictionary<string, string> bizParameters = new Dictionary<string, string>(); ArrayList akeys = new ArrayList(parameters.Keys); akeys.Sort(); foreach (string k in akeys) { string v = (string)parameters[k]; if (!string.IsNullOrEmpty(k)) { bizParameters.Add(k.ToLower(), v); } } if (!bizParameters.Any(p => p.Key.ToLower() == "appkey")) bizParameters.Add("appkey", TenpayUtil.appkey); string bizString = FormatBizQueryParaMap(bizParameters, false); return SHA1Util.Sha1(bizString); } public string FormatBizQueryParaMap(Dictionary<string, string> paraMap, bool urlencode) { string buff = ""; try { var result = from pair in paraMap orderby pair.Key select pair; foreach (KeyValuePair<string, string> pair in result) { if (pair.Key != "") { string key = pair.Key; string val = pair.Value; if (urlencode) { val = System.Web.HttpUtility.UrlEncode(val); } buff += key.ToLower() + "=" + val + "&"; } } if (buff.Length == 0 == false) { buff = buff.Substring(0, (buff.Length - 1) - (0)); } } catch (Exception e) { throw e; //throw new SDKRuntimeException(e.Message); } return buff; } //輸出XML public string parseXML() { StringBuilder sb = new StringBuilder(); sb.Append("<xml>"); int iIsNumber = 0; foreach (string k in parameters.Keys) { string v = (string)parameters[k]; if (int.TryParse(v, out iIsNumber)) { sb.Append("<" + k + ">" + v + "</" + k + ">"); } else { sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">"); } } sb.Append("</xml>"); return sb.ToString(); } /** 設置debug信息 */ public void setDebugInfo(String debugInfo) { this.debugInfo = debugInfo; } public Hashtable getAllParameters() { return this.parameters; } protected virtual string getCharset() { return this.httpContext.Request.ContentEncoding.BodyName; } }
4. 實體
#region 微信sdk public partial class WX_JSSDK { public string access_token { get; set; } public string ticket { get; set; } } #endregion #region 百度坐標轉換 public partial class BaiDuCoordinates { public string status { get; set; } public List<bc_result> result { get; set; } } public partial class bc_result { public string x { get; set; } public string y { get; set; } } #endregion
更多關于C#相關內容感興趣的讀者可查看本站專題:《C#常見控件用法教程》、《WinForm控件用法總結》、《C#數據結構與算法教程》、《C#面向對象程序設計入門教程》及《C#程序設計之線程使用技巧總結》
希望本文所述對大家C#程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。