【开源】电子围栏-测距离-测面积-拉框放大-实时路况-逆地理编码的实现
最近项目上涉及到地图,考虑到精度等问题,最终选择了51ditu。要实现电子围栏等等功能,经过几天努力,大致有了个雏形,由于是第一次接触HTML和JavaScript编程,三天下来脑袋大了不少,碰到了一些问题,暂时还在挣扎当中,现在我将雏形工程发布出来,目的在于向大家学习,希望得到各位的指点和教导,以期我的工程能够日益完美。
一、相关文件说明:
(1) 工程文件我已经放到了http://download.csdn.net/detail/zhangyuehua123/3704087上,免积分下载(可以进入我的资源列表,排在第一个的就是)。为了方便阅读和交流,我在下面也贴出了完整的代码。
(2) 实时交流方式:QQ--1803220843, MSN--yichangzyh@163.com。期盼讨论、指教!谢谢~~~
二、工程运用目的:
因工程项目需要,用C#设计一个车辆监控软件,其中重要的一部分就是将地图嵌入到软件界面当中。我的思路是运用其强大的webbrowser控件来实现嵌入地图功能。因此,调试Javascript描述的HTML网页就成了工作当中的第一步。
三、地图功能需求:
(1) 测距离。在地图上点击任意两个位置,计算出物理距离。
(2) 测面积。在地图上拖拽一个多边形,计算出面积。
(3) 电子围栏。在地图上拖拽一个矩形框,当车辆(暂时用标注marker来模拟)在矩形框内的时候,处于正常状态;当车辆驶出矩形框外的时候,报警。
(4)实时路况。提供部分城市的实时路况信息。这个功能51dituAPI支持。
(5)逆地理编码详细描述。在地图上点击任意一个标注(marker),信息浮窗提示当前位置的具体地点。这个功能51dituAPI支持。
(6)地图鹰眼。
(7)历史轨迹播放。首先选择车辆,然后选择历史轨迹时间(如从2011-10-18-21:00到2011-10-19-21:00),再选择播放速度,点击播放按钮,就可以在地图上播放出历史行车轨迹。
(8)鼠标右键。放大、缩小、添加标注功能。
四、雏形版本功能:
(1) 功能:测距离。
状态:已经完美解决。
问题:无。
(2) 功能:测面积。
状态:已经完美解决。
问题:无。
(3) 功能:电子围栏。
状态:已经解决大部分,可以拖拽一个矩形框,用标注(marker)模拟一辆车,当marker在矩形框内的时候,提示没有越界,矩形框显示绿色;当marker拖拽出矩形框时,提示车辆越界,此时矩形框呈红色。
问题:① 只能先拖拽矩形框,然后才能拖拽标注(marker),否则提示出错。
② 想用更多的标注(marker)来模拟汽车,用鼠标右键来实现添加标注功能。但是marker能够添加进去,但是不能实现类似可以拖拽的marker那样提示经纬度的功能,所以暂时只能通过拖拽地图上唯一的一个“可以拖拽的标注(marker)”来模拟汽车时候越界。
(4) 功能:实时路况。
状态:已经完美解决。
问题:无。
(5)功能:逆地理编码详细描述。
状态:已经完美解决。
问题:标注还是太少,最好是能用更多的“动态的marker”来模拟汽车,在每个marker上单击就可以显示当前的地理位置信息提示窗。
(6) 功能:地图鹰眼。
状态:已经完美解决。
问题:无。
(7)功能:历史轨迹播放。
状态:还没开始做。
问题:我的思路是:
①将车辆信息(主要是经纬度数据)存储在本地Xml文件中,然后用javascript读取经纬度数据,调用51ditu的API,在地图上添加marker,设置系统时间(添加一个定时器),用于地图刷新,这样可以实现“播放速度”功能,选择播放速度实际上就是选择不同的定时器时间。
②至于“选择历史轨迹的起止时间”,暂时的想法也是通过javascript从Xml文件中读取历史信息,选择不同的时间段,获取其时间段内的经纬度值,然后在地图上marker出来。
(8)功能:鼠标右键。
状态:解决了一部分。
问题:功能单一,还需扩展。
五、雏形版本截图:
六、附源代码:
- <html xmlns:v="urn:schemas-microsoft-com:vml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=GB2312"/>
- <style type="text/css">v\:*{behavior:url(#default#VML);}</style>
- <style type="text/css">
- html,body
- {
- background:#FFFFFF;
- overflow : auto;
- }
- table
- {
- font-size:12px;
- font-weight:bold;
- color:#E066FF;
- }
- input
- {
- font-size: 12px;
- color:#E066FF;
- }
- </style>
- <script language="javascript" src="http://api.51ditu.com/js/maps.js"></script>
- <script language="javascript" src="http://api.51ditu.com/js/traffic.js"></script>
- <script language="javascript">
- var map;
- var mgr;
- var poit;
- var scaleControl; /* 比例尺控件 */
- var icon; /* 标注自定义图标样式 */
- var mapText; /* 添加文字标签 */
- var controlZoom; /* 拉框放大控件 */
- var controlDistance; /* 测距离控件 */
- var controlMianji; /* 侧面积控件 */
- var aryRightMenu; /* 右键菜单数组 */
- var zoomIn; /* 右键放大 */
- var zoomOut; /* 右键缩小 */
- var markerRightMenu; /* 右键添加标注 */
- var menuRightMenu; /* 添加右键菜单控件到地图上 */
- var LatMin; /* 矩形框的边界值,最小维度 */
- var LatMax; /* 矩形框的边界值,最大维度 */
- var LonMin; /* 矩形框的边界值,最小经度 */
- var LonMax; /* 矩形框的边界值,最大经度 */
- var rect; /* 矩形框对象 */
- var controlOfweilan; /* 建立新的拉框查找控件对象 */
- var markerToDrag; /* 可拖拽的标注对象 */
- /*===================== 主函数 ===================== */
- function onLoad()
- {
- map=new LTMaps("mapDiv"); /* 创建地图 */
- point = new LTPoint( 10645971,2956742 );
- map.centerAndZoom( point,2 );
- map.setMapCursor("hand","move"); /* 设置鼠标在地图上的形状 */
- map.addControl(new LTStandMapControl());
- map.addControl(new LTOverviewMapControl()); /* 添加鹰眼 */
- mgr = new LTTraffic(map);
- scaleControl=new LTScaleControl(); /* 添加比例尺 */
- scaleControl.units=[[1000,"km"],[1,"m"]];
- scaleControl.setColor("red");
- scaleControl.setLeft(280);
- map.addControl(scaleControl);
- map.handleMouseScroll(true); /* 鼠标滚轮操作 */
- map.mapCartoonControl(true); /* 滚轮操作时,地图动画效果展示放大和缩小 */
- LTEvent.bind(map,"dblclick",map,function(){{this.zoomIn()}}); /* 双击放大地图 */
- icon=new LTIcon("C:\\centerPoi.gif",[24,24],[12,12]); /* 添加标注 */
- var marker = new LTMarker( point,icon );
- map.addOverLay( marker );
- LTEvent.addListener( marker , "click" , doitForMarker); /* 给标记添加点击事件,点击显示当前的详细地理位置 */
- mapText = new LTMapText( marker ); /* 为标注添加文字标签 */
- mapText.setLabel("{2}" );
- mapText.setBackgroundColor("#CAFF70");
- mapText.setFontColor("#D15FEE");
- map.addOverLay( mapText );
- var myHtml="我在这里,这是第1个标记";
- var infoWin=mapText.openInfoWinHtml(myHtml);
- infoWin.setTitle("这里是我的标记的标题");
- LTEvent.addListener( mapText , "click" ,getClickCallBack(mapText,myHtml));
- controlZoom = new LTZoomInControl();
- controlZoom.setTop( 400 );
- controlZoom.setLeft( 30 );
- controlZoom.setLabel("拉框放大"); /*拉框放大*/
- map.addControl(controlZoom);
- controlDistance=new LTPolyLineControl();
- controlDistance.setTop( 350 );
- controlDistance.setLeft( 30 );
- controlDistance.setLabel(" 测距离 "); /*测距离按钮*/
- controlDistance.lineColor="red";
- controlDistance.lineStroke=1;
- controlDistance.lineOpacity=1;
- controlDistance.lineStyle="ShortDash";
- controlDistance.lineArrow=["Open","Open"];
- map.addControl(controlDistance);
- LTEvent.addListener(controlDistance,"draw",onDraw);
- controlMianji = new LTPolygonControl();
- map.addControl( controlMianji );
- controlMianji.setTop( 300 );
- controlMianji.setLeft( 30 );
- controlMianji.setLabel(" 测面积 "); /*测面积按钮*/
- aryRightMenu = new Array();
- zoomIn = new LTMenuItem(); /* 右键放大 */
- zoomIn.id = "zoomIn";
- zoomIn.menuText = "放大";
- zoomIn.functionName = mapZoomIn;
- aryRightMenu.push(zoomIn);
- zoomOut = new LTMenuItem(); /* 右键缩小 */
- zoomOut.id = "zoomOut";
- zoomOut.menuText ="缩小";
- zoomOut.functionName = mapZoomOut;
- aryRightMenu.push(zoomOut);
- markerRightMenu = new LTMenuItem(); /* 右键添加标注 */
- markerRightMenu.id = "marker";
- markerRightMenu.menuText ="在此添加标注";
- markerRightMenu.functionName = mapMarker;
- aryRightMenu.push(markerRightMenu);
- menuRightMenu = new LTMenuControl(aryRightMenu); /* 添加右键菜单控件到地图上 */
- map.addMenuControl(menuRightMenu);
- controlOfweilan = new LTZoomSearchControl("red","red",1,0.4); /* 建立新的拉框查找控件 */
- controlOfweilan.setTop( 450 );
- controlOfweilan.setLeft( 30 );
- controlOfweilan.setLabel("电子围栏" );
- map.addControl(controlOfweilan); /* 添加控件到地图 */
- markerToDrag=new LTMarker(point);
- markerToDrag.enableDrag();
- map.addOverLay(markerToDrag);
- LTEvent.addListener(markerToDrag,"dragend",onDragEnd); /* 设置用户在拖拽标记之后执行onDragEnd函数 */
- LTEvent.addListener(controlOfweilan,"mouseup",doit); /* 设置在用户拉框完成之后执行doit函数 */
- }
- /*====================== 在标记被点击的时候执行的函数,marker的onClick监听的事件 ====================== */
- function doitForMarker()
- {
- onClickForMarker();
- }
- /*====================== 在标记被点击的时候执行的函数 ====================== */
- function onClickForMarker()
- {
- var reg=new LTRegoLoader();
- LTEvent.bind(reg,"loaded",reg,myLocation);
- reg.loadDescribe(point);
- }
- /*====================== onClickForMarker函数中,reg对象绑定的事件myLocation ====================== */
- function myLocation(obj)
- {
- var myHtml = obj.describe; /* 逆地理信息描述 */
- var infoWin=mapText.openInfoWinHtml(myHtml);
- infoWin.setTitle("当前具体位置");
- }
- /*====================== 本函数是在用户每次拉框操作完成之后执行的操作,bounds是代表用户拉框选择的区域的范围 ====================== */
- function doit(bounds)
- {
- var str="电子围栏区域坐标为:\n";
- str+="起点:"+bounds.getXmin()+","+bounds.getYmax()+"\n";
- str+="终点:"+bounds.getXmax()+","+bounds.getYmin()+"\n";
- alert(str);
- LatMin = bounds.getYmin(); /* 保存当前矩形框的经纬度值,在后面的判断中要用到 */
- LatMax = bounds.getYmax();
- LonMin = bounds.getXmin();
- LonMax = bounds.getXmax();
- rect = new LTRect(bounds); /* 矩形框对象 */
- map.addOverLay(rect); /* 将矩形框对象添加到地图上 */
- }
- /*====================== 本函数是在用户每次拖拽标注操作完成之后执行的操作 ======================*/
- function onDragEnd(point)
- {
- var str="标注被拖动到:\n";
- str+="经度:"+point.getLongitude()+"\n";
- str+="纬度:"+point.getLatitude()+ "\n";
- alert(str);
- if(point.getLongitude()>LonMin && point.getLongitude()<LonMax && point.getLatitude()<LatMax && point.getLatitude()>LatMin)
- {
- alert("您当前的位置在矩形内,OK!");
- rect.setLineColor("blue");
- rect.setFillColor("green");
- rect.setLineStroke(3);
- }
- else
- {
- alert("您的位置不在在矩形内,Warning!");
- rect.setLineColor("red");
- rect.setFillColor("red");
- rect.setLineStroke(5);
- }
- }
- /*====================== 右键菜单====================== */
- function mapZoomIn(){ map.zoomIn(); }
- function mapZoomOut(){ map.zoomOut(); }
- function mapMarker(p){ var markerRightMenu0 = new LTMarker(p); map.addOverLay(markerRightMenu0); }
- /*====================== 测距====================== */
- function onDraw(points,length,polyline)
- {
- alert("结束测距");
- }
- /*====================== 添加信息浮窗 ====================== */
- function getClickCallBack(mapText,myHtml)
- {
- return function()
- {
- mapText.openInfoWinHtml( myHtml );
- }
- }
- /*====================== 打开实时交通 ====================== */
- function openTraffic()
- {
- mgr.addTips(); /* 显示路况提示信息*/
- if(mgr.getTrafficEnabled()) /* 判断实时交通是否开启,true为开启,false为关闭 */
- {
- alert("实时交通已经开启");
- return;
- }
- var city = document.getElementById("city"); /* 将地图定位到下拉菜单所显示的城市*/
- map.centerAndZoom(city.value,8);
- mgr.openTraffic(city.value); /*打开实时交通*/
- }
- /*====================== 关闭时实交通 ======================*/
- function closeTraffic()
- {
- mgr.removeTips(); /* 显示路况提示信息 */
- mgr.closeTraffic(); /* 关闭时实交通 */
- }
- /*====================== 更换城市 ====================== */
- function changeCity()
- {
- if(mgr && mgr.getTrafficEnabled()) /*如果实时交通已打开,将其关闭*/
- {
- mgr.closeTraffic();
- }
- var city = document.getElementById("city");
- map.centerAndZoom(city.value,8); /* 将地图定位到下拉菜单所显示的城市 */
- }
- </script>
- </head>
- <body onLoad="onLoad()">
- <body leftmargin= "0 " topmargin= "0 " marginwidth= "0" marginheight= "0 ">
- <div id="mapDiv" style="position:absolute;width:100%; height:100%;"></div>
- <div id="trafficID" style="position:absolute;right:180px;">
- <table>
- <tr>
- <td>实时路况:
- <select id="city" onChange="changeCity();">
- <option value="beijing">北京</option>
- <option value="shanghai">上海</option>
- <option value="guangzhou">广州</option>
- <option value="shenzhen">深圳</option>
- <option value="chengdu">成都</option>
- <option value="chongqing">重庆</option>
- <option value="shenyang">沈阳</option>
- </select>
- <input type="button" name="button" value="开启" onClick="openTraffic();">
- <input type="button" name="button" value="关闭" onClick="closeTraffic();">
- </td>
- </tr>
- </table>
- </div>
- </body>
- </html>