网页|微软
自Google推出地图服务以后,微软和百渡也相继推出地图服务。地图成为目下网络流行的时尚,如果你想追赶它,那么来吧,我将会帮助你学会使用微软的Virtual Earth Map Control,为你的网站添加一道亮丽的风景。
本文最终效果图:
MapControl控件
Virtual Earth Map Control脚本可以在MSN网站下载:http://virtualearth.msn.com/js/MapControl.js。
当然你可以直接在网站中链接这个脚本,但这会导致一些安全上的问题,因为缺省情况下大部分的浏览器不会允许来自其他的不是当前正在浏览的站点的JavaScript程序运行。使用者必须确认他们允许来自VirtualEarth的脚本运行,这样会给用户不爽的感觉。
简单的方式就是下载MapControl.js文件到你的站点,这样就可以轻松访问并进行编程了。
创建Map Control实例
为了创建一个Map Control实例,你需要在你的页面里写一个小方法。这将会创建一个MapControl的实例,在页面上放置它,并设置control里初始显示的内容。
VE_MapControl的构造函数原型如下:
VE_MapControl(Latitude, Longitude, Zoom, MapStyle, PositionType, Left, Top, Width, Height);
Latitude:在control里显示的地图中心的纬度;
Longitude:在control里显示的地图中心的经度;
Zoom:显示地图的缩放尺度。可以设置为2到18的数。2是允许的最远的俯瞰距离,18是允许的最近的俯瞰距离。
MapStyle:显示地图的风格。目前有3种式样可选:高空的(aerial),道路的(road)和混合的(hybrid)。用每种式样的首字母小写来代表该式样。
·a-aerial:显示高空的卫星图像。
·r-road:显示地区的街道地图;
·h-hybrid:显示以上两者的结合,卫星图像将和道路和位置信息重叠在一起。
PositionType:control在页面上的放置的方式,可选项为相对(relative)和绝对(absolute)。
Left:control左边在页面上的位置。
Top:control上部在页面上的位置。
Width:control宽度。
Height:control高度。
例子:
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 400, 10, 400, 300);
一个简单的具有Virtual Earth map control的页面可以如下创建:
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
map.onEndContinuousPan = function(e)
{
document.getElementById("info").innerHTML =
’Latitude = ’ + e.latitude +
’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
</body>
</html>
效果图如下所示,你可以使用一些control的特性:
·拖动整个地图刷新显示
·使用鼠标滚轮进行缩放
·双击某个地点进行放大
从Map Control接收事件
当control上显示的地图变化的时候,map control会触发事件,事件提供了有关地图的相关信息。
你可以从control上获取的事件有:
· onStartContinuousPan
· onEndContinuousPan
· onStartZoom
· onEndZoom
· onMouseClick
· onMouseDown
· onMouseUp
所有的事件函数都传入一个参数。事件参数在MapControl.js这样被定义:
function VE_MapEvent(srcMapControl,latitude,longitude,zoomLevel)
{
this.srcMapControl=srcMapControl;
this.latitude=latitude;
this.longitude=longitude;
this.zoomLevel=zoomLevel;
}
纬度(latitude)和经度(longitude)表明了地图的中心位置。缩放尺度(zoomlevel)提供了可以缩放的尺度的量。
我们首先看到的是第一个event--载入事件(panning event)。每次地图开始或者停止载入或者卷动(scrolling)时都会触发此事件。当地图开始卷动时onStartContinousPan事件会触发,当map control停止卷动地图时onEndContinousPan事件会被触发。
我们可以给上一步中创建的简单页面增加一些代码,来处理onEndContinuousPan事件,显示当前map的中心信息。
代码如下:
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
map.onEndContinuousPan = function(e)
{
document.getElementById("info").innerHTML =’Latitude = ’ + e.latitude +
’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
</body>
</html>
我们可以通过增加一个函数处理onEndZoom事件完成以上功能:
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =’Latitude = ’ + e.latitude +’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
</body>
</html>
地图显示如下:
变换地图样式
上面我们已经介绍了有三种样式可以选择:
·a-aerial:显示高空的卫星图像。
·r-road:显示地区的街道地图;
·h-hybrid:显示以上两者的结合,卫星图像将和道路和位置信息重叠在一起。
当map control显示的时候,可以通过SetMapStyle函数来变换地图样式:
SetMapStyle(mapStyle)
函数通过mapStyle参数来设置式样,如上文所述,使用a,r或者h。
我们可以通过增加两个checkbox来允许用户改变地图样式:
<html>
<head>
<title>My Virtual Earth</title>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = ’r’;
if (Aerial.checked && Vector.checked)
{
s = ’h’;
}
else if (Aerial.checked)
{
s = ’a’;
}
map.SetMapStyle(s);
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" >
Aerial Style
</div>
</body>
</html>
效果如下:
给地图增加图钉(pin)标记
增加图钉标记的功能允许我们在map control上指出特殊位置。图钉在map control上显示覆盖的信息。AddPushpin方法的原型如下:
AddPushpin(id,lat,lon,width,height,className,innerHtml)
id:图钉的标识符。在map control上每个图钉都具有唯一的标识号。
lat:放置图钉的地点的纬度。
lon:放置图钉的地点的经度。
width:图钉的宽度。
height:图钉的高度。
width和height使用来计算图钉的偏移,使得图钉可以放置到指定的经纬度。
提示:如果你希望使得图钉的底部右脚处于指定的经纬度,你需要将这些值乘2:
Classname:图钉的样式类型(style class)的名称。如果没有这个参数图钉不会显示。样式可以通过CSS文件描述或者通过嵌入式的代码描述。
innerHTML:显示在图钉上的文字。
下面的例子中,使用onMouseClick事件,当用户点击的时候给点击处增加一个图钉:
<html>
<head>
<title>My Virtual Earth</title>
<style type="text/css" media=screen>
<!--
.pin
{
width:44px;height:17px;
font-family:Arial,sans-serif;
font-weight:bold;font-size:8pt;
color:White;overflow:hidden;
cursor:pointer;text-decoration:none;
text-align:center;background:#0000FF;
border:1px solid #FF0000;
z-index:5;
}
-->
</style>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
map.onMouseClick = function(e)
{
map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’);
}
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = ’r’;
if (Aerial.checked && Vector.checked)
{
s = ’h’;
}
else if (Aerial.checked)
{
s = ’a’;
}
map.SetMapStyle(s);
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" >
Aerial Style
</div>
</body>
</html>
这样会导致一些问题:
·每次地图被拖动时,另外一个图钉被增加。
·双击地图进行放大的功能无法完成,因为每次接收到双击事件,图钉首先会被增加。
·单个标识符可以增加多个图钉。
一个解决方案是对onMouseClick事件进行特殊处理,我们可以每次增加一个图钉的时候移除以前的图钉。
使用RemovePushpin函数移去一个图钉:
RemovePushpin(id);
这个函数通过传入的id标识符来去除某个图钉。
去除一个图钉也会同时移去所有相同标识符的图钉。
上文中的代码可以修改以移去以前所有的图钉:
map.onMouseClick = function(e){
map.RemovePushpin(’pin’);
map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’);
}
这样就只有一个图钉来标明上次点击的位置:
增加导航Control
map control有一些内在的导航特性,但是有些时候需要提供一些额外的control在web页面上来允许用户来控制地图的导航。下面我们介绍如何在web页面上增加按钮来控制地图的显示。
载入
我们首先为地图的移动增加按钮。在HTML的Body元素中可以增加一些简单的HTML代码:
<input type="button" value="Pan Up" style="position:absolute;left:60px;top:600px;"/>
<input type="button" value="Pan Left" style="position:absolute;left:10px;top:630px;"/>
<input type="button" value="Pan Right" style="position:absolute;left:100px;top:630px;"/>
<input type="button" value="Pan Down" style="position:absolute;left:45px;top:660px;"/>
下面增加对点击按钮的事件进行处理的脚本段。使用PanMap方法。它可以接受2个参数,x和y。它们指出了在x和y方向上可以移动多少位置。
function DoPanUp()
{
map.PanMap(0, -100);
}
function DoPanDown()
{
map.PanMap(0, 100);
}
function DoPanLeft()
{
map.PanMap(-100, 0);
}
function DoPanRight()
{
map.PanMap(100, 0);
}
如果你在浏览器里进行浏览,并且点击按钮,你会发现地图在一次次的跳跃。这样的用户体验可不好。最好是使得地图在各个方向上慢慢的平滑卷动。可以使用ContinuousPan函数来控制。除了x和y之外,它还接受一个参数,这个参数指定了进行平滑卷动的次数。这样可以指定多次的移动来提供地图平滑卷动的效果。
function DoPanUp()
{
map.ContinuousPan(0, -10, 20);
}
function DoPanDown()
{
map.ContinuousPan(0, 10, 20);
}
function DoPanLeft()
{
map.ContinuousPan(-10, 0, 20);
}
function DoPanRight()
{
map.ContinuousPan(10, 0, 20);
}
缩放
下面增加两个按钮用于缩放:
<input type="button" value="Zoom In" style="position:absolute;left:250px;top:630px;"/>
<input type="button" value="Zoom Out" style="position:absolute;left:340px;top:630px;"/>
下面的代码实现ZoomIn和ZoomOut函数,每个函数给缩放尺度增或者减1。
function DoZoomIn() { map.ZoomIn(); }function DoZoomOut() { map.ZoomOut(); }
如果你按照上面所说进行编程,那么你的页面和文中开始的图是基本类似的。完整代码如下:
<html>
<head>
<title>My Virtual Earth</title>
<style type="text/css" media=screen>
<!--
.pin
{
width:44px;height:17px;
font-family:Arial,sans-serif;
font-weight:bold;font-size:8pt;
color:White;overflow:hidden;
cursor:pointer;text-decoration:none;
text-align:center;background:#0000FF;
border:1px solid #FF0000;
z-index:5;
}
-->
</style>
<script src="MapControl.js"></script>
<script>
var map = null;
function OnPageLoad()
{
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
’Latitude = ’ + e.latitude +
’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
map.onMouseClick = function(e)
{
map.RemovePushpin(’pin’);
map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’);
}
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = ’r’;
if (Aerial.checked && Vector.checked)
{
s = ’h’;
}
else if (Aerial.checked)
{
s = ’a’;
}
map.SetMapStyle(s);
}
function DoPanUp() { map.ContinuousPan(0, -10, 20); }
function DoPanDown() { map.ContinuousPan(0, 10, 20); }
function DoPanLeft() { map.ContinuousPan(-10, 0, 20); }
function DoPanRight() { map.ContinuousPan(10, 0, 20); }
function DoZoomIn() { map.ZoomIn(); }
function DoZoomOut() { map.ZoomOut(); }
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" >
Aerial Style
</div>
<input type="button" value="Pan Up" style="position:absolute;left:60px;top:600px;"/>
<input type="button" value="Pan Left" style="position:absolute;left:10px;top:630px;"/>
<input type="button" value="Pan Right" style="position:absolute;left:100px;top:630px;"/>
<input type="button" value="Pan Down" style="position:absolute;left:45px;top:660px;"/>
<input type="button" value="Zoom In" style="position:absolute;left:250px;top:630px;"/>
<input type="button" value="Zoom Out" style="position:absolute;left:340px;top:630px;"/>
</body>
</html>
设置其他control的脚本
本文一开始我就提到可以从http://virtualearth.msn.com/js/MapControl.js页面找到我们所需要的Virtual Earth Map Control,这里我们同样需要另外一个包含其他control的脚本文件,这个文件可以在http://virtualearth.msn.com/js/ve.js下载到。
同样如果你需要在你自己的站点使用这个脚本,你必须将这个脚本文件拷贝到你自己的站点。如果你从VirtualEarth站点直接使用这个脚本,用户将会收到安全警告,也可能会根本都看不见这个control。
你必须引进这个脚本:
<script src="/ViaVirtualEarth/Portals/0/VE.js"></script>
这里要说明的是其他的窗口部件假设你的页面上的map control是命名地图。
罗盘控制
第一个我们将要增加的是罗盘control。它提供了在地图上进行漫游的各种方式。它是通过一个图像代表的,最后使用一个透明的gif图像以免其覆盖所需要的地图。你可以自己创建或者使用本例中的图片。
在OnPageLoad方法里你可以通过创建一个文档元素VE_Compass并设置它的元素属性来创建和摆放罗盘control。
最好的方式就是将其单独作为一个方法,从OnPageLoad方法里进行调用。
function CreateCompass()
{
var el=document.createElement("div");
el.id="VE_Compass";
el.style.background="url(images/compass.gif)";
el.onmousedown=VE_Compass._MouseDown;
el.onmouseup=VE_Compass._MouseUp;
el.onmousemove=VE_Compass._MouseMove;
el.style.position="absolute";
el.style.top = 100;
el.style.left = 15;
el.style.zIndex=31;
el.style.width = 93;
el.style.height = 91;
VE_Compass.element=el;
document.body.appendChild(el);
}
function OnPageLoad(){ CreateCompass(); ...
页面此时会显示一个罗盘在地图左上角,你可以用它来漫游整个地图。
地图比例尺组件
地图比例尺组件提供了对地图显示的比例的调整功能,这在估算距离的时候比较有用。组件是由2行的一个表格来表示的。在代码里必须正确的定义表格和行的名称,这些名称可以被其他的VE.js文件中的代码使用以在地图变化的时候更新比例尺
首先在HTML中增加一个表格:
<table id="VE_MapScale" cellpadding="0" cellspacing="0" unselectable="on">
<tr>
<td>
<div id="VE_MapScaleLabel" unselectable="on"> </div>
</td>
</tr>
<tr>
<td>
<div id="VE_MapScaleBar" unselectable="on"> </div>
</td>
</tr>
</table>
然后增加一些样式来定义最终的比例尺的显示:
#VE_MapScale
{
position: absolute;
width: 150px;
height: 18px;
padding: 0;
margin: 0;
z-index: 31;
}
#VE_MapScaleLabel
{
height: 22px;
font-family: Verdana;
font-size: 12pt;
color: black;
overflow: hidden;
}
#VE_MapScaleBar
{
width: 150px;
height: 5px;
background: green;
overflow: hidden;
}
增加如下的代码在OnPageLoad方法里,以在地图上摆放比例尺,并且显示初始的比例大小:
PositionElement(document.getElementById("VE_MapScale"), 300, 550, 150, 18);
UpdateMapScale();
最后当每次缩放的时候,比例尺都会需要被更新。在OnPageLoad函数中,我们增加对此事件进行处理的代码。我们需要增加一个对更新比例尺的调用。
map.onEndZoom=function(e){ document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude+’), Zoom=’ + e.zoomLevel; UpdateMapScale();}
缩放控制
缩放control提供了一个灵活的用户接口,用来控制地图的缩放。它还提供了可视化的回馈,用来提供地图可以缩放的量以及当前的比例信息。
首先我们需要增加一些样式表来描述control的样子,它主要包含4个部分:主体条,滑动杆,左边的缩小控制和右边的放大控制。每个部分都需要一个图片文件来定义如何显示这些控制部分。
在这里我创建了简单的图片,你也可以拷贝过去使用。缩放的样式定义应该和下面的类似:
.VE_ZoomControl_minus
{
position: absolute;
width: 26px;
height: 32px;
background: url(images/ZoomOut.gif);
display: inline;
text-align: center;
text-decoration: none;
color: black;
}
.VE_ZoomControl_plus
{
position: absolute;
width: 26px;
height: 32px;
background: url(images/ZoomIn.gif);
display: inline;
text-align: center;
text-decoration: none;
color: black;
}
.VE_ZoomControl_bar
{
position: absolute;
width: 128px;
height: 32px;
background: url(images/ZoomBar.gif);
display: inline;
}
.VE_ZoomControl_slider
{
position: absolute;
width: 8px;
height: 24px;
background: url(images/ZoomSlider.gif);
overflow: hidden;
display: inline;
}
这些创建缩放控制的代码可以被放到OnPageLoad函数的最后,以在调入页面的同时初始化这些control。
var zm=VE_ZoomControl.Create(5, 550, 9, "absolute");
document.body.appendChild(zm);
为了让缩放控制反映出当前的缩放尺度,我们需要在每次缩放发生的时候调节它。所以在onEndZoom函数的最后增加对control的刷新:
map.onEndZoom=function(e)
{
document.getElementById("info").innerHTML = ’Latitude = ’ + e.latitude + ’, Longitude = ’ + e.longitude + ’), Zoom=’ + e.zoomLevel; UpdateMapScale();
VE_ZoomControl.SetZoomLevel(map.GetZoomLevel());
}
下面我们看一看我们目前的页面是什么样子了,它已经增加了三个大的组件了,如下所示:
添加便笺条
和其他control一样,我们首先需要定义便笺条的样式,我们使用和Virtual Earth网站一样的样式:
.VE_Panel_el
{
overflow: hidden;
z-index: 31;
border: 1px solid #cbcbcb;
padding: 0;
margin: 0;
background: white;
}
.VE_Panel_title
{
position: absolute;
padding-top: 2px;
padding-left: 5px;
overflow: hidden;
z-index: 32;
font-family: Verdana,sans-serif;
font-size: 8pt;
font-weight: bold;
color: rgb(230,250,255);
text-transform: uppercase;
cursor: default;
white-space: nowrap;
text-overflow: ellipsis;
}
.VE_Panel_title_blue{ background: #0030cc;}
.VE_Panel_cb
{
padding-left: 1px;
width: 18px; height: 18px;
color: white;
text-align: center;
font-size: 7pt;
font-family: Verdana;
font-weight: bold;
overflow: hidden;
cursor: pointer;
}
.VE_Panel_cb_blue
{
background: #001d7a;
border: solid 2px #0030cc;
}
.VE_Panel_tb
{
height: 18px;
padding-top: 3px;
padding-left: 2px;
font-family: Verdana,sans-serif;
font-size: 8pt;
overflow: hidden;
}
.VE_Panel_tb_blue
{
background: #ccd8ff;
}
.VE_Panel_tb td
{
font-family: Verdana,sans-serif;
font-size: 8pt;
}
.VE_Panel_tb a{ color: #000080;}
.VE_Panel_tb a: hover{ color: #ff9900;}
.VE_Panel_body
{
padding: 5px;
font-family: Verdana,sans-serif;
font-size: 8pt;
overflow: auto;
}
在OnPageLoad函数最后我们创建并显示便笺条,我们需要定义其窗口戴孝,以使其做相应的显示。然后我们可以调用CreatePanel来显示:
windowWidth=700;
windowHeight=500;
VE_Scratchpad.CreatePanel();
VE_Scratchpad.Show();
如果你用浏览器浏览页面,你将会看到便笺条看起来和Virtual Earth上的显示的基本一样,如下图:
我们可以对便笺条的一些属性进行设置,以改变其看起来的式样。首先可以增加一些欢迎信息或者介绍文字等等。下面的代码增加了一些介绍文字:
VE_Scratchpad._introText="Your scratchpad is empty.";
我们也可以改变便笺条的菜单项,通过GetToolbar函数完成,如果我们提供自己的这个函数的版本那么就可以改变菜单。这个函数返回一个HTML字符串,其内容是便笺条上的菜单的显示内容。在如下的例子里我们有Clear和Email(和Virtual Earth相同),也有一个Add的菜单项。同样它必须在CreatePanel之前声明:
VE_Scratchpad._GetToolbar=function()
{
var html="<table cellpadding=\"0\" cellspacing=\"0\" ";
html+="border=\"0\" align=\"left\">";
html+="<tr><td valign=\"top\" align=\"center\">";
html+="<a href=\"javascript:VE_Scratchpad.Clear();\" ";
html+="oncontextmenu=\"return false;\">Clear Pad</a> | ";
html+="<a href=\"javascript:VE_Scratchpad.Email();\" ";
html+="oncontextmenu=\"return false;\">Email this...</a> ";
html+="</td></tr><tr><td> </td></tr></table>";
return html;
}
这两个菜单项将会调用VEScratchpad.Clear()和VEScratchpad.Email()函数。
下面我们修改VEScratchpad.Email函数:
VE_Scratchpad.Email=
function()
{
var body="";
var urlprefix=GetUrlPrefix();
var first=true;
var ids="";
var e=VE_Scratchpad.entities;
if(e==null||e.length==0)
{
alert("Nothing to send!");
return;
}
var lengthToSend=Math.min(MaxScratchpadItemsToSend,e.length);
for(var i=0;i<lengthToSend;i++)
{
var escapedID=escape(e[i].GetSerializedId());
if(!escapedID) {continue;
}
body+=escape(e[i].name+"\n"+e[i].description+"\n\n");
if(!first) { ids+=","; }
ids+=escapedID;
first=false;
}
var allids=escape("Virtual Earth Scratch Pad from Dr. Neil\n" + urlprefix + "\n\n");
window.open(’mailto:?subject=My%20Virtual%20Earth%20Scratch%20Pad&body=’ + allids + body);
}
给便笺条增加一项
现在我们给Add函数增加相应的代码,以在便笺条上增加一项内容。首先我们使用地图中心来定位:
VE_Scratchpad.Add=function()
{
VE_Scratchpad.AddLocation( "Point", map.GetCenterLatitude(), map.GetCenterLongitude(), "my added point", "LOC");
}
这是我们用来提高其展示效果的方式,当然也可以修改其中的内容。
首先我们从Virtual Earth使用的样式表(CSS)中借用一点样式:
.VE_Pushpin
{
width: 23px; height: 17px;
font-family: Arial,sans-serif;
font-weight: bold;
font-size: 8pt;
color: White;
overflow: hidden;
cursor: pointer;
text-decoration: none;
text-align: center;
padding-top: 1px;
}
.VE_Pushpin_blue
{
background: url(http://virtualearth.msn.com/i/pins/blue.gif);
z-index: 19;
}
在Virtual Earth站点上,每个便笺条边上就有一个X号来关闭它。在我们创建的便笺条中我们必须创建一个X号图案来代表它。便笺条代码里会寻找的图像是在URL里:<your url>/i/remove.gif。图像大小11×11象素。
添加查找功能
为了进行地图查找,我们必须使用Virtual Earth查找管理器(Search Manager)。这里比较不好的一点是必须访问你网站外部的文件,而这样会导致一个对用户的安全警告信息。
重要提示:它只能在浏览器允许跨站点数据访问的时候使用。缺省情况下浏览器不允许这样作。
在Internet Explorer里你可以这样修改,以允许跨站点数据访问:
1. 在工具菜单里选择Internet选项
2. 选择安全tab
3. 点击自定义级别按钮
4. 在列表里选择其他这个数型列表
5. 允许"跨域浏览数据"
在HTML文件的body段的最后增加一个按钮和输入框来允许用户输入地点并点击按钮进行查找:
<input type="button" value="Find" id="FindButton" name="FindButton" style="position:absolute;left:10px;top:700"/>
<input type="text" name="WhereText" size="20" id="WhereText" style="position:absolute;left:60px;top:700"/>
在代码段中增加一个查找函数DoFind:
function DoFind()
{
var where = document.getElementById("WhereText").value;
VE_SearchManager._ResetPaging();
VE_SearchManager._CancelAllRequests();
VE_SearchManager.searchPage="http://virtualearth.msn.com/search.aspx";
VE_SearchManager._DoSearch(where, where);
}
页面将会进行查找并将查找结果位置显示在地图中央。同时我们也可以将查找的地点增加到便笺条上。我们需要对代码进行处理,使得在查找完成后可以做相应的工作。
新的Dofind方法将会做更多的工作,和VE_SEarchManger._DoSearch函数类似:
function DoFind()
{
var where = document.getElementById("WhereText").value;
var a="";
var b=escape(where);
var c=map.GetLatitude(0);
var d=map.GetLongitude(windowWidth);
var e=map.GetLatitude(windowHeight);
var f=map.GetLongitude(0);
var g="";
var i="";
var r=0;
var url="http://virtualearth.msn.com/search.aspx"+"?a="+a+"&b="+b+"&c="+c+"&d="+d+"&e="+e+"&f="+f+"&g="+g+"&i="+i+"&r="+r;
if(!VE_SearchManager.xmlHttp)
{
VE_SearchManager.xmlHttp=GetXmlHttp();
}
var xmlHttp=VE_SearchManager.xmlHttp;
if(xmlHttp)
{
xmlHttp.open("POST",url,true);
xmlHttp.onreadystatechange=FindResponseHandler;
VE_SearchManager.searching=true;
xmlHttp.send("");
}
}
FindResponseHandler=function()
{
var x = VE_SearchManager.xmlHttp;
if(x.readyState==4)
{
VE_SearchManager.searching = false;
var code = x.responseText;
try
{
eval(code);
}
catch(ex){}
VE_Scratchpad.AddLocation(
document.getElementById("WhereText").value,
map.GetCenterLatitude(),
map.GetCenterLongitude(),"", "LOC");
}
}
结束语
本文全部代码如下:
<html>
<head>
<title>My Virtual Earth</title>
<style type="text/css" media="screen">
<!--
.pin
{
width:44px;height:17px;
font-family:Arial,sans-serif;
font-weight:bold;font-size:8pt;
color:White;overflow:hidden;
cursor:pointer;text-decoration:none;
text-align:center;background:#0000FF;
border:1px solid #FF0000;
z-index:5;
}
#VE_MapScale
{
position: absolute;
width: 150px;
height: 18px;
padding: 0;
margin: 0;
z-index: 31;
}
#VE_MapScaleLabel
{
height: 22px;
font-family: Verdana;
font-size: 12pt;
color: black;
overflow: hidden;
}
#VE_MapScaleBar
{
width: 150px;
height: 5px;
background: green;
overflow: hidden;
}
.VE_ZoomControl_minus
{
position: absolute;
width: 26px;
height: 32px;
background: url(images/ZoomOut.gif);
display: inline;
text-align: center;
text-decoration: none;
color: black;
}
.VE_ZoomControl_plus
{
position: absolute;
width: 26px;
height: 32px;
background: url(images/ZoomIn.gif);
display: inline;
text-align: center;
text-decoration: none;
color: black;
}
.VE_ZoomControl_bar
{
position: absolute;
width: 128px;
height: 32px;
background: url(images/ZoomBar.gif);
display: inline;
}
.VE_ZoomControl_slider
{
position: absolute;
width: 8px;
height: 24px;
background: url(images/ZoomSlider.gif);
overflow: hidden;
display: inline;
}
.VE_Panel_el
{
overflow: hidden;
z-index: 31;
border: 1px solid #cbcbcb;
padding: 0;
margin: 0;
background: white;
}
.VE_Panel_title
{
position: absolute;
padding-top: 2px;
padding-left: 5px;
overflow: hidden;
z-index: 32;
font-family: Verdana,sans-serif;
font-size: 8pt;
font-weight: bold;
color: rgb(230,250,255);
text-transform: uppercase;
cursor: default;
white-space: nowrap;
text-overflow: ellipsis;
}
.VE_Panel_title_blue
{
background: #0030cc;
}
.VE_Panel_cb
{
padding-left: 1px;
width: 18px;
height: 18px;
color: white;
text-align: center;
font-size: 7pt;
font-family: Verdana;
font-weight: bold;
overflow: hidden;
cursor: pointer;
}
.VE_Panel_cb_blue
{
background: #001d7a;
border: solid 2px #0030cc;
}
.VE_Panel_tb
{
height: 18px;
padding-top: 3px;
padding-left: 2px;
font-family: Verdana,sans-serif;
font-size: 8pt;
overflow: hidden;
}
.VE_Panel_tb_blue
{
background: #ccd8ff;
}
.VE_Panel_tb td
{
font-family: Verdana,sans-serif;
font-size: 8pt;
}
.VE_Panel_tb a
{
color: #000080;
}
.VE_Panel_tb a: hover
{
color: #ff9900;
}
.VE_Panel_body
{
padding: 5px;
font-family: Verdana,sans-serif;
font-size: 8pt;
overflow: auto;
}
.VE_Pushpin
{
width: 23px;
height: 17px;
font-family: Arial,sans-serif;
font-weight: bold;
font-size: 8pt;
color: White;
overflow: hidden;
cursor: pointer;
text-decoration: none;
text-align: center;padding-top: 1px;
}
.VE_Pushpin_blue
{
background: url(http: //virtualearth.msn.com/i/pins/blue.gif);
z-index: 19;
}
-->
</style>
<script src="MapControl.js"></script>
<script src="VE.js"></script>
<script>
var map = null;
function CreateCompass()
{
var el = document.createElement("div");
el.id="VE_Compass";
el.style.background="url(images/compass.gif)";
el.onmousedown=VE_Compass._MouseDown;
el.onmouseup=VE_Compass._MouseUp;
el.onmousemove=VE_Compass._MouseMove;
el.style.position="absolute";
el.style.top = 100;
el.style.left = 15;
el.style.zIndex=31;
el.style.width = 93;
el.style.height = 91;
VE_Compass.element=el;
document.body.appendChild(el);
}
function OnPageLoad()
{
CreateCompass();
map = new VE_MapControl(32.69, -117.13, 12, ’r’, "absolute", 10, 100, 700, 500);
document.body.appendChild(map.element);
var updateInfo = function(e)
{
document.getElementById("info").innerHTML =
’Latitude = ’ + e.latitude +
’, Longitude = ’ + e.longitude +
’, Zoom=’ + e.zoomLevel;
}
map.onEndContinuousPan = updateInfo;
map.onEndZoom = updateInfo;
map.onMouseClick = function(e)
{
map.RemovePushpin(’pin’);
map.AddPushpin(’pin’, e.latitude, e.longitude, 88, 34, ’pin’, ’MyPin’);
}
PositionElement(document.getElementById("VE_MapScale"), 300, 550, 150, 18);
UpdateMapScale();
var zm = VE_ZoomControl.Create(5,550,9,"absolute");
document.body.appendChild(zm);
windowWidth=700;
windowHeight=500;
VE_Scratchpad.Add=function()
{
VE_Scratchpad.AddLocation("Point",map.GetCenterLatitude(),map.GetCenterLongitude(),"my added point","LOC");
}
VE_Scratchpad.Email=function()
{
var body="";
var urlprefix=GetUrlPrefix();
var first=true;
var ids="";
var e=VE_Scratchpad.entities;
if(e==null||e.length==0)
{
alert("Nothing to send!");
return;
}
var lengthToSend=Math.min(MaxScratchpadItemsToSend,e.length);
for(var i=0;i<lengthToSend;i++)
{
var escapedID=escape(e[i].GetSerializedId());
if(!escapedID) {continue;}
body+=escape(e[i].name+"\n"+e[i].description+"\n\n");
if(!first) { ids+=","; }
ids+=escapedID;
first=false;
}
var allids=escape("Virtual Earth Scratch Pad from Dr. Neil\n" + urlprefix + "\n\n");
window.open(’mailto:?subject=My%20Virtual%20Earth%20Scratch%20Pad&body=’ + allids + body);
}
VE_Scratchpad._GetToolbar=function()
{
var html="<table cellpadding=\"0\" cellspacing=\"0\" ";
html+="border=\"0\" align=\"left\">";
html+="<tr><td valign=\"top\" align=\"center\">";
html+="<a href=\"javascript:VE_Scratchpad.Clear();\" ";
html+="oncontextmenu=\"return false;\">Clear Pad</a> | ";
html+="<a href=\"javascript:VE_Scratchpad.Email();\" ";
html+="oncontextmenu=\"return false;\">Email this...</a> ";
html+="</td></tr><tr><td> </td></tr></table>";
return html;
}
VE_Scratchpad._introText="Your scratchpad is empty.";
VE_Scratchpad.CreatePanel();
VE_Scratchpad.Show();
}
function ChangeMapStyle()
{
var Aerial = document.getElementById("AerialStyleCheck");
var Vector = document.getElementById("VectorStyleCheck");
var s = ’r’;
if (Aerial.checked && Vector.checked)
{
s = ’h’;
}
else if (Aerial.checked)
{
s = ’a’;
}
map.SetMapStyle(s);
}
function DoPanUp() { map.ContinuousPan(0, -10, 20); }
function DoPanDown() { map.ContinuousPan(0, 10, 20); }
function DoPanLeft() { map.ContinuousPan(-10, 0, 20); }
function DoPanRight() { map.ContinuousPan(10, 0, 20); }
function DoZoomIn() { map.ZoomIn(); }
function DoZoomOut() { map.ZoomOut(); }
function DoFind()
{
var where = document.getElementById("WhereText").value;
var a="";
var b=escape(where);
var c=map.GetLatitude(0);
var d=map.GetLongitude(windowWidth);
var e=map.GetLatitude(windowHeight);
var f=map.GetLongitude(0);
var g="";
var i="";
var r=0;
var url="http://virtualearth.msn.com/search.aspx"+"?a="+a+"&b="+b+"&c="+c+"&d="+d+"&e="+e+"&f="+f+"&g="+g+"&i="+i+"&r="+r;
if(!VE_SearchManager.xmlHttp)
{
VE_SearchManager.xmlHttp=GetXmlHttp();
}
var xmlHttp=VE_SearchManager.xmlHttp;
if(xmlHttp)
{
xmlHttp.open("POST",url,true);
xmlHttp.onreadystatechange=FindResponseHandler;
VE_SearchManager.searching=true;
xmlHttp.send("");
}
}
FindResponseHandler=function()
{
var x = VE_SearchManager.xmlHttp;
if(x.readyState==4)
{
VE_SearchManager.searching = false;
var code = x.responseText;
try
{
eval(code);
}
catch(ex){}
VE_Scratchpad.AddLocation(
document.getElementById("WhereText").value,
map.GetCenterLatitude(),
map.GetCenterLongitude(), "", "LOC");
}
}
</script>
</head>
<body >
<div id="info" style="font-size:10pt">
</div>
<div id="MapStyle" style="POSITION:absolute;LEFT:470px;TOP:60px">
<input id="VectorStyleCheck" type="checkbox" name="VectorStyleCheck" checked="checked">
Street Style
<input id="AerialStyleCheck" type="checkbox" name="AerialStyleCheck" >
Aerial Style
</div>
<input type="button" value="Pan Up" id="PanUpButton" name="PanUpButton" style="position:absolute;left:60px;top:600"/>
<input type="button" value="Pan Left" id="PanLeftButton" name="PanLeftButton" style="position:absolute;left:10px;top:630"/>
<input type="button" value="Pan Right" id="PanRightButton" name="PanRightButton" style="position:absolute;left:100px;top:630"/>
<input type="button" value="Pan Down" id="PanDownButton" name="PanDownButton" style="position:absolute;left:45px;top:660"/>
<input type="button" value="Zoom In" id="ZoomInButton" name="ZoomInButton" style="position:absolute;left:250px;top:630"/>
<input type="button" value="Zoom Out" id="ZoomOutButton" name="ZoomOutButton" style="position:absolute;left:340px;top:630"/>
<table id="VE_MapScale" cellpadding="0" cellspacing="0" unselectable="on">
<tr>
<td>
<div id="VE_MapScaleLabel" unselectable="on">
</div>
</td>
</tr>
<tr>
<td>
<div id="VE_MapScaleBar" unselectable="on">
</div>
</td>
</tr>
</table>
<input type="button" value="Find" id="FindButton" name="FindButton" style="position:absolute;left:10px;top:700"/>
<input type="text" name="WhereText" size="20" id="WhereText" style="position:absolute;left:60px;top:700"/>
</body>
</html>