百度地图API GL使用总结
JavaScript API GL v1.0是目前版本最新的百度地图API,相比于JavaScript API v3.0界面更加美观,功能更加强大。
项目需求
从后端读取起点和终点的地址,在地图上显示两者之间的路径。 获得路径上所有点的坐标,用以显示卡车的虚拟位置。
具体实现
解析地址
var map = new BMapGL. Map ( 'container' ) ;
var myGeo = new BMapGL. Geocoder ( ) ;
myGeo. getPoint ( '北京市海淀区上地10街' , function ( point ) {
if ( point) {
map. centerAndZoom ( point, 16 ) ;
map. addOverlay ( new BMapGL. Marker ( point, { title: '北京市海淀区上地10街' } ) )
} else {
alert ( '您选择的地址没有解析到结果!' ) ;
}
} , '北京市' )
分析代码可以得知:getPoint函数用以将地址字符串解析为Point,并通过回调函数进一步对Point进行处理。
显示路径
获得路径可以有多种选择,例如:驾车路线,步行路径,公交路径,骑行路径等等。百度也提供了货车路径的规划,但需要向百度递交申请,过程较为繁琐,所以最终考虑选择使用驾车路线规划。 从官方文档中可以得到示例代码:
var map = new BMapGL. Map ( "container" ) ;
map. centerAndZoom ( new BMapGL. Point ( 116.404 , 39.915 ) , 11 ) ;
var p1 = new BMapGL. Point ( 116.301934 , 39.977552 ) ;
var p2 = new BMapGL. Point ( 116.508328 , 39.919141 ) ;
var driving = new BMapGL. DrivingRoute ( map, { renderOptions: { map: map, autoViewport: true } } ) ;
driving. search ( p1, p2) ;
分析代码可以得知:search函数用以获得p1,p2两个坐标之间的路径 将以上两个示例代码结合可以很自然的想到以下代码:
var map = new BMapGL. Map ( "container" ) ;
map. centerAndZoom ( new BMapGL. Point ( 116.404 , 39.915 ) , 11 ) ;
var myGeo = new BMapGL. Geocoder ( ) ;
var p1, p2;
myGeo. getPoint ( '北京市海淀区上地10街' , function ( point ) {
if ( point) {
p1 = point;
} else {
alert ( '您选择的地址没有解析到结果!' ) ;
}
} )
myGeo. getPoint ( '北京市海淀区颐和园路5号' , function ( point ) {
if ( point) {
p2 = point;
} else {
alert ( '您选择的地址没有解析到结果!' ) ;
}
} )
var driving = new BMapGL. DrivingRoute ( map, { renderOptions: { map: map, autoViewport: true } } ) ;
driving. search ( p1, p2) ;
但实际上以上代码是不能运行的,在search函数被调用之前输出p1和p2可以发现两者都是undefined。这是因为getPoint函数其实是异步函数,执行顺序并非按照顺序执行,所以会导致无法对p1和p2赋值。所以改变策略,考虑使用函数嵌套的手段进行赋值:
var map = new BMapGL. Map ( "container" ) ;
map. centerAndZoom ( new BMapGL. Point ( 116.404 , 39.915 ) , 11 ) ;
var myGeo = new BMapGL. Geocoder ( ) ;
myGeo. getPoint ( '北京市海淀区上地10街' , function ( point ) {
if ( point) {
var p1 = point;
myGeo. getPoint ( '北京市海淀区颐和园路5号' , function ( point ) {
if ( point) {
var p2 = point;
var driving = new BMapGL. DrivingRoute ( map, { renderOptions: { map: map, autoViewport: true } } ) ;
driving. search ( p1, p2) ;
} else {
alert ( '您选择的地址没有解析到结果!' ) ;
}
} )
} else {
alert ( '您选择的地址没有解析到结果!' ) ;
}
} )
经测试,可以正常运行:
获取坐标
获得坐标在官方文档中并没有相关的代码供参考,所以只能自行解决。 网络上许多和获取路径上坐标的代码多为:
driving. search ( p1, p2) ;
var pts = driving. getResults ( ) . getPlan ( 0 ) . getRoute ( 0 ) . getPath ( ) ;
但这实际上是无法运行的,会显示Cannot read property ‘getPlan’ of undefined: 在查看了计算驾车距离和时间的相关示例代码后可以知道在DrivingRoute中参数renderOptions可以传入一个回调函数完成对route结果的处理,即:
var p2 = point;
var searchComplete = function ( results ) {
if ( driving. getStatus ( ) != BMAP_STATUS_SUCCESS ) {
return ;
}
var plan = results. getPlan ( 0 ) . getRoute ( 0 ) . getPath ( ) ;
}
var driving = new BMapGL. DrivingRoute ( map, {
renderOptions: { map: map, autoViewport: true } ,
onSearchComplete: searchComplete,
} ) ;
driving. search ( p1, p2) ;
以上代码可以成功输出,返回结果为一个数组,包含路径上所有点的经纬度: 可以使用Marker在地图上标注点的位置:
var marker1 = new BMapGL. Marker ( new BMapGL. Point ( plan[ i] . lng, plan[ i] . lat) ) ;
map. addOverlay ( marker1) ;
完整代码
function generateMap ( sendAddress, receiveAddress, createTime, status ) {
var map = new BMapGL. Map ( "container" ) ;
var myGeo = new BMapGL. Geocoder ( ) ;
myGeo. getPoint ( sendAddress, function ( point ) {
if ( point) {
var p1 = point;
map. centerAndZoom ( point, 16 ) ;
myGeo. getPoint ( receiveAddress, function ( point ) {
if ( point) {
var p2 = point;
var searchComplete = function ( results ) {
if ( driving. getStatus ( ) != BMAP_STATUS_SUCCESS ) {
return ;
}
var plan = results. getPlan ( 0 ) . getRoute ( 0 ) . getPath ( ) ;
if ( status == "ON_THE_WAY" ) {
var len = plan. length - 1 ;
var now = parseInt ( Date. now ( ) / 1000 ) ;
var time1 = Date. parse ( createTime) / 1000 ;
var i = parseInt ( ( now - time1) / 259200 * len) ;
if ( i > len) i = len;
var marker1 = new BMapGL. Marker ( new BMapGL. Point ( plan[ i] . lng, plan[ i] . lat) ) ;
map. addOverlay ( marker1) ;
}
}
var driving = new BMapGL. DrivingRoute ( map, {
renderOptions: { map: map, autoViewport: true } ,
onSearchComplete: searchComplete,
} ) ;
driving. search ( p1, p2) ;
} else {
alert ( '收货地址没有解析到结果!' ) ;
}
} )
} else {
alert ( '发货地址没有解析到结果!' ) ;
}
} )
map. enableScrollWheelZoom ( true ) ;
var scaleCtrl = new BMapGL. ScaleControl ( ) ;
map. addControl ( scaleCtrl) ;
var zoomCtrl = new BMapGL. ZoomControl ( ) ;
map. addControl ( zoomCtrl) ;
var navi3DCtrl = new BMapGL. NavigationControl3D ( ) ;
map. addControl ( navi3DCtrl) ;
}