形状

请选择平台: Android iOS JavaScript

包含红色多段实线的地图

借助 Google Maps API for Android,您可以通过一些简单的方式向地图中添加形状,从而根据您的应用需要对地图进行自定义。

  • Polyline(多段线)是一系列相连的线段,可组成您想要的任何形状,并可用于在地图上标记路径和路线。
  • Polygon(多边形)是一种封闭形状,可用于在地图上标记区域。
  • Circle(圆形)是在地图上绘制的圆圈在地球表面的准确地理位置的投影。

对于所有上述形状,您都可以通过改变若干属性来自定义其外观。

代码示例

在添加用于表示路线和区域的多段线和多边形的教程中,包含简单 Android 应用的所有代码。

此外,GitHub 上的 ApiDemos 代码库中也有一些示例演示了如何使用形状及其地图项:

多段线

Polyline 类在地图上定义一组相连的线段。Polyline 对象包含一组 LatLng 位置,并可创建一系列线段,依照先后次序将这些位置连接起来。

请观看这段视频,了解如何通过使用多段线在地图上绘制路径,帮助您的用户到达目的地。

如需创建多段线,请先创建一个 PolylineOptions 对象并为其添加点。点表示地球表面上的点,以 LatLng 对象的形式表示。系统会按照您向 PolylineOptions 对象添加点的顺序在各点之间绘制线段。

如需向 PolylineOptions 对象添加点,请调用 PolylineOptions.add()。请注意,该方法带有可变数量的参数,因此您可以一次添加多个点(如果点已存在于列表中,您还可以调用 PolylineOptions.addAll(Iterable<LatLng>))。

然后,您可以调用 GoogleMap.addPolyline(PolylineOptions),将多段线添加到地图中。该方法会返回 Polyline 对象,您稍后可利用该对象对多段线做出改动。

以下代码段说明了如何向地图添加矩形:

Kotlin



// Instantiates a new Polyline object and adds points to define a rectangle
val polylineOptions = PolylineOptions()
    .add(LatLng(37.35, -122.0))
    .add(LatLng(37.45, -122.0)) // North of the previous point, but at the same longitude
    .add(LatLng(37.45, -122.2)) // Same latitude, and 30km to the west
    .add(LatLng(37.35, -122.2)) // Same longitude, and 16km to the south
    .add(LatLng(37.35, -122.0)) // Closes the polyline.

// Get back the mutable Polyline
val polyline = map.addPolyline(polylineOptions)

      

Java


// Instantiates a new Polyline object and adds points to define a rectangle
PolylineOptions polylineOptions = new PolylineOptions()
    .add(new LatLng(37.35, -122.0))
    .add(new LatLng(37.45, -122.0))  // North of the previous point, but at the same longitude
    .add(new LatLng(37.45, -122.2))  // Same latitude, and 30km to the west
    .add(new LatLng(37.35, -122.2))  // Same longitude, and 16km to the south
    .add(new LatLng(37.35, -122.0)); // Closes the polyline.

// Get back the mutable Polyline
Polyline polyline = map.addPolyline(polylineOptions);

      

该矩形随即会显示在地图上,如下所示:

包含矩形多段线的地图

如需在添加多段线后改变其形状,您可以调用 Polyline.setPoints(),并为多段线提供一个新的点列表。

在将多段线添加到地图之前和之后,您都可以自定义其外观。如需进一步了解相关信息,请参阅下文有关自定义外观的部分。

多段线自定义

您可以通过以下几种方式对多段线的外观进行自定义:

  • 多色多段线:将多段线的各个线段设置为不同的颜色。
  • 渐变多段线:使用 2 种颜色之间的渐变效果为多段线着色。
  • 印花多段线:使用重复显示的位图来为多段线设置样式。

如需使用多段线自定义功能,您必须使用 18.1.0 版或更高版本的 Maps SDK for Android,并使用最新版 Maps SDK for Android 渲染程序

创建多色多段线

包含多色多段线的地图

您可以使用跨度分别为多段线的各个线段着色,只需创建 StyleSpan 对象,然后使用 addSpan()addSpans() 方法将这些对象添加到 PolylineOptions 数组即可。默认情况下,该数组中的每一项将用来设置相应线段的颜色。以下示例展示了如何通过设置线段颜色来创建带有红色和绿色线段的多段线:

Kotlin



val line = map.addPolyline(
    PolylineOptions()
        .add(LatLng(47.6677146, -122.3470447), LatLng(47.6442757, -122.2814693))
        .addSpan(StyleSpan(Color.RED))
        .addSpan(StyleSpan(Color.GREEN))
)

      

Java


Polyline line = map.addPolyline(new PolylineOptions()
        .add(new LatLng(47.6677146,-122.3470447), new LatLng(47.6442757,-122.2814693))
        .addSpan(new StyleSpan(Color.RED))
        .addSpan(new StyleSpan(Color.GREEN)));

      

创建渐变多段线

包含渐变多段线的地图

您可以通过指定两个 32 位 Alpha-红-绿-蓝 (ARGB) 整数来指定描边的起始颜色和结束颜色,以这种方式定义渐变。可通过调用 PolylineOptions.addSpan() 在形状的 options 对象上设置此属性。以下示例展示了如何在华盛顿州的林地公园动物园与柯克兰之间创建颜色由红色变为黄色的渐变多段线。

Kotlin



val line = map.addPolyline(
    PolylineOptions()
        .add(LatLng(47.6677146, -122.3470447), LatLng(47.6442757, -122.2814693))
        .addSpan(
            StyleSpan(
                StrokeStyle.gradientBuilder(
                    Color.RED,
                    Color.YELLOW
                ).build()
            )
        )
)

      

Java


Polyline line = map.addPolyline(new PolylineOptions()
        .add(new LatLng(47.6677146,-122.3470447), new LatLng(47.6442757,-122.2814693))
        .addSpan(new StyleSpan(StrokeStyle.gradientBuilder(Color.RED, Color.YELLOW).build())));

      

创建印花多段线

包含印花多段线的地图

您可以将多段线的外观设置为重复显示的位图纹理。为此,请创建值为 TextureStyleStampStyle,然后通过调用 PolylineOptions.addSpan() 来在形状的 options 对象中设置此属性,如下所示:

Kotlin



val stampStyle =
    TextureStyle.newBuilder(BitmapDescriptorFactory.fromResource(R.drawable.walking_dot)).build()
val span = StyleSpan(StrokeStyle.colorBuilder(Color.RED).stamp(stampStyle).build())
map.addPolyline(
    PolylineOptions()
        .add(LatLng(47.6677146, -122.3470447), LatLng(47.6442757, -122.2814693))
        .addSpan(span)
)

      

Java


StampStyle stampStyle =
        TextureStyle.newBuilder(BitmapDescriptorFactory.fromResource(R.drawable.walking_dot)).build();
StyleSpan span = new StyleSpan(StrokeStyle.colorBuilder(Color.RED).stamp(stampStyle).build());
map.addPolyline(new PolylineOptions()
        .add(new LatLng(47.6677146,-122.3470447), new LatLng(47.6442757,-122.2814693))
        .addSpan(span));

      

多段线事件

默认情况下,多段线无法点击。您可以通过调用 Polyline.setClickable(boolean) 来允许和禁止点击。

使用 OnPolylineClickListener 可以监听可点击的多段线上的点击事件。如需在地图上设置此监听器,请调用 GoogleMap.setOnPolylineClickListener(OnPolylineClickListener)。当用户点击多段线时,您会收到 onPolylineClick(Polyline) 回调。

多边形

Polygon 对象与 Polyline 对象类似,因为它们都包含一系列有序的坐标。不过,多边形并不是开放式的,它们用于定义闭合环路内的区域,并且内部是实心的。

您可以按照添加 Polyline 的方法向地图添加 Polygon。首先,需要创建一个 PolygonOptions 对象并为其添加一些点。这些点将组成多边形的轮廓。然后通过调用 GoogleMap.addPolygon(PolygonOptions)(该函数会返回 Polygon 对象),将多边形添加到地图中。

以下代码段的作用是向地图添加一个矩形。

Kotlin



// Instantiates a new Polygon object and adds points to define a rectangle
val rectOptions = PolygonOptions()
    .add(
        LatLng(37.35, -122.0),
        LatLng(37.45, -122.0),
        LatLng(37.45, -122.2),
        LatLng(37.35, -122.2),
        LatLng(37.35, -122.0)
    )

// Get back the mutable Polygon
val polygon = map.addPolygon(rectOptions)

      

Java


// Instantiates a new Polygon object and adds points to define a rectangle
PolygonOptions polygonOptions = new PolygonOptions()
    .add(new LatLng(37.35, -122.0),
        new LatLng(37.45, -122.0),
        new LatLng(37.45, -122.2),
        new LatLng(37.35, -122.2),
        new LatLng(37.35, -122.0));

// Get back the mutable Polygon
Polygon polygon = map.addPolygon(polygonOptions);

      

如需在添加多边形后改变其形状,您可以调用 Polygon.setPoints() 并为该多边形的轮廓提供新的点列表。

在将多边形添加到地图之前和之后,您都可以自定义其外观。如需进一步了解相关信息,请参阅下文有关自定义外观的部分。

多边形自动完成

以上示例中的多边形包含五个坐标,但请注意,其中第一个坐标和最后一个坐标的位置相同,这样就定义了一个环路。不过,实际上由于多边形定义的就是封闭区域,因而无需定义这最后一个坐标。如果最后一个坐标不同于第一个坐标,API 将通过在坐标序列的末尾追加第一个坐标来自动“封闭”多边形。

以下两个多边形是相同的,针对其中任一个调用 polygon.getPoints() 都将返回所有 4 个点。

Kotlin



val polygon1 = map.addPolygon(
    PolygonOptions()
        .add(
            LatLng(0.0, 0.0),
            LatLng(0.0, 5.0),
            LatLng(3.0, 5.0),
            LatLng(0.0, 0.0)
        )
        .strokeColor(Color.RED)
        .fillColor(Color.BLUE)
)
val polygon2 = map.addPolygon(
    PolygonOptions()
        .add(
            LatLng(0.0, 0.0),
            LatLng(0.0, 5.0),
            LatLng(3.0, 5.0)
        )
        .strokeColor(Color.RED)
        .fillColor(Color.BLUE)
)

      

Java


Polygon polygon1 = map.addPolygon(new PolygonOptions()
    .add(new LatLng(0, 0),
        new LatLng(0, 5),
        new LatLng(3, 5),
        new LatLng(0, 0))
    .strokeColor(Color.RED)
    .fillColor(Color.BLUE));

Polygon polygon2 = map.addPolygon(new PolygonOptions()
    .add(new LatLng(0, 0),
        new LatLng(0, 5),
        new LatLng(3, 5))
    .strokeColor(Color.RED)
    .fillColor(Color.BLUE));

      

创建空心多边形

可以在一个 Polygon 对象中组合多个路径来创建复杂形状,如填充环,或“圆环”(其中的多边形区域在多边形内呈“岛状”)。复杂形状总是由多个较简单的路径组成。

您必须在同一区域内定义两个路径。两个区域中的较大者定义填充区域,它是一个没有附加选项的简单多边形。然后,将第二个路径传递给 addHole() 方法。当较小的第二个路径被较大路径完全包围时,就会产生好像多边形的一部分被挖掉的效果。如果该孔与多边形轮廓相交,多边形渲染时将不做任何填充。

以下代码段将创建一个矩形,并使其具有一个较小的矩形孔。

Kotlin



val hole = listOf(
    LatLng(1.0, 1.0),
    LatLng(1.0, 2.0),
    LatLng(2.0, 2.0),
    LatLng(2.0, 1.0),
    LatLng(1.0, 1.0)
)
val hollowPolygon = map.addPolygon(
    PolygonOptions()
        .add(
            LatLng(0.0, 0.0),
            LatLng(0.0, 5.0),
            LatLng(3.0, 5.0),
            LatLng(3.0, 0.0),
            LatLng(0.0, 0.0)
        )
        .addHole(hole)
        .fillColor(Color.BLUE)
)

      

Java


List<LatLng> hole = Arrays.asList(new LatLng(1, 1),
    new LatLng(1, 2),
    new LatLng(2, 2),
    new LatLng(2, 1),
    new LatLng(1, 1));
Polygon hollowPolygon = map.addPolygon(new PolygonOptions()
    .add(new LatLng(0, 0),
        new LatLng(0, 5),
        new LatLng(3, 5),
        new LatLng(3, 0),
        new LatLng(0, 0))
    .addHole(hole)
    .fillColor(Color.BLUE));

      

地图上会显示空心多边形,如下所示:

包含空心矩形多段线的地图

多边形事件

默认情况下,多边形无法点击。您可以通过调用 Polygon.setClickable(boolean) 来允许和禁止点击。

使用 OnPolygonClickListener 可以监听可点击的多边形上的点击事件。如需在地图上设置此监听器,请调用 GoogleMap.setOnPolygonClickListener(OnPolygonClickListener)。当用户点击多边形时,您会收到 onPolygonClick(Polygon) 回调。

圆形

带有圆形的地图

除了常规的 Polygon 类之外,Maps API 还包含 Circle 对象的专属类,用以简化其构建过程。

如需构建圆形,您必须指定以下两个属性:

  • center,以 LatLng 形式表示。
  • radius(以米为单位)。

然后便可将圆形定义为地球表面上所有与给定 center 的距离为 radius 米的点的集合。Maps API 使用墨卡托投影法在平面上呈现球形,由于所用方式的缘故,当圆形位于地图上靠近赤道的位置时,呈现的将是近乎完美的圆,而随着圆形距离赤道越来越远,则愈发(在屏幕上)呈现为非圆形状。

如需在添加圆形后改变其形状,您可以调用 Circle.setRadius()Circle.setCenter() 并提供新值。

在将圆形添加到地图之前和之后,您都可以自定义其外观。如需进一步了解相关信息,请参阅下文有关自定义外观的部分。

以下代码段会通过构建 CircleOptions 对象和调用 GoogleMap.addCircle(CircleOptions),为地图添加一个圆形:

Kotlin



// Instantiates a new CircleOptions object and defines the center and radius
val circleOptions = CircleOptions()
    .center(LatLng(37.4, -122.1))
    .radius(1000.0) // In meters

// Get back the mutable Circle
val circle = map.addCircle(circleOptions)

      

Java


// Instantiates a new CircleOptions object and defines the center and radius
CircleOptions circleOptions = new CircleOptions()
    .center(new LatLng(37.4, -122.1))
    .radius(1000); // In meters

// Get back the mutable Circle
Circle circle = map.addCircle(circleOptions);

      

圆形事件

默认情况下,圆无法点击。您可以通过使用 CircleOptions.clickable(boolean) 调用 GoogleMap.addCircle() 或通过调用 Circle.setClickable(boolean) 来允许和禁止点击。

使用 OnCircleClickListener 可以监听可点击的圆形上的点击事件。如需在地图上设置此监听器,请调用 GoogleMap.setOnCircleClickListener(OnCircleClickListener)

当用户点击某个圆形时,您会收到 onCircleClick(Circle) 回调,如以下代码示例所示:

Kotlin



val circle = map.addCircle(
    CircleOptions()
        .center(LatLng(37.4, -122.1))
        .radius(1000.0)
        .strokeWidth(10f)
        .strokeColor(Color.GREEN)
        .fillColor(Color.argb(128, 255, 0, 0))
        .clickable(true)
)
map.setOnCircleClickListener {
    // Flip the r, g and b components of the circle's stroke color.
    val strokeColor = it.strokeColor xor 0x00ffffff
    it.strokeColor = strokeColor
}

      

Java


Circle circle = map.addCircle(new CircleOptions()
    .center(new LatLng(37.4, -122.1))
    .radius(1000)
    .strokeWidth(10)
    .strokeColor(Color.GREEN)
    .fillColor(Color.argb(128, 255, 0, 0))
    .clickable(true));

map.setOnCircleClickListener(new GoogleMap.OnCircleClickListener() {
    @Override
    public void onCircleClick(Circle circle) {
        // Flip the r, g and b components of the circle's stroke color.
        int strokeColor = circle.getStrokeColor() ^ 0x00ffffff;
        circle.setStrokeColor(strokeColor);
    }
});

      

自定义外观

在向地图添加形状之前和之后,您都可以改变其外观,其中前者是通过在 options 对象上指定所需属性来实现。此外,所有属性的 getter 方法都已公开,以便您轻松获取形状的当前状态。

以下代码段将会添加一条蓝色的粗多段线,其中包含从墨尔本至珀斯的测地线段。下文将详细介绍这些属性。

Kotlin



val polyline = map.addPolyline(
    PolylineOptions()
        .add(LatLng(-37.81319, 144.96298), LatLng(-31.95285, 115.85734))
        .width(25f)
        .color(Color.BLUE)
        .geodesic(true)
)

      

Java


Polyline polyline = map.addPolyline(new PolylineOptions()
    .add(new LatLng(-37.81319, 144.96298), new LatLng(-31.95285, 115.85734))
    .width(25)
    .color(Color.BLUE)
    .geodesic(true));

      

地图如下所示:

包含从墨尔本至珀斯的多段线的地图

注意:尽管这些属性大都可以应用于上述任何一种形状,但某些属性可能不适用于特定形状(例如,多段线不能有填充颜色,因为它没有内部区域)。

描边颜色

描边颜色是一个 32 位 Alpha-红-绿-蓝 (ARGB) 整数,用于指定形状描边的不透明度和颜色。可通过调用 *Options.strokeColor()(如果是多段线,则调用 PolylineOptions.color())在形状的 options 对象上设置此属性。如果未指定该属性,则默认描边颜色为黑色 (Color.BLACK)。

向地图添加形状后,可通过调用 getStrokeColor()(对于多段线,则是调用 getColor())来获取描边颜色,并可通过调用 setStrokeColor() (setColor() for a polyline) 更改描边颜色。

填充颜色

填充颜色仅适用于多边形和圆,不适用于多段线,因为多段线没有指定的内部区域。多边形孔内的区域不属于多边形的内部区域,因此即使设置了填充颜色,系统也不会为该部分着色。

填充颜色是一个 32 位 Alpha-红-绿-蓝 (ARGB) 整数,用于指定形状内部的不透明度和颜色。可通过调用 *Options.fillColor() 在形状的 options 对象上设置此属性。如果未指定该属性,则默认描边颜色为透明色 (Color.TRANSPARENT)。

向地图添加形状后,可通过调用 getFillColor() 来获取填充颜色,并可通过调用 setFillColor() 来更改填充颜色。

描边宽度

线的描边宽度,表示为以像素 (px) 为单位的浮点数。该宽度不会随地图的缩放而缩放(即,形状在所有缩放级别下的描边宽度均相同)。可通过调用 *Options.strokeWidth()(对于多段线,则是调用 PolylineOptions.width())在形状的 option 对象上设置此属性。如果未指定,则默认描边宽度为 10 像素。

向地图添加形状后,可通过调用 getStrokeWidth()(对于多段线,则是调用 getWidth())来获取描边宽度,并可通过调用 setStrokeWidth() (setWidth() for a polyline) 更改描边宽度。

描边图案

多边形和圆形的轮廓以及多段线的默认描边图案是实线。您可以为 PatternItem 对象指定自定义描边图案,其中每一项都是短划线、点或间隙。

以下示例将多段线的图案设置成了按如下顺序重复显示的图案:一个点、后跟一个长度为 20 像素的间隙、一个长度为 30 像素的短划线,以及另一个 20 像素的间隙。

Kotlin



val pattern = listOf(
    Dot(), Gap(20F), Dash(30F), Gap(20F)
)
polyline.pattern = pattern

      

Java


List<PatternItem> pattern = Arrays.asList(
    new Dot(), new Gap(20), new Dash(30), new Gap(20));
polyline.setPattern(pattern);

      

图案沿直线重复显示,从为形状指定的第一个顶点处的第一个图案项开始。

连接类型

对于多段线和多边形的轮廓,您可以指定棱台或圆角 JointType,以替代默认的固定斜角连接。

以下示例将为多段线应用圆角连接:

Kotlin



polyline.jointType = JointType.ROUND

      

Java


polyline.setJointType(JointType.ROUND);

      

连接类型会影响线条的内部转弯。如果该线条的描边图案包含短划线,当短划线横跨连接时,连接类型也适用。连接类型不会影响点,因为它们始终为圆形。

线帽

您可以为多段线的各个端点指定 Cap 样式。选项包括平端(默认)、方端、圆端或自定义位图。在 PolylineOptions.startCapPolylineOptions.endCap 中设置样式,或者使用相应的 getter 和 setter 方法。

以下代码段会为多段线的起点指定一个圆帽。

Kotlin



polyline.startCap = RoundCap()

      

Java


polyline.setStartCap(new RoundCap());

      

以下代码段会为尾帽指定自定义位图:

Kotlin



polyline.endCap = CustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow), 16F)

      

Java


polyline.setEndCap(
    new CustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow), 16));

      

使用自定义位图时,您应该指定参考描边宽度(以像素为单位)。API 会相应缩放位图。参考描边宽度是您在图片原始尺寸下,为线帽设计位图图像时使用的描边宽度。默认的参考描边宽度为 10 像素。提示:若要确定参考描边宽度,请在图片编辑器中以 100% 缩放比例打开位图图像,并参照图片绘制所需的线条描边宽度。

如果您使用 BitmapDescriptorFactory.fromResource() 创建位图,请务必使用密度无关资源 (nodpi)。

测地线段

测地设置只适用于多段线和多边形。它不适用于圆,因为按照定义圆并非线段的集合。

测地设置决定多段线/多边形连续顶点之间线段的绘制方式。测地线段是指沿地球表面(球体)依循最短路径的线段,在采用墨卡托投影法的地图上经常以曲线形式出现。非测地线段在地图上绘制为直线。

可通过调用 *Options.geodesic() 在形状的 option 对象上设置此属性,true 表示应将线段绘制为测地线段,false 表示应将线段绘制为直线。如果未指定该属性,则默认绘制非测地线段 (false)。

向地图添加形状后,可通过调用 isGeodesic() 来获取测地设置,并可通过调用 setGeodesic() 更改测地设置。

Z-index

Z-index 用于指定该形状相对于地图上其他叠加层(其他形状、地面叠加层和图块叠加层)的叠放顺序。Z-index 较高的叠加层在 Z-index 较低的叠加层之上绘制。Z-index 相同的两个叠加层按任意顺序绘制。

请注意,无论其他叠加层的 Z-index 如何,标记始终在其他叠加层之上绘制。

可通过调用 *Options.zIndex() 在形状的 options 对象上设置此属性。如果未指定该属性,则默认的 Z-index 为 0。向地图添加形状后,可通过调用 getZIndex() 来获取 Z-index,并可通过调用 setZIndex() 更改 Z-index。

显示设置

显示设置用于指定是否应在地图上绘制形状,其中 true 表示应绘制形状,false 表示不应绘制形状。您可以利用它暂时不在地图上显示某个形状。如需从地图上永久性地移除形状,请针对相应形状调用 remove()

可通过调用 *Options.visible() 在形状的 options 对象上设置此属性。如果未指定该属性,则默认显示设置为 true。向地图添加形状后,可通过调用 isVisible() 来获取显示设置,并可通过调用 setVisible() 更改显示设置。

将数据与形状关联

您可以使用形状的 setTag() 方法存储具有多段线、多边形或圆形的任意数据对象,并使用 getTag() 检索对象。例如,调用 Polyline.setTag() 以存储具有多段线的数据对象,并调用 Polyline.getTag() 来检索数据对象。

以下代码定义了指定多段线的一个任意代码 (A)。

Kotlin



val polyline = map.addPolyline(
    PolylineOptions()
        .clickable(true)
        .add(
            LatLng(-35.016, 143.321),
            LatLng(-34.747, 145.592),
            LatLng(-34.364, 147.891),
            LatLng(-33.501, 150.217),
            LatLng(-32.306, 149.248),
            LatLng(-32.491, 147.309)
        )
)
polyline.tag = "A"

      

Java


Polyline polyline = map.addPolyline((new PolylineOptions())
    .clickable(true)
    .add(new LatLng(-35.016, 143.321),
        new LatLng(-34.747, 145.592),
        new LatLng(-34.364, 147.891),
        new LatLng(-33.501, 150.217),
        new LatLng(-32.306, 149.248),
        new LatLng(-32.491, 147.309)));

polyline.setTag("A");

      

以下示例展示了使用形状存储和检索数据将会很有帮助的情形:

  • 您的应用可能需要使用不同类型的形状,并且您希望在用户点击这些形状时通过不同方式处理它们。
  • 您可能会与包含唯一记录标识符的系统对接,其中形状表示该系统中的特定记录。
  • 形状数据可能会指示用于确定形状 Z-index 的优先级。