DotNet 调用百度地图 LBS 服务 API
最近公司项目中需要根据两个地点的交通路径和距离做一些数据推荐,为了程序的稳定和用户体验所以想从百度地图 API 采集数据保存到数据库中,经过一翻研究之后选定了百度地图 Web 服务 API 中的 Direction API ,最后写了个服务去定时采集。
关于 Direction API 的相关说明这里不做详细阐述了,大家可以去百度地图 API 的页面去详细了解,地址:http://developer.baidu.com/map/direction-api.htm。
一、准备工作
1、首先要去申请一个密钥,地址:http://lbsyun.baidu.com/apiconsole/key?application=key
根据自己的需求选择相应的功能,需要注意的是如果请求校验方式选择了sn校验方式的话,在请求 Api 地址的时候需要传入sn参数。
如下图所示:
2、下表是请求接口参数
参数 | 是否必须 | 格式举例 | 参数含义 |
---|---|---|---|
origin | 必选 | 名称:百度大厦 坐标格式为:lat<纬度>,lng<经度> 名称+经纬度:百度大厦|40.056878,116.30815 |
起点名称或经纬度,或者可同时提供名称和经纬度,此时经纬度优先级高,将作为导航依据,名称只负责展示。 |
destination | 必选 | 名称:天安门 经纬度:39.915285, 116.403857 坐标格式为:lat<纬度>,lng<经度> 名称+经纬度:百度大厦|40.056878,116.30815 |
起点名称或经纬度,或者可同时提供名称和经纬度,此时经纬度优先级高,将作为导航依据,名称只负责展示。 |
mode | 选填,默认为driving | driving(驾车模式) | 导航模式,包括:driving(驾车)、walking(步行)、transit(公交) |
region | 必填 | 北京 | 公交、步行导航时该参数必填。 |
origin_region | 必填 | 北京 | 起始点所在城市,驾车导航时必填。 |
destination_region | 必填 | 北京 | 终点所在城市,驾车导航时必填。 |
output | 选填,默认为xml | json | 表示输出类型,可设置为xml或json,默认为xml。 |
coord_type | 选填,默认为bd09ll | gcj02(国测局坐标,如google,soso地图均采用该坐标) | 坐标类型,可选参数,默认为bd09ll。允许的值为:bd09ll(百度经纬度坐标)、bd09mc(百度摩卡托坐标)、gcj02(国测局加密坐标)、wgs84(gps设备获取的坐标)。 |
waypoints | 选填 | 奎科科技大厦|西单 | 途经点集合,包括一个或多个用竖线字符 "|" 分隔的地址名称或经纬度。 |
tactics | 选填 | 11 | 导航策略。导航路线类型,10,不走高速;11、最少时间;12、最短路径。 |
ak | 必填 | E4805d16520de693a3fe707cdc962045 | 用户的访问权限 |
sn | 选填 | 用户的权限签名 | |
timestamp | sn存在时必填 | 时间戳,与sn配合使用。 |
3、通过 GET 请求采集 API 数据
请求 API 的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /// <summary> /// 发送 API 请求并返回方案信息。 /// </summary> /// <returns></returns> private static T RequestApi<T>( string origin, string origin_region, string destination, string destination_region, string mode) { string apiUrl = "http://api.map.baidu.com/direction/v1" ; //string ak = "E4805d16520de693a3fe707cdc962045"; string apiKey = "E4805d16520de693a3fe707cdc962045" ; // string output = "json" ; //string origin_region = "北京"; //string origin = "清华大学"; //string destination = "北京大学"; //string destination_region = "北京"; //string mode = "driving"; IDictionary< string , string > param = new Dictionary< string , string >(); param.Add( "ak" , apiKey); param.Add( "output" , output); if (mode == "driving" ) { param.Add( "origin_region" , origin_region); param.Add( "destination_region" , destination_region); } else { param.Add( "region" , origin_region); } param.Add( "origin" , origin); param.Add( "destination" , destination); param.Add( "mode" , mode); string result = string .Empty; //初始化方案信息实体类。 T info = default (T); try { //以 Get 形式请求 Api 地址 result = HttpUtils.DoGet(apiUrl, param); info = JsonHelper.FromJsonTo<T>(result); } catch (Exception) { info = default (T); throw ; } return info; } |
HttpUtils 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | /// <summary> /// 提供 Http 相关方法。 /// </summary> public class HttpUtils { /// <summary> /// 执行HTTP GET请求。 /// </summary> /// <param name="url">请求地址</param> /// <param name="parameters">请求参数</param> /// <returns>HTTP响应</returns> public static string DoGet( string url, IDictionary< string , string > parameters) { if (parameters != null && parameters.Count > 0) { if (url.Contains( "?" )) { url = url + "&" + BuildPostData(parameters); } else { url = url + "?" + BuildPostData(parameters); } } HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); req.ServicePoint.Expect100Continue = false ; req.Method = "GET" ; req.KeepAlive = true ; req.UserAgent = "Test" ; req.ContentType = "application/x-www-form-urlencoded;charset=utf-8" ; HttpWebResponse rsp = null ; try { rsp = (HttpWebResponse)req.GetResponse(); } catch (WebException webEx) { if (webEx.Status == WebExceptionStatus.Timeout) { rsp = null ; } } if (rsp != null ) { if (rsp.CharacterSet != null ) { Encoding encoding = Encoding.GetEncoding(rsp.CharacterSet); return GetResponseAsString(rsp, encoding); } else { return string .Empty; } } else { return string .Empty; } } /// <summary> /// 把响应流转换为文本。 /// </summary> /// <param name="rsp">响应流对象</param> /// <param name="encoding">编码方式</param> /// <returns>响应文本</returns> private static string GetResponseAsString(HttpWebResponse rsp, Encoding encoding) { StringBuilder result = new StringBuilder(); Stream stream = null ; StreamReader reader = null ; try { // 以字符流的方式读取HTTP响应 stream = rsp.GetResponseStream(); reader = new StreamReader(stream, encoding); // 每次读取不大于256个字符,并写入字符串 char [] buffer = new char [256]; int readBytes = 0; while ((readBytes = reader.Read(buffer, 0, buffer.Length)) > 0) { result.Append(buffer, 0, readBytes); } } catch (WebException webEx) { if (webEx.Status == WebExceptionStatus.Timeout) { result = new StringBuilder(); } } finally { // 释放资源 if (reader != null ) reader.Close(); if (stream != null ) stream.Close(); if (rsp != null ) rsp.Close(); } return result.ToString(); } /// <summary> /// 组装普通文本请求参数。 /// </summary> /// <param name="parameters">Key-Value形式请求参数字典。</param> /// <returns>URL编码后的请求数据。</returns> private static string BuildPostData(IDictionary< string , string > parameters) { StringBuilder postData = new StringBuilder(); bool hasParam = false ; IEnumerator<KeyValuePair< string , string >> dem = parameters.GetEnumerator(); while (dem.MoveNext()) { string name = dem.Current.Key; string value = dem.Current.Value; // 忽略参数名或参数值为空的参数 if (! string .IsNullOrEmpty(name) && ! string .IsNullOrEmpty(value)) { if (hasParam) { postData.Append( "&" ); } postData.Append(name); postData.Append( "=" ); postData.Append(Uri.EscapeDataString(value)); hasParam = true ; } } return postData.ToString(); } } |
通过循环调用 RequestApi 的方式就可以获取两个地点的交通数据了。
Json 转换后的实体类可以通过 json2csharp 工具直接生成,地址:http://json2csharp.com/。
二、需要注意的是:
1、这个 API 有时候请求之后响应时间较长,经常会超时,所以我在 HttpUtils 类里抛出了 WebException 异常。
2、Json 转换的方法里也要做异常处理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2012-04-09 DotNet 项目中集成 Enterprise Library 数据库访问模块