形状和线条

请选择平台: Android iOS

您可以向地图添加各种形状。形状是地图上的一种对象,与 LatLng 坐标系相关联。Maps JavaScript API 中的 3D 地图支持向地图添加线条和多边形。

多段线

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

添加多段线

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

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

  • outerColor:格式为 "#FFFFFF" 的十六进制 HTML 颜色。
  • outerWidth:介于 0.01.0 之间的数值,可解读为 strokeWidth 的百分比。
  • strokeColor:格式为 "#FFFFFF" 的十六进制 HTML 颜色。
  • strokeWidth:线条的宽度(以像素为单位)。
  • geodesic:多边形的边缘是遵循地球的曲率,还是绘制为直线。
  • altitudeMode:如何解读坐标中的海拔高度分量
  • drawsOccludedSegments:一个布尔值,用于指示是否应绘制被对象(例如建筑物)遮挡的多边形部分。
  • extruded:一个布尔值,用于指示是否应将折线连接到地面。

let map;
async function init() {
    const { Map3DElement, Polyline3DElement } =
        await google.maps.importLibrary('maps3d');

    map = new Map3DElement({
        center: { lat: 37.7927, lng: -122.402, altitude: 65.93 },
        range: 3362.87,
        tilt: 64.01,
        heading: 25.0,
        mode: 'SATELLITE',
        gestureHandling: 'COOPERATIVE',
    });

    document.body.append(map);

    const polyline = new Polyline3DElement({
        path: [
            { lat: 37.80515638571346, lng: -122.4032569467164 },
            { lat: 37.80337073509504, lng: -122.4012878349353 },
            { lat: 37.79925208843463, lng: -122.3976697250461 },
            { lat: 37.7989102378512, lng: -122.3983408725656 },
            { lat: 37.79887832784348, lng: -122.3987094864192 },
            { lat: 37.79786443410338, lng: -122.4066878788802 },
            { lat: 37.79549248916587, lng: -122.4032992702785 },
            { lat: 37.78861484290265, lng: -122.4019489189814 },
            { lat: 37.78618687561075, lng: -122.398969592545 },
            { lat: 37.7892310309145, lng: -122.3951458683092 },
            { lat: 37.7916358762409, lng: -122.3981969390652 },
        ],
        strokeColor: 'blue',
        outerColor: 'white',
        strokeWidth: 10,
        outerWidth: 0.4,
        altitudeMode: 'RELATIVE_TO_GROUND', // Place it on the ground (as it has no altitude it will just be at ground height).
        drawsOccludedSegments: true, // Show the line through the buildings or anything else that might get in the way.
    });

    map.append(polyline);
}

void init();

交互式多段线

以下示例在注册点击事件后切换多段线的 drawsOccludedSegments 属性。

let map;
async function init() {
    const { Map3DElement, Polyline3DInteractiveElement } =
        await google.maps.importLibrary('maps3d');

    map = new Map3DElement({
        center: { lat: 37.7927, lng: -122.402, altitude: 65.93 },
        range: 3362.87,
        tilt: 64.01,
        heading: 25.0,
        mode: 'SATELLITE',
        gestureHandling: 'COOPERATIVE',
    });

    document.body.append(map);

    const polyline = new Polyline3DInteractiveElement({
        coordinates: [
            { lat: 37.80515638571346, lng: -122.4032569467164 },
            { lat: 37.80337073509504, lng: -122.4012878349353 },
            { lat: 37.79925208843463, lng: -122.3976697250461 },
            { lat: 37.7989102378512, lng: -122.3983408725656 },
            { lat: 37.79887832784348, lng: -122.3987094864192 },
            { lat: 37.79786443410338, lng: -122.4066878788802 },
            { lat: 37.79549248916587, lng: -122.4032992702785 },
            { lat: 37.78861484290265, lng: -122.4019489189814 },
            { lat: 37.78618687561075, lng: -122.398969592545 },
            { lat: 37.7892310309145, lng: -122.3951458683092 },
            { lat: 37.7916358762409, lng: -122.3981969390652 },
        ],
        strokeColor: 'blue',
        outerColor: 'white',
        strokeWidth: 10,
        outerWidth: 0.4,
        altitudeMode: 'RELATIVE_TO_GROUND', // Place it on the ground (as it has no altitude it will just be at ground height).
        drawsOccludedSegments: true, // Show the line through the buildings or anything else that might get in the way.
    });

    polyline.addEventListener('gmp-click', function () {
        // Toggle whether the line draws occluded segments.
        this.drawsOccludedSegments = !this.drawsOccludedSegments;
    });

    map.append(polyline);
}

void init();

多边形

多边形表示由闭合路径(或环路)封闭的区域,由一系列坐标定义。Polygon3DElement 对象与 Polyline3DElement 对象类似,因为它们都包含一系列有序的坐标。多边形使用描边和填充区绘制而成。您可以为多边形的边缘(描边)定义自定义颜色和宽度,并为封闭区域(填充区)定义自定义颜色和不透明度。颜色应以十六进制HTML格式表示,不支持颜色名称。

Polygon3DElement 对象可以描述复杂形状,其中包括:

  • 由单个多边形定义的多个不连续区域。
  • 带孔的区域。
  • 一个或多个区域的交集。

要定义复杂形状,需要使用包含多条路径的多边形。

添加多边形

由于多边形区域可能包含多条单独路径,因此 Polygon3DElement 对象的 paths 属性会指定一个数组的数组。每个数组都会定义一个单独的有序 LatLng 坐标序列。

对于仅包含一条路径的基本多边形,您可以只使用一个 LatLng 坐标数组来构建 Polygon3DElement。在构建完成后将此数组存储到 path 属性内时,Maps JavaScript API 中的 3D 地图会将其转换为一个数组的数组。

async function init() {
    const { Map3DElement, Polygon3DElement } =
        await google.maps.importLibrary('maps3d');

    const map3DElement = new Map3DElement({
        center: { lat: 40.6842, lng: -74.0019, altitude: 1000 },
        heading: 340,
        tilt: 70,
        mode: 'HYBRID',
        gestureHandling: 'COOPERATIVE',
    });

    const polygonOptions = {
        strokeColor: '#0000ff80',
        strokeWidth: 8,
        fillColor: '#ff000080',
        drawsOccludedSegments: false,
    };

    const examplePolygon = new Polygon3DElement(polygonOptions);

    examplePolygon.path = [
        { lat: 40.7144, lng: -74.0208 },
        { lat: 40.6993, lng: -74.019 },
        { lat: 40.7035, lng: -74.0004 },
    ];

    map3DElement.append(examplePolygon);

    document.body.append(map3DElement);
}

void init();

交互式多边形

以下示例在注册点击事件后更改多边形的内部和外部颜色。

async function init() {
    const { Map3DElement, Polygon3DInteractiveElement } =
        await google.maps.importLibrary('maps3d');

    const map = new Map3DElement({
        center: { lat: 40.6842, lng: -74.0019, altitude: 1000 },
        heading: 340,
        tilt: 70,
        mode: 'HYBRID',
        gestureHandling: 'COOPERATIVE',
    });

    document.body.append(map);

    const polygonOptions = {
        strokeColor: '#0000ff80',
        strokeWidth: 8,
        fillColor: '#ff000080',
        drawsOccludedSegments: false,
    };

    const examplePolygon = new Polygon3DInteractiveElement(polygonOptions);

    examplePolygon.path = [
        { lat: 40.7144, lng: -74.0208 },
        { lat: 40.6993, lng: -74.019 },
        { lat: 40.7035, lng: -74.0004 },
        { lat: 40.7144, lng: -74.0208 },
    ];

    examplePolygon.addEventListener('gmp-click', function (event) {
        // change the color of the polygon stroke and fill colors to a random alternatives!
        this.fillColor = randomizeHexColor(this.fillColor);
        this.strokeColor = randomizeHexColor(this.strokeColor);
        console.log(event);
    });

    map.append(examplePolygon);
}

function randomizeHexColor(originalHexColor) {
    console.log(originalHexColor);
    const alpha = originalHexColor.substring(7);

    // Generate random values for Red, Green, Blue (0-255)
    const r = Math.floor(Math.random() * 256);
    const g = Math.floor(Math.random() * 256);
    const b = Math.floor(Math.random() * 256);

    console.log(r + ' ' + g + ' ' + b);

    // Convert decimal to 2-digit hex, padding with '0' if needed
    const rHex = ('0' + r.toString(16)).slice(-2);
    const gHex = ('0' + g.toString(16)).slice(-2);
    const bHex = ('0' + b.toString(16)).slice(-2);

    // Combine parts: '#' + random RGB + original Alpha (if any)
    return `#${rHex}${gHex}${bHex}${alpha}`;
}

void init();