這兩天一直在研究百度地圖開放平台的各種好玩的東西,閑暇之余自己動手體驗了一番,果然是妙趣橫生,而且還可以自定義理想中的地圖,不得不說,百度地圖的開放平台為我們的應用提供了很多的便利,之前我們已經學習了地圖的基礎應用和相關的控件的使用,今天,我們繼續深入學習,百度地圖API給我們提供的覆蓋物。
一、地圖覆蓋物概述:
所有疊加或覆蓋到地圖的內容,我們統稱為地圖覆蓋物。如標注、矢量圖形元素(包括:折線和多邊形和圓)、信息窗口等。覆蓋物擁有自己的地理坐標,當您拖動或縮放地圖時,它們會相應的移動。
地圖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);
好啦,關於百度地圖覆蓋物的相關知識我們已經學習的差不多啦,但學以致用,理論和實踐相結合,勤學勤練才是提升自身技能的唯一方法,小伙伴們,加油吧!