標記 (舊版)

選取平台: Android iOS JavaScript

簡介

您可以使用標記代表地圖上的位置。標記預設會使用標準圖片,不過,標記可以顯示自訂圖片,而這種標記通常稱為「圖示」。標記和圖示是 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 物件會定義圖片,也會定義圖示的 sizeorigin (例如所需圖片是精靈圖的一部分),以及應該放置圖示熱點的 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 版起正式取代 MarkerImageIcon 物件常值支援的參數與 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 擴充類別、標記叢集和管理,以及疊加層自訂功能,請參閱開放原始碼程式庫