簡介
您可以使用標記代表地圖上的位置。標記預設會使用標準圖片,不過,標記可以顯示自訂圖片,而這種標記通常稱為「圖示」。標記和圖示是 Marker
類型的物件。您可以在標記的建構函式內設定自訂圖示,或是針對標記呼叫 setIcon()
。進一步瞭解如何自訂標記圖片。
概括而言,標記是一種疊加層。如要瞭解其他類型的疊加層,請參閱「在地圖上繪圖」一文。
使用者可以與標記互動。舉例來說,標記預設會接收 'click'
事件,因此您可以加入事件監聽器,以在事件發生時開啟資訊視窗並顯示自訂資訊。您可以將標記的 draggable
屬性設為 true
,允許使用者移動地圖上的標記。如要進一步瞭解可拖曳的標記,請參閱下文。
加入標記
google.maps.Marker
結構函式會使用一個 Marker options
物件常值來指定標記的起始屬性。
下列欄位格外重要,通常是在建立標記時設定:
-
position
(必要) 會指定LatLng
來識別標記的起始位置。如要擷取LatLng
,其中一項方法是使用地理編碼服務。 -
map
(選用) 會指定要加入標記的Map
。如果您在建立標記時不指定地圖,這個標記就不會附加到 (或顯示在) 地圖上。如果之後要新增標記,您可以呼叫標記的setMap()
方法。
下例會將簡易標記加進地圖中的澳洲中心點「烏魯魯」:
TypeScript
function initMap(): void { const myLatLng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: myLatLng, } ); new google.maps.Marker({ position: myLatLng, map, title: "Hello World!", }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
function initMap() { const myLatLng = { lat: -25.363, lng: 131.044 }; const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: myLatLng, }); new google.maps.Marker({ position: myLatLng, map, title: "Hello World!", }); } window.initMap = initMap;
測試範例程式碼
上例使用標記選項中的 map
屬性,在建立標記時將標記加進地圖。或者,您也可以使用標記的 setMap()
方法,直接將標記加進地圖,如下例所示:
var myLatlng = new google.maps.LatLng(-25.363882,131.044922); var mapOptions = { zoom: 4, center: myLatlng } var map = new google.maps.Map(document.getElementById("map"), mapOptions); var marker = new google.maps.Marker({ position: myLatlng, title:"Hello World!" }); // To add the marker to the map, call setMap(); marker.setMap(map);
標記的 title
會顯示為工具提示。
如果您不想在標記的建構函式中傳遞任何 Marker options
,可以改為在建構函式最後一個引數中傳遞空白物件 {}
。
移除標記
如要從地圖中移除標記,請呼叫 setMap()
方法,並以引數形式傳遞 null
。
marker.setMap(null);
請注意,上述方法並不會刪除標記,只會從地圖中移除。如果要刪除標記,請先從地圖中移除,然後將標記本身設為 null
。
如要管理一組標記,請建立陣列來存放標記。如要移除標記,您可以使用這個陣列,依序針對當中的每個標記呼叫 setMap()
。如要刪除標記,請從地圖中移除,然後將陣列的 length
設為 0
以移除所有標記參照。
自訂標記圖片
如要自訂標記的視覺外觀,您可以指定要顯示的圖片檔或向量圖示,而非預設的 Google 地圖圖釘圖示。您可以透過標記標籤加入文字,使用複雜圖示定義可點擊的區域,以及設定標記的堆疊順序。
採用圖片圖示的標記
在最基本的情況下,圖示可以指定要使用的圖片,而非預設的 Google 地圖圖釘圖示。如要指定這類圖示,請將標記的 icon
屬性設為圖片的網址。Maps JavaScript API 會自動調整圖示尺寸。
TypeScript
// This example adds a marker to indicate the position of Bondi Beach in Sydney, // Australia. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 4, center: { lat: -33, lng: 151 }, } ); const image = "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"; const beachMarker = new google.maps.Marker({ position: { lat: -33.89, lng: 151.274 }, map, icon: image, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example adds a marker to indicate the position of Bondi Beach in Sydney, // Australia. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 4, center: { lat: -33, lng: 151 }, }); const image = "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png"; const beachMarker = new google.maps.Marker({ position: { lat: -33.89, lng: 151.274 }, map, icon: image, }); } window.initMap = initMap;
測試範例程式碼
採用向量圖示的標記
您可以使用自訂 SVG 向量路徑,定義標記的視覺外觀。方法很簡單,只要將含有所需路徑的 Symbol
物件常值,傳遞至標記的 icon
屬性即可。您可以使用 SVG 路徑標記法定義自訂路徑,也可以使用 google.maps.SymbolPath 中的其中一個預先定義路徑。您必須使用 anchor
屬性,才能在縮放等級變更時正確顯示標記。進一步瞭解如何使用符號來建立向量圖示 (標記和折線適用)。
TypeScript
// This example uses SVG path notation to add a vector-based symbol // as the icon for a marker. The resulting icon is a marker-shaped // symbol with a blue fill and no border. function initMap(): void { const center = new google.maps.LatLng(-33.712451, 150.311823); const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 9, center: center, } ); const svgMarker = { path: "M-1.547 12l6.563-6.609-1.406-1.406-5.156 5.203-2.063-2.109-1.406 1.406zM0 0q2.906 0 4.945 2.039t2.039 4.945q0 1.453-0.727 3.328t-1.758 3.516-2.039 3.070-1.711 2.273l-0.75 0.797q-0.281-0.328-0.75-0.867t-1.688-2.156-2.133-3.141-1.664-3.445-0.75-3.375q0-2.906 2.039-4.945t4.945-2.039z", fillColor: "blue", fillOpacity: 0.6, strokeWeight: 0, rotation: 0, scale: 2, anchor: new google.maps.Point(0, 20), }; new google.maps.Marker({ position: map.getCenter(), icon: svgMarker, map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// This example uses SVG path notation to add a vector-based symbol // as the icon for a marker. The resulting icon is a marker-shaped // symbol with a blue fill and no border. function initMap() { const center = new google.maps.LatLng(-33.712451, 150.311823); const map = new google.maps.Map(document.getElementById("map"), { zoom: 9, center: center, }); const svgMarker = { path: "M-1.547 12l6.563-6.609-1.406-1.406-5.156 5.203-2.063-2.109-1.406 1.406zM0 0q2.906 0 4.945 2.039t2.039 4.945q0 1.453-0.727 3.328t-1.758 3.516-2.039 3.070-1.711 2.273l-0.75 0.797q-0.281-0.328-0.75-0.867t-1.688-2.156-2.133-3.141-1.664-3.445-0.75-3.375q0-2.906 2.039-4.945t4.945-2.039z", fillColor: "blue", fillOpacity: 0.6, strokeWeight: 0, rotation: 0, scale: 2, anchor: new google.maps.Point(0, 20), }; new google.maps.Marker({ position: map.getCenter(), icon: svgMarker, map: map, }); } window.initMap = initMap;
測試範例程式碼
標記標籤
標記標籤是顯示在標記內的字母或數字。本節中的標記圖片會顯示含有字母「B」的標記標籤。您可以指定標記標籤做為字串,或是做為包含字串和其他標籤屬性的 MarkerLabel
物件。
建立標記時,您可以在 MarkerOptions
物件中指定 label
屬性。或者,您也可以針對 Marker 物件呼叫 setLabel()
,在現有標記上設定標籤。
下例會在使用者按下地圖後顯示包含標籤的標記:
TypeScript
// In the following example, markers appear when the user clicks on the map. // Each marker is labeled with a single alphabetical character. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let labelIndex = 0; function initMap(): void { const bangalore = { lat: 12.97, lng: 77.59 }; const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: bangalore, } ); // This event listener calls addMarker() when the map is clicked. google.maps.event.addListener(map, "click", (event) => { addMarker(event.latLng, map); }); // Add a marker at the center of the map. addMarker(bangalore, map); } // Adds a marker to the map. function addMarker(location: google.maps.LatLngLiteral, map: google.maps.Map) { // Add the marker at the clicked location, and add the next-available label // from the array of alphabetical characters. new google.maps.Marker({ position: location, label: labels[labelIndex++ % labels.length], map: map, }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// In the following example, markers appear when the user clicks on the map. // Each marker is labeled with a single alphabetical character. const labels = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let labelIndex = 0; function initMap() { const bangalore = { lat: 12.97, lng: 77.59 }; const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: bangalore, }); // This event listener calls addMarker() when the map is clicked. google.maps.event.addListener(map, "click", (event) => { addMarker(event.latLng, map); }); // Add a marker at the center of the map. addMarker(bangalore, map); } // Adds a marker to the map. function addMarker(location, map) { // Add the marker at the clicked location, and add the next-available label // from the array of alphabetical characters. new google.maps.Marker({ position: location, label: labels[labelIndex++ % labels.length], map: map, }); } window.initMap = initMap;
測試範例程式碼
複雜圖示
您可以指定複雜的形狀來表示可點擊的區域,以及圖示相對於其他疊加層的顯示方式 (即「堆疊順序」)。透過這種方式指定的圖示,應將其中的 icon
屬性設為 Icon
類型的物件。
Icon
物件會定義圖片,也會定義圖示的 size
和 origin
(例如所需圖片是精靈圖的一部分),以及應該放置圖示熱點的 anchor
(以起點為準)。
如果在自訂標記中使用標籤,您可以透過 Icon
物件中的 labelOrigin
屬性調整標籤位置。
TypeScript
// The following example creates complex markers to indicate beaches near // Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond // to the base of the flagpole. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 10, center: { lat: -33.9, lng: 151.2 }, } ); setMarkers(map); } // Data for the markers consisting of a name, a LatLng and a zIndex for the // order in which these markers should display on top of each other. const beaches: [string, number, number, number][] = [ ["Bondi Beach", -33.890542, 151.274856, 4], ["Coogee Beach", -33.923036, 151.259052, 5], ["Cronulla Beach", -34.028249, 151.157507, 3], ["Manly Beach", -33.80010128657071, 151.28747820854187, 2], ["Maroubra Beach", -33.950198, 151.259302, 1], ]; function setMarkers(map: google.maps.Map) { // Adds markers to the map. // Marker sizes are expressed as a Size of X,Y where the origin of the image // (0,0) is located in the top left of the image. // Origins, anchor positions and coordinates of the marker increase in the X // direction to the right and in the Y direction down. const image = { url: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png", // This marker is 20 pixels wide by 32 pixels high. size: new google.maps.Size(20, 32), // The origin for this image is (0, 0). origin: new google.maps.Point(0, 0), // The anchor for this image is the base of the flagpole at (0, 32). anchor: new google.maps.Point(0, 32), }; // Shapes define the clickable region of the icon. The type defines an HTML // <area> element 'poly' which traces out a polygon as a series of X,Y points. // The final coordinate closes the poly by connecting to the first coordinate. const shape = { coords: [1, 1, 1, 20, 18, 20, 18, 1], type: "poly", }; for (let i = 0; i < beaches.length; i++) { const beach = beaches[i]; new google.maps.Marker({ position: { lat: beach[1], lng: beach[2] }, map, icon: image, shape: shape, title: beach[0], zIndex: beach[3], }); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates complex markers to indicate beaches near // Sydney, NSW, Australia. Note that the anchor is set to (0,32) to correspond // to the base of the flagpole. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 10, center: { lat: -33.9, lng: 151.2 }, }); setMarkers(map); } // Data for the markers consisting of a name, a LatLng and a zIndex for the // order in which these markers should display on top of each other. const beaches = [ ["Bondi Beach", -33.890542, 151.274856, 4], ["Coogee Beach", -33.923036, 151.259052, 5], ["Cronulla Beach", -34.028249, 151.157507, 3], ["Manly Beach", -33.80010128657071, 151.28747820854187, 2], ["Maroubra Beach", -33.950198, 151.259302, 1], ]; function setMarkers(map) { // Adds markers to the map. // Marker sizes are expressed as a Size of X,Y where the origin of the image // (0,0) is located in the top left of the image. // Origins, anchor positions and coordinates of the marker increase in the X // direction to the right and in the Y direction down. const image = { url: "https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png", // This marker is 20 pixels wide by 32 pixels high. size: new google.maps.Size(20, 32), // The origin for this image is (0, 0). origin: new google.maps.Point(0, 0), // The anchor for this image is the base of the flagpole at (0, 32). anchor: new google.maps.Point(0, 32), }; // Shapes define the clickable region of the icon. The type defines an HTML // <area> element 'poly' which traces out a polygon as a series of X,Y points. // The final coordinate closes the poly by connecting to the first coordinate. const shape = { coords: [1, 1, 1, 20, 18, 20, 18, 1], type: "poly", }; for (let i = 0; i < beaches.length; i++) { const beach = beaches[i]; new google.maps.Marker({ position: { lat: beach[1], lng: beach[2] }, map, icon: image, shape: shape, title: beach[0], zIndex: beach[3], }); } } window.initMap = initMap;
測試範例程式碼
將 MarkerImage
物件轉換為 Icon
類型
直到 Maps JavaScript API 3.10 版為止,複雜圖示都是定義為 MarkerImage
物件。3.10 版新增的 Icon
物件常值,自 3.11 版起正式取代 MarkerImage
。Icon
物件常值支援的參數與 MarkerImage
相同,因此您只要移除建構函式,將先前的參數包裝在 {}
的參數中,並新增每個參數的名稱,就能輕鬆將 MarkerImage
轉換為 Icon
。舉例來說:
var image = new google.maps.MarkerImage( place.icon, new google.maps.Size(71, 71), new google.maps.Point(0, 0), new google.maps.Point(17, 34), new google.maps.Size(25, 25));
會變成
var image = { url: place.icon, size: new google.maps.Size(71, 71), origin: new google.maps.Point(0, 0), anchor: new google.maps.Point(17, 34), scaledSize: new google.maps.Size(25, 25) };
對標記進行最佳化處理
您可進行最佳化處理來將多個標記算繪為單一靜態元素,藉此提升效能。這個做法在需要使用大量標記時相當實用。根據預設,Maps JavaScript API 會決定是否對標記進行最佳化處理。如有大量標記,Maps JavaScript API 會嘗試在算繪標記時進行最佳化。不過,並不是所有的標記都能最佳化。在某些情況下,Maps JavaScript API 可能需要以不經最佳化處理的方式算繪標記。如果您使用 GIF 動畫或 PNG 圖片,或是每一個標記都必須算繪成個別 DOM 元素,請停用最佳化算繪。下例顯示如何建立最佳化標記:
var marker = new google.maps.Marker({ position: myLatlng, title:"Hello World!", optimized: true });
將標記設為易於讀取
如要將標記設計為易於讀取,您可以加入點擊事件監聽器事件,並將 optimized
設為 false
。點擊事件監聽器會使標記具有按鈕語意,這些語意可透過鍵盤瀏覽和螢幕閱讀器等方式存取。使用 title
選項即可顯示標記的無障礙文字。
在下例中,按下 Tab 鍵時,焦點會落在第一個標記,接著,就能使用方向鍵在標記之間移動。再次按下 Tab 鍵,即可繼續在其他地圖控制項之間移動。如要開啟標記內含的資訊視窗,可以按一下標記,或是在已選取標記的狀態下按下 Enter 鍵或空格鍵。資訊視窗關閉後,焦點就會回到相關標記。
TypeScript
// The following example creates five accessible and // focusable markers. function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 12, center: { lat: 34.84555, lng: -111.8035 }, } ); // Set LatLng and title text for the markers. The first marker (Boynton Pass) // receives the initial focus when tab is pressed. Use arrow keys to // move between markers; press tab again to cycle through the map controls. const tourStops: [google.maps.LatLngLiteral, string][] = [ [{ lat: 34.8791806, lng: -111.8265049 }, "Boynton Pass"], [{ lat: 34.8559195, lng: -111.7988186 }, "Airport Mesa"], [{ lat: 34.832149, lng: -111.7695277 }, "Chapel of the Holy Cross"], [{ lat: 34.823736, lng: -111.8001857 }, "Red Rock Crossing"], [{ lat: 34.800326, lng: -111.7665047 }, "Bell Rock"], ]; // Create an info window to share between markers. const infoWindow = new google.maps.InfoWindow(); // Create the markers. tourStops.forEach(([position, title], i) => { const marker = new google.maps.Marker({ position, map, title: `${i + 1}. ${title}`, label: `${i + 1}`, optimized: false, }); // Add a click listener for each marker, and set up the info window. marker.addListener("click", () => { infoWindow.close(); infoWindow.setContent(marker.getTitle()); infoWindow.open(marker.getMap(), marker); }); }); } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates five accessible and // focusable markers. function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 12, center: { lat: 34.84555, lng: -111.8035 }, }); // Set LatLng and title text for the markers. The first marker (Boynton Pass) // receives the initial focus when tab is pressed. Use arrow keys to // move between markers; press tab again to cycle through the map controls. const tourStops = [ [{ lat: 34.8791806, lng: -111.8265049 }, "Boynton Pass"], [{ lat: 34.8559195, lng: -111.7988186 }, "Airport Mesa"], [{ lat: 34.832149, lng: -111.7695277 }, "Chapel of the Holy Cross"], [{ lat: 34.823736, lng: -111.8001857 }, "Red Rock Crossing"], [{ lat: 34.800326, lng: -111.7665047 }, "Bell Rock"], ]; // Create an info window to share between markers. const infoWindow = new google.maps.InfoWindow(); // Create the markers. tourStops.forEach(([position, title], i) => { const marker = new google.maps.Marker({ position, map, title: `${i + 1}. ${title}`, label: `${i + 1}`, optimized: false, }); // Add a click listener for each marker, and set up the info window. marker.addListener("click", () => { infoWindow.close(); infoWindow.setContent(marker.getTitle()); infoWindow.open(marker.getMap(), marker); }); }); } window.initMap = initMap;
測試範例程式碼
將標記製作成動畫
您可以將標記製作成動畫,在各種情況下展現動態動作。如果要指定標記呈現的動畫效果,請使用標記的 animation
屬性 (類型為 google.maps.Animation
)。支援的 Animation
值如下:
-
DROP
表示標記第一次加到地圖上時,應從地圖頂端落到最終位置。當標記停止時,動畫會隨之停止,且animation
會還原為null
。這類動畫通常是在建立Marker
時指定。 -
BOUNCE
表示標記應在原地彈跳。在animation
屬性明確設為null
前,彈跳標記都會持續彈跳。
您可以針對 Marker
物件呼叫 setAnimation()
,啟用現有標記的動畫效果。
TypeScript
// The following example creates a marker in Stockholm, Sweden using a DROP // animation. Clicking on the marker will toggle the animation between a BOUNCE // animation and no animation. let marker: google.maps.Marker; function initMap(): void { const map = new google.maps.Map( document.getElementById("map") as HTMLElement, { zoom: 13, center: { lat: 59.325, lng: 18.07 }, } ); marker = new google.maps.Marker({ map, draggable: true, animation: google.maps.Animation.DROP, position: { lat: 59.327, lng: 18.067 }, }); marker.addListener("click", toggleBounce); } function toggleBounce() { if (marker.getAnimation() !== null) { marker.setAnimation(null); } else { marker.setAnimation(google.maps.Animation.BOUNCE); } } declare global { interface Window { initMap: () => void; } } window.initMap = initMap;
JavaScript
// The following example creates a marker in Stockholm, Sweden using a DROP // animation. Clicking on the marker will toggle the animation between a BOUNCE // animation and no animation. let marker; function initMap() { const map = new google.maps.Map(document.getElementById("map"), { zoom: 13, center: { lat: 59.325, lng: 18.07 }, }); marker = new google.maps.Marker({ map, draggable: true, animation: google.maps.Animation.DROP, position: { lat: 59.327, lng: 18.067 }, }); marker.addListener("click", toggleBounce); } function toggleBounce() { if (marker.getAnimation() !== null) { marker.setAnimation(null); } else { marker.setAnimation(google.maps.Animation.BOUNCE); } } window.initMap = initMap;
測試範例程式碼
如果您有許多標記,或許不會想要同時放到地圖上。您可以使用 setTimeout()
,透過下列形式隔開標記動畫的顯示時間:
function drop() { for (var i =0; i < markerArray.length; i++) { setTimeout(function() { addMarkerMethod(); }, i * 200); } }
將標記設為可拖曳
如要允許使用者將標記拖曳至地圖上的其他位置,請將標記選項中的 draggable
設為 true
。
var myLatlng = new google.maps.LatLng(-25.363882,131.044922); var mapOptions = { zoom: 4, center: myLatlng } var map = new google.maps.Map(document.getElementById("map"), mapOptions); // Place a draggable marker on the map var marker = new google.maps.Marker({ position: myLatlng, map: map, draggable:true, title:"Drag me!" });
進一步自訂標記
如要完全自訂標記,請參閱自訂彈出式視窗範例。
如要瞭解 Marker 擴充類別、標記叢集和管理,以及疊加層自訂功能,請參閱開放原始碼程式庫。