任务如下:设计一个网页,提供输入框,由用户输入起始地址。目的地址是一个下拉框,里面是BCIT的5个校区。界面上还有1个“get directions”的按钮。用户输入起始、目的地址后,点击按钮,界面就显示地图和路线说明。如图:
实现起来也比较容易:
1、在html文件中包含jQuery和google MAP。
2、调用google.maps.Geocoder()方法获取用户输入起始地址的经纬度。目标地址的经纬度可以事先查好,写到下拉列表的value中去。调用可参考
谷歌地图定位服务编程接口
3、使用起始、目的地址为参数,调用google map的direction service,来获取路线图和路线说明。调用可参考
谷歌地图路线服务编程接口
然后就可以了。但出现了2个问题:1)选取不同的起始地、目的地,重新获取路线时,以前地路线图和路线说明没有清除,仍旧留在地图上。看上去很乱。2)刷新页面,第一次点击“获取路线”按钮时,系统仅绘出2个地标,却没有绘制路线图和路线说明。此后再点击则是正常的。
问题1 的原因在于把语句directionsDisplay = new google.maps.DirectionsRenderer()放入了点击获取路线按钮所调用的函数中,把它放入到页面的初始化函数中仅调用一次。得以解决。
问题2 的原因是调用Geocode方法时,对它的返回值处理不当。因为Ajax是异步调用,获取起始地址的经纬度还没有从服务器端得到响应时,程序就继续向下处理了。所以后面调用获取路线时,服务器就会抱怨没有提供起始地址。解决起来也简单:把调用路线服务的代码放入到调用Geocode方法的callback中就可以了。即:
geocoder.geocode({'address': address}, function(results, status) {
var location = results[0].geometry.location;
var startLatlng = new google.maps.LatLng(location.lat(), location.lng());
addMarker(startLatlng);
// Create a new Marker object for destination.
var endAddress = $( "#selectCampus").val();
var endLat = endAddress.substring(0, endAddress.indexOf(','));
var endLng = endAddress.substring(endAddress.indexOf(',') + 1);
endLatlng = new google.maps.LatLng(endLat, endLng);
addMarker(endLatlng);
var request = {
origin:startLatlng,
destination:endLatlng,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
else {
alert('Directions Service was not successful for the following reason: ' + status);
}
});
});
代码中标示为绿色的部分代码就是调用路线服务所用。如果把这部分代码移到这个函数之外,就会出现异步调用的问题。