覆蓋物


#

地圖覆蓋物概述

所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標註、向量圖形元素(包括:折線和多邊形和圓)、資訊視窗等。覆蓋物擁有自己的地理座標,當您拖曳或縮放地圖時,它們會相應的移動。

地圖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);