• [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;
                }
            }
        }
  • 相关阅读:
    常用的Javascript设计模式
    jQuery动画高级用法——详解animation中的.queue()函数
    区分苹果Safari浏览器
    自定义 placeholder 文本颜色
    Three.js资源
    动态添加样式表规则
    GitHub 上一份很受欢迎的前端代码优化指南
    [转载]盒模型display:-webkit-box;的使用
    CSS3 Background-size
    Ubuntu上安装torque过程
  • 原文地址:https://www.cnblogs.com/howesdomo/p/4452782.html
Copyright © 2020-2023  润新知