改进了前往机场的导航

图片

机场是大型多航站楼综合体,精准导航对于及时到达和出发至关重要。Google Maps Geocoding API 通常会返回一个坐标(纬度/经度),在大多数情况下,该坐标是大机场综合体的质心。此应用是一款互动式工具,专门用于帮助用户在大型复杂场所(例如机场内的特定航站楼或上下车点)内精确定位和直观显示确切位置。

图片

以下是其实现方式:

机场/场馆搜索:用户首先搜索主要地点(例如,“英迪拉·甘地国际机场”)使用仅限印度的 Google Places 自动补全输入。

子位置发现:选择主位置后,脚本会使用 Google Places API 来提取详细信息,其中最重要的是与该地点关联的任何列出的“子目的地”(例如 1 号航站楼、3 号航站楼、特定登机口等,如果 Google 的数据中包含这些信息)。

可视化地图:脚本使用 Geocoding API 查找主要目的地及其子目的地的坐标。

然后,它会显示主要目的地,并在地图上为每个识别出的子目的地放置不同的可点击标记(蓝色圆圈)。

精确定位:点击子目的地标记会突出显示该标记(变为绿色),并打开一个信息窗口,其中显示子目的地的名称和其他可用详细信息(如地址或类型),以便用户确认他们已选择正确的特定点。 情境视图:地图会自动调整视图 (fitBounds),以确保所有相关标记(主要目的地 + 子目的地)都清晰可见。

机场导航应用中的 Google Maps Platform API

本文档介绍了所提供的“前往机场”演示应用中使用的主要 Google Maps Platform API 及其参数。该应用利用多项服务来提供地图显示、地点搜索、详细地点信息和高级位置信息洞见。

1. 地图初始化和显示

应用的基础是互动式地图本身。

  • 使用的 APIgoogle.maps.Map(来自 Maps JavaScript API)
  • 用途:在网页上创建并显示交互式地图。
  • 关键参数
    • center:定义地图的初始地理中心。 在此应用中,它最初设置为德里的坐标 ({ lat: 28.461835685621395, lng: 77.05004035761647 })。
    • zoom:设置地图的初始缩放级别。 DEFAULT_ZOOM_LEVEL (15) 用于特写视图。
    • mapId:在 Google Cloud 控制台中配置的地图样式的唯一标识符。

2. 地点搜索和自动补全

搜索栏功能由 Places API 提供支持。

  • 使用的 APIgoogle.maps.places.Autocomplete(来自 Maps JavaScript API 的地点库)
  • 用途:在用户输入内容时,为地理位置搜索提供预测性文字补全功能,建议机场等相关地点。
  • 关键参数
    • input:用户在其中输入查询的 HTML 输入元素 (#search-input)。
    • componentRestrictions:将搜索结果过滤为特定国家/地区。在此示例中,{ country: 'in' } 将结果限制为印度。
    • fields:指定要为所选地点返回的数据字段。['place_id'] 最初用于仅检索地点的唯一标识符,从而优化数据传输。
  • 如何使用自动补全功能
    // Initialize Autocomplete
    const autocomplete = new google.maps.places.Autocomplete(input, {
      componentRestrictions: { country: 'in' },
      fields: ['place_id'],
    });

    // Add listener to the Autocomplete
    autocomplete.addListener('place_changed', async () => {
      const place = autocomplete.getPlace();
      if (!place.place_id) {
        return;
      }
      // Once a place is selected, fetch details
      await getPlaceDetails(place.place_id);
    });

3. 检索详细的地点信息和处理子目的地

从自动补全建议中选择地点后,系统会提取更全面的详细信息。

  • 使用的 API:Places API(通过对 https://places.googleapis.com/v1/places/{placeId} 的直接 fetch 调用)
  • 用途:检索特定地点的丰富详细信息,包括其显示名称、地址、类型,以及最重要的 subDestinations(例如,机场等大型综合体内的各个航站楼或重要区域)。
  • 网址中的关键参数
    1. {placeId}:所选地点的唯一标识符。
    2. fields:指定要检索的确切数据字段。应用请求 iddisplayNamesubDestinationstypesformattedAddress。这对于控制费用和仅接收必要的数据至关重要。
  • 如何根据位置信息获取 subDestinations
async function getPlaceDetails(placeId) {
  // Construct the URL for the Places API (v1) details endpoint
  // The 'fields' parameter is crucial for requesting subDestinations
  const url = `https://places.googleapis.com/v1/places/${placeId}?key=YOUR_API_KEY&fields=id,displayName,subDestinations,types,formattedAddress`;

  const response = await fetch(url);
  const data = await response.json();

  // Accessing subDestinations from the Places API response
  if (data.subDestinations && data.subDestinations.length > 0) {
    for (const subDestination of data.subDestinations) {
      // Each subDestination object contains an 'id' and 'displayName'
      console.log(`Sub-destination ID: ${subDestination.id}`);
      console.log(`Sub-destination Name: ${subDestination.displayName?.text}`);
      // This subDestination.id is then used in a geocoding call (as shown in section 4)
    }
  }
}

**Handling `subDestinations`:** When the Places API returns
`subDestinations`, the application initiates a process for each one:
1.  **Geocoding:** It uses the `google.maps.Geocoder` to convert
    each `subDestination.id` into its precise geographical coordinates
    (`lat`, `lng`).
1.  **Marker Placement:** A distinct marker is added to the map for
    each sub-destination. These markers are styled with a blue circle icon
    to differentiate them.
1.  **Map Bounds Adjustment:** The `google.maps.LatLngBounds` object
    is used to dynamically expand the map's view to encompass all retrieved
    sub-destinations, verifying they are all visible within the current map
    frame.
1.  **Interactive Information Window:** A `click` listener is
    attached to each sub-destination marker. When clicked, the marker's
    icon changes to green, and an `InfoWindow` appears, displaying the
    sub-destination's name, address, and types. This provides immediate,
    detailed context to the user.

4. 地理编码和反向地理编码:获取子目的地的详细信息

应用使用地理编码主要出于以下两种目的:将地点 ID 转换为坐标,以及将坐标转换回位置详情。本部分重点介绍了如何使用地理编码来获取有关子目的地的详细信息。

  • 使用的 APIgoogle.maps.Geocoder(来自 Maps JavaScript API)和 Geocoding API(通过对 https://maps.googleapis.com/maps/api/geocode/json 的直接 fetch 调用)
  • 用途
    • google.maps.Geocoder:用于将 placeId(从自动补全或 Places API 获取)转换为地理坐标 (lat, lng) 和视口,从而使地图能够正确地居中显示并缩放所选地点及其子目的地。
    • Geocoding API (fetch):用于反向地理编码(将纬度和经度转换为人类可读的地址),以及检索高级位置数据,例如建筑物轮廓和导航点。
  • 关键参数
    • google.maps.Geocoder.geocode()
      • placeId:要进行地理编码的地点 ID。
      • location:用于逆向地理编码的 LatLng 对象。
    • Geocoding API fetch 调用:
      • latlng:用于反向地理编码的纬度和经度坐标。
      • extra_computations=BUILDING_AND_ENTRANCES:此关键参数会请求额外的数据,特别是建筑物轮廓和入口信息,然后用于显示建筑物轮廓和导航点。

如何使用 subDestination ID 获取更多详情(例如位置、格式化地址、类型)

function geocodeAndAddMarker(subDestination, bounds) {
  return new Promise((resolve, reject) => {
    const geocoder = new google.maps.Geocoder();
    // Using the subDestination.id to geocode and get location details
    geocoder.geocode({ placeId: subDestination.id }, (results, status) => {
      if (status === "OK" && results[0]) {
        const location = results[0].geometry.location;
        const displayName = subDestination.displayName?.text || "Sub-destination";
        const formattedAddress = results[0].formatted_address; // Further detail from Geocoding
        const types = results[0].types; // Further detail from Geocoding

        const marker = new google.maps.Marker({
          map: map,
          position: location,
          title: displayName,
          icon: {
            path: google.maps.SymbolPath.CIRCLE,
            fillColor: 'blue',
            fillOpacity: 0.6,
            strokeWeight: 0,
            scale: 8
          }
        });

        marker.addListener('click', () => {
          marker.setIcon({
            path: google.maps.SymbolPath.CIRCLE,
            fillColor: 'green',
            fillOpacity: 0.6,
            strokeWeight: 0,
            scale: 8
          });
          const infowindow = new google.maps.InfoWindow({
            content: `<b>${displayName}</b><br><p>Address: ${formattedAddress}</p><p>Types: ${types.join(', ')}</p>`,
          });
          infowindow.open(map, marker);
        });
        bounds.extend(location);
        resolve(true);
      } else {
        reject(new Error(`Geocoding failed for placeId: ${subDestination.id}`));
      }
    });
  });
}

5. 显示标记

标记用于突出显示地图上的特定位置。

  • 使用的 APIgoogle.maps.Marker(来自 Maps JavaScript API)和 google.maps.marker.AdvancedMarkerElement(来自 Maps JavaScript API 的标记库)与 google.maps.marker.PinElement
  • 用途
    • google.maps.Marker:用于初始可拖动标记(尽管在提供的代码中 draggable 设置为 false,但它是该功能的一部分)和第 3 部分中描述的基本子目的地标记。
    • AdvancedMarkerElementPinElement:用于视觉上更清晰的导航点标记,允许自定义标记的图钉样式。
  • 关键参数
    • position:放置标记的 LatLng 坐标。
    • map:将显示标记的地图实例。
    • title:将光标悬停在标记上时显示的文字。
    • icon:允许为 google.maps.Marker 使用自定义图标(例如,google.maps.SymbolPath.CIRCLE(采用自定义颜色)。
    • content:对于 AdvancedMarkerElement,此属性允许嵌入自定义 HTML 内容,包括用于预设样式的图钉的 PinElement
    • PinElement 参数:backgroundborderColorglyphColorscale,用于自定义视觉效果。

6. 显示建筑物轮廓

应用可以直观地呈现建筑物的占地面积。

  • 使用的 APIgoogle.maps.Data(来自 Maps JavaScript API)
  • 用途:显示地理数据,例如建筑轮廓(以 GeoJSON display_polygon 形式从 Geocoding API 的 extra_computations 返回)。
  • 关键参数
    • map:应用数据层的地图实例。
    • style:定义 GeoJSON 要素的视觉外观(例如,strokeColorfillColorfillOpacity)。
    • addGeoJson():用于向图层添加 GeoJSON 数据的方法。

7. 地图边界和缩放

验证地图视图是否涵盖所有相关位置。

  • 使用的 APIgoogle.maps.LatLngBounds(来自 Maps JavaScript API)
  • 用途:动态调整地图的视口,以适应一组地理点(例如,主要地点及其所有子目的地)。
  • 主要方法
    • extend(location):向边界添加 LatLng 点,并在必要时扩大边界。
    • fitBounds(bounds):调整地图的中心和缩放级别,以显示 LatLngBounds 对象定义的整个区域。

通过结合使用这些 Google Maps Platform API,该应用可提供全面而互动的体验,让用户能够搜索地点、查看地点详情,以及直观呈现相关地理信息,例如子目的地和建筑轮廓。

实施注意事项 请注意,此功能并非适用于所有机场区域,并且取决于(机场航站楼)数据的可用性。

资源 Geocoding API Places API Maps JavaScript API

作者: