形状和线条

请选择平台: Android iOS JavaScript

您可以向地图添加各种形状。形状是地图上的一种对象,与某个纬度/经度坐标相关联。可用的形状包括以下几种:线条多边形圆形矩形。您还可以配置形状,让用户可以修改或拖动形状

多段线

要在地图上绘制线条,可以使用多段线。Polyline 类可定义地图上的线性相连线段叠加层。Polyline 对象包含一组 LatLng 位置,并可创建一系列线段,依照先后次序将这些位置连接起来。

添加多段线

Polyline 构造函数可接受一组 PolylineOptions(用于指定线条的 LatLng 坐标)和一组样式(用于调整多段线的视觉行为)。

Polyline 对象在地图上绘制为一系列直线段。您可以在构建线条时通过 PolylineOptions 指定线条描边的自定义颜色、粗细和不透明度,也可以在构建后更改这些属性。多段线支持下列描边样式:

  • strokeColor,用于指定 "#FFFFFF" 格式的十六进制 HTML 颜色。Polyline 类不支持使用颜色名称来指定颜色。
  • strokeOpacity,用于指定介于 0.01.0 之间的一个数值,以确定线条颜色的不透明度。默认值为 1.0
  • strokeWeight,用于指定线条的宽度(以像素为单位)。

多段线的 editable 属性用于指定用户是否可以修改相应形状。请参阅下面的用户可修改的形状。同样,您可以设置 draggable 属性,允许用户拖动相应线条

此示例创建了一条 2 像素宽的红色多段线,用于显示从加利福尼亚州奥克兰到澳大利亚布里斯班的首次跨太平洋航班的航线。

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.

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

  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 google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2,
  });

  flightPath.setMap(map);
}

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

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.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 3,
    center: { lat: 0, lng: -180 },
    mapTypeId: "terrain",
  });
  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 google.maps.Polyline({
    path: flightPlanCoordinates,
    geodesic: true,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2,
  });

  flightPath.setMap(map);
}

window.initMap = initMap;
查看示例

试用示例

移除多段线

要从地图中移除多段线,请调用 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;
let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 7,
    center: { lat: 41.879, lng: -87.624 }, // Center the map on Chicago, USA.
  });

  poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
  });
  poly.setMap(map);

  // Add a listener for the click event
  map.addListener("click", addLatLng);
}

// Handles click events on a map, and adds a new point to the Polyline.
function addLatLng(event: google.maps.MapMouseEvent) {
  const path = poly.getPath();

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

  // Add a new marker at the new plotted point on the polyline.
  new google.maps.Marker({
    position: event.latLng,
    title: "#" + path.getLength(),
    map: map,
  });
}

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

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;
let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 7,
    center: { lat: 41.879, lng: -87.624 }, // Center the map on Chicago, USA.
  });
  poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
  });
  poly.setMap(map);
  // Add a listener for the click event
  map.addListener("click", addLatLng);
}

// Handles click events on a map, and adds a new point to the Polyline.
function addLatLng(event) {
  const path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear.
  path.push(event.latLng);
  // Add a new marker at the new plotted point on the polyline.
  new google.maps.Marker({
    position: event.latLng,
    title: "#" + path.getLength(),
    map: map,
  });
}

window.initMap = initMap;
查看示例

试用示例

自定义多段线

您可以向多段线添加符号形式的矢量图。通过结合使用符号和 PolylineOptions 类,您可以从很多方面控制地图上多段线的外观和风格。有关箭头虚线自定义符号动画符号的信息,请参阅符号

多边形

多边形表示由闭合路径(或环路)封闭的区域,由一系列坐标定义。Polygon 对象与 Polyline 对象类似,因为它们都包含一系列有序的坐标。多边形使用描边和填充区绘制而成。您可以为多边形的边缘(描边)定义自定义颜色、粗细和不透明度,并为封闭区域(填充区)定义自定义颜色和不透明度。颜色应以十六进制 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 包含四组 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 对象的专属类,用以简化其构建过程。

添加矩形

RectanglePolygon 类似,您也可以为矩形的边缘(描边)定义自定义颜色、粗细和不透明度,并为矩形内的区域(填充区)定义自定义颜色和不透明度。颜色应以十六进制数值 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 对象的专属类,用以简化其构建过程。

添加圆形

CirclePolygon 类似,您也可以为圆形的边缘(描边)定义自定义颜色、粗细和不透明度,并为圆形内的区域(填充区)定义自定义颜色和不透明度。颜色应以十六进制数值 HTML 样式表示。

Polygon 不同的是,您无需为 Circle 定义 paths。不过,圆形有两个用于定义其形状的其他属性:

  • center,用于指定圆心的 google.maps.LatLng
  • radius,用于指定圆形的半径(以米为单位)。

圆形的 editable 属性用于指定用户是否可以修改相应形状。请参阅下面的用户可修改的形状。同样,您可以设置 draggable 属性,以允许用户拖动相应圆形

以下示例使用圆圈显示日本京都各地点之间的大致步行时间。从菜单中选择所需的距离,点击地图以重新居中显示圆圈,然后拖动圆圈以重新定位。

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap;

async function initMap() {
    // Import the needed libraries.
    // Request needed libraries.
    (await google.maps.importLibrary('maps')) as google.maps.MapsLibrary;
    (await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary;
    // Get the gmp-map element.
    const mapElement = document.querySelector(
        'gmp-map'
    ) as google.maps.MapElement;

    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan

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

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

    const walkingCircle = new google.maps.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 google.maps.marker.AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        //@ts-ignore
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);

    // Wait for the map to finish drawing its tiles.
    google.maps.event.addListenerOnce(innerMap, 'tilesloaded', function () {
        // 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', (event) => {
            const target = event.target as HTMLInputElement;
            walkingCircle.setRadius(Number(target.value));
        });
    });

    // Handle user click, reset the map center and position the circle.
    innerMap.addListener('click', (mapsMouseEvent) => {
        const newCenter = mapsMouseEvent.latLng;
        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();
    });
}

initMap();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
async function initMap() {
    // Import the needed libraries.
    // Request needed libraries.
    (await google.maps.importLibrary('maps'));
    (await google.maps.importLibrary('marker'));
    // Get the gmp-map element.
    const mapElement = document.querySelector('gmp-map');
    const initialCenter = { lat: 34.98956821576194, lng: 135.74239981260283 }; // Hotel Emion, Kyoto, Japan
    // Get the inner map.
    const innerMap = mapElement.innerMap;
    const buttons = document.querySelectorAll('input[name="radius"]');
    const walkingCircle = new google.maps.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 google.maps.marker.AdvancedMarkerElement({
        position: initialCenter,
        title: 'A marker using a custom SVG image.',
        //@ts-ignore
        anchorLeft: '-50%',
        anchorTop: '-50%',
    });
    centerMarker.append(pinSvg);
    mapElement.append(centerMarker);
    // Wait for the map to finish drawing its tiles.
    google.maps.event.addListenerOnce(innerMap, 'tilesloaded', function () {
        // 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', (event) => {
            const target = event.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;
        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();
    });
}
initMap();

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>
        <!-- prettier-ignore -->
        <script>(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", v: "weekly"});</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 在用户停止拖动形状时触发。

如需详细了解如何处理事件,请参阅关于事件的文档