圖案和線條

選取平台: Android iOS JavaScript

您可以將各種形狀加到地圖中。形狀是地圖上的一種物件,與某個經緯度座標相關聯。可用的形狀如下:線條、多邊形、圓形和矩形。此外,您也可以設定形狀供使用者編輯或拖曳。

折線

如要在地圖上繪製線條,請使用折線。Polyline 類別定義地圖上連接線段的線性疊加層。Polyline 物件由 LatLng 地點陣列組成,可建立依序連接各個地點的一系列線段。

加入折線

Polyline 建構函式會採用一組 PolylineOptions 來指定線條的 LatLng 座標,並採用一組樣式來調整折線的視覺行為。

Polyline 是由地圖上一系列直線段繪製而成的物件。建立線條時,您可以在 PolylineOptions 內指定線條筆劃的自訂色彩、粗細和不透明度,但也可以在建立線條後變更這些屬性。折線支援下列筆劃樣式:

  • strokeColor 可指定 "#FFFFFF" 格式的十六進位 HTML 顏色。Polyline 類別不支援具名顏色。
  • strokeOpacity 可指定 0.0 和 1.0 之間的數值,以決定線條色彩的不透明度。預設值為 1.0。
  • strokeWeight 可以像素為單位,指定線條的寬度。

折線的 editable 屬性可指定使用者能否編輯形狀。請參閱下方的「使用者可編輯的形狀」一節。同樣地,您可以設定 draggable 屬性,讓使用者能夠拖曳線條。

這個範例會建立兩像素寬的紅色折線,顯示加州奧克蘭和澳洲布里斯本之間的第一趟跨太平洋航班路徑。

TypeScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();

JavaScript

// This example creates a 2-pixel-wide red polyline showing the path of
// the first trans-Pacific flight between Oakland, CA, and Brisbane,
// Australia which was made by Charles Kingsford Smith.
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    const { Polyline } = await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;

    const flightPlanCoordinates = [
        { lat: 37.772, lng: -122.214 },
        { lat: 21.291, lng: -157.821 },
        { lat: -18.142, lng: 178.431 },
        { lat: -27.467, lng: 153.027 },
    ];
    const flightPath = new Polyline({
        path: flightPlanCoordinates,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
    });

    flightPath.setMap(innerMap);
}

void init();
查看範例

試用範例

移除折線

如要從地圖中移除折線,請呼叫 setMap() 方法,並以引數形式傳遞 null。在下例中,flightPath 是折線物件:

flightPath.setMap(null);

請注意,上述方法並不會刪除折線,只會從地圖中移除。如果要刪除折線,請先從地圖中移除,然後將折線本身設為 null。

檢查折線

折線可將一系列的座標指定為 LatLng 物件的陣列,線條的路徑則取決於這些座標。如要擷取座標,請呼叫 getPath() 來傳回 MVCArray 類型的陣列。如要處理及檢查陣列,請進行以下操作:

  • getAt() 會在指定索引值 (從零開始計算) 傳回 LatLng。
  • insertAt() 會在指定索引值 (從零開始計算) 插入傳遞的 LatLng。請注意,在該索引值的任何現有座標,都會向前移動。
  • removeAt() 會從指定索引值 (從零開始計算) 移除 LatLng。

以下範例說明如何根據點擊動作建構折線 (點選地圖即可新增頂點)。

TypeScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly: google.maps.Polyline;
const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event: google.maps.MapMouseEvent) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();

JavaScript

/**
 * This example creates an interactive map which constructs a polyline based on
 * user clicks. Note that the polyline only appears once its path property
 * contains two LatLng coordinates.
 */

let poly;
const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Import the needed libraries.
    const [{ Polyline }, { AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('maps'),
        google.maps.importLibrary('marker'),
    ]);

    innerMap = mapElement.innerMap;

    poly = new Polyline({
        strokeColor: '#000000',
        strokeOpacity: 1.0,
        strokeWeight: 3,
    });
    poly.setMap(innerMap);

    // Handles click events on a map, and adds a new point to the Polyline.
    innerMap.addListener('click', (event) => {
        const latLng = event.latLng;
        if (!latLng) return;

        const path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(latLng);

        // Add a new marker at the new plotted point on the polyline.
        new AdvancedMarkerElement({
            position: latLng,
            title: '#' + path.getLength(),
            map: innerMap,
        });
    });
}

void init();
查看範例

試用範例

自訂折線

您可以將向量圖片以符號的形式加到折線上。此外,只要結合使用符號和 PolylineOptions 類別,就能進一步決定地圖上折線的外觀和風格。如要瞭解箭頭、虛線、自訂符號和動畫符號,請參閱「符號」一文。

多邊形

多邊形是指封閉式路徑 (或迴圈) 圍起的區域,以一系列座標定義而成。Polygon 物件與 Polyline 物件類似,都是由一系列座標依序組成。多邊形是以線條筆劃和填滿區域繪製而成。您可以自訂多邊形外緣 (筆劃) 的顏色、粗細和不透明度,以及外緣以內區域 (填滿) 的顏色和不透明度。顏色應以 16 進位 HTML 格式來表示,不得使用顏色名稱。

Polygon 物件可描述複雜的形狀,包括:

  • 由單一多邊形定義的多個非連續區域。
  • 有孔的區域。
  • 一或多個區域的重疊部分。

如要定義複雜的形狀,請使用內含多條路徑的多邊形。

注意:如要繪製多邊形,使用資料層是一種簡單的做法。資料層可為您處理多邊形環繞的情況,方便繪製有孔的多邊形。請參閱資料層說明文件。

加入多邊形

多邊形區域可能包含數個獨立路徑,因此 Polygon 物件的 paths 屬性會指定一組陣列,其中每個陣列的類型都是 MVCArray。每個陣列都會定義一組單獨依序排列的 LatLng 座標。

如果是只由一條路徑組成的簡易多邊形,您可以使用單一 LatLng 座標陣列建構 Polygon。建構完成後,將這個簡易陣列儲存在 paths 屬性內時,Maps JavaScript API 會將該陣列轉換成一組陣列。如果是由單一路徑組成的多邊形,API 會提供簡易的 getPath() 方法。

多邊形的 editable 屬性可指定使用者能否編輯形狀。請參閱下方的「使用者可編輯的形狀」一節。同樣地,您可以設定 draggable 屬性,讓使用者能夠拖曳形狀。

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
      mapTypeId: "terrain",
    }
  );

  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });
  // Define the LatLng coordinates for the polygon's path.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
    { lat: 25.774, lng: -80.19 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
查看範例

測試範例程式碼

多邊形自動完成

上例中的 Polygon 是由 4 組 LatLng 座標所組成,不過請注意,第一組和最後一組座標定義相同位置,因而形成一個迴圈。但實際上,多邊形會定義封閉區域,因此您不必指定最後一組座標。Maps JavaScript API 會繪製一段線條,將任何指定路徑的最後一個位置接回第一個位置,自動完成多邊形。

下例與前例相同,唯獨省略最後一個 LatLng:查看範例。

移除多邊形

如要從地圖中移除多邊形,請呼叫 setMap() 方法,並以引數形式傳遞 null。在下例中,bermudaTriangle 是多邊形物件:

bermudaTriangle.setMap(null);

請注意,上述方法並不會刪除多邊形,只會從地圖中移除。如果要刪除多邊形,請先從地圖中移除,然後將多邊形本身設為 null。

檢查多邊形

多邊形會將其中的一系列座標指定為一組陣列,其中每個陣列的類型都是 MVCArray。每個「葉狀」陣列都是 LatLng 座標陣列,用於指定單一路徑。如要擷取這些座標,請呼叫 Polygon 物件的 getPaths() 方法。陣列是 MVCArray,因此如要處理及檢查陣列,請進行以下操作:

  • getAt() 會在指定索引值 (從零開始計算) 傳回 LatLng。
  • insertAt() 會在指定索引值 (從零開始計算) 插入傳遞的 LatLng。請注意,在該索引值的任何現有座標,都會向前移動。
  • removeAt() 會從指定索引值 (從零開始計算) 移除 LatLng。

TypeScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.

let map: google.maps.Map;

let infoWindow: google.maps.InfoWindow;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords: google.maps.LatLngLiteral[] = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);

  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);

  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event: any) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this as google.maps.Polygon;
  const vertices = polygon.getPath();

  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);

  infoWindow.open(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.
let map;
let infoWindow;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
    mapTypeId: "terrain",
  });

  // Define the LatLng coordinates for the polygon.
  const triangleCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Construct the polygon.
  const bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
  // Add a listener for the click event.
  bermudaTriangle.addListener("click", showArrays);
  infoWindow = new google.maps.InfoWindow();
}

function showArrays(event) {
  // Since this polygon has only one path, we can call getPath() to return the
  // MVCArray of LatLngs.
  // @ts-ignore
  const polygon = this;
  const vertices = polygon.getPath();
  let contentString =
    "<b>Bermuda Triangle polygon</b><br>" +
    "Clicked location: <br>" +
    event.latLng.lat() +
    "," +
    event.latLng.lng() +
    "<br>";

  // Iterate over the vertices.
  for (let i = 0; i < vertices.getLength(); i++) {
    const xy = vertices.getAt(i);

    contentString +=
      "<br>" + "Coordinate " + i + ":<br>" + xy.lat() + "," + xy.lng();
  }

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);
  infoWindow.open(map);
}

window.initMap = initMap;
查看範例

測試範例程式碼

在多邊形中加入一個孔

如要在多邊形內建立空白區域,您必須建立兩條路徑,一條包含在另一條內。如要建立這個孔,定義內部路徑的座標必須與定義外部路徑的座標順序相反。舉例來說,如果外部路徑的座標為順時針順序,內部路徑就必須是逆時針順序。

注意:資料層可為您處理內部和外部路徑的順序,方便繪製有孔的多邊形。請參閱資料層說明文件。

下例繪製含有兩條路徑的多邊形,內部路徑的環繞方向與外部路徑相反。

TypeScript

// This example creates a triangular polygon with a hole in it.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 5,
      center: { lat: 24.886, lng: -70.268 },
    }
  );

  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];

  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];

  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a triangular polygon with a hole in it.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 5,
    center: { lat: 24.886, lng: -70.268 },
  });
  // Define the LatLng coordinates for the polygon's  outer path.
  const outerCoords = [
    { lat: 25.774, lng: -80.19 },
    { lat: 18.466, lng: -66.118 },
    { lat: 32.321, lng: -64.757 },
  ];
  // Define the LatLng coordinates for the polygon's inner path.
  // Note that the points forming the inner path are wound in the
  // opposite direction to those in the outer path, to form the hole.
  const innerCoords = [
    { lat: 28.745, lng: -70.579 },
    { lat: 29.57, lng: -67.514 },
    { lat: 27.339, lng: -66.668 },
  ];
  // Construct the polygon, including both paths.
  const bermudaTriangle = new google.maps.Polygon({
    paths: [outerCoords, innerCoords],
    strokeColor: "#FFC107",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FFC107",
    fillOpacity: 0.35,
  });

  bermudaTriangle.setMap(map);
}

window.initMap = initMap;
查看範例

測試範例程式碼

矩形

除了一般的 Polygon 類別之外,Google Maps JavaScript API 也包含 Rectangle 物件的專屬類別,可用於簡化建構過程。

加入矩形

Rectangle 與 Polygon 類似,可讓您自訂矩形外緣 (筆劃) 的色彩、粗細和不透明度,以及矩形內部 (填滿) 的色彩和不透明度。色彩應以 16 進位 HTML 樣式來表示。

有別於 Polygon,您無須定義 Rectangle 的 paths。不過,矩形的 bounds 屬性會指定矩形的 google.maps.LatLngBounds,以定義形狀。

矩形的 editable 屬性可指定使用者能否編輯形狀。請參閱下方的「使用者可編輯的形狀」一節。同樣地,您可以設定 draggable 屬性,讓使用者能夠拖曳矩形。

TypeScript

// This example adds a red rectangle to a map.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 33.678, lng: -116.243 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example adds a red rectangle to a map.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 33.678, lng: -116.243 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle({
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35,
    map,
    bounds: {
      north: 33.685,
      south: 33.671,
      east: -116.234,
      west: -116.251,
    },
  });
}

window.initMap = initMap;
查看範例

測試範例程式碼

下方程式碼會在每次使用者縮放地圖時,建立一個矩形。矩形尺寸取決於可視區域。

TypeScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 11,
      center: { lat: 40.74852, lng: -73.981687 },
      mapTypeId: "terrain",
    }
  );

  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds() as google.maps.LatLngBounds,
    });
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// This example creates a rectangle based on the viewport
// on any 'zoom-changed' event.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 11,
    center: { lat: 40.74852, lng: -73.981687 },
    mapTypeId: "terrain",
  });
  const rectangle = new google.maps.Rectangle();

  map.addListener("zoom_changed", () => {
    // Get the current bounds, which reflect the bounds before the zoom.
    rectangle.setOptions({
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map,
      bounds: map.getBounds(),
    });
  });
}

window.initMap = initMap;
查看範例

測試範例程式碼

移除矩形

如要從地圖中移除矩形,請呼叫 setMap() 方法,並以引數形式傳遞 null。

rectangle.setMap(null);

請注意,上述方法並不會刪除矩形,只會從地圖中移除。如果要刪除矩形,請先從地圖中移除,然後將矩形本身設為 null。

圓形

除了一般的 Polygon 類別之外,Google Maps JavaScript API 也包含 Circle 物件的專屬類別,可用於簡化建構過程。

加入圓形

Circle 與 Polygon 類似,可讓您自訂圓形外緣 (筆劃) 的色彩、粗細和不透明度,以及圓形內部 (填滿) 的色彩和不透明度。色彩應以 16 進位 HTML 樣式來表示。

有別於 Polygon,您無須定義 Circle 的 paths。不過,圓形會有兩個額外屬性來定義形狀:

  • center 會指定圓形中心點的 google.maps.LatLng。
  • radius 會指定圓形的半徑 (以公尺為單位)。

圓形的 editable 屬性可指定使用者能否編輯形狀。請參閱下方的「使用者可編輯的形狀」一節。同樣地,您可以設定 draggable 屬性,讓使用者能夠拖曳圓形。

以下範例使用圓圈顯示日本京都各地點間的概略步行時間。從選單中選取所需距離,按一下地圖重新置中圓形,然後拖曳圓形重新放置。

TypeScript

const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target as HTMLInputElement;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener(
        'click',
        (
            mapsMouseEvent:
                | google.maps.MapMouseEvent
                | google.maps.IconMouseEvent
        ) => {
            const newCenter = mapsMouseEvent.latLng;
            if (!newCenter) return;
            walkingCircle.setCenter(newCenter);
            centerMarker.position = newCenter;
            innerMap.panTo(newCenter);
        }
    );

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;

async function init() {
    // Request needed libraries.
    const [{ Circle }, { AdvancedMarkerElement }, { event }] =
        await Promise.all([
            google.maps.importLibrary('maps'),
            google.maps.importLibrary('marker'),
            google.maps.importLibrary('core'),
        ]);

    // Set the initial map center point.
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

    // Get the inner map.
    innerMap = mapElement.innerMap;

    // Get the buttons.
    const buttons = document.querySelectorAll('input[name="radius"]');

    // Create the circle.
    const walkingCircle = new Circle({
        strokeColor: '#ffdd00ff',
        strokeOpacity: 0.8,
        strokeWeight: 2,
        fillColor: '#ffdd00ff',
        fillOpacity: 0.35,
        map: innerMap,
        center: initialCenter,
        radius: 400,
        draggable: true,
        editable: false,
    });

    // Define a "Crosshair" vector icon
    const parser = new DOMParser();
    const svgString = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="-6 -6 12 12"><path d="M -6,0 L 6,0 M 0,-6 L 0,6" stroke="black" stroke-width="1"/></svg>`;

    const pinSvg = parser.parseFromString(
        svgString,
        'image/svg+xml'
    ).documentElement;

    const centerMarker = new AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    event.addListenerOnce(innerMap, 'tilesloaded', () => {
        // Get the controls div
        const controls = document.getElementById('control-panel');

        // Display controls once map is loaded.
        if (controls) {
            controls.style.display = 'block';
        }
    });

    // Add event listener to update the radius based on user selection.
    buttons.forEach((button) => {
        button.addEventListener('change', (changeEvent) => {
            const target = changeEvent.target;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener('click', (mapsMouseEvent) => {
        const newCenter = mapsMouseEvent.latLng;
        if (!newCenter) return;
        walkingCircle.setCenter(newCenter);
        centerMarker.position = newCenter;
        innerMap.panTo(newCenter);
    });

    // Handle user dragging the circle, update the center marker position.
    walkingCircle.addListener('center_changed', () => {
        centerMarker.position = walkingCircle.getCenter();
    });
}

void init();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#control-panel {
    display: none; /* Set to 'display: block' after the map loads. */
    background-color: #fff;
    border: 2px solid #fff;
    border-radius: 3px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: 'Roboto', sans-serif;
    font-size: medium;
    margin: 10px;
    padding: 10px;
}

HTML

<html>
    <head>
        <title>Circles</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <script>
            // prettier-ignore
            (g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
                key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8"
            });
        </script>
    </head>
    <body>
        <gmp-map
            center="34.98956821576194, 135.74239981260283"
            zoom="15"
            map-id="DEMO_MAP_ID">
            <div id="control-panel" slot="control-inline-start-block-start">
                <input
                    id="short-walk"
                    type="radio"
                    name="radius"
                    value="400"
                    checked />
                <label for="short-walk">Short Walk (~5 minutes)</label><br />
                <input
                    id="medium-walk"
                    type="radio"
                    name="radius"
                    value="800" />
                <label for="medium-walk">Medium Walk (~15 minutes)</label><br />
                <input id="long-walk" type="radio" name="radius" value="1600" />
                <label for="long-walk">Long Walk (~30 minutes) </label>
            </div>
        </gmp-map>
    </body>
</html>
查看範例

試用範例

移除圓形

如要從地圖中移除圓形,請呼叫 setMap() 方法,並以引數形式傳遞 null。

circle.setMap(null);

請注意,上述方法並不會刪除圓形,只會從地圖中移除。如果要刪除圓形,請先從地圖中移除,然後將圓形本身設為 null。

使用者可編輯和可拖曳的形狀

如果將形狀設為可編輯,形狀中就會加入控點,供使用者直接在地圖上重新調整位置、形狀和尺寸。此外,您也可以將形狀設為可拖曳,方便使用者將形狀移至地圖上的其他位置。

使用者對物件所做的變更不會保留到下一個工作階段。如要儲存使用者所做的編輯內容,請自行擷取並保存這些資訊。

將形狀設為可編輯

只要將形狀選項中的 editable 設為 true,即可將任何形狀 (折線、多邊形、圓形和矩形) 設為可供使用者編輯。

var bounds = {
  north: 44.599,
  south: 44.490,
  east: -78.443,
  west: -78.649
};

// Define a rectangle and set its editable property to true.
var rectangle = new google.maps.Rectangle({
  bounds: bounds,
  editable: true
});

查看範例

將形狀設為可拖曳

根據預設,在地圖上繪製的形狀會固定在某個位置。如要允許使用者將形狀拖曳至地圖上的其他位置,請將形狀選項中的 draggable 設為 true。

var redCoords = [
  {lat: 25.774, lng: -80.190},
  {lat: 18.466, lng: -66.118},
  {lat: 32.321, lng: -64.757}
];

// Construct a draggable red triangle with geodesic set to true.
new google.maps.Polygon({
  map: map,
  paths: redCoords,
  strokeColor: '#FF0000',
  strokeOpacity: 0.8,
  strokeWeight: 2,
  fillColor: '#FF0000',
  fillOpacity: 0.35,
  draggable: true,
  geodesic: true
});

將多邊形或折線設為可拖曳後,建議您一併將多邊形或折線的 geodesic 屬性設為 true,以轉換為測地多邊形或測地折線。

測地多邊形移動時,實際的地理形狀會保持不變,因此在麥卡托投影中南北移動時,形狀就會扭曲。至於非測地多邊形,則會一律保持在畫面上的初始外觀。

在測地折線中,線段會繪製成地表上兩點之間的最短路徑,並假設地球是球體,相比之下,麥卡托投影中則是繪製成直線。

如要進一步瞭解座標系統,請參閱「地圖與圖塊座標」指南。

下方地圖顯示尺寸和維度大致相同的兩個三角形。紅色三角形的 geodesic 屬性已設為 true,請注意形狀在往北移動時的變化。

查看範例

監聽編輯事件

形狀編輯完成後,會觸發事件,如下所列:

形狀 事件
圓形 radius_changed
center_changed
多邊形 insert_at
remove_at
set_at

事件監聽器必須設定在多邊形的路徑上。如果多邊形有多條路徑,則每條路徑都必須設定事件監聽器。

折線 insert_at
remove_at
set_at

監聽器必須設定在折線的路徑上。

矩形 bounds_changed

以下是一些實用的程式碼片段:

google.maps.event.addListener(circle, 'radius_changed', function() {
  console.log(circle.getRadius());
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  console.log('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  console.log('Vertex removed from inner path.');
});

google.maps.event.addListener(rectangle, 'bounds_changed', function() {
  console.log('Bounds changed.');
});

如要瞭解系統如何處理矩形編輯事件,請查看範例。

監聽拖曳事件

拖曳形狀時,會在拖曳動作的開始、結束以及過程中觸發事件。以下是拖曳折線、多邊形、圓形和矩形時會觸發的事件。

事件 說明
dragstart 在使用者開始拖曳形狀時觸發。
drag 在使用者拖曳形狀時重複觸發。
dragend 在使用者停止拖曳形狀時觸發。

如要進一步瞭解系統如何處理事件,請參閱事件相關說明文件。