【开源】电子围栏-测距离-测面积-拉框放大-实时路况-逆地理编码的实现
最近项目上涉及到地图,考虑到精度等问题,最终选择了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>
转载自:https://blog.csdn.net/zhangyuehua123/article/details/6895305