覆蓋物
地圖覆蓋物概述
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標註、向量圖形元素(包括:折線和多邊形和圓)、資訊視窗等。覆蓋物擁有自己的地理座標,當您拖曳或縮放地圖時,它們會相應的移動。
地圖API提供瞭如下幾種覆蓋物:
Overlay:覆蓋物的抽象基類,所有的覆蓋物均繼承此類的方法。
Marker:標註表示地圖上的點,可自訂標註的圖示。
Label:表示地圖上的文字標註,您可以自訂標註的文字內容。
Polyline:表示地圖上的折線。
Polygon:表示地圖上的多邊形。多邊形類似於閉合的折線,另外您也可以為其添加填滿顏色。
Circle: 表示地圖上的圓。
InfoWindow:資訊視窗也是一種特殊的覆蓋物,它可以展示更豐富的文字和多媒體訊息。注意:同一時刻只能有一個資訊視窗在地圖上開啟。
可以使用map.addOverlay方法在地圖上新增覆蓋物,使用map.removeOverlay方法移除覆蓋物,注意此方法不適用於InfoWindow。
標註
標註表示地圖上的點。 API提供了預設圖示樣式,您也可以透過Icon類別來指定自訂圖示。 Marker的建構子的參數為Point和MarkerOptions(可選)。注意:當您使用自訂圖示時,標註的地理座標點將位於標註所用圖示的中心位置,您可透過Icon的offset屬性修改標定位置。
下面的範例在地圖中心點上新增了一個標註,並使用預設的標註樣式。
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); // 创建标注 map.addOverlay(marker); // 将标注添加到地图中
#定義標註圖標
透過Icon類別可實現自訂標註的圖標,下面範例透過參數MarkerOptions的icon屬性進行設置,您也可以使用marker.setIcon()方法。
var map = new BMap.Map("container"); var point = new BMap.Point(116.404, 39.915); map.centerAndZoom(point, 15); // 编写自定义函数,创建标注 function addMarker(point, index){ // 创建图标对象 var myIcon = new BMap.Icon("markers.png", new BMap.Size(23, 25), { // 指定定位位置。 // 当标注显示在地图上时,其所指向的地理位置距离图标左上 // 角各偏移10像素和25像素。您可以看到在本例中该位置即是 // 图标中央下端的尖角位置。 offset: new BMap.Size(10, 25), // 设置图片偏移。 // 当您需要从一幅较大的图片中截取某部分作为标注图标时,您 // 需要指定大图的偏移位置,此做法与css sprites技术类似。 imageOffset: new BMap.Size(0, 0 - index * 25) // 设置图片偏移 }); // 创建标注对象并添加到地图 var marker = new BMap.Marker(point, {icon: myIcon}); map.addOverlay(marker); } // 随机向地图添加10个标注 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); }
監聽標註事件
事件方法與Map事件機制相同。可參考事件部分。
marker.addEventListener("click", function(){ alert("您点击了标注"); });
可托拽的標註
marker的enableDragging和disableDragging方法可用來開啟和關閉標註的拖曳功能。預設標示不支援拖曳,您需要呼叫marker.enableDragging()方法來開啟拖曳功能。在標示開啟拖曳功能後,您可以監聽標示的dragend事件來捕捉拖曳後標註的最新位置。
marker.enableDragging(); marker.addEventListener("dragend", function(e){ alert("当前位置:" + e.point.lng + ", " + e.point.lat); })
記憶體釋放
#在API 1.0版本中,如果您需要在地圖中重複添加大量的標註,這可能會佔用較多的記憶體資源。如果您的標註在移除後不再使用,可呼叫Overlay.dispose()方法來釋放記憶體。注意在1.0版本中,呼叫此方法後標註將不能再次加入地圖。自1.1版本開始,您不在需要使用此方法來釋放記憶體資源,API會自動幫助您完成此工作。
例如,您可以在標註被移除後呼叫此方法:
map.removeOverlay(marker); marker.dispose(); // 1.1 版本不需要这样调用
資訊視窗
資訊視窗在地圖上方的浮動顯示HTML內容。資訊視窗可直接在地圖上的任意位置打開,也可以在標註物件上開啟(此時資訊視窗的座標與標註的座標一致)。您可以使用InfoWindow來建立一個資訊窗實例,注意同一時刻地圖上只能有一個資訊視窗處於開啟狀態。
var opts = { width : 250, // 信息窗口宽度 height: 100, // 信息窗口高度 title : "Hello" // 信息窗口标题 } var infoWindow = new BMap.InfoWindow("World", opts); // 创建信息窗口对象 map.openInfoWindow(infoWindow, map.getCenter()); // 打开信息窗口
折線
#Polyline表示地圖上的折線覆蓋物。它包含一組點,並將這些點連接起來形成折線。
新增折線
折線在地圖上繪製為一系列直線段。可以自訂這些線段的顏色、粗細和透明度。顏色可以是十六進位數字形式(例如:#ff0000)或是顏色關鍵字(例如:red)。
Polyline的繪圖需要瀏覽器支援向量繪圖功能。在Internet Explorer中,地圖使用VML繪製折線;在其他瀏覽器中使用SVG或Canvas
以下程式碼段會在兩點之間建立6像素寬的藍色折線:
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版本起支援使用者自訂覆蓋物。
要建立自訂覆蓋物,您需要做以下工作:
1.定義一個自訂覆蓋物的建構函數,透過建構函數參數可以傳遞一些自由的變數。
2.設定自訂覆蓋物物件的prototype屬性為Overlay的實例,以便繼承覆蓋物基底類別。
3.實作initialize方法,當呼叫map.addOverlay方法時,API會呼叫此方法。
4.實作draw方法。
定義建構子並繼承Overlay
首先您需要定義自訂覆蓋物的建構函數,在下面的範例中我們定義一個名為SquareOverlay的建構函數,它包含中心點和邊長兩個參數,用來在地圖上建立一個方形覆蓋物。
// 定义自定义覆盖物的构造函数 function SquareOverlay(center, length, color){ this._center = center; this._length = length; this._color = color; } // 继承API的BMap.Overlay SquareOverlay.prototype = new BMap.Overlay();
初始化自訂覆蓋物
當呼叫map.addOverlay方法新增自訂覆蓋物時,API會呼叫該物件的initialize方法用來初始化覆蓋物,在初始化過程中需要建立覆蓋物所需的DOM元素,並加入地圖對應的容器中。
地圖提供了若干容器供覆蓋物展示,透過map.getPanes方法可以得到這些容器元素,它們包括:
floatPane
markerMouseTarget
floatShadow
#labelPane
markerPane
mapPane
這些物件代表了不同的覆蓋物容器元素,它們之間存在著覆蓋關係,最上一層為floatPane,用於顯示資訊視窗內容,下面依序為標註點選區域圖層、資訊視窗陰影圖層、文字標註圖層、標註圖層和向量圖形圖層。
我們自訂的方形覆蓋物可以添加到任意圖層上,這裡我們選擇添加到markerPane上,作為其一個子結點。
// 实现初始化方法 SquareOverlay.prototype.initialize = function(map){ // 保存map对象实例 this._map = map; // 创建div元素,作为自定义覆盖物的容器 var div = document.createElement("div"); div.style.position = "absolute"; // 可以根据参数设置元素外观 div.style.width = this._length + "px"; div.style.height = this._length + "px"; div.style.background = this._color; // 将div添加到覆盖物容器中 map.getPanes().markerPane.appendChild(div); // 保存div实例 this._div = div; // 需要将div元素作为方法的返回值,当调用该覆盖物的show、 // hide方法,或者对覆盖物进行移除时,API都将操作此元素。 return div;
繪製覆蓋物
到目前為止,我們只是把覆蓋物添加到了地圖上,但是並沒有將它放置在正確的位置。您需要在draw方法中設定覆蓋物的位置,每當地圖狀態改變(例如:位置移動、等級變化)時,API都會呼叫覆蓋物的draw方法,用於重新計算覆蓋物的位置。透過map.pointToOverlayPixel方法可以將地理座標轉換到覆蓋物的所需的像素座標。
// 实现绘制方法 SquareOverlay.prototype.draw = function(){ // 根据地理坐标转换为像素坐标,并设置给容器 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"; }
移除覆蓋物
當呼叫map.removeOverlay或map.clearOverlays方法時,API會自動移除initialize方法傳回的DOM元素。
顯示和隱藏覆蓋物
自訂覆蓋物會自動繼承Overlay的show和hide方法,方法會修改由initialize方法傳回的DOM元素的style. display屬性。如果自訂覆蓋物元素較為複雜,您也可以自己實作show和hide方法。
// 实现显示方法 SquareOverlay.prototype.show = function(){ if (this._div){ this._div.style.display = ""; } } // 实现隐藏方法 SquareOverlay.prototype.hide = function(){ if (this._div){ this._div.style.display = "none"; } }
自訂其他方法 透過建構函數的prototype屬性,您可以加入任何自訂的方法,例如下面這個方法每調用一次就能改變覆蓋物的顯示狀態:
// 添加自定义方法 SquareOverlay.prototype.toggle = function(){ if (this._div){ if (this._div.style.display == ""){ this.hide(); } else { this.show(); } } }
新增覆蓋物
您現在已經完成了一個完整的自訂覆蓋物的編寫,可以新增到地圖上了。
// 初始化地图 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);