覆蓋物
地圖覆蓋物概述
所有疊加或覆蓋到地圖的內(nèi)容,我們統(tǒng)稱為地圖覆蓋物。如標(biāo)注、矢量圖形元素(包括:折線和多邊形和圓)、信息窗口等。覆蓋物擁有自己的地理坐標(biāo),當(dāng)您拖動或縮放地圖時(shí),它們會相應(yīng)的移動。
地圖API提供了如下幾種覆蓋物:
Overlay:覆蓋物的抽象基類,所有的覆蓋物均繼承此類的方法。
Marker:標(biāo)注表示地圖上的點(diǎn),可自定義標(biāo)注的圖標(biāo)。
Label:表示地圖上的文本標(biāo)注,您可以自定義標(biāo)注的文本內(nèi)容。
Polyline:表示地圖上的折線。
Polygon:表示地圖上的多邊形。多邊形類似于閉合的折線,另外您也可以為其添加填充顏色。
Circle: 表示地圖上的圓。
InfoWindow:信息窗口也是一種特殊的覆蓋物,它可以展示更為豐富的文字和多媒體信息。注意:同一時(shí)刻只能有一個信息窗口在地圖上打開。
可以使用map.addOverlay方法向地圖添加覆蓋物,使用map.removeOverlay方法移除覆蓋物,注意此方法不適用于InfoWindow。
標(biāo)注
標(biāo)注表示地圖上的點(diǎn)。API提供了默認(rèn)圖標(biāo)樣式,您也可以通過Icon類來指定自定義圖標(biāo)。Marker的構(gòu)造函數(shù)的參數(shù)為Point和MarkerOptions(可選)。注意:當(dāng)您使用自定義圖標(biāo)時(shí),標(biāo)注的地理坐標(biāo)點(diǎn)將位于標(biāo)注所用圖標(biāo)的中心位置,您可通過Icon的offset屬性修改標(biāo)定位置。
下面的示例向地圖中心點(diǎn)添加了一個標(biāo)注,并使用默認(rèn)的標(biāo)注樣式。
var map = new BMap.Map("container"); var point = new BMap.Point(116.404, 39.915); map.centerAndZoom(point, 15); var marker = new BMap.Marker(point); // 創(chuàng)建標(biāo)注 map.addOverlay(marker); // 將標(biāo)注添加到地圖中
定義標(biāo)注圖標(biāo)
通過Icon類可實(shí)現(xiàn)自定義標(biāo)注的圖標(biāo),下面示例通過參數(shù)MarkerOptions的icon屬性進(jìn)行設(shè)置,您也可以使用marker.setIcon()方法。
var map = new BMap.Map("container"); var point = new BMap.Point(116.404, 39.915); map.centerAndZoom(point, 15); // 編寫自定義函數(shù),創(chuàng)建標(biāo)注 function addMarker(point, index){ // 創(chuàng)建圖標(biāo)對象 var myIcon = new BMap.Icon("markers.png", new BMap.Size(23, 25), { // 指定定位位置。 // 當(dāng)標(biāo)注顯示在地圖上時(shí),其所指向的地理位置距離圖標(biāo)左上 // 角各偏移10像素和25像素。您可以看到在本例中該位置即是 // 圖標(biāo)中央下端的尖角位置。 offset: new BMap.Size(10, 25), // 設(shè)置圖片偏移。 // 當(dāng)您需要從一幅較大的圖片中截取某部分作為標(biāo)注圖標(biāo)時(shí),您 // 需要指定大圖的偏移位置,此做法與css sprites技術(shù)類似。 imageOffset: new BMap.Size(0, 0 - index * 25) // 設(shè)置圖片偏移 }); // 創(chuàng)建標(biāo)注對象并添加到地圖 var marker = new BMap.Marker(point, {icon: myIcon}); map.addOverlay(marker); } // 隨機(jī)向地圖添加10個標(biāo)注 var bounds = map.getBounds(); var lngSpan = bounds.maxX - bounds.minX; var latSpan = bounds.maxY - bounds.minY; for (var i = 0; i < 10; i ++) { var point = new BMap.Point(bounds.minX + lngSpan * (Math.random() * 0.7 + 0.15), bounds.minY + latSpan * (Math.random() * 0.7 + 0.15)); addMarker(point, i); }
監(jiān)聽標(biāo)注事件
事件方法與Map事件機(jī)制相同??蓞⒖际录糠帧?/p>
marker.addEventListener("click", function(){ alert("您點(diǎn)擊了標(biāo)注"); });
可托拽的標(biāo)注
marker的enableDragging和disableDragging方法可用來開啟和關(guān)閉標(biāo)注的拖拽功能。默認(rèn)情況下標(biāo)注不支持拖拽,您需要調(diào)用marker.enableDragging()方法來開啟拖拽功能。在標(biāo)注開啟拖拽功能后,您可以監(jiān)聽標(biāo)注的dragend事件來捕獲拖拽后標(biāo)注的最新位置。
marker.enableDragging(); marker.addEventListener("dragend", function(e){ alert("當(dāng)前位置:" + e.point.lng + ", " + e.point.lat); })
內(nèi)存釋放
在API 1.0版本中,如果您需要在地圖中反復(fù)添加大量的標(biāo)注,這可能會占用較多的內(nèi)存資源。如果您的標(biāo)注在移除后不再使用,可調(diào)用Overlay.dispose()方法來釋放內(nèi)存。注意在1.0版本中,調(diào)用此方法后標(biāo)注將不能再次添加到地圖上。自1.1版本開始,您不在需要使用此方法來釋放內(nèi)存資源,API會自動幫助您完成此工作。
例如,您可以在標(biāo)注被移除后調(diào)用此方法:
map.removeOverlay(marker); marker.dispose(); // 1.1 版本不需要這樣調(diào)用
信息窗口
信息窗口在地圖上方的浮動顯示HTML內(nèi)容。信息窗口可直接在地圖上的任意位置打開,也可以在標(biāo)注對象上打開(此時(shí)信息窗口的坐標(biāo)與標(biāo)注的坐標(biāo)一致)。 您可以使用InfoWindow來創(chuàng)建一個信息窗實(shí)例,注意同一時(shí)刻地圖上只能有一個信息窗口處于打開狀態(tài)。
var opts = { width : 250, // 信息窗口寬度 height: 100, // 信息窗口高度 title : "Hello" // 信息窗口標(biāo)題 } var infoWindow = new BMap.InfoWindow("World", opts); // 創(chuàng)建信息窗口對象 map.openInfoWindow(infoWindow, map.getCenter()); // 打開信息窗口
折線
Polyline表示地圖上的折線覆蓋物。它包含一組點(diǎn),并將這些點(diǎn)連接起來形成折線。
添加折線
折線在地圖上繪制為一系列直線段??梢宰远x這些線段的顏色、粗細(xì)和透明度。顏色可以是十六進(jìn)制數(shù)字形式(比如:#ff0000)或者是顏色關(guān)鍵字(比如:red)。
Polyline的繪制需要瀏覽器支持矢量繪制功能。在Internet Explorer中,地圖使用VML繪制折線;在其他瀏覽器中使用SVG或者Canvas
以下代碼段會在兩點(diǎn)之間創(chuàng)建6像素寬的藍(lán)色折線:
var polyline = new BMap.Polyline([ new BMap.Point(116.399, 39.910), new BMap.Point(116.405, 39.920) ], {strokeColor:"blue", strokeWeight:6, strokeOpacity:0.5} ); map.addOverlay(polyline);
自定義覆蓋物
API自1.1版本起支持用戶自定義覆蓋物。
要創(chuàng)建自定義覆蓋物,您需要做以下工作:
1.定義一個自定義覆蓋物的構(gòu)造函數(shù),通過構(gòu)造函數(shù)參數(shù)可以傳遞一些自由的變量。
2.設(shè)置自定義覆蓋物對象的prototype屬性為Overlay的實(shí)例,以便繼承覆蓋物基類。
3.實(shí)現(xiàn)initialize方法,當(dāng)調(diào)用map.addOverlay方法時(shí),API會調(diào)用此方法。
4.實(shí)現(xiàn)draw方法。
定義構(gòu)造函數(shù)并繼承Overlay
首先您需要定義自定義覆蓋物的構(gòu)造函數(shù),在下面的示例中我們定義一個名為SquareOverlay的構(gòu)造函數(shù),它包含中心點(diǎn)和邊長兩個參數(shù),用來在地圖上創(chuàng)建一個方形覆蓋物。
// 定義自定義覆蓋物的構(gòu)造函數(shù) function SquareOverlay(center, length, color){ this._center = center; this._length = length; this._color = color; } // 繼承API的BMap.Overlay SquareOverlay.prototype = new BMap.Overlay();
初始化自定義覆蓋物
當(dāng)調(diào)用map.addOverlay方法添加自定義覆蓋物時(shí),API會調(diào)用該對象的initialize方法用來初始化覆蓋物,在初始化過程中需要創(chuàng)建覆蓋物所需要的DOM元素,并添加到地圖相應(yīng)的容器中。
地圖提供了若干容器供覆蓋物展示,通過map.getPanes方法可以得到這些容器元素,它們包括:
floatPane
markerMouseTarget
floatShadow
labelPane
markerPane
mapPane
這些對象代表了不同的覆蓋物容器元素,它們之間存在著覆蓋關(guān)系,最上一層為floatPane,用于顯示信息窗口內(nèi)容,下面依次為標(biāo)注點(diǎn)擊區(qū)域?qū)印⑿畔⒋翱陉幱皩?、文本?biāo)注層、標(biāo)注層和矢量圖形層。
我們自定義的方形覆蓋物可以添加到任意圖層上,這里我們選擇添加到markerPane上,作為其一個子結(jié)點(diǎn)。
// 實(shí)現(xiàn)初始化方法 SquareOverlay.prototype.initialize = function(map){ // 保存map對象實(shí)例 this._map = map; // 創(chuàng)建div元素,作為自定義覆蓋物的容器 var div = document.createElement("div"); div.style.position = "absolute"; // 可以根據(jù)參數(shù)設(shè)置元素外觀 div.style.width = this._length + "px"; div.style.height = this._length + "px"; div.style.background = this._color; // 將div添加到覆蓋物容器中 map.getPanes().markerPane.appendChild(div); // 保存div實(shí)例 this._div = div; // 需要將div元素作為方法的返回值,當(dāng)調(diào)用該覆蓋物的show、 // hide方法,或者對覆蓋物進(jìn)行移除時(shí),API都將操作此元素。 return div;
繪制覆蓋物
到目前為止,我們僅僅把覆蓋物添加到了地圖上,但是并沒有將它放置在正確的位置上。您需要在draw方法中設(shè)置覆蓋物的位置,每當(dāng)?shù)貓D狀態(tài)發(fā)生變化(比如:位置移動、級別變化)時(shí),API都會調(diào)用覆蓋物的draw方法,用于重新計(jì)算覆蓋物的位置。通過map.pointToOverlayPixel方法可以將地理坐標(biāo)轉(zhuǎn)換到覆蓋物的所需要的像素坐標(biāo)。
// 實(shí)現(xiàn)繪制方法 SquareOverlay.prototype.draw = function(){ // 根據(jù)地理坐標(biāo)轉(zhuǎn)換為像素坐標(biāo),并設(shè)置給容器 var position = this._map.pointToOverlayPixel(this._center); this._div.style.left = position.x - this._length / 2 + "px"; this._div.style.top = position.y - this._length / 2 + "px"; }
移除覆蓋物
當(dāng)調(diào)用map.removeOverlay或者map.clearOverlays方法時(shí),API會自動將initialize方法返回的DOM元素進(jìn)行移除。
顯示和隱藏覆蓋物
自定義覆蓋物會自動繼承Overlay的show和hide方法,方法會修改由initialize方法返回的DOM元素的style.display屬性。如果自定義覆蓋物元素較為復(fù)雜,您也可以自己實(shí)現(xiàn)show和hide方法。
// 實(shí)現(xiàn)顯示方法 SquareOverlay.prototype.show = function(){ if (this._div){ this._div.style.display = ""; } } // 實(shí)現(xiàn)隱藏方法 SquareOverlay.prototype.hide = function(){ if (this._div){ this._div.style.display = "none"; } }
自定義其他方法 通過構(gòu)造函數(shù)的prototype屬性,您可以添加任何自定義的方法,比如下面這個方法每調(diào)用一次就能改變覆蓋物的顯示狀態(tài):
// 添加自定義方法 SquareOverlay.prototype.toggle = function(){ if (this._div){ if (this._div.style.display == ""){ this.hide(); } else { this.show(); } } }
添加覆蓋物
您現(xiàn)在已經(jīng)完成了一個完整的自定義覆蓋物的編寫,可以添加到地圖上了。
// 初始化地圖 var map = new BMap.Map("container"); var point = new BMap.Point(116.404, 39.915); map.centerAndZoom(point, 15); // 添加自定義覆蓋物 var mySquare = new SquareOverlay(map.getCenter(), 100, "red"); map.addOverlay(mySquare);