项目中需要利用登记的区域和地址在百度地图上定位,并获取该地址的经纬度。
本次功能对我来说主要难点如下:
1、百度地图API的基本使用方法,请首选使用百度地图的JavaScript大众版(PS:之前使用WebAPI会导致WebBrowser浏览出现很多问题);
JavaScript大众版网址:http://developer.baidu.com/map/index.php?title=jspopular
2、WPF WebBrowser控件中的JavaScript与WPF的交互;
3、WPF WebBrowser中IE缓存问题,导致开发调试时间增加;
4、WPF WebBrowser中如何禁止JS报错弹窗提示;
项目可以到百度云盘下载:http://pan.baidu.com/s/1o6MHxSA
主要代码如下:
ViewBaiduMapByLoaction.cs代码
public partial class ViewBaiduMapByLoaction : Window
{
/// <summary>
/// IP地址
/// </summary>
public string IP
{// TODO : 设置IP(IIS)
get { return "192.168.1.215"; }
} /// <summary>
/// 端口
/// </summary>
public string Port
{// TODO : 设置端口(IIS)
get { return ""; }
} /// <summary>
/// 百度API Key (AK)
/// </summary>
public string BaiduAK
{
get { return "yRnTso4E6HW32nxqHEY82wXi"; }
} public BaiduMapByLoactionViewModel ViewModel; public ViewBaiduMapByLoaction()
{
InitializeComponent();
this.initUI();
this.initEvent();
} private void initUI()
{
this.ViewModel = new BaiduMapByLoactionViewModel();
this.DataContext = this.ViewModel;
} private void initEvent()
{
this.wbBaiduMap.LoadCompleted += new LoadCompletedEventHandler(webBrowser_LoadCompleted); // JavaScript 与 WPF 交互
this.wbBaiduMap.Navigated += (a, b) => { this.hideScriptErrors(this.wbBaiduMap, true); }; // 阻止JS报错弹窗(可以注释)
this.btnSearch.Click += this.btnSearch_Click;
this.btnGetAddressFromWeb.Click += this.btnGetAddressFromWeb_Click;
} /// <summary>
/// 阻止JS报错弹窗(建议不使用)
/// </summary>
/// <param name="wb"></param>
/// <param name="hide"></param>
private void hideScriptErrors(WebBrowser wb, bool hide)
{
var fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
if (fiComWebBrowser == null) return;
var objComWebBrowser = fiComWebBrowser.GetValue(wb);
if (objComWebBrowser == null)
{
wb.Loaded += (o, s) => hideScriptErrors(wb, hide); //In case we are to early
return;
}
objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { hide });
Cursor = Cursors.Arrow;
} private void btnSearch_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(this.ViewModel.CityOrProvince) && string.IsNullOrEmpty(this.ViewModel.Address))
{
MessageBox.Show("请输入城市 / 地址。。。", "错误");
return;
} try
{
Cursor = Cursors.Wait;
this.getGPSInfoByAddress();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误");
}
} /// <summary>
/// 访问ASPX显示地图
/// </summary>
private void getGPSInfoByAddress()
{
try
{
// 清除IE缓存
foreach (string strFileName in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.Cookies)))
{
if (strFileName.ToLower().IndexOf("index.dat") == -) { File.Delete(strFileName); }
} string uri = string.Format("http://{0}:{1}/WebServer/ViewMapByAddress.aspx?{2}{3}{4}",
this.IP,
this.Port,
!string.IsNullOrEmpty(this.ViewModel.Address) ? string.Format("address={0}", this.ViewModel.Address) : string.Empty,
!string.IsNullOrEmpty(this.ViewModel.CityOrProvince) ? string.Format("&city={0}", this.ViewModel.CityOrProvince) : string.Empty,
!string.IsNullOrEmpty(this.BaiduAK) ? string.Format("&ak={0}", this.BaiduAK) : string.Empty
); this.wbBaiduMap.Navigate(uri);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误");
}
} /// <summary>
/// Web控件 与 JavaScript交互
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
this.wbBaiduMap.ObjectForScripting = new JSCallback(this);
} /// <summary>
/// 从浏览器控件中复制经纬度信息到WPF界面中
/// JS 与 WPF 交互
/// </summary>
/// <param name="lng"></param>
/// <param name="lat"></param>
public void SetLongitudeAndLatitude(string lng, string lat)
{
this.ViewModel.Lng = lng;
this.ViewModel.Lat = lat;
} /// <summary>
/// WPF 与 JS 交互 获取浏览器控件中的值到WPF中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void btnGetAddressFromWeb_Click(object sender, RoutedEventArgs e)
{
try
{
this.wbBaiduMap.InvokeScript("setAddress");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "错误");
}
} } #region JSCallBack [ComVisible(true)]
public class JSCallback
{
private ViewBaiduMapByLoaction Main
{
get;
set;
} public JSCallback(ViewBaiduMapByLoaction main)
{
this.Main = main;
} public void SetLongitudeAndLatitude(string lng, string lat)
{
this.Main.SetLongitudeAndLatitude(lng, lat);
} public void SetAddress(string address)
{
if (!string.IsNullOrEmpty(address))
{
this.Main.ViewModel.AddressFromWeb = address;
}
}
} #endregion
ViewMapByAddress.aspx代码如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ViewMapByAddress.aspx.cs" Inherits="BaiduMap_DEMO.WebServer.ViewMapByAddress" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
html {
width: 100%;
height: 100%;
margin: 0;
font-family: "微软雅黑";
} body {
width: 100%;
height: 100%;
margin: 0;
font-family: "微软雅黑";
} #allmap {
height: 100%;
width: 100%;
} #r-result {
width: 100%;
}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=yRnTso4E6HW32nxqHEY82wXi"></script>
<title>地址解析</title>
</head>
<body>
<div id="allmap">
</div>
</body>
</html>
<script type="text/javascript">
// 百度地图API功能
var map = new BMap.Map("allmap");
var point = new BMap.Point(0, 0); var geoPoint = new BMap.Point(0, 0);
var myZoomLevel = <%=ZoomLevel %>;
var addressString = ""; // map.centerAndZoom(point, myZoomLevel);
map.enableScrollWheelZoom(); // 创建地址解析器实例
var myGeo = new BMap.Geocoder();
// 将地址解析结果显示在地图上,并调整地图视野
myGeo.getPoint("<%=Address %>", function (_point) {
if (_point) {
geoPoint = _point;
map.centerAndZoom(geoPoint, myZoomLevel); // ******** 添加自定义控件 ********
// 定义一个控件类,即function
function ZoomControl() {
// 默认停靠位置和偏移量
this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
this.defaultOffset = new BMap.Size(10, 10);
} // 通过JavaScript的prototype属性继承于BMap.Control
ZoomControl.prototype = new BMap.Control(); // 自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回
// 在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
ZoomControl.prototype.initialize = function (map) {
// 创建一个DOM元素
var div = document.createElement("div");
// 添加文字说明
div.appendChild(document.createTextNode("获取经纬度"));
// 设置样式
div.style.cursor = "pointer";
div.style.border = "1px solid gray";
div.style.backgroundColor = "red"; // 绑定事件
div.onclick = function (e) {
setLongitudeAndLatitude();
} // 添加DOM元素到地图中
map.getContainer().appendChild(div);
// 将DOM元素返回
return div;
} // 创建控件
var myZoomCtrl = new ZoomControl();
// 添加到地图当中
map.addControl(myZoomCtrl);
// ******** End of 添加自定义控件 ******** // ******** 添加 BMap.Marker (红点) ********
addressString = "<%=Address %>";
var diyMarker = new BMap.Marker(_point);
diyMarker.setTitle("<%=Address %>"); var label = new BMap.Label("<%=Address %>"+ "(" + geoPoint.lng + ", " + geoPoint.lat + ")", { offset: new BMap.Size(20, -10) });
diyMarker.setLabel(label);
map.addOverlay(diyMarker);
// ******** End of 添加 BMap.Marker (红点) ******** } else {
alert("警告:您输入的街道没有解析到结果。");
geoPoint = "";
}
}, "<%=City %>"); // ******** 添加导航栏 ********
// 添加带有定位的导航控件
var navigationControl = new BMap.NavigationControl({
// 靠左上角位置
anchor: BMAP_ANCHOR_TOP_RIGHT,
// LARGE类型
type: BMAP_NAVIGATION_CONTROL_LARGE,
// 启用显示定位
enableGeolocation: true
});
map.addControl(navigationControl); // ******** 单击地图事件 ********
map.addEventListener("click", function (e) {
map.clearOverlays();
var pt = e.point;
myGeo.getLocation(pt, function (rs) {
if (!!rs.addressComponents) {
var addComp = rs.addressComponents; // addressComponents 有多个属性 // 省(Province);市(City);区(District);街(Street);房号(StreetNumber)
geoPoint = pt;
var diyMarker = new BMap.Marker(pt); // 创建百度地图红点 addressString = addComp.city + addComp.district + addComp.street + addComp.streetNumber;
diyMarker.setTitle(addressString); var label = new BMap.Label(addressString + "(" + geoPoint.lng + ", " + geoPoint.lat + ")", { offset: new BMap.Size(20, -10) }); // 创建标注,并设置标注位置
diyMarker.setLabel(label); map.addOverlay(diyMarker);
}
});
}); function setAddress() // 获取地址信息
{
if(!!addressString)
{
window.external.SetAddress(addressString);
}
else
{
alert("警告:请点击地图获取设置查询地点。");
}
} function setLongitudeAndLatitude() // 获取经纬度信息
{
if(!!geoPoint)
{
window.external.SetLongitudeAndLatitude(geoPoint.lng, geoPoint.lat);
}
else
{
alert("警告:请点击地图获取设置查询地点。");
}
} </script>
ViewMapByAddress.aspx.cs 代码如下:
public partial class ViewMapByAddress : System.Web.UI.Page
{
/// <summary>
/// 城市
/// </summary>
public string City { get; set; } /// <summary>
/// 地址
/// </summary>
public string Address { get; set; } /// <summary>
/// 百度地图缩放层级
/// </summary>
public int ZoomLevel { get; set; } protected void Page_Load(object sender, EventArgs e)
{
this.City = this.Request["city"];
this.Address = this.Request["address"]; this.ZoomLevel = ; if (string.IsNullOrEmpty(this.Address) && !string.IsNullOrEmpty(this.City))
{
this.Address = this.City;
this.ZoomLevel = ;
}
}
}