使用 Places 界面套件构建交互式商店查找工具

目标

本文档详细介绍了使用 Google Maps Platform(特别是 Maps JavaScript API 和地点界面套件:地点详情元素)开发交互式商店查找器应用的关键步骤。您将学习如何创建用于显示实体店位置的地图、动态更新可见实体店的列表,以及显示每个实体店的丰富地点信息。

前提条件

建议您熟悉以下内容:

在您的项目中启用 Maps JavaScript APIPlaces 界面套件

在开始之前,请先确认您已加载 Maps JavaScript API 并导入了高级标记地点界面套件所需的库。本文档还假定您具备 Web 开发(包括 HTML、CSS 和 JavaScript)方面的工作知识。

初始设置

第一步是向页面添加地图。此地图将用于显示与您的实体店位置相关的图钉。

您可以通过以下两种方式向页面添加地图:

  1. 使用 gmp-map HTML Web 组件
  2. 使用 JavaScript

请选择最适合您的用例的方法。本指南适用于实现映射的两种方式。

演示

此演示展示了实时运作的商店查找工具,其中显示了位于湾区的 Google 办公室位置。系统会为每个地点显示地点详情元素,以及一些示例属性。

加载和显示商店位置

在本部分中,我们将加载您的实体店数据并在地图上显示这些数据。本指南假定您有一个存储库,其中包含可供提取的现有商店信息。您的商店数据可以来自各种来源,例如数据库。 在此示例中,我们假设本地 JSON 文件 (stores.json) 包含一个商店对象数组,每个对象代表一个商店位置。每个对象都应至少包含 namelocation(包含 latlng)和 place_id

如果您还没有商店营业地点的地点 ID,可以通过多种方式检索这些 ID。如需了解详情,请参阅地点 ID 文档

stores.json 文件中的商店详情条目示例如下。其中包含名称、位置(经度/纬度)和地点 ID 字段。有一个对象用于存储商店营业时间(已截断)。此外,还有两个布尔值可帮助描述商店位置的量身定制功能。

{
  "name": "Example Store Alpha",
  "location": { "lat": 51.51, "lng": -0.12 },
  "place_id": "YOUR_STORE_PLACE_ID",
  "opening_hours": { "Monday": "09:00 - 17:00", "...": "..." },
  "new_store_design": true,
  "indoor_seating": false
}

在 JavaScript 代码中,提取实体店位置的数据,并在地图上为每个实体店显示一个图钉。

示例如下。此函数接受一个包含商店详细信息的对象,并根据每个商店的位置创建一个标记。

function displayInitialMarkers(storeLocations) {
    if (!AdvancedMarkerElement || !LatLng || !mapElement) return;
    storeLocations.forEach(store => {
        if (store.location) {
            const marker = new AdvancedMarkerElement({
                position: new LatLng(store.location.lat, store.location.lng),
                title: store.name
            });
            mapElement.appendChild(marker);
        }
    });
}

加载商店并在地图上显示代表其位置的图钉后,使用 HTML 和 CSS 创建边栏,以显示各个商店的详细信息。

此阶段商店定位工具可能如下所示:

图片

监听地图视口更改

为了优化性能和用户体验,请更新您的应用,以便仅在相应位置位于可见地图区域(视口)内时,才在边栏中显示标记和详细信息。这涉及监听地图视口更改、对这些事件进行去抖动,然后仅重新绘制必要的标记。

将事件监听器附加到地图的空闲事件。此事件会在任何平移或缩放操作完成后触发,为您的计算提供稳定的视口。

map.addListener('idle', debounce(updateMarkersInView, 300));

上述代码段会监听 idle 事件,并调用 debounce 函数。使用去抖函数可确保您的标记更新逻辑仅在用户停止与地图互动一段时间后运行,从而提升性能。

function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        const context = this;
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            func.apply(context, args);
        }, delay);
    };
}

以上代码是一个 debounce 函数示例。它接受一个函数和延迟参数,可在空闲监听器中看到传入的参数。300 毫秒的延迟足以等待地图停止移动,而不会给界面增加明显的延迟。超时期限过后,系统会调用传递的函数(在本例中为 updateMarkersInView)。

updateMarkersInView 函数应执行以下操作:

从地图中清除所有现有标记

检查商店的位置是否在当前地图边界内,例如:

if (map.getBounds().contains(storeLatLng)) {
  // logic
}

在上述 if 语句中,编写代码以在边栏中显示标记和商店详细信息(如果商店位置位于地图视口内)。

使用地点详情元素显示丰富的地点详情

在此阶段,应用会显示所有商店位置,用户可以根据地图视口对其进行过滤。为了进一步提升用户体验,我们使用地点详情元素添加了有关每家商店的丰富详细信息,例如照片、评价和无障碍设施信息。此示例专门使用了地点详情紧凑元素

数据源中的每个实体店位置都必须具有相应的地点 ID。此 ID 可唯一标识 Google 地图上的位置,对于提取其详细信息至关重要。您通常会预先获取这些地点 ID,并将其存储在每个商店记录中。

在应用中集成地点详情紧凑元素

当系统确定某个商店位于当前地图视口内并在边栏中呈现时,您可以为其动态创建并插入地点详情紧凑元素。

对于当前正在处理的商店,请从您的数据中检索地点 ID。地点 ID 用于控制该元素将显示在哪个地点。

在 JavaScript 中,动态创建 PlaceDetailsCompactElement 的实例。系统还会创建一个新的 PlaceDetailsPlaceRequestElement,将地点 ID 传递给它,并将其附加到 PlaceDetailsCompactElement。最后,使用 PlaceContentConfigElement 配置该元素将要显示的内容。

以下函数假定已导入必要的酒店信息界面 Kit 库,并且此函数的调用范围内可用这些库,并且传递给该函数的 storeData 包含 place_id

此函数将返回元素,调用代码将负责将其附加到 DOM。

function createPlaceDetailsCompactElement(storeData) {
    // Create the main details component
    const detailsCompact = new PlaceDetailsCompactElement();
    detailsCompact.setAttribute('orientation', 'vertical'); // Or 'horizontal'

    // Specify the Place ID
    const placeRequest = new PlaceDetailsPlaceRequestElement();
    placeRequest.place = storeData.place_id;
    detailsCompact.appendChild(placeRequest);

    // Configure which content elements to display
    const contentConfig = new PlaceContentConfigElement();
    // For this example, we'll render media, rating, accessibility, and attribution:
    contentConfig.appendChild(new PlaceMediaElement({ lightboxPreferred: true }));
    contentConfig.appendChild(new PlaceRatingElement());
    contentConfig.appendChild(new PlaceAccessibleEntranceIconElement());
    // Configure attribution
    const placeAttribution = new PlaceAttributionElement();
    placeAttribution.setAttribute('light-scheme-color', 'gray');
    placeAttribution.setAttribute('dark-scheme-color', 'gray');
    contentConfig.appendChild(placeAttribution);
    detailsCompact.appendChild(contentConfig);
    // Return the element
    return detailsCompact;
}

在上面的示例代码中,该元素配置为显示地点照片、评价和无障碍信息。您可以通过添加或移除其他可用内容元素来自定义此项,如需了解所有可用选项,请参阅 PlaceContentConfigElement 文档。

地点详情紧凑元素支持通过 CSS 自定义属性设置样式。这样,您就可以根据应用的设计来自定义其外观(颜色、字体等)。在 CSS 文件中应用这些自定义属性。如需了解受支持的 CSS 属性,请参阅 PlaceDetailsCompactElement 参考文档。

此阶段应用可能呈现的外观示例:

图片

改进实体店查找器

您已为商店查找器应用打下坚实的基础。现在,不妨考虑几种扩展其功能的方法,打造更加丰富、更加以用户为中心的体验。

添加自动补全

将搜索输入框与地点自动补全功能集成,改进用户查找可搜索商店的区域的方式。当用户输入地址、社区或地图注点并选择建议时,请将地图程序设为自动以该位置为中心,从而触发附近商店的更新。为此,请添加输入字段并将地点自动补全功能附加到该字段。选择某条建议后,地图可将该点置于中心。请务必将其配置为偏向于您的运营区域或将结果限制在您的运营区域。

检测位置

通过实现检测用户当前地理位置的功能,为用户提供即时相关内容,尤其是移动用户。在获得浏览器权限以检测用户位置后,自动将地图中心定位到用户的位置,并显示最近的商店。在寻找即时选项时,用户非常重视此附近功能。添加用于请求位置信息访问权限的按钮或初始提示。

显示距离和路线

用户找到感兴趣的商店后,通过集成 Routes API,您可以显著提升用户体验历程。对于您列出的每家商店,计算并显示其距离用户当前所在位置或搜索地点的距离。此外,提供一个按钮或链接,使用 Routes API 生成从用户所在位置到所选商店的路线。然后,您可以在地图上显示此路线,或关联到 Google 地图以供导航,从而实现从查找商店到实际前往商店的顺畅过渡。

通过实现这些扩展程序,您可以使用 Google 地图平台的更多功能,构建更全面、更便捷的商店定位工具,直接满足常见用户需求。

总结

本指南演示了构建互动式商店查找工具的核心步骤。您已了解如何使用 Maps JavaScript API 在地图上显示您自己的商店位置、根据视口变化动态更新可见的商店,以及最重要的是,如何根据 Places 界面 Kit 显示您自己的商店数据。通过将现有商店信息(包括地点 ID)与地点详情元素搭配使用,您可以为每个营业地点提供丰富且标准化的详细信息,为打造人性化的商店定位工具奠定坚实的基础。

试用 Maps JavaScript APIPlaces 界面套件,利用强大的基于组件开发工具快速开发复杂的位置信息应用。通过结合使用这些功能,您可以为用户打造富有吸引力且信息丰富的体验。

贡献者

Henrik Valve | DevX 工程师