Hình dạng và đường kẻ

Chọn nền tảng: Android iOS JavaScript

Bạn có thể thêm nhiều hình dạng vào bản đồ của mình. Hình dạng là một đối tượng trên bản đồ, gắn liền với toạ độ vĩ độ/kinh độ. Bạn có thể sử dụng các hình dạng sau: đường, đa giác, hình tròn và hình chữ nhật. Bạn cũng có thể định cấu hình hình dạng để người dùng có thể chỉnh sửa hoặc kéo hình dạng, hoặc kết hợp hình dạng với Thư viện hình học (google.maps.GeometryLibrary) để kiểm tra ranh giới khoanh vùng địa lý và vùng an toàn.

Hình nhiều đường

Để vẽ một đường trên bản đồ, hãy sử dụng hình nhiều đường. Lớp Polyline xác định một lớp phủ tuyến tính gồm các đoạn thẳng được kết nối trên bản đồ. Đối tượng Polyline bao gồm một mảng gồm các vị trí LatLng và tạo một loạt các đoạn thẳng nối các vị trí đó theo một trình tự có thứ tự.

Thêm hình nhiều đường

Hàm khởi tạo Polyline lấy một tập hợp PolylineOptions chỉ định toạ độ LatLng của đường thẳng và một tập hợp kiểu để điều chỉnh hành vi trực quan của hình nhiều đường.

Các đối tượng Polyline được vẽ dưới dạng một loạt các đoạn thẳng trên bản đồ. Bạn có thể chỉ định màu sắc tuỳ chỉnh, độ đậm và độ mờ cho nét vẽ của đường trong PolylineOptions khi tạo đường hoặc bạn có thể thay đổi các thuộc tính đó sau khi tạo. Hình nhiều đường hỗ trợ các kiểu nét vẽ sau:

  • strokeColor chỉ định màu HTML thập lục phân của định dạng "#FFFFFF". Lớp Polyline không hỗ trợ màu có tên.
  • strokeOpacity chỉ định một giá trị số từ 0.0 đến 1.0 để xác định độ mờ của màu đường kẻ. Giá trị mặc định là 1.0.
  • strokeWeight chỉ định chiều rộng của đường kẻ theo pixel.

Thuộc tính editable của hình nhiều đường chỉ định liệu người dùng có thể chỉnh sửa hình dạng hay không. Xem phần hình dạng mà người dùng có thể chỉnh sửa bên dưới. Tương tự, bạn có thể đặt thuộc tính draggable để cho phép người dùng kéo đường.

Ví dụ này tạo một hình nhiều đường màu đỏ rộng 2 pixel, cho thấy đường bay của chuyến bay xuyên Thái Bình Dương đầu tiên giữa Oakland, California và Brisbane, Úc.

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();
Xem ví dụ

Xoá hình nhiều đường

Để xoá một hình nhiều đường khỏi bản đồ, hãy gọi phương thức setMap(), truyền null làm đối số. Trong ví dụ sau, flightPath là một đối tượng hình nhiều đường:

flightPath.setMap(null);

Xin lưu ý rằng phương thức trên không xoá hình nhiều đường. Thao tác này sẽ xoá hình nhiều đường khỏi bản đồ. Nếu muốn xoá hình nhiều đường, bạn nên xoá hình đó khỏi bản đồ, sau đó đặt chính hình nhiều đường đó thành null.

Kiểm tra một đường đa tuyến

Hình nhiều đường chỉ định một loạt toạ độ dưới dạng một mảng các đối tượng LatLng. Các toạ độ này xác định đường dẫn của đường kẻ. Để truy xuất toạ độ, hãy gọi getPath(). Thao tác này sẽ trả về một mảng thuộc loại MVCArray. Bạn có thể thao tác và kiểm tra mảng bằng các thao tác sau:

  • getAt() trả về LatLng tại một giá trị chỉ mục dựa trên số 0 nhất định.
  • insertAt() chèn một LatLng đã truyền vào một giá trị chỉ mục dựa trên số 0 đã cho. Xin lưu ý rằng mọi toạ độ hiện có tại giá trị chỉ mục đó đều được di chuyển về phía trước.
  • removeAt() xoá LatLng tại một giá trị chỉ mục dựa trên số 0 nhất định.

Ví dụ sau đây minh hoạ cách tạo một hình nhiều đường dựa trên các lượt nhấp (nhấp vào bản đồ để thêm một đỉnh).

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();
Xem ví dụ

Tuỳ chỉnh hình nhiều đường

Bạn có thể thêm hình ảnh dựa trên vectơ vào một hình nhiều đường dưới dạng biểu tượng. Khi kết hợp các biểu tượng và lớp PolylineOptions, bạn có thể kiểm soát giao diện của hình nhiều đường trên bản đồ. Xem phần Ký hiệu để biết thông tin về mũi tên, đường đứt nét, ký hiệu tuỳ chỉnh và ký hiệu động.

Đa giác

Đa giác đại diện cho một khu vực được bao quanh bởi một đường dẫn khép kín (hoặc vòng lặp), được xác định bằng một loạt toạ độ. Đối tượng Polygon tương tự như đối tượng Polyline ở chỗ chúng bao gồm một loạt toạ độ theo trình tự có thứ tự. Đa giác được vẽ bằng nét vẽ và màu nền. Bạn có thể xác định màu sắc tuỳ chỉnh, độ đậm và độ mờ tuỳ chỉnh cho cạnh của đa giác (nét vẽ) cũng như màu sắc và độ mờ tuỳ chỉnh cho vùng được bao quanh (màu nền). Màu phải được chỉ định ở định dạng HTML thập lục phân. Không hỗ trợ tên màu.

Đối tượng Polygon có thể mô tả các hình dạng phức tạp, bao gồm:

  • Nhiều khu vực không liền kề được xác định bằng một đa giác.
  • Khu vực có lỗ.
  • Giao điểm của một hoặc nhiều khu vực.

Để xác định một hình dạng phức tạp, bạn sử dụng một đa giác có nhiều đường dẫn.

Lưu ý: Lớp dữ liệu cung cấp một cách đơn giản để vẽ đa giác. Thao tác này xử lý việc cuộn đa giác cho bạn, giúp bạn dễ dàng vẽ đa giác có lỗ hơn. Hãy xem tài liệu về Lớp dữ liệu.

Thêm đa giác

Vì một khu vực đa giác có thể bao gồm nhiều đường dẫn riêng biệt, nên thuộc tính paths của đối tượng Polygon chỉ định một mảng gồm các mảng, mỗi mảng thuộc loại MVCArray. Mỗi mảng xác định một chuỗi riêng biệt gồm các toạ độ LatLng được sắp xếp theo thứ tự.

Đối với đa giác đơn giản chỉ gồm một đường dẫn, bạn có thể tạo Polygon bằng một mảng toạ độ LatLng duy nhất. Maps JavaScript API sẽ chuyển đổi mảng đơn giản thành một mảng gồm các mảng khi tạo và lưu trữ mảng đó trong thuộc tính paths. API này cung cấp một phương thức getPath() đơn giản cho các đa giác bao gồm một đường dẫn.

Thuộc tính editable của đa giác chỉ định xem người dùng có thể chỉnh sửa hình dạng hay không. Xem phần hình dạng mà người dùng có thể chỉnh sửa bên dưới. Tương tự, bạn có thể đặt thuộc tính draggable để cho phép người dùng kéo hình dạng.

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;
Xem ví dụ

Tự động hoàn thành đa giác

Polygon trong ví dụ trên bao gồm bốn tập hợp toạ độ LatLng, nhưng hãy lưu ý rằng tập hợp đầu tiên và tập hợp cuối cùng xác định cùng một vị trí, tức là hoàn thành vòng lặp. Tuy nhiên, trên thực tế, vì đa giác xác định các khu vực khép kín, nên bạn không cần chỉ định tập hợp toạ độ cuối cùng. Maps JavaScript API sẽ tự động hoàn tất đa giác bằng cách vẽ một nét nối vị trí cuối cùng với vị trí đầu tiên cho bất kỳ đường dẫn nào.

Ví dụ sau đây giống hệt với ví dụ trước, ngoại trừ việc bỏ qua LatLng cuối cùng: xem ví dụ.

Xoá đa giác

Để xoá một đa giác khỏi bản đồ, hãy gọi phương thức setMap() truyền null làm đối số. Trong ví dụ sau, bermudaTriangle là một đối tượng đa giác:

bermudaTriangle.setMap(null);

Xin lưu ý rằng phương thức trên không xoá đa giác. Thao tác này sẽ xoá đa giác khỏi bản đồ. Nếu muốn xoá đa giác, bạn nên xoá đa giác đó khỏi bản đồ, sau đó đặt chính đa giác đó thành null.

Kiểm tra đa giác

Một đa giác chỉ định chuỗi toạ độ của nó dưới dạng một mảng gồm các mảng, trong đó mỗi mảng thuộc loại MVCArray. Mỗi mảng "lá" là một mảng gồm các toạ độ LatLng chỉ định một đường dẫn duy nhất. Để truy xuất các toạ độ này, hãy gọi phương thức getPaths() của đối tượng Polygon. Vì mảng là một MVCArray, nên bạn sẽ cần thao tác và kiểm tra mảng đó bằng các thao tác sau:

  • getAt() trả về LatLng tại một giá trị chỉ mục dựa trên số 0 nhất định.
  • insertAt() chèn một LatLng đã truyền vào một giá trị chỉ mục dựa trên số 0 đã cho. Xin lưu ý rằng mọi toạ độ hiện có tại giá trị chỉ mục đó đều được di chuyển về phía trước.
  • removeAt() xoá LatLng tại một giá trị chỉ mục dựa trên số 0 nhất định.

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;
Xem ví dụ

Tạo lỗ trong đa giác

Để tạo một vùng trống trong đa giác, bạn cần tạo hai đường dẫn, một đường dẫn bên trong đường dẫn kia. Để tạo lỗ, toạ độ xác định đường dẫn bên trong phải theo thứ tự ngược lại với toạ độ xác định đường dẫn bên ngoài. Ví dụ: nếu toạ độ của đường dẫn bên ngoài theo thứ tự chiều kim đồng hồ thì đường dẫn bên trong phải ngược chiều kim đồng hồ.

Lưu ý: Lớp dữ liệu xử lý thứ tự của đường dẫn bên trong và bên ngoài cho bạn, giúp bạn dễ dàng vẽ đa giác có lỗ hơn. Hãy xem tài liệu về Lớp dữ liệu.

Ví dụ sau đây vẽ một đa giác có hai đường dẫn, trong đó đường dẫn bên trong được uốn theo hướng ngược lại với đường dẫn bên ngoài.

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;
Xem ví dụ

Các hình chữ nhật

Ngoài lớp Polygon chung, API JavaScript của Google Maps còn có một lớp cụ thể cho các đối tượng Rectangle để đơn giản hoá việc xây dựng các đối tượng đó.

Thêm hình chữ nhật

Rectangle tương tự như Polygon ở chỗ bạn có thể xác định màu sắc tuỳ chỉnh, độ đậm và độ mờ tuỳ chỉnh cho cạnh của hình chữ nhật (nét vẽ) cũng như màu sắc tuỳ chỉnh và độ mờ tuỳ chỉnh cho vùng bên trong hình chữ nhật (màu nền). Màu sắc phải được chỉ định theo kiểu HTML số thập lục phân.

Không giống như Polygon, bạn không xác định paths cho Rectangle. Thay vào đó, hình chữ nhật có thuộc tính bounds xác định hình dạng của hình chữ nhật bằng cách chỉ định google.maps.LatLngBounds cho hình chữ nhật.

Thuộc tính editable của hình chữ nhật chỉ định xem người dùng có thể chỉnh sửa hình dạng hay không. Xem phần hình dạng mà người dùng có thể chỉnh sửa bên dưới. Tương tự, bạn có thể đặt thuộc tính draggable để cho phép người dùng kéo hình chữ nhật.

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;
Xem ví dụ

Mã sau đây tạo một hình chữ nhật mỗi khi người dùng thay đổi mức thu phóng trên bản đồ. Kích thước của hình chữ nhật được xác định theo khung nhìn.

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;
Xem ví dụ

Xoá hình chữ nhật

Để xoá một hình chữ nhật khỏi bản đồ, hãy gọi phương thức setMap() truyền null làm đối số.

rectangle.setMap(null);

Xin lưu ý rằng phương thức trên không xoá hình chữ nhật. Thao tác này sẽ xoá hình chữ nhật khỏi bản đồ. Nếu muốn xoá hình chữ nhật, bạn nên xoá hình chữ nhật đó khỏi bản đồ, sau đó đặt chính hình chữ nhật đó thành null.

Vòng tròn

Ngoài lớp Polygon chung, API JavaScript của Google Maps còn có một lớp cụ thể cho các đối tượng Circle để đơn giản hoá việc tạo các đối tượng này.

Thêm vòng kết nối

Circle tương tự như Polygon ở chỗ bạn có thể xác định màu sắc tuỳ chỉnh, độ đậm và độ mờ tuỳ chỉnh cho cạnh của hình tròn (nét vẽ) cũng như màu sắc tuỳ chỉnh và độ mờ tuỳ chỉnh cho vùng bên trong hình tròn (màu nền). Màu sắc phải được chỉ định theo kiểu HTML số thập lục phân.

Không giống như Polygon, bạn không xác định paths cho Circle. Thay vào đó, hình tròn có thêm hai thuộc tính xác định hình dạng của nó:

  • center chỉ định google.maps.LatLng của tâm đường tròn.
  • radius chỉ định bán kính của hình tròn, tính bằng mét.

Thuộc tính editable của hình tròn chỉ định xem người dùng có thể chỉnh sửa hình dạng hay không. Xem phần hình dạng mà người dùng có thể chỉnh sửa bên dưới. Tương tự, bạn có thể đặt thuộc tính draggable để cho phép người dùng kéo vòng tròn.

Ví dụ sau đây sử dụng các vòng tròn để cho biết thời gian đi bộ ước chừng giữa các địa điểm ở Kyoto, Nhật Bản. Chọn khoảng cách cần thiết trong trình đơn, nhấp vào bản đồ để đặt lại tâm của vòng tròn và kéo vòng tròn để đặt lại vị trí.

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: "GOOGLE_MAPS_API_KEY"
            });
        </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>
Xem ví dụ

Xoá vòng kết nối

Để xoá một hình tròn khỏi bản đồ, hãy gọi phương thức setMap() truyền null làm đối số.

circle.setMap(null);

Lưu ý rằng phương thức trên không xoá vòng tròn. Thao tác này sẽ xoá hình tròn khỏi bản đồ. Nếu muốn xoá hình tròn, bạn nên xoá hình tròn đó khỏi bản đồ, sau đó đặt hình tròn thành null.

Hình dạng mà người dùng có thể chỉnh sửa và kéo

Việc đặt một hình dạng ở chế độ có thể chỉnh sửa sẽ thêm các ô điều khiển vào hình dạng đó. Người dùng có thể sử dụng các ô điều khiển này để đặt lại vị trí, định hình lại và đổi kích thước hình dạng ngay trên bản đồ. Bạn cũng có thể đặt một hình dạng ở chế độ kéo được để mọi người có thể di chuyển hình dạng đó đến một vị trí khác trên bản đồ.

Những thay đổi do người dùng thực hiện đối với đối tượng sẽ không được lưu giữ giữa các phiên. Nếu muốn lưu nội dung chỉnh sửa của người dùng, bạn phải tự thu thập và lưu trữ thông tin.

Cho phép chỉnh sửa hình dạng

Bạn có thể đặt bất kỳ hình dạng nào (hình nhiều đường, đa giác, hình tròn và hình chữ nhật) thành hình dạng mà người dùng có thể chỉnh sửa bằng cách đặt editable thành true trong các tuỳ chọn của hình dạng.

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
});

Xem ví dụ

Tạo hình dạng có thể kéo

Theo mặc định, hình dạng được vẽ trên bản đồ sẽ được cố định ở một vị trí. Để cho phép người dùng kéo một hình dạng đến một vị trí khác trên bản đồ, hãy đặt draggable thành true trong các tuỳ chọn hình dạng.

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
});

Khi bật tính năng kéo trên đa giác hoặc hình nhiều đường, bạn cũng nên cân nhắc việc đặt đa giác hoặc hình nhiều đường thành trắc địa bằng cách đặt thuộc tính geodesic của đa giác hoặc hình nhiều đường thành true.

Đa giác trắc địa sẽ giữ nguyên hình dạng địa lý thực khi được di chuyển, khiến đa giác có vẻ bị méo khi di chuyển về phía bắc hoặc phía nam trong phép chiếu Mercator. Đa giác không trắc địa sẽ luôn giữ nguyên hình dạng ban đầu trên màn hình.

Trong một hình nhiều đường trắc địa, các đoạn của hình nhiều đường được vẽ dưới dạng đường đi ngắn nhất giữa hai điểm trên bề mặt Trái Đất, giả sử Trái Đất là một hình cầu, trái ngược với các đường thẳng trên phép chiếu Mercator.

Để biết thêm thông tin về hệ toạ độ, hãy tham khảo hướng dẫn về toạ độ bản đồ và ô.

Bản đồ sau đây cho thấy hai hình tam giác có kích thước và kích thước gần giống nhau. Hình tam giác màu đỏ có thuộc tính geodesic được đặt thành true. Hãy chú ý cách hình dạng của nó thay đổi khi di chuyển về phía bắc.

Xem ví dụ

Lắng nghe các sự kiện chỉnh sửa

Khi một hình dạng được chỉnh sửa, một sự kiện sẽ được kích hoạt sau khi chỉnh sửa xong. Những sự kiện này được liệt kê dưới đây.

Hình dạng Sự kiện
Hình tròn radius_changed
center_changed
Đa giác insert_at
remove_at
set_at

Bạn phải đặt trình nghe trên đường dẫn của đa giác. Nếu đa giác có nhiều đường dẫn, thì bạn phải đặt trình nghe trên mỗi đường dẫn.

Hình nhiều đường insert_at
remove_at
set_at

Bạn phải đặt trình nghe trên đường dẫn của hình nhiều đường.

Rectangle bounds_changed

Một số đoạn mã hữu ích:

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.');
});

Xem ví dụ về cách xử lý sự kiện chỉnh sửa trên hình chữ nhật: xem ví dụ.

Theo dõi sự kiện kéo

Khi một hình dạng được kéo, các sự kiện sẽ được kích hoạt khi bắt đầu và kết thúc hành động kéo cũng như trong quá trình kéo. Các sự kiện sau đây được kích hoạt cho hình nhiều đường, đa giác, hình tròn và hình chữ nhật.

Sự kiện Mô tả
dragstart Được kích hoạt khi người dùng bắt đầu kéo hình dạng.
drag Được kích hoạt nhiều lần trong khi người dùng đang kéo hình dạng.
dragend Được kích hoạt khi người dùng ngừng kéo hình dạng.

Để biết thêm thông tin về cách xử lý sự kiện, hãy xem tài liệu về sự kiện.

Khoanh vùng địa lý và ranh giới vùng an toàn

Google Maps Platform không cung cấp API Khoanh vùng địa lý độc lập. Để hiển thị bán kính khoanh vùng địa lý hoặc vùng an toàn trên bản đồ web và kiểm tra xem toạ độ trực tiếp có nằm trong ranh giới đó hay không, hãy kết hợp các hình dạng với Thư viện hình học (google.maps.GeometryLibrary) được tải thông qua google.maps.importLibrary("geometry"):

Ví dụ sau đây vẽ một vùng an toàn hình tròn và một hàng rào địa lý đa giác, sau đó kiểm tra xem toạ độ trực tiếp có nằm trong mỗi ranh giới hay không:

const {Circle, Polygon} = await google.maps.importLibrary("maps");
const {poly} = await google.maps.importLibrary("geometry");

const livePosition = {lat: 37.424, lng: -122.085};

// 1. Circular geofence (500-meter radius)
const circularGeofence = new Circle({
  map,
  center: {lat: 37.422, lng: -122.084},
  radius: 500,
});
const isInsideCircle = poly.containsLocation(livePosition, circularGeofence);

// 2. Polygonal geofence
const polygonGeofence = new Polygon({
  map,
  paths: [
    {lat: 37.420, lng: -122.088},
    {lat: 37.420, lng: -122.080},
    {lat: 37.426, lng: -122.080},
    {lat: 37.426, lng: -122.088},
  ],
});
const isInsidePolygon = poly.containsLocation(livePosition, polygonGeofence);