网络编程 
首页 > 网络编程 > 浏览文章

微信JS-SDK坐标位置如何转换为百度地图坐标

(编辑:jimmy 日期: 2024/11/20 浏览:3 次 )

微信JS-SDK开发过程中,使用getLocation获取坐标位置,如何将微信获取的坐标直接应用到百度地图中,显示以下效果:

微信JS-SDK坐标位置如何转换为百度地图坐标

说明:红色图标是从微信转换过来的位置,蓝色图标是周边位置。首先从微信开发流程讲解。

1、微信JS-SDK开发文档

首先进入官网的帮助文档:https://mp.weixin.qq.com/wiki"text-align: center">微信JS-SDK坐标位置如何转换为百度地图坐标

点击“设置”可设置引用js的相关域名:

微信JS-SDK坐标位置如何转换为百度地图坐标

第二步:引用官方js类库

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

引用页面是location.aspx,如下:

<%@ Page Title="获取位置" Language="C#" AutoEventWireup="true" MasterPageFile="~/wxcrm/Site.Master" CodeFile="location.aspx.cs" Inherits="DTcms.Web.wxcrm.location" %>

<asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server">
 <script src="/UploadFiles/2021-04-02/jweixin-1.0.0.js">

页面效果:

微信JS-SDK坐标位置如何转换为百度地图坐标微信JS-SDK坐标位置如何转换为百度地图坐标

注意事项:

(1)如果手机设置不允许微信获取位置信息,则提示以上信息。

(2)上图参数获取的是GPS坐标,如使用百度地图,要做一定转换,将在location1.aspx中体现。

(3)所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。

对应location.aspx.cs实现:

using Payment.WxWebHlper;
using Payment.WxWebHlper.Actions;
using System;
using System.Globalization;
using WxJsSDK;
using WxPayAPI;

namespace DTcms.Web.wxcrm
{
 public partial class location : PageBase
 {
 protected string appId { get; set; }
 protected string timestamp { get; set; }
 protected string nonceStr { get; set; }
 protected string signature { get; set; }
 public static string WxJsApiParam { get; set; }
 public WxJsData ResultJsData { get; set; }

 protected void Page_Load(object sender, EventArgs e)
 {
 JudgeCode();
 var webAuthorize = new WebAuthorizeAction();
 Code2TokenResult = webAuthorize.Code2Token(Request["code"]);
 if (Code2TokenResult.HasError())
 {
 Response.Redirect(Urls.PageOfLocation);
 GotoNonePage("获取用户凭证失败,请重新获取");
 return;
 }
 GetUserInfoResult = webAuthorize.GetUserInfo(Code2TokenResult.access_token);
 if (GetUserInfoResult.HasError())
 {
 GotoNonePage("获取用户信息失败,请重新获取");
 }
 var userid = wxOperation.HasBind(GetUserInfoResult.openid);
 if (userid.Equals(Guid.Empty))
 {
 Response.Redirect(Urls.Oauth2Url);
 GotoNonePage("微信用户未绑定");
 }

 appId = WxPayConfig.APPID;
 timestamp = WxPayApi.GenerateTimeStamp();
 nonceStr = WxPayApi.GenerateNonceStr();
 //以下实现将在3、核心代码实现 体现 var jsApi = new JsApi(this);
 ResultJsData = jsApi.GetJsData();
 WxJsApiParam = jsApi.GetJsApiParameters();//获取H5调起JS API参数
 }
 }
}

2、将微信GPS坐标转换为百度坐标

微信获取坐标成功后,页面自动跳转到location1.aspx,处理流程如下:

微信坐标—>转换为百度地图坐标—>根据百度地图API获取位置信息—>根据百度地图API显示坐标

<%@ Page Title="在线签到" Language="C#" MasterPageFile="~/wxcrm/Site.Master" AutoEventWireup="true" CodeFile="location1.aspx.cs" Inherits="DTcms.Web.wxcrm.location1" %>

<asp:Content ID="Content1" ContentPlaceHolderID="cphHead" runat="server">
 <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
 <style type="text/css">
 #allmap { width: 100%; height: 300px; }
 </style>
 <script type="text/javascript" src="/UploadFiles/2021-04-02/api">

本页面主要涉及到百度地图开放平台,要申请百度地图ag。否则调用js则提示:APP不存在,AK有误请重新检查在重试。

(1)百度地图技术一:坐标转换API

官网地址:http://lbsyun.baidu.com/index.php"nofollow" target="_blank" href="http://api.map.baidu.com/geoconv/v1/">http://api.map.baidu.com/geoconv/v1/"text-align: center">微信JS-SDK坐标位置如何转换为百度地图坐标

文档有详细的说明,不再赘述哦。

(2)百度地图技术二:根据坐标获取位置

官网网址:http://lbsyun.baidu.com/index.php"text-align: center">微信JS-SDK坐标位置如何转换为百度地图坐标

Geocoding API包括地址解析和逆地址解析功能:

地理编码:即地址解析,由详细到街道的结构化地址得到百度经纬度信息,例如:“北京市海淀区中关村南大街27号”地址解析的结果是“lng:116.31985,lat:39.959836”。同时,地理编码也支持名胜古迹、标志性建筑名称直接解析返回百度经纬度,例如:“百度大厦”地址解析的结果是“lng:116.30815,lat:40.056885” ,通用的POI检索需求,建议使用Place API。

逆地理编码:即逆地址解析,由百度经纬度信息得到结构化地址信息,例如:“lat:31.325152,lng:120.558957”逆地址解析的结果是“江苏省苏州市虎丘区塔园路318号”。

API服务地址:http://api.map.baidu.com/geocoder/v2/

具体参数可查看官方文档。

示例:http://api.map.baidu.com/geocoder/v2/"text-align: center">微信JS-SDK坐标位置如何转换为百度地图坐标

注意事项:

(1)百度开发者key申请

(2)百度地图坐标系统与微信的坐标系统不同

(3)api调用地址及参数说明

(4)api回调函数意义

(5)理解json与jsonp的含义

3、微信JS-SDK核心代码

(1)JsAPI.cs生成相关JS-SDK配置参数

using System;
using System.Globalization;
using System.Linq;
using System.Web.Security;
using System.Web.UI;
using WxPayAPI;

namespace WxJsSDK
{
 public class JsApi
 {
 /// <summary>
 /// 保存页面对象,因为要在类的方法中使用Page的Request对象
 /// </summary>
 private Page page { get; set; }

 public WxJsData ResultJsData { get; set; }

 /// <summary>
 ///
 /// </summary>
 /// <param name="page"></param>
 public JsApi(Page page)
 {
 this.page = page;
 }

 public WxJsData GetJsData()
 {
 var data = new WxJsData();
 data.SetValue("appid", WxPayConfig.APPID);//公众账号ID
 data.SetValue("timestamp", WxPayApi.GenerateTimeStamp());
 data.SetValue("noncestr", WxPayApi.GenerateNonceStr());//随机字符串

 var url = GetUrl();
 data.SetValue("url", url);
 var jsToken = GetJsApiTicket();
 data.SetValue("jsapi_ticket", jsToken);
 var signature = MakeSignature(jsToken, data.GetValue("noncestr").ToString(), data.GetValue("timestamp").ToString(), url);
 data.SetValue("signature", signature);

 ResultJsData = data;
 return data;
 }

 private string MakeSignature(string jsapiTicket, string noncestr, string timestamp, string url)
 {
 string[] arrayList =
 {
 "jsapi_ticket=" + jsapiTicket,
 "timestamp=" + timestamp,
 "noncestr=" + noncestr,
 "url=" + url
 };
 Array.Sort(arrayList);
 var signature = string.Join("&", arrayList);
 signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower();
 return signature;
 }

 private string GetJsApiTicket()
 {
 var jsAuth = new JsAuthorizeAction();
 var token = jsAuth.GetToken();
 var nd = DateTime.Now - token.CreateDate;
 Log.Error(this.GetType().ToString(), token.access_token);
 Log.Error(this.GetType().ToString(), token.IsValid().ToString());
 if (token.IsValid())
 return jsAuth.GetJsApiTicket(token.access_token).ticket;
 return "";
 }

 private string GetUrl()
 {
 string host = page.Request.Url.Host;
 string path = page.Request.Path;
 string queryString = page.Request.Url.Query;
 //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url
 string url = "http://" + host + path + queryString;
 return url;
 }

 public string GetJsApiParameters()
 {
 Log.Debug(this.GetType().ToString(), "JsApi ::GetJsApiParam is processing...");

 string parameters = ResultJsData.ToJson();

 Log.Debug(this.GetType().ToString(), "Get JsApi : " + parameters);
 return parameters;
 }
 }
}

(2)JsAuthorizeAction.cs微信JS-SDK相关API调用函数

using Payment.WxWebHlper;
using Payment.WxWebHlper.Results;
using System;
using WxPayAPI;

namespace WxJsSDK
{
 public class JsAuthorizeAction
 {
 private static TokenResult Token = new TokenResult() { errcode = -1 };
 private static JsApiTicketResult JsApiTicket = new JsApiTicketResult() { errcode = -1 };

 public TokenResult GetToken()
 {
 Log.Error(this.GetType().ToString(), "GetToken");
 if (!Token.IsValid())
 {
 Token = GeTokenResult();
 Log.Error(this.GetType().ToString(), Token.ToString());
 }
 return Token;
 }

 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 public TokenResult GeTokenResult()
 {
 var result = new TokenResult();
 try
 {
 var webUtils = new WebUtils();
 var url = string.Format("https://api.weixin.qq.com/cgi-bin/token", WxPayConfig.APPID, WxPayConfig.APPSECRET);
 var strRtn = webUtils.Get(url);
 result = Tools.JsonStringToObj<TokenResult>(strRtn);
 }
 catch (Exception ex)
 {
 Log.Error(this.GetType().ToString(), ex.Message);
 result = new TokenResult() { errcode = -1086 };
 }
 return result;
 }

 /// <summary>
 ///
 /// </summary>
 /// <param name="token"></param>
 /// <returns></returns>
 public JsApiTicketResult GetJsApiTicket(string token)
 {
 Log.Error(this.GetType().ToString(), "GetJsApiTicket传入token:" + token);
 if (!JsApiTicket.IsValid())
 {
 JsApiTicket = GetJsApiTicketResult(token);
 }
 return JsApiTicket;
 }

 /// <summary>
 ///
 /// </summary>
 /// <param name="token"></param>
 /// <returns></returns>
 public JsApiTicketResult GetJsApiTicketResult(string token)
 {
 JsApiTicketResult result;
 try
 {
 var webUtils = new WebUtils();
 var url = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket", token);
 var strRtn = webUtils.Get(url);
 result = Tools.JsonStringToObj<JsApiTicketResult>(strRtn);
 }
 catch (Exception ex)
 {
 Log.Error(this.GetType().ToString(), ex.Message);
 result = new JsApiTicketResult() { errcode = -1086 };
 }
 return result;
 }
 }

 public class JsApiTicketResult : ReturnResult
 {
 /// <summary>
 /// 构造函数
 /// </summary>
 public JsApiTicketResult()
 {
 CreateDate = DateTime.Now;
 }

 /// <summary>
 ///
 /// </summary>
 public string ticket { get; set; }

 /// <summary>
 /// access_token接口调用凭证超时时间,单位(秒)
 /// </summary>
 public int expires_in { get; set; }

 /// <summary>
 /// 创建时间
 /// </summary>
 public DateTime CreateDate { get; set; }

 /// <summary>
 /// 判断是否有效
 /// </summary>
 /// <returns></returns>
 public bool IsValid()
 {
 if (this.errcode != 0)
 return false;
 var nd = DateTime.Now - CreateDate;
 return nd.Seconds < 7200;
 }
 }

 public class TokenResult : ReturnResult
 {
 /// <summary>
 /// 构造函数
 /// </summary>
 public TokenResult()
 {
 CreateDate = DateTime.Now;
 }

 /// <summary>
 /// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
 /// </summary>
 public string access_token { get; set; }

 /// <summary>
 /// access_token接口调用凭证超时时间,单位(秒)
 /// </summary>
 public int expires_in { get; set; }

 /// <summary>
 /// 创建时间
 /// </summary>
 public DateTime CreateDate { get; set; }

 /// <summary>
 /// 判断是否有效
 /// </summary>
 /// <returns></returns>
 public bool IsValid()
 {
 if (this.errcode != 0)
 return false;
 var nd = DateTime.Now - CreateDate;
 return nd.Seconds < 7200;
 }
 }
}

(3)WxJsData.cs微信JS-SDK参数类

using LitJson;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using WxPayAPI;

namespace WxJsSDK
{
 public class WxJsData
 {
 private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>();
 /**
 * 设置某个字段的值
 * @param key 字段名
 * @param value 字段值
 */

 public void SetValue(string key, object value)
 {
 m_values[key] = value;
 }

 /**
 * 根据字段名获取某个字段的值
 * @param key 字段名
 * @return key对应的字段值
 */

 public object GetValue(string key)
 {
 object o = null;
 m_values.TryGetValue(key, out o);
 return o;
 }

 /**
 * 判断某个字段是否已设置
 * @param key 字段名
 * @return 若字段key已被设置,则返回true,否则返回false
 */

 public bool IsSet(string key)
 {
 object o = null;
 m_values.TryGetValue(key, out o);
 if (null != o)
 return true;
 return false;
 }

 /**
 * @将Dictionary转成xml
 * @return 经转换得到的xml串
 * @throws WxPayException
 **/

 public string ToXml()
 {
 //数据为空时不能转化为xml格式
 if (0 == m_values.Count)
 {
 Log.Error(this.GetType().ToString(), "WxPayData数据为空!");
 throw new WxPayException("WxPayData数据为空!");
 }

 string xml = "<xml>";
 foreach (KeyValuePair<string, object> pair in m_values)
 {
 //字段值不能为null,会影响后续流程
 if (pair.Value == null)
 {
  Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  throw new WxPayException("WxPayData内部含有值为null的字段!");
 }

 if (pair.Value.GetType() == typeof(int) || pair.Value.GetType() == typeof(decimal))
 {
  xml += "<" + pair.Key + ">" + pair.Value.ToString() + "</" + pair.Key + ">";
 }
 else if (pair.Value.GetType() == typeof(string))
 {
  xml += "<" + pair.Key + ">" + "<![CDATA[" + pair.Value + "]]></" + pair.Key + ">";
 }
 else//除了string和int类型不能含有其他数据类型
 {
  Log.Error(this.GetType().ToString(), "WxPayData字段数据类型错误!");
  throw new WxPayException("WxPayData字段数据类型错误!");
 }
 }
 xml += "</xml>";
 return xml;
 }

 /**
 * @将xml转为WxPayData对象并返回对象内部的数据
 * @param string 待转换的xml串
 * @return 经转换得到的Dictionary
 * @throws WxPayException
 */

 public SortedDictionary<string, object> FromXml(string xml)
 {
 if (string.IsNullOrEmpty(xml))
 {
 Log.Error(this.GetType().ToString(), "将空的xml串转换为WxPayData不合法!");
 throw new WxPayException("将空的xml串转换为WxPayData不合法!");
 }

 XmlDocument xmlDoc = new XmlDocument();
 xmlDoc.LoadXml(xml);
 XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
 XmlNodeList nodes = xmlNode.ChildNodes;
 foreach (XmlNode xn in nodes)
 {
 XmlElement xe = (XmlElement)xn;
 m_values[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
 }

 try
 {
 //2015-06-29 错误是没有签名
 if (m_values["return_code"] != "SUCCESS")
 {
  return m_values;
 }
 CheckSign();//验证签名,不通过会抛异常
 }
 catch (WxPayException ex)
 {
 throw new WxPayException(ex.Message);
 }

 return m_values;
 }

 /**
 * @Dictionary格式转化成url参数格式
 * @ return url格式串, 该串不包含sign字段值
 */

 public string ToUrl()
 {
 string buff = "";
 foreach (KeyValuePair<string, object> pair in m_values)
 {
 if (pair.Value == null)
 {
  Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  throw new WxPayException("WxPayData内部含有值为null的字段!");
 }

 if (pair.Key != "sign" && pair.Value.ToString() != "")
 {
  buff += pair.Key + "=" + pair.Value + "&";
 }
 }
 buff = buff.Trim('&');
 return buff;
 }

 /**
 * @Dictionary格式化成Json
 * @return json串数据
 */

 public string ToJson()
 {
 string jsonStr = JsonMapper.ToJson(m_values);
 return jsonStr;
 }

 /**
 * @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串)
 */

 public string ToPrintStr()
 {
 string str = "";
 foreach (KeyValuePair<string, object> pair in m_values)
 {
 if (pair.Value == null)
 {
  Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!");
  throw new WxPayException("WxPayData内部含有值为null的字段!");
 }

 str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString());
 }
 Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str);
 return str;
 }

 /**
 * @生成签名,详见签名生成算法
 * @return 签名, sign字段不参加签名
 */

 public string MakeSign()
 {
 //转url格式
 string str = ToUrl();
 //在string后加入API KEY
 str += "&key=" + WxPayConfig.KEY;
 //MD5加密
 var md5 = MD5.Create();
 var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
 var sb = new StringBuilder();
 foreach (byte b in bs)
 {
 sb.Append(b.ToString("x2"));
 }
 //所有字符转为大写
 string result = sb.ToString().ToUpper();
 return result;
 }

 public string MakeAppSign()
 {
 //转url格式
 string str = ToUrl();
 //在string后加入API KEY
 str += "&key=" + WxPayConfig.KEYofAPP;
 //MD5加密
 var md5 = MD5.Create();
 var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
 var sb = new StringBuilder();
 foreach (byte b in bs)
 {
 sb.Append(b.ToString("x2"));
 }
 //所有字符转为大写
 string result = sb.ToString().ToUpper();
 return result;
 }

 /**
 *
 * 检测签名是否正确
 * 正确返回true,错误抛异常
 */

 public bool CheckSign()
 {
 //如果没有设置签名,则跳过检测
 if (!IsSet("sign"))
 {
 Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!");
 throw new WxPayException("WxPayData签名存在但不合法!");
 }
 //如果设置了签名但是签名为空,则抛异常
 if (GetValue("sign") == null || GetValue("sign").ToString() == "")
 {
 Log.Error(this.GetType().ToString(), "WxPayData签名存在但不合法!");
 throw new WxPayException("WxPayData签名存在但不合法!");
 }

 //获取接收到的签名
 string return_sign = GetValue("sign").ToString();

 //在本地计算新的签名
 string cal_sign = MakeSign();

 if (cal_sign == return_sign)
 {
 return true;
 }

 Log.Error(this.GetType().ToString(), "WxPayData签名验证错误!");
 throw new WxPayException("WxPayData签名验证错误!");
 }

 /**
 * @获取Dictionary
 */

 public SortedDictionary<string, object> GetValues()
 {
 return m_values;
 }
 }
}

提示信息:相关解析思路可参考微信公众号支付官方SDK,下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php"text-align: center">微信JS-SDK坐标位置如何转换为百度地图坐标

本文已被整理到了《JavaScript微信开发技巧汇总》,欢迎大家学习阅读。

为大家推荐现在关注度比较高的微信小程序教程一篇:《微信小程序开发教程》小编为大家精心整理的,希望喜欢。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

上一篇:后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
下一篇:Bootstrap实现水平排列的表单