[WPF] 浏览百度地图并获取经纬度地址信息

项目中需要利用登记的区域和地址在百度地图上定位,并获取该地址的经纬度。

本次功能对我来说主要难点如下:
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 "34322"; }
        }

        /// <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") == -1) { 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 = 18;

            if (string.IsNullOrEmpty(this.Address) && !string.IsNullOrEmpty(this.City))
            {
                this.Address = this.City;
                this.ZoomLevel = 8;
            }
        }
    }
时间: 2024-12-09 14:27:27

[WPF] 浏览百度地图并获取经纬度地址信息的相关文章

百度地图api获取经纬度和城市名称

想集成百度API定位需要完成以下步骤: 1:注册开发者 2:申请key 3:下载jar包 4:代码集成 先看下效果: 1:注册开发者 最好提前申请,审核需要1,2天 2:申请key 本人用的是Android Studio,所以用命令行查看SHA1码 3:下载jar包 只需下载"定位功能"的开发包即可 4:代码集成(详细可见官方讲解,以下代码以简洁实用为主) package com.union.roid.testroid; import android.app.Activity; imp

利用百度地图API获取当前位置信息

利用百度地图API可以做很多事情,个人感觉最核心也是最基础的就是定位功能了.这里分享一个制作的JS可以实现登录网页后定位: 1 <script type="text/javascript"> 2 var map; 3 var gpsPoint; 4 var baiduPoint; 5 var gpsAddress; 6 var baiduAddress; 7 var x; 8 var y; 9 function getLocation() { 10 //根据IP获取城市 1

html5移动端根据百度地图api获取详细地址

<script type="text/javascript" src="js/BMap.js" ></script> <script type="text/javascript"> // 扩展API是否准备好,如果没有则监听"plusready"事件 if(window.plus){ plusReady(); }else{ document.addEventListener( "p

根据百度地图API获取指定地点的经纬度

做项目时,遇到对地点获取地图中对应的经纬度,作一下笔记,以备以后直接使用 package com.hpzx.data; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.n

逆向地理编码--根据地址搜索定位,点击地图、获取经纬度信息

1.地图使用的是高德.效果如下图: 2.前端代码: <!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>    <met

百度地图坐标获取器

直接把百度地图坐标获取器放到dom里面有时会 引起js失效:用iframe标签就会涉及到父窗口的操作 代码如下 父窗口 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv=&

HTML5页面直接调用百度地图API,获取当前位置,直接导航目的地(转)

HTML5页面直接调用百度地图API,获取当前位置,直接导航目的地 我是应用在微信中,自定义菜单,菜单直接链接到这个HTML5页面,获取当前位置后,页面中定好目的地,这样打开页面后直接进入导航页面 可以省下先发送位置信息后,点确定再出导航,省一步, <!DOCTYPE html> <html lang="zh-cmn-Hans"> <meta charset="UTF-8"> <meta name="viewpor

通过百度地图API实现搜索地址--第三方开源--百度地图(三)

搜索地址功能是建立在能够通过百度地图API获取位置的基础上 通过百度地图定位获取位置详情:http://www.cnblogs.com/zzw1994/p/5008134.html 1 package com.zzw.baidumappoint; 2 3 import com.baidu.location.BDLocation; 4 import com.baidu.location.BDLocationListener; 5 import com.baidu.location.Location

基于 html5 geolocation来获取经纬度地址(copy)

geolocation来获取经纬度地址 以前如果要获取互联网用户所在地都是根据用户的IP地址来获取地理位置,这样获取到的数据和真实数据有很大的偏差.为了获取更加精确的位置,可以使用了html5的geolocation来获取经纬度,然后再获取所在地理位置,如何获取,我在下面会说到.先说下基本概念. Geolocation在的navigator 对象中,我们可以通过 navigator.geolocation 来使用它.不支持 geolocation 的浏览器并不包含这一对象,那么可以通过下面的代码