百度地图api的使用(基于C#)

百度地图api使用

1.C#窗体中放置WebBrowser控件

  • WebBrowser控件允许我们在里面放置HTML(HyperText Markup Language,超文本标记语言)

  • 事实上就是个嵌入的浏览器,当我们写了HTML代码之后,由浏览器帮我们完成渲染,不同浏览器对于HTML的渲染方式大体一样,但是IE和Chrome略有差异,C#内置WebBrowser控件的内核为IE7 见下图

在这里插入图片描述

  • 控件的Name属性默认为 Name = webBrowser1

  • ScriptErrorsSuppressed = False 该属性用来指示当html页面出错的时候,是否弹出错误提示,如果设置为True则就算html出错不会弹出提示框,建议改为False这样出错就可以及时发现并处理

2. 写Html绘制基础地图

html css javascript三者关系

html是骨架 css是皮肤 js是肌肉

在这里插入图片描述

  • api的请求格式为: http://api.map.baidu.com/api?v=2.0&ak=您的密钥 v=2.0 即使用的版本
  • 一定得需要连网才能请求成功

Html主体部分如下:

<!DOCTYPE html>
<html>
<head>
    //控制信息
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Hello, World</title>
    //css部分
    <style type="text/css">
        body, html, #container {
     
     
            width: 100%;
            height: 100%;
            overflow: hidden;
            margin: 0;
            font-family: "微软雅黑";
        }
    </style>
    //javascript部分
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的ak">
    </script>
</head>

<body>
<div id="container"></div>
<script type="text/javascript">
    // 创建地图实例
    var map = new BMap.Map("container");
    // 创建点坐标
    var point = new BMap.Point(102.857476, 24.860112);
    // 初始化地图,设置中心点坐标和地图级别
    //地图级别用来显示缩放的级别
    map.centerAndZoom(point, 16);

    //开启鼠标滚轮缩放
    map.enableScrollWheelZoom(true);

    //不同控件的位置不同
    var opts = {
     
     anchor: BMAP_ANCHOR_TOP_LEFT};
    map.addControl(new BMap.NavigationControl(opts));
    var opts = {
     
     anchor: BMAP_ANCHOR_BOTTOM_RIGHT};
    map.addControl(new BMap.ScaleControl(opts));
    var opts = {
     
     anchor: BMAP_ANCHOR_TOP_RIGHT};
    map.addControl(new BMap.MapTypeControl(opts));
</script>
</body>
</html>

上述代码效果如下:
在这里插入图片描述

3.数据库的设计

​ 因为上述代码中设计到了经度和纬度,所以不可避免地需要在数据库中添加lng和lat这两个字段:
在这里插入图片描述
具体地经纬度坐标拾取可以通过 这个网站

4.在各个路口放置文字标签

在这里插入图片描述

参考 这个网站

实现思路是在树形菜单加载的同时就调用前端javascript完成每个路口文字标注的渲染

  1. html需要添加以下js函数:
<script charset="utf-8">
    function flags(lat, lng, name) {
    
    
        //将传入的坐标新建一个点
        var point = new BMap.Point(lng, lat);
		//设置
        var opts = {
    
    
            position: point,    // 指定文本标注所在的地理位置
            offset: new BMap.Size(10, -10)    //设置文本偏移量
        }
         // 创建文本标注对象,使用name(交叉口的名称)作为标签的内容
        var label = new BMap.Label(name, opts); 
        label.setStyle({
    
    
            color: "red",
            fontSize: "12px",
            height: "20px",
            lineHeight: "20px",
            fontFamily: "微软雅黑"
        });
        map.addOverlay(label);
    }
</script>
  1. c#中需要调用上面这个js函数,需要传递参数,参数要包装在一个string数组中进行传递。
//调用前端js函数完成路口注释文字的摆放
webBrowser1.Document.InvokeScript("flags", new string[] { sdr.GetDouble("lat").ToString(), sdr.GetDouble("lng").ToString(), sdr.GetString(sdr.GetOrdinal("t_fx1")).ToString() + "-" + sdr.GetString(sdr.GetOrdinal("t_fx2")).ToString() });
  1. 同时c#窗体中还要加上参数webBrowser1.ObjectForScripting = this; 才可以允许c#调用前端函数

5.双击树形菜单时地图定位到交叉口位置

​ 只要获取到树形菜单选中的节点,然后调用一个js函数,把这个节点的经度、纬度传给前端,让js完成渲染即可。可以使用节点的Level属性获取该节点的深度,从而完成判断,如果深度为0,则是根节点,如果是1,则为叶子节点。

c#代码如下:

private void treeView1_DoubleClick(object sender, EventArgs e) {
    
    
    string lat = "for init", lng = "for init";
	//获取当前选中的节点
    TreeNode cur = treeView1.SelectedNode;
    //可能用户没有选中节点,此时cur为null
    if (cur != null && cur.Level >= 1) {
    
    
        MySqlCommand cmd = new MySqlCommand("select * from tlc_jckb where t_id='" + cur.Name + "'", conn);
        MySqlDataReader sdr = cmd.ExecuteReader();
        if (sdr.Read()) {
    
    
            //获取经度纬度
            lat = sdr.GetString(sdr.GetOrdinal("lat"));
            lng = sdr.GetString(sdr.GetOrdinal("lng"));
        }
        sdr.Close();
        //调用javascript完成前端地图的移动
        webBrowser1.Document.InvokeScript("setpos", new string[] {
    
     lat, lng });
    }
}

相应的html中需要添加js函数:

<script charset="utf-8">
    //给出经纬度,定位到那个点
    function setpos(lat, lng) {
    
    
        //将传入的坐标新建一个点
        var point = new BMap.Point(lng, lat);
        //设置小图像来定位到那个点
        map.centerAndZoom(point, 18);
        //设置小图像来定位到那个点
        var myIcon = new BMap.Icon("icon.png", new BMap.Size(32, 32), {
    
    
            //相对位置
            anchor: new BMap.Size(10, 10)
        });
        //添加小图标
        var marker = new BMap.Marker(point, {
    
    icon: myIcon});
        map.addOverlay(marker);
    }
</script>

其中的小旗摆放可以参考:这个网站

6.点击地图时c#选中相应节点

  1. 要想的嵌入的html可以调用c#函数,要设置系统属性 [System.Runtime.InteropServices.ComVisible(true)] 因为前端如果可以调用后端函数操作后端,是很不安全的

  2. 在地图的html中加入一个前端js监听

    map.addEventListener("click", function (e) {
          
          
    	window["external"].judge_pos(e.point.lat, e.point.lng);
    }
    

    监听点击时间,所以每在地图上点击一下,就会触发这个监听函数,监听的同时收集点击坐标的经度、纬度,然后调用后端c#函数进行处理,judge_pos为c#中的函数。

  3. judge_pos函数在c#中的定义

    从前端获得了点击的经度和纬度,那么如何判断点击的点是否在已有的交叉口附近呢?

    思路是这样的:在c#中定义一个坐标数组,用来存储已有的交叉口的经度和纬度,c#内置已经有这个类了,就是Point类和PointF类,不过要使用PointF类,因为后者支持坐标为小数。然后让前端传回来的经度和纬度与这些交叉口一一比较,如果经度差和纬度差同时小于某个阈值,就认为鼠标单击的是这个路口

    public void judge_pos(double lat, double lng) {
          
          
        //允许的经纬度偏差阈值
        const double accuracy = 0.002;
        //遍历每一个路口
        for (int i = 1; i <= count; i++) {
          
          
            if (Math.Abs(lat - ptarry[i].X) < accuracy && Math.Abs(lng - ptarry[i].Y) < accuracy) {
          
          
                //找到该路口的node,Find()函数是查找的键 key
                TreeNode cur = treeView1.Nodes.Find(i.ToString(), true)[0];
                //该节点为选中状态
                treeView1.SelectedNode = cur;
                //调用数据库获得路口的名称
                MySqlCommand cmd = new MySqlCommand("select * from tlc_jckb where t_id='" + i + "'", conn);
                MySqlDataReader sdr = cmd.ExecuteReader();
                if (sdr.Read()) {
          
          
                    lkm1 = sdr.GetString(sdr.GetOrdinal("t_fx1"));  //路口方向街名1
                    lkm2 = sdr.GetString(sdr.GetOrdinal("t_fx2"));  //路口方向街名2
                }
                sdr.Close();
                //弹出消息框提示
                MessageBox.Show("已经选中 " + lkm1 + "-" + lkm2 + " 路口");
                treeView1.Focus();
                break;
            }
        }
    }
    

    谢谢观看!

猜你喜欢

转载自blog.csdn.net/Raymond_YP/article/details/108599022