繪圖庫
本文檔中的概念僅适用于
google.maps.drawing
庫中提供的地圖項。預設情況下,系統在加載 Maps JavaScript API 時不會加載該庫,您必須使用
libraries
引導程式參數進行明确指定。
http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing
DrawingManager
類提供了一個圖形界面,以供使用者在地圖上繪制多邊形、矩形、折線、圓形和标記。
DrawingManager
對象以如下方式建立:
var drawingManager = new google.maps.drawing.DrawingManager();
drawingManager.setMap(map);
DrawingManager 選項
DrawingManager
構造函數采用一組選項,以定義要顯示的控件集、控件的位置以及初始繪圖狀态。
-
的DrawingManager
屬性用于定義 DrawingManager 的初始繪圖狀态。該屬性接受drawingMode
常量,且預設為google.maps.drawing.OverlayType
(在此情況下啟動 DrawingManager 時,光标會處于非繪圖模式)。null
-
的DrawingManager
屬性用于定義地圖上的繪圖工具選擇界面的可見性。該屬性接受布爾值。drawingControl
- 您還可以使用
的DrawingManager
屬性,定義控件的位置以及控件中應表示的疊加層的類型。drawingControlOptions
-
用于定義繪圖控件在地圖上的位置,且接受position
常量。google.maps.ControlPosition
-
是一組drawingModes
常量,且用于定義繪圖控件形狀選擇器中包含的疊加層類型。系統将始終顯示手形圖示,以便使用者無需繪圖即可與地圖進行互動。google.maps.drawing.OverlayType
-
- 您可為每種疊加層類型都指定一組預設屬性,以便定義首次建立相應疊加層時所采用的外觀。這些屬性可在疊加層的
屬性(其中{overlay}Options
表示疊加層的類型)中進行定義。例如,圓形的填充屬性、筆觸屬性、zIndex 和可點選性可使用{overlay}
屬性進行定義。如果已傳遞任何大小、位置或地圖值,則系統會忽略這些預設屬性。circleOptions
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [google.maps.drawing.OverlayType.MARKER, google.maps.drawing.OverlayType.CIRCLE]
},
markerOptions: {
icon: new google.maps.MarkerImage('http://www.example.com/icon.png')
},
circleOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
zIndex: 1,
editable: true
}
});
drawingManager.setMap(map);
更新繪圖工具控件
建立
DrawingManager
對象後,您可調用
setOptions()
并傳遞新的值,以進行更新。
drawingManager.setOptions({
drawingControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT,
drawingModes: [google.maps.drawing.OverlayType.MARKER]
}
});
使用以下方法即可隐藏或顯示繪圖工具控件:
// To hide:
drawingManager.setOptions({
drawingControl: false
});
// To show:
drawingManager.setOptions({
drawingControl: true
});
要從
map
對象删除繪圖工具控件,請使用以下方法:
隐藏繪圖控件會導緻繪圖工具控件無法顯示,不過
DrawingManager
類的所有功能仍然可用。這樣即可實作您自己的控件(如有必要)。從
map
對象删除
DrawingManager
會導緻所有繪圖功能停用;要恢複繪圖地圖項,請務必使用
drawingManager.setMap(map)
将
DrawingManager
對象重新附加到地圖,或者構造新的該對象。
繪圖事件
建立形狀疊加層後,會觸發以下兩個事件:
-
事件(其中{overlay}complete
代表疊加層類型,例如{overlay}
、circlecomplete
等)。對相應疊加層的引用會作為參數進行傳遞。polygoncomplete
-
事件。包含overlaycomplete
和對相應疊加層的引用的對象常量會作為參數進行傳遞。OverlayType
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
var radius = circle.getRadius();
});
google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
if (event.type == google.maps.drawing.OverlayType.CIRCLE) {
var radius = event.overlay.getRadius();
}
});
資訊視窗
InfoWindow
用于在地圖上方以浮動視窗的形式顯示内容。資訊視窗有點像漫畫書上的文字氣泡框,它有一個内容區域和一條錐形引線,引線的頭位于地圖的指定位置上。點選 Google 地圖上的商戶标記後,您就可以看到活動的資訊視窗了。
InfoWindow
構造函數采用
InfoWindow options
對象,以指定一組關于資訊視窗的顯示方式的初始參數。建立完畢後,所生成的資訊視窗不會添加到地圖上。要顯示該資訊視窗,您需要對
InfoWindow
調用
open()
方法,并向其傳遞要在其上打開資訊視窗的
Map
,以及用于錨定該資訊視窗的
Marker
(可選)。(如果未提供任何标記,則會在該資訊視窗的
position
屬性處将其打開。)
InfoWindow options
對象是一個包含以下字段的對象常量:
-
,其中包含要在資訊視窗打開後顯示在其中的文本字元串或 DOM 節點。content
-
,其中包含從資訊視窗的尖端到其錨定位置的偏移量。實際上,您無需修改此字段。pixelOffset
-
,其中包含此資訊視窗錨定位置處的position
。請注意,在标記上打開資訊視窗後,系統會自動使用一個新位置更新該值。LatLng
-
,用于指定資訊視窗的最大寬度(以像素為機關)。預設情況下,資訊視窗會根據其内容進行擴充,并且如果是為填充地圖而進行擴充的,則其文本會自動換行。如果您實作了maxWidth
,那麼資訊視窗将會自動換行以強制适應像素寬度。如果螢幕的實際使用面積允許的話,那麼資訊視窗在達到最大寬度後仍然可以垂直擴充。maxWidth
InfoWindow
的内容可以是文本字元串、HTML 代碼段,也可以就是 DOM 元素。要設定此内容,請在
InfoWindow options
構造函數中傳遞該内容,或者對資訊視窗顯式調用
setContent()
。要顯式調整内容的大小,您可以使用
<div>
進行調整,或者啟用滾動功能(如果您希望的話)。請注意,如果您沒有啟用滾動功能,且内容的大小又超出了資訊視窗的可用空間,那麼内容可能會從資訊視窗中“溢”出。
您可以将
InfoWindow
附加到
Marker
對象(在此情況下,資訊視窗的位置取決于标記的位置)上,或者地圖上所指定的
LatLng
位置。如果您一次隻想顯示一個資訊視窗(正如 Google 地圖上的相應行為),隻需建立一個資訊視窗,然後在地圖事件(例如使用者點選)完畢後将其重新配置設定到不同的位置或标記即可。不過與 Google Maps API V2 中的相應行為不同,如果您選擇執行以上操作,那麼地圖可能會立即顯示多個
InfoWindow
對象。
要更改某個資訊視窗的位置,您可以對該資訊視窗調用
setPosition()
以顯式更改其位置,或者使用
InfoWindow.open()
方法将其附加到新标記。請注意,如果您在沒有傳遞标記的情況下調用了
open()
,那麼
InfoWindow
将會使用建構完畢後通過
InfoWindow options
對象所指定的位置。
以下代碼顯示了澳洲中心位置的标記。點選該标記可顯示資訊視窗。
var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var mapOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var contentString = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h2 id="firstHeading" class="firstHeading">Uluru</h2>'+
'<div id="bodyContent">'+
'<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
'sandstone rock formation in the southern part of the '+
'Northern Territory, central Australia. It lies 335 km (208 mi) '+
'south west of the nearest large town, Alice Springs; 450 km '+
'(280 mi) by road. Kata Tjuta and Uluru are the two major '+
'features of the Uluru - Kata Tjuta National Park. Uluru is '+
'sacred to the Pitjantjatjara and Yankunytjatjara, the '+
'Aboriginal people of the area. It has many springs, waterholes, '+
'rock caves and ancient paintings. Uluru is listed as a World '+
'Heritage Site.</p>'+
'<p>Attribution: Uluru, <a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194" target="_blank" rel="external nofollow" >'+
'http://en.wikipedia.org/w/index.php?title=Uluru</a> (last visited June 22, 2009).</p>'+
'</div>'+
'</div>';
var infowindow = new google.maps.InfoWindow({
content: contentString
});
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title:"Uluru (Ayers Rock)"
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
地面疊加層
多邊形在表示不規則的區域時很有用,但不能顯示圖檔。要在地圖上放置一張圖檔,請使用
GroundOverlay
對象。
GroundOverlay
的構造函數指定圖檔的網址和
LatLngBounds
作為參數。圖檔将在地圖上的給定邊界内呈現,并與地圖的投影一緻。
以下示例将紐澤西州紐瓦克的一幅老地圖作為疊加層放在地圖上:
var newark = new google.maps.LatLng(40.740, -74.18);
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(40.716216,-74.213393),
new google.maps.LatLng(40.765641,-74.139235));
var mapOptions = {
zoom: 13,
center: newark,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var oldmap = new google.maps.GroundOverlay(
"http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg",
imageBounds);
oldmap.setMap(map);
自定義疊加層
Google Maps API V3 提供了用于建立自定義疊加層的
OverlayView
類。
OverlayView
是一個基類,可為您提供在建立疊加層時必須實作的若幹方法。該類還提供了一些方法,用于實作螢幕坐标和地圖位置之間的轉換。
要建立自定義疊加層,請執行以下操作:
- 将自定義對象的
設定為prototype
的新執行個體。這可以有效地實作疊加層類的“子類化”。google.maps.OverlayView()
- 為自定義疊加層建立構造函數,并将該構造函數中的所有初始化參數都設定為自定義屬性。
- 在原型中實作
方法,以将疊加層附加到地圖。在地圖準備好附加疊加層後,系統将會調用onAdd()
。OverlayView.onAdd()
- 在原型中實作
方法,以處理對象的視覺顯示。同樣,在對象首次顯示後,系統将會調用draw()
。OverlayView.draw()
- 您還應實作
方法,以清理疊加層中添加的所有元素。onRemove()
我們将會在以下各部分中逐漸介紹這些操作。
疊加層的子類化
我們将會使用
OverlayView
建立簡單的圖檔疊加層(類似于 V2 API 中的
GGroundOverlay
)。我們将建立一個
USGSOverlay
對象,其中包含了相關區域的 USGS 圖檔以及該圖檔的邊界。
var overlay;
function initialize() {
var myLatLng = new google.maps.LatLng(62.323907, -150.109291);
var mapOptions = {
zoom: 11,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var swBound = new google.maps.LatLng(62.281819, -150.287132);
var neBound = new google.maps.LatLng(62.400471, -150.005608);
var bounds = new google.maps.LatLngBounds(swBound, neBound);
// Photograph courtesy of the U.S. Geological Survey
var srcImage = 'images/talkeetna.png';
overlay = new USGSOverlay(bounds, srcImage, map);
}
接下來,我們将建立一個該類的構造函數,并将已傳遞的參數初始化為新對象的屬性。此外,我們還需要顯式地将
OverlayView
中的
USGSOverlay
子類化。為此,我們會将新類的
prototype
設為相應父類的一個執行個體。(由于我們不希望修改父類,是以将此處的原型設為了執行個體,而非該父類。)
function USGSOverlay(bounds, image, map) {
// Now initialize all properties.
this.bounds_ = bounds;
this.image_ = image;
this.map_ = map;
// We define a property to hold the image's
// div. We'll actually create this div
// upon receipt of the add() method so we'll
// leave it null for now.
this.div_ = null;
// Explicitly call setMap() on this overlay
this.setMap(map);
}
USGSOverlay.prototype = new google.maps.OverlayView();
目前,我們還無法在疊加層的構造函數中将此疊加層附加到地圖上。具體而言,我們需要確定所有的地圖窗格(用于指定對象在地圖上的顯示順序)都可用。API 提供了一種幫助程式方法,可以非常友善地表明是否執行了上述操作。我們将會在下一部分中介紹如何處理該方法。
初始化疊加層
當疊加層完成首次示例化并處于準備顯示狀态時,我們需要通過浏覽器的 DOM 将其附加到地圖。API 會顯示相關資訊以表明:系統已認證調用疊加層的
onAdd()
方法将其添加到地圖。在處理此方法時,我們會建立一個用于存儲圖檔的
<div>
,然後添加一個
<img>
元素并将其附加到
<div>
,最後将疊加層附加到地圖的一個“窗格”(即 DOM 樹中的節點)。
一組
MapPanes
類型的窗格用于指定不同的層在地圖上的堆疊順序。您可以使用以下窗格,并按以下枚舉順序(由下至上,第一個窗格在最下面)堆疊這些窗格:
-
MapPanes.mapPane
-
MapPanes.overlayLayer
-
MapPanes.overlayShadow
-
MapPanes.overlayImage
-
MapPanes.floatShadow
-
MapPanes.overlayMouseTarget
-
MapPanes.floatPane
由于我們的圖檔為“地面疊加層”,是以将會使用
overlayLayer
地圖窗格。建立該窗格後,我們将以子對象的形式向其附加對象。
USGSOverlay.prototype.onAdd = function() {
// Note: an overlay's receipt of onAdd() indicates that
// the map's panes are now available for attaching
// the overlay to the map via the DOM.
// Create the DIV and set some basic attributes.
var div = document.createElement('div');
div.style.border = "none";
div.style.borderWidth = "0px";
div.style.position = "absolute";
// Create an IMG element and attach it to the DIV.
var img = document.createElement("img");
img.src = this.image_;
img.style.width = "100%";
img.style.height = "100%";
div.appendChild(img);
// Set the overlay's div_ property to this DIV
this.div_ = div;
// We add an overlay to a map via one of the map's panes.
// We'll add this overlay to the overlayImage pane.
var panes = this.getPanes();
panes.overlayLayer.appendChild(div);
}
繪制疊加層
請注意,在上述操作中,我們實際上并未調用任何特殊的視覺顯示。每當需要在地圖上繪制疊加層時(包括首次添加疊加層時),API 都會對疊加層調用獨立的
draw()
方法。
是以,我們将會實作此
draw()
方法,然後使用
getProjection()
檢索疊加層的
MapCanvasProjection
,并計算對象的右上角和左下角錨定點的準确坐标,進而重新調整
<div>
的大小;同時,此操作還可重新調整圖檔的大小,以使其與我們在疊加層的構造函數中所指定的範圍相比對。
USGSOverlay.prototype.draw = function() {
// Size and position the overlay. We use a southwest and northeast
// position of the overlay to peg it to the correct position and size.
// We need to retrieve the projection from this overlay to do this.
var overlayProjection = this.getProjection();
// Retrieve the southwest and northeast coordinates of this overlay
// in latlngs and convert them to pixels coordinates.
// We'll use these coordinates to resize the DIV.
var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
// Resize the image's DIV to fit the indicated dimensions.
var div = this.div_;
div.style.left = sw.x + 'px';
div.style.top = ne.y + 'px';
div.style.width = (ne.x - sw.x) + 'px';
div.style.height = (sw.y - ne.y) + 'px';
}
删除疊加層
我們還會添加
onRemove()
方法,以便從地圖徹底删除疊加層。如果之前将疊加層的
map
屬性設為了
null
,那麼系統将會自動通過 API 調用此方法。
USGSOverlay.prototype.onRemove = function() {
this.div_.parentNode.removeChild(this.div_);
this.div_ = null;
}
隐藏和顯示疊加層
如果您想要隐藏或顯示(而不隻是建立或删除)疊加層,您可實作自己的
hide()
和
show()
方法,以調整疊加層的可見性。此外,您也可以将疊加層與地圖的 DOM 分離,不過此操作的成本略高。請注意,如果您随後将疊加層重新附加到了地圖的 DOM,那麼系統将會重新調用疊加層的
onAdd()
方法。
以下示例介紹了如何将
hide()
和
show()
方法添加到疊加層的原型,以切換容器
<div>
的可見性。此外,我們還添加了
toogleDOM()
方法,該方法可将疊加層附加到地圖,或将兩者分離開來。請注意,如果我們将可見性設為
"hidden"
,那麼系統會通過
toggleDOM()
将地圖與 DOM 分離;如果我們稍後重新附加了地圖,那麼疊加層會再次顯示出來,這是因為我們利用疊加層的
onAdd()
方法重新建立了其中所包含的
<div>
。
// Note that the visibility property must be a string enclosed in quotes
USGSOverlay.prototype.hide = function() {
if (this.div_) {
this.div_.style.visibility = "hidden";
}
}
USGSOverlay.prototype.show = function() {
if (this.div_) {
this.div_.style.visibility = "visible";
}
}
USGSOverlay.prototype.toggle = function() {
if (this.div_) {
if (this.div_.style.visibility == "hidden") {
this.show();
} else {
this.hide();
}
}
}
USGSOverlay.prototype.toggleDOM = function() {
if (this.getMap()) {
this.setMap(null);
} else {
this.setMap(this.map_);
}
}
// Now we add an input button to initiate the toggle method
// on the specific overlay
<div id ="toolbar" width="100%; height:20px;" style="text-align:center">
<input type="button" value="Toggle Visibility" οnclick="overlay.toggle();"></input>
<input type="button" value="Toggle DOM Attachment" οnclick="overlay.toggleDOM();"></input>
</div>
<div id="map_canvas" style="width: 100%; height: 95%;"></div>