zoukankan      html  css  js  c++  java
  • C#调用百度地图API经验分享(四)

    这一篇,记录一下我调用的地图API实现的功能。下面介绍的都是一些片段的节选,不能直接复制就运行。在实现之前肯定要加载地图,先放一个webbroser控件,然后如下:

    [csharp] view plain copy
     
     print?
    1. private void Form1_Load(object sender, EventArgs e)  
    2.         {  
    3.   
    4.             string str_url = Application.StartupPath + "\最终合并版本(昨晚修改).html";  
    5.             Uri url = new Uri(str_url);  
    6.             webBrowser1.Url = url;  
    7.             webBrowser1.ObjectForScripting = this;  
    8.                      
    9.         }  



        而为了能与JS交互,首先引入using System.Security.Permissions;,然后在namespace下必须加入两行:

    [csharp] view plain copy
     
     print?
    1. namespace WebBroser_Test_V1._0  
    2. {  
    3.     [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]  
    4.   
    5.     [System.Runtime.InteropServices.ComVisibleAttribute(true)]  
    6.   
    7.   
    8.     public partial class Form1 : Form  
    9.     {  
    10.                public Form1()  
    11.         {  
    12.             InitializeComponent();  
    13.         }  
    14.         private void Form1_Load(object sender, EventArgs e)  
    15.         {  
    16.   
    17.             string str_url = Application.StartupPath + "\最终合并版本(昨晚修改).html";  
    18.             Uri url = new Uri(str_url);  
    19.             webBrowser1.Url = url;  
    20.             webBrowser1.ObjectForScripting = this;  
    21.            // timer1.Enabled = true;           
    22.         }  
    23. }  


     

    有了上面的基础,就可以实现以下功能了。

    1.鼠标放在屏幕上移动时,实时的显示坐标。

    放入一个timer和一个StatusScrip:

    [csharp] view plain copy
     
     print?
    1. private void timer1_Tick(object sender, EventArgs e)  
    2.         {  
    3.             try  
    4.             {  
    5.                 string tag_lng = webBrowser1.Document.GetElementById("mouselng").InnerText;  
    6.                 string tag_lat = webBrowser1.Document.GetElementById("mouselat").InnerText;  
    7.                 double dou_lng, dou_lat;  
    8.                 if (double.TryParse(tag_lng, out dou_lng) && double.TryParse(tag_lat, out dou_lat))  
    9.                 {  
    10.                     toolstatus_CurrentLocation.Text ="当前坐标:"+ dou_lng.ToString("F5") + "," + dou_lat.ToString("F5");  
    11.                 }  
    12.             }  
    13.             catch (Exception ee)  
    14.             { MessageBox.Show(ee.Message); }  
    15.             
    16.         }  


     

    放入一个button命名及代码如下:

    [csharp] view plain copy
     
     print?
    1. private void btnGetLocation_Click(object sender, EventArgs e)  
    2.        {  
    3.            if (btnGetLocation.Text == "开启实时坐标")  
    4.            {  
    5.                timer1.Enabled = true;  
    6.                btnGetLocation.Text = "关闭实时坐标";  
    7.            }  
    8.            else  
    9.            {  
    10.                btnGetLocation.Text = "开启实时坐标";  
    11.                timer1.Enabled = false;  
    12.            }  
    13.        }  


    JS脚本如下:

    [javascript] view plain copy
     
     print?
    1. var map =new BMap.Map("allmap");  
    2. var first_locate=new BMap.Point(108.953098,34.2778);  
    3. map.centerAndZoom(first_locate,15);     
    4. map.enableScrollWheelZoom(true);  
    5. map.addEventListener("mousemove",GetlngAndlat);     
    6. function GetlngAndlat(e)  
    7. {if(e.point.lng!=null)  
    8.  {  
    9.    
    10.  document.getElementById("mouselng").innerHTML=e.point.lng;  
    11.   document.getElementById("mouselat").innerHTML=e.point.lat;  
    12.  }  
    13. }  


     

    2.开启测距工具(百度自己开发的)

    拖一个按钮:

    [csharp] view plain copy
     
     print?
    1. //开启测距工具按钮  
    2.         private void btnOpenDistance_Click(object sender, EventArgs e)  
    3.         {  
    4.             webBrowser1.Document.InvokeScript("openGetDistance");  
    5.         }  


     

    为了加载这个工具,是需要引入百度的另一个工具库:

    JS如下:

    [javascript] view plain copy
     
     print?
    1. <script type="text/javascript" src="./JScript/DistanceTool_min.js"></script>  
    2. function openGetDistance()  
    3. {  
    4.  var myDis=new BMapLib.DistanceTool(map);//map为上面已经初始化好的地图实例  
    5.  myDis.open();  
    6. }  


     

    //上面这个DistanceTool_min.js在百度的DEMO里有,我只是把它考到我的DEBUG下了,具体路径自己解决。

    3.右击鼠标给地图上放marker,每一个marker的icon换成小汽车,并且显示坐标编号和坐标值,然后每放置一次,将数据存入数据库

    //放标注

    [csharp] view plain copy
     
     print?
    1. private void btnPutMarker_Click(object sender, EventArgs e)  
    2.        {  
    3.            if (radioButton1.Checked || radioButton2.Checked || radioButton3.Checked || radioButton4.Checked)  
    4.                webBrowser1.Document.InvokeScript("PUTANDSEND");  
    5.            else  
    6.            {  
    7.                MessageBox.Show("至少选择一项!");  
    8.            }  
    9.        }  
    10.        //得到Radiobutton的值  
    11.        public string setWhichCar()  
    12.        {  
    13.            if (radioButton1.Checked)  
    14.                return "1";  
    15.            if (radioButton2.Checked)  
    16.                return "2";  
    17.            if (radioButton3.Checked)  
    18.                return "3";  
    19.            if (radioButton4.Checked)  
    20.                return "4";  
    21.            return "Erro";  
    22.        }  
    23.        //将从JS里得到的汽车数据显示到文本框内,并且存入数据库  
    24.        public void PutIntotextBox(object markerIndex,object carNumber,object JSlng,object JSlat)  
    25.        {  
    26.            text_index.Text =markerIndex.ToString();  
    27.            text_num.Text = (string)carNumber;  
    28.            text_lng.Text = JSlng.ToString();  
    29.            text_lat.Text = JSlat.ToString();  
    30.            string sql = "insert into 汽车轨迹数据 values ('"+text_num.Text+"','"+text_index.Text+"','"+text_lng.Text+"','"+text_lat.Text+"','"+DateTime.Now.ToString()+"')";  
    31.            DBfunction.getcom(sql);  
    32.              
    33.        }  


           

    JS脚本如下:

    [javascript] view plain copy
     
     print?
    1. //---------------放标注,并且将JS的数据传送给WINFORM------------  
    2. function PUTANDSEND()  
    3. {  
    4.   map.addEventListener("rightclick",putAndsend);  
    5. }  
    6. function putAndsend(e)  
    7. {  
    8.   //放标注  
    9.   var p1=new BMap.Point(e.point.lng,e.point.lat);  
    10.   var marker = new BMap.Marker(p1,{icon:myIcon});//将标注的图标改为小汽车  
    11.   map.addOverlay(marker);  
    12.   marker_num++;//标注索引,这个是个全局变量  
    13.   var whichCar=window.external.setWhichCar();  
    14.   var label=new BMap.Label(whichCar+"号车-坐标"+marker_num+":"+  
    15. "("+e.point.lng+","+e.point.lat+")",{offset:new BMap.Size(20,-10)});  
    16.   marker.setLabel(label);  
    17.   //给WINFORM传值  
    18.   window.external.PutIntotextBox(marker_num,whichCar,e.point.lng,e.point.lat);  
    19.     
    20. }  



    4.根据上面已经模拟的汽车历史坐标,可以查询具体车辆的历史轨迹(即从数据库里提取数据,画轨迹)

    [csharp] view plain copy
     
     print?
    1. private void btnDrawOrit_Click(object sender, EventArgs e)  
    2.         {  
    3.             string ss = "^[0-9]*$"; //正则表达式  
    4.             string cc = text_whichCar.Text.Trim().ToString();  
    5.             bool match = Regex.IsMatch(cc, ss);  
    6.             if (Convert.ToInt32(text_whichCar.Text) > 4 || !match||text_whichCar.Text.Trim().Equals(String.Empty))  
    7.             // webBrowser1.Document.InvokeScript("PUTANDSEND");  
    8.             {  
    9.                 MessageBox.Show("您输入的不是数字,或者编号不在范围内!");  
    10.             }  
    11.             else  
    12.             {  
    13.                 string getdata_sql = "select * from 汽车轨迹数据 where 汽车编号=" + text_whichCar.Text;  
    14.                 whichCarData(getdata_sql);  
    15.             }  
    16.         }  


     

    //从数据库里的取出经纬度传送给JS
           

    [csharp] view plain copy
     
     print?
    1. public void whichCarData(string limit_sql)  
    2.        {        
    3.                OleDbDataReader DR = DBfunction.getread(limit_sql);  
    4.                ArrayList a = new ArrayList();  
    5.                while (DR.Read())  
    6.                {  
    7.                    a.Add(DR[2]);//经度  
    8.                    a.Add(DR[3]);//纬度  
    9.                    Rows_Num++;  
    10.                }  
    11.                if (Rows_Num == 0)  
    12.                    MessageBox.Show("该车辆,无历史信息!");  
    13.                else  
    14.                {  
    15.                    for (int i = 0; i <= 2 * Rows_Num - 1; i++)  
    16.                    {  
    17.                        pointArr[i] = Convert.ToDouble(a[i]);  
    18.                    }  
    19.   
    20.                    webBrowser1.Document.InvokeScript("DrawOrit1");  
    21.                }  
    22.        }  
    23.       //辅助方法  
    24.        //获取计数  
    25.        public int getRowsNumber()  
    26.        {  
    27.            return Rows_Num;  
    28.        }  
    29. //根据索引获取特定坐标  
    30.        public double Getpoints(int index)  
    31.        { return pointArr[index]; }  



    JS脚本如下:

    //------------从后台数据库获得点集合来画轨迹(无参数版本),测试可用

    [javascript] view plain copy
     
     print?
    1. function DrawOrit1()  
    2. {  
    3.  var Array=[];  
    4. var total_num= window.external.getRowsNumber();  
    5. for(var i=0;i<=2*total_num-1;i++)  
    6. {  
    7.  Array.push(window.external.Getpoints(i));  
    8. }  
    9.   
    10. var PointArr=[];  
    11. for(var i=0;i<=Array.length-1;i+=2)  
    12. {//偶数索引存经度,奇数存维度  
    13.   PointArr.push(new BMap.Point(Array[i],Array[i+1]));  
    14. }  
    15. var polyline = new BMap.Polyline(PointArr, {strokeColor:"blue", strokeWeight:6,   strokeOpacity:0.5});  //定义折线  
    16.   map.addOverlay(polyline);  
    17. window.external.ClearRows_num();//重置窗体计数器  
    18. }  


     


    5.打开绘图工具,这个工具可以画直线,圆,矩形等等,其中我这里用的主要是画圆的方法,画好圆后,可以得到哪些车辆在这个圆内,并将其标注出来(其实就是一个预警范围)。

    //开启画图工具按钮

    [csharp] view plain copy
     
     print?
    1. private void btnDrawPicture_Click(object sender, EventArgs e)  
    2.       {  
    3.           if (radio_Circle.Checked)  
    4.           { webBrowser1.Document.InvokeScript("drawCircle"); }  
    5.           else  
    6.           { webBrowser1.Document.InvokeScript("drawRec"); }  
    7.       }  


          

     //搜索当前车辆位置,返回各个车辆的坐标

    [csharp] view plain copy
     
     print?
    1. public double SearchAllCars(int index)  
    2.         {  
    3.              
    4.             string sql="select * from 汽车轨迹数据";  
    5.             OleDbDataReader dr= DBfunction.getread(sql);  
    6.            ArrayList allCars = new ArrayList();  
    7.             while (dr.Read())  
    8.             {  
    9.                 allCars.Add(dr[2]);  
    10.                 allCars.Add(dr[3]);  
    11.             }  
    12.             Danger_Num = allCars.Count;  
    13.             double[] sendto_JS = new double[allCars.Count];  
    14.             allCars.CopyTo(sendto_JS);  
    15.              
    16.                 return sendto_JS[index];  
    17.         }  
    18. //全局变量,返回有危险的车辆个数  
    19.         public int GetdangerNum()  
    20.         { return Danger_Num; }  


     

    JS脚本如下:

    [javascript] view plain copy
     
     print?
    1. <!--加载鼠标绘制工具-->  
    2. <script type="text/javascript" src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js"></script>  
    3. <link rel="stylesheet" href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" />  
    4. //回调获得覆盖物的信息(修改后的版本,已测试可用)  
    5.     var complete=function(e)  
    6.    {  
    7.     overlays.push(e.overlay);  
    8.     if (e.drawingMode == BMAP_DRAWING_CIRCLE)   
    9.           {  
    10.             //随便赋值,刷新一遍数据库(此方法只为演示,实际中要另考虑算法)  
    11.           var test=  window.external.SearchAllCars(0);  
    12.              
    13.              
    14.          var circle_radius=e.overlay.getRadius();//半径  
    15.           //圆心  
    16.          var circle_point=new BMap.Point(e.overlay.getCenter().lng,e.overlay.getCenter().lat);  
    17.          //从WINFORM里取出数据  
    18.          var dangerCars=[];  
    19.          var pointlen=window.external.GetdangerNum();  
    20.    
    21.          for(var k=0;k<=pointlen-1;k++)  
    22.           {  
    23.              dangerCars.push(window.external.SearchAllCars(k));  
    24.           }  
    25.          var BMappoints=[];//创建百度地图接口规定的数组  
    26.          for(var j=0;j<=dangerCars.length-1;j+=2)  
    27.           {  
    28.             BMappoints.push(new BMap.Point(dangerCars[j],dangerCars[j+1]));  
    29.           }  
    30.             
    31.           for(var i=0;i<=BMappoints.length-1;i++)  
    32.           {  
    33.             if(map.getDistance(circle_point,BMappoints[i])<=circle_radius)  
    34.             {  
    35.                AddMarker(BMappoints[i]);//调用添加标注版本V3.0  
    36.             }      
    37.           }  
    38.             
    39.         }  
    40.             
    41.       };  
    42. //线条样式  
    43.     var styleOptions = {  
    44.         strokeColor:"blue",    //边线颜色。  
    45.         fillColor:"blue",      //填充颜色。当参数为空时,圆形将没有填充效果。  
    46.         strokeWeight: 3,       //边线的宽度,以像素为单位。  
    47.         strokeOpacity: 1,    //边线透明度,取值范围0 - 1。  
    48.         fillOpacity: 0.3,      //填充的透明度,取值范围0 - 1。  
    49.         strokeStyle: 'solid' //边线的样式,solid或dashed。  
    50.     }  
    51.     //实例化鼠标绘制工具  
    52.     var drawingManager = new BMapLib.DrawingManager(map, {  
    53.         isOpen: true, //是否开启绘制模式  
    54.         enableDrawingTool: true, //是否显示工具栏  
    55.         drawingToolOptions: {  
    56.             anchor: BMAP_ANCHOR_TOP_RIGHT, //位置  
    57.             offset: new BMap.Size(5, 5), //偏离值  
    58.             scale: 0.8, //工具栏缩放比例  
    59.             drawingTypes : [           
    60.             BMAP_DRAWING_CIRCLE,    
    61.             BMAP_DRAWING_RECTANGLE   
    62.          ]  
    63.   
    64.         },  
    65.         circleOptions: styleOptions, //圆的样式   
    66.         rectangleOptions: styleOptions //矩形的样式  
    67.     });  
    68.   
    69.       
    70.       
    71.     //添加鼠标绘制工具监听事件,用于获取绘制结果  
    72.    drawingManager.addEventListener('overlaycomplete',complete);  
    73.       
    74.  //drawingManager.enableCalculate();  
    75.   
    76.       
    77.     //----------------------公用方法,用元素id获取元素的值-------------------  
    78.     function $(id){  
    79.         return document.getElementById(id);  
    80.     }  
    81.   
    82.     //------------------画矩形,让WINFORM调用---------------  
    83.     function drawRec(){  
    84. drawingManager.setDrawingMode(BMAP_DRAWING_RECTANGLE);}  
    85.     //------------------画圆,让WINFORM调用----------------  
    86.      function drawCircle(){  
    87. drawingManager.setDrawingMode(BMAP_DRAWING_CIRCLE);}  
    88.     //------------------清除所有已画图形,让WINFORM调用--------------------  
    89.     function clearAll() {  
    90.         for(var i = 0; i < overlays.length; i++){  
    91.             map.removeOverlay(overlays[i]);  
    92.         }  
    93.         overlays.length = 0  
    94.     }  


     


        这个功能比较复杂,必须要加入前两行的库连接才可以。因为画圆可以得到圆心和半径,所以我只需要从数据库里取出点,然后一一测量其与圆心的距离,然后和半径比较,只要小于半径则就在圆内标注。起初头让我画矩形,画矩形的DEMO如下:

    [javascript] view plain copy
     
     print?
    1. //回调获得覆盖物信息,未使用该版本  
    2.     var overlaycomplete = function(e){  
    3.         overlays.push(e.overlay);  
    4.         var result = "";  
    5.          
    6.         result += e.drawingMode + ":";  
    7.          
    8.         if (e.drawingMode == BMAP_DRAWING_CIRCLE) {  
    9.              
    10.             var circle_radius=e.overlay.getRadius();  
    11.             var circle_point=new BMap.Point(e.overlay.getCenter().lng,e.overlay.getCenter().lat);  
    12.             alert(map.getDistance(circle_point,tests[1]));  
    13.              for(var i=0;i<3;i++)  
    14.           {  
    15.             if(map.getDistance(circle_point,tests[i])<=circle_radius)  
    16.             {  
    17.                AddMarker(tests[i]);  
    18.             }      
    19.           }  
    20.             alert(result);  
    21.         }  
    22.         if (e.drawingMode == BMAP_DRAWING_POLYLINE || e.drawingMode == BMAP_DRAWING_POLYGON || e.drawingMode == BMAP_DRAWING_RECTANGLE) {  
    23.             result += ' 所画的点个数:' + e.overlay.getPath()[1].lng;  
    24.             alert(result);  
    25.         }  
    26.           
    27.     };  


     

        这里是修改的百度DEMO,其中有一行result += ' 所画的点个数:' + e.overlay.getPath()[1].lng;在百度原有的demo里是这样写的result += ' 所画的点个数:' + e.overlay.getPath().length;只会返回一个数据,我仔细看了下函数名,getPath(),而且还有length的属性,那么肯定是数组,而且是返回的边或者点的个数,而边一定是由点组成的,根据之前的Ployline函数可以推测,这个函数必定是一个存放多边形点的数组,那么我就试了试e.overlay.getPath()[1].lng,看能不能取到某个点的经度值,果然不出我所料,可以的,当时兴奋了好一阵子,有了这个方法,矩形的四个点就都能记录,那么就可以跟数据库里取出的点直接进行经纬度比较,也可以标注预警范围,不过还是没有用圆方便。

        由于时间确实很紧,手头还有事要做,只能写到这里了,欢迎交流,喷也行,哈哈。

  • 相关阅读:
    SPOJ GSS4 Can you answer these queries IV ——树状数组 并查集
    SPOJ GSS3 Can you answer these queries III ——线段树
    SPOJ GSS2 Can you answer these queries II ——线段树
    SPOJ GSS1 Can you answer these queries I ——线段树
    BZOJ 2178 圆的面积并 ——Simpson积分
    SPOJ CIRU The area of the union of circles ——Simpson积分
    HDU 1724 Ellipse ——Simpson积分
    HDU 1071 The area ——微积分
    HDU 4609 3-idiots ——FFT
    BZOJ 2194 快速傅立叶之二 ——FFT
  • 原文地址:https://www.cnblogs.com/jjg0519/p/6674520.html
Copyright © 2011-2022 走看看