百度地图热力图--批量地址转换应用(基于百度api)

时间:2024-12-02 12:37:51

需求:把外卖订餐地址做个用户分布热力图

思路分析:第一步去百度地图api开放平台找例子 http://lbsyun.baidu.com/jsdemo.htm#c1_15

首先从百度API的demo例子参考静态页面,其中数据格式是

百度地图热力图--批量地址转换应用(基于百度api)

然后我们就想把数据库里的地址批量转换但是百度API没有提供批量转换的接口。
但是我们找到了百度webapi单个地址转换的接口

百度地图热力图--批量地址转换应用(基于百度api)

利用这个接口,在后台读取地址和统计个数,返回一个json

百度地图热力图--批量地址转换应用(基于百度api)

用HttpWebRequest去发起get请求返回json,在把返回的json转成对象

百度地图热力图--批量地址转换应用(基于百度api)

这里套了三层,所以数据结构构造成这样(一开始不这么写获取是null)

百度地图热力图--批量地址转换应用(基于百度api)百度地图热力图--批量地址转换应用(基于百度api)

百度地图热力图--批量地址转换应用(基于百度api)

单个地址转换写好了,下面用一个list<T>装一下,foreach遍历依次赋值,用个一般处理程序得到json

百度地图热力图--批量地址转换应用(基于百度api)

最后把前台界面的数组换成ajax请求数据,要把async设置成false同步请求,不然就会跳过这里往下执行,这里用匿名函数返回一个数组

百度地图热力图--批量地址转换应用(基于百度api)

最后结果

百度地图热力图--批量地址转换应用(基于百度api)

代码:

  public static T RequestApi<T>(string address)
{
string apiUrl = "http://api.map.baidu.com/geocoder/v2/";
string apiKey = "6Gra1QZ4gWrsrUgirWZ0Z1NdfFrh0mD3"; //
string output = "json"; IDictionary<string, string> param = new Dictionary<string, string>();
param.Add("ak", apiKey);
param.Add("output", output); param.Add("address", address); string result = string.Empty; //初始化方案信息实体类。
T info = default(T);
try
{
//以 Get 形式请求 Api 地址
result = HttpUtils.DoGet(apiUrl, param);
info = JsonHelper.FromJson<T>(result);
}
catch (Exception)
{
info = default(T);
throw;
} return info;
}
 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 > )
{
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[];
int readBytes = ;
while ((readBytes = reader.Read(buffer, , buffer.Length)) > )
{
result.Append(buffer, , 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();
} }
 public static class JsonHelper
{
private static JsonSerializerSettings _jsonSettings; static JsonHelper()
{
IsoDateTimeConverter datetimeConverter = new IsoDateTimeConverter();
datetimeConverter.DateTimeFormat = "yyyy-MM-dd HH:mm:ss"; _jsonSettings = new JsonSerializerSettings();
_jsonSettings.MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore;
_jsonSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
_jsonSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
_jsonSettings.Converters.Add(datetimeConverter);
} /// <summary>
/// 将指定的对象序列化成 JSON 数据。
/// </summary>
/// <param name="obj">要序列化的对象。</param>
/// <returns></returns>
public static string ToJson(this object obj)
{
try
{
if (null == obj)
return null; return JsonConvert.SerializeObject(obj, Formatting.None, _jsonSettings);
}
catch (Exception ex)
{ return null;
}
} /// <summary>
/// 将指定的 JSON 数据反序列化成指定对象。
/// </summary>
/// <typeparam name="T">对象类型。</typeparam>
/// <param name="json">JSON 数据。</param>
/// <returns></returns>
public static T FromJson<T>(this string json)
{
try
{
return JsonConvert.DeserializeObject<T>(json, _jsonSettings);
}
catch (Exception ex)
{ return default(T);
}
}
}

最后结果:

  public static IEnumerable<JWCDTO> GetAllJW()
{
List<BigDataDTO> p = GetAll().ToList(); List<JWCDTO> list = new List<JWCDTO>(); ;
foreach (BigDataDTO pp in p)
{
string address = pp.Address;
int count = pp.count;
BGDTO bg = Re.RequestApi<BGDTO>(address);
if(bg==null)
{
continue;
}
string lat = bg.result.location.lat;
string lng = bg.result.location.lng;
JWCDTO log = ToProductDTO(lat, lng, count);
list.Add(log);//list.Add(ToLog(row)); } return list; }

JW.ashx:

  public class JW : IHttpHandler
{ public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json";
List<JWCDTO> p;
p = ReJson.GetAllJW().ToList();
context.Response.Write(new JavaScriptSerializer().Serialize(p));
} public bool IsReusable
{
get
{
return false;
}
}
}

前台页面:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ReJson.aspx.cs" Inherits="XZ.UI.Web.Admin.ReJson" %>

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=1fReIR62vFbOc2vgrBnRAGyUtLkgoIIH"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
<script src="../Scripts/jquery-1.9.1.min.js" type="text/javascript"></script> <title></title>
<style type="text/css">
ul,li{list-style: none;margin:0;padding:0;float:left;}
html{height:100%}
body{height:100%;margin:0px;padding:0px;font-family:"微软雅黑";}
#container{height:700px;width:100%;}
#r-result{width:100%;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<div id="container"></div>
<div id="r-result">
<input type="button" onclick="openHeatmap();" value="显示热力图"/><input type="button" onclick="closeHeatmap();" value="关闭热力图"/>
</div>
</div>
</form>
</body>
</html> <script type="text/javascript">
var map = new BMap.Map("container"); // 创建地图实例 var point = new BMap.Point(118.906886, 31.895532);
map.centerAndZoom(point, 15); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(); // 允许滚轮缩放 if (!isSupportCanvas()) {
alert('热力图目前只支持有canvas支持的浏览器,您所使用的浏览器不能使用热力图功能~')
} heatmapOverlay = new BMapLib.HeatmapOverlay({ "radius": 20 });
map.addOverlay(heatmapOverlay);
heatmapOverlay.setDataSet({ data: function () {
var serie = [];
$.ajax({
url: "JW.ashx",
dataType: "json",
async: false,
success: function (dataJson) {
for (var i = 0; i < dataJson.length; i++) {
var item = {
lat: dataJson[i].lat,
lng: dataJson[i].lng,
count: dataJson[i].count
};
serie.push(item);
}
}
});
return serie;
} (), max: 100 });
//是否显示热力图
function openHeatmap() {
heatmapOverlay.show();
}
function closeHeatmap() {
heatmapOverlay.hide();
}
closeHeatmap();
function setGradient() {
/*格式如下所示:
{
0:'rgb(102, 255, 0)',
.5:'rgb(255, 170, 0)',
1:'rgb(255, 0, 0)'
}*/
var gradient = {};
var colors = document.querySelectorAll("input[type='color']");
colors = [].slice.call(colors, 0);
colors.forEach(function (ele) {
gradient[ele.getAttribute("data-key")] = ele.value;
});
heatmapOverlay.setOptions({ "gradient": gradient });
}
//判断浏览区是否支持canvas
function isSupportCanvas() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
}
</script>