自定義覆蓋物
API自1.1版本起支持用戶自定義覆蓋物。
要?jiǎng)?chuàng)建自定義覆蓋物,您需要做以下工作:
1.定義一個(gè)自定義覆蓋物的構(gòu)造函數(shù),通過(guò)構(gòu)造函數(shù)參數(shù)可以傳遞一些自由的變量。
2.設(shè)置自定義覆蓋物對(duì)象的prototype屬性為Overlay的實(shí)例,以便繼承覆蓋物基類。
3.實(shí)現(xiàn)initialize方法,當(dāng)調(diào)用map.addOverlay方法時(shí),API會(huì)調(diào)用此方法。
4.實(shí)現(xiàn)draw方法。
定義構(gòu)造函數(shù)并繼承Overlay
首先您需要定義自定義覆蓋物的構(gòu)造函數(shù),在下面的示例中我們定義一個(gè)名為SquareOverlay的構(gòu)造函數(shù),它包含中心點(diǎn)和邊長(zhǎng)兩個(gè)參數(shù),用來(lái)在地圖上創(chuàng)建一個(gè)方形覆蓋物。
// 定義自定義覆蓋物的構(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會(huì)調(diào)用該對(duì)象的initialize方法用來(lái)初始化覆蓋物,在初始化過(guò)程中需要?jiǎng)?chuàng)建覆蓋物所需要的DOM元素,并添加到地圖相應(yīng)的容器中。
地圖提供了若干容器供覆蓋物展示,通過(guò)map.getPanes方法可以得到這些容器元素,它們包括:
floatPane
markerMouseTarget
floatShadow
labelPane
markerPane
mapPane
這些對(duì)象代表了不同的覆蓋物容器元素,它們之間存在著覆蓋關(guān)系,最上一層為floatPane,用于顯示信息窗口內(nèi)容,下面依次為標(biāo)注點(diǎn)擊區(qū)域?qū)印⑿畔⒋翱陉幱皩?、文本?biāo)注層、標(biāo)注層和矢量圖形層。
我們自定義的方形覆蓋物可以添加到任意圖層上,這里我們選擇添加到markerPane上,作為其一個(gè)子結(jié)點(diǎn)。
// 實(shí)現(xiàn)初始化方法
SquareOverlay.prototype.initialize = function(map){
// 保存map對(duì)象實(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方法,或者對(duì)覆蓋物進(jìn)行移除時(shí),API都將操作此元素。
return div;
}
繪制覆蓋物
到目前為止,我們僅僅把覆蓋物添加到了地圖上,但是并沒(méi)有將它放置在正確的位置上。您需要在draw方法中設(shè)置覆蓋物的位置,每當(dāng)?shù)貓D狀態(tài)發(fā)生變化(比如:位置移動(dòng)、級(jí)別變化)時(shí),API都會(huì)調(diào)用覆蓋物的draw方法,用于重新計(jì)算覆蓋物的位置。通過(guò)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會(huì)自動(dòng)將initialize方法返回的DOM元素進(jìn)行移除。
顯示和隱藏覆蓋物
自定義覆蓋物會(huì)自動(dòng)繼承Overlay的show和hide方法,方法會(huì)修改由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";
}
}
自定義其他方法 通過(guò)構(gòu)造函數(shù)的prototype屬性,您可以添加任何自定義的方法,比如下面這個(gè)方法每調(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)完成了一個(gè)完整的自定義覆蓋物的編寫(xiě),可以添加到地圖上了。
// 初始化地圖
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);
實(shí)現(xiàn)上圖效果的JS代碼示例:
<script type="text/javascript">
// 創(chuàng)建Map實(shí)例
var mp = new BMap.Map("allmap", {enableMapClick:false});
// 設(shè)置地圖背景色為白色
mp.getContainer().style.background = '#FFF';
var point = new BMap.Point(110.1, 35.1);
// 默認(rèn)顯示中心點(diǎn)和地圖層級(jí)
mp.centerAndZoom(point, 5);
mp.addControl(new BMap.NavigationControl());
mp.addControl(new BMap.NavigationControl());
//顯示比例尺在右下角
mp.addControl(new BMap.ScaleControl({anchor: BMAP_ANCHOR_BOTTOM_RIGHT, isOpen: true}));
//右上角顯示電子地圖和衛(wèi)星圖切換
mp.addControl(new BMap.MapTypeControl({mapTypes: [BMAP_NORMAL_MAP,BMAP_SATELLITE_MAP]}));
mp.enableScrollWheelZoom(); // 啟用滾輪放大縮小。
mp.enableKeyboard(); // 啟用鍵盤(pán)操作。
mp.enableContinuousZoom(); //啟用連續(xù)縮放效果
function ComplexCustomOverlay(point, text, mouseoverText){
this._point = point;
this._text = text;
this._overText = mouseoverText;
}
ComplexCustomOverlay.prototype = new BMap.Overlay();
ComplexCustomOverlay.prototype.initialize = function(map){
this._map = map;
var div = this._div = document.createElement("div");
div.style.position = "absolute";
div.style.zIndex = BMap.Overlay.getZIndex(this._point.lat);
div.style.backgroundColor = "#EE5D5B";
div.style.border = "1px solid #BC3B3A";
div.style.color = "white";
div.style.height = "18px";
div.style.padding = "2px";
div.style.lineHeight = "18px";
div.style.whiteSpace = "nowrap";
div.style.MozUserSelect = "none";
div.style.fontSize = "12px"
var span = this._span = document.createElement("span");
div.appendChild(span);
span.appendChild(document.createTextNode(this._text));
var that = this;
var arrow = this._arrow = document.createElement("div");
arrow.style.background = "url(images/label.png) no-repeat";
arrow.style.position = "absolute";
arrow.style.width = "11px";
arrow.style.height = "10px";
arrow.style.top = "22px";
arrow.style.left = "10px";
arrow.style.overflow = "hidden";
div.appendChild(arrow);
div.onmouseover = function(){
this.style.backgroundColor = "#6BADCA";
this.style.borderColor = "#0000ff";
this.getElementsByTagName("span")[0].innerHTML = that._overText;
arrow.style.backgroundPosition = "0px -20px";
}
div.onmouseout = function(){
this.style.backgroundColor = "#EE5D5B";
this.style.borderColor = "#BC3B3A";
this.getElementsByTagName("span")[0].innerHTML = that._text;
arrow.style.backgroundPosition = "0px 0px";
}
mp.getPanes().labelPane.appendChild(div);
return div;
}
ComplexCustomOverlay.prototype.draw = function(){
var map = this._map;
var pixel = map.pointToOverlayPixel(this._point);
this._div.style.left = pixel.x - parseInt(this._arrow.style.left) + "px";
this._div.style.top = pixel.y - 30 + "px";
}
var txt = "銀湖海岸城", mouseoverTxt = txt + " " + parseInt(Math.random() * 1000,10)
+ "套" ;
var myCompOverlay = new ComplexCustomOverlay(new BMap.Point(116.407845,39.914101),
"銀湖海岸城",mouseoverTxt);
mp.addOverlay(myCompOverlay);
</script>