要在自己的脚本中用到BingMap的API,需引入其脚本,在JavaScript中的代码如下:
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
你可以直接打开这个网址,查看其源码,也可把源码拷贝过来,直接利用,而省去访问网站的时间,并且有提示功能。
定义地图时,首先要有一个容器来装Map,再者是为Map提供自定义参数。实例代码如下:
var mapOptions = {
credentials: "Your Key",
center: location,
zoom: 8,
width: 699,
height: 499
};
map = new Microsoft.Maps.Map($("#divMap")[0], mapOptions);
$("#divMap")[0]为div的ID,这里用到了JQuery。 在此提供Key一个:AqDcxSckkf-bc2zXZcU-D6TKNpqFOLgdwgfhdwxvHn_dNq-sTNaveqFuKg8q2mu9
现在Map定义好了,来重点讲一下在里面的球面操作吧。
计算球面距离
球面距离计算公式:d(x1,y1,x2,y2)=r*arccos(sin(x1)*sin(x2)+cos(x1)*cos(x2)*cos(y1-y2)) ,x1,y1是纬度\经度的弧度单位,r为地球半径
js实例代码如下:
function getArcDistance(start, end) {
var EARTH_RADIUS = 6378.140;
//角度转化成弧度,使用时请注意传进来的点的经纬度是以角度表示的
var radLat1 = start.latitude * Math.PI / 180.0;
var radLat2 = end.latitude * Math.PI / 180.0;
var radLon1 = start.longitude * Math.PI / 180.0;
var radLon2 = end.longitude * Math.PI / 180.0;
var s = Math.acos(Math.sin(radLat1) * Math.sin(radLat2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.cos(radLon1 - radLon2));
s = s * EARTH_RADIUS;
s = Math.round(s * 10000) / 10000;
return s;
}
画多边形
在这里我不讲带环的多边形,只对简单多边形的两条边是否相交进行判断,毕竟多数情况下,我们不希望自己画的多边形有一条边从另一条边跨过去。
如图1,不规则的多边形 如图2,简单规则多边形,像三角形,正方形之类的都是
当画好第一个点后,第二个点只要不和第一点重合,无论画哪都没错,但多边形不可能只有两个点的,至少也得三个。不过因为bingMap中要求多边形的终点必须和起点相同,所以存进去时都有四个点。规则多边形要求,在画当前点时,当前点跟已经画好的最后一点的连线不能和其它线段交叉(注意不是相交),而判断两条线段是否交叉,则只要判断两条的端点是否在另一条线段的两侧,如果在线段1的两端在线段2的两侧,并且线段2的两端也在线段1的两侧,则两线段交叉,否则不交叉。js实例如下
function isLocCorrect(pts, pt) {
len = pts.length;
if (len < 2) {
return true;
}
else if (len == 2) {
//如果在画第三个点,则只要判断第三个点是否在已经画好的线段上
return !isPointInLine(pts[0], pts[1], pt);
}
else {
var i = 0;
//当闭合多边形时,应该判断第一个点(也就是最后一个点,我们会自动把它加到多边形的点集合里面去)是否也遵守此规则
if (pt.x = pts[0].x && pt.y == pts[0].y) {
i = i + 1;
}
for (i; i < len - 2; ++i) {
//判断除它相邻边以外的其它边是否与自己相交(自己即loc与最后一点的连线)
var t1 = isRightOfLine(pts[i], pts[i + 1], pts[len - 1]);
var t2 = isRightOfLine(pts[i], pts[i + 1], pt);
if (t1 != t2) {//如果不在同一侧
var s1 = isRightOfLine(pts[len - 1], pt, pts[i]);
var s2 = isRightOfLine(pts[len - 1], pt, pts[i + 1]);
if (s1 != s2) {//如果不在同一侧
return false; //此时两边必相交,故不为规则多边形
}
}
}
}
return true;
}
//判断一点是否在线段上(注意,不包括在此线段的延长线上)
function isPointInLine(start, end, pt) {
if (((pt.x > start.x && pt.x < end.x) || (pt.x > end.x && pt.x < start.x))
&& ((pt.y > start.y && pt.y < end.y) || (pt.y > end.y && pt.y < start.y))
&& (pt.y - start.y) / (pt.x - start.x) == (end.y - start.y) / (end.x - start.x)) {
return true;
}
return false;
}
//线段Line L: A*x+B*y+C=0; 方向:(x1,y1)-->(x2,y2), New Point P(x,y)
//A=y2-y1, B=x1-x2, C=x2*y1-x1*y2
//if A*x+B*y+C>0, P在L的左侧
//if A*x+B*y+C<0, P在L的右侧
//if A*x+B*y+C=0, P在L上
function isRightOfLine(start, end, pt) {
if (((end.y - start.y) * pt.x + (start.x - end.x) * pt.y + end.x * start.y - start.x * end.y) < 0) {
return true;
}
return false;
}
画圆
BingMap不支持画圆,但我们可以用画多边形的形式来画圆,每一弧度画一条边,圆也就由360条一弧度的边组成,在此我们画360条一弧度的边,也就是一个完整的圆了。
js实例代码如下:
function drawCircle(origin, radius) {
var EARTH_RADIUS = 6378.140;
//圆心纬度
var lat = (origin.latitude * Math.PI) / 180;
//圆心经度
var lon = (origin.longitude * Math.PI) / 180;
var d = parseFloat(radius) / EARTH_RADIUS;
var locs = new Array();
for (i = 0; i <= 360; i++) {
var loc = new Microsoft.Maps.Location(0, 0);
var bearing = i * Math.PI / 180;
loc.latitude = Math.asin(Math.sin(lat) * Math.cos(d) + Math.cos(lat) * Math.sin(d) * Math.cos(bearing));
loc.longitude = ((lon + Math.atan2(Math.sin(bearing) * Math.sin(d) * Math.cos(lat), Math.cos(d) - Math.sin(lat) * Math.sin(loc.latitude))) * 180) / Math.PI;
loc.latitude = (loc.latitude * 180) / Math.PI;
locs.push(loc);
}
var options = {
fillColor: new Microsoft.Maps.Color(50, 255, 0, 0),
strokeColor: new Microsoft.Maps.Color(255, 0, 0, 0)
};
var circle = new Microsoft.Maps.Polygon(locs, options);
map.entities.push(circle);
}
效果图
要学习BingMap,再给出些好的网站和博客,大家可以参考一下:
http://msdn.microsoft.com/en-us/library/gg427611.aspx
http://www.bingmapsportal.com/isdk/ajaxv7
http://myzhijie.iteye.com/blog/670402