实时数据驱动型样式

本文档介绍了为何以及如何使用 Maps JavaScript API 实现 Google 边界的动态数据驱动型样式设置,这对于各行各业和细分领域的各种应用场景都非常有用。

纽约市出租车数量(按邮政编码)
纽约市出租车数量动画(按邮政编码边界,模拟、延时):
纽约市出租车数量(按邮政编码划分,延时摄影) 地图图例

数据驱动型样式是 Google Maps Platform 的一项功能,可让您利用 Google 的行政边界多边形,为这些多边形设置样式以在地图上显示,并结合您自己的数据制作形式多样的自定义地图,以便进行可视化分析并更好地了解您的数据。本文档将讨论一些应用场景,说明为何以及如何通过集成动态数据 Feed,在地图上使用数据驱动型样式近乎实时地直观呈现数据。

借助数据驱动型样式,您可以创建地图来显示数据的地理分布,动态自定义多边形样式,并通过点击事件与数据互动。这些功能可用于为各种应用场景和行业创建信息丰富且引人入胜的地图。

以下是一些可能适用于在数据驱动型样式上显示动态数据更新的地图的使用场景示例:

  • 拼车:实时更新可用于识别需求量大的区域,在这种情况下,一些提供商可能会采用高峰期定价。
  • 交通运输:实时更新可用于识别拥堵区域,从而帮助确定最佳替代路线。
  • 选举:在大选之夜,实时民调数据可用于直观呈现选举结果。
  • 工作人员安全:实时更新可用于实时跟踪事件进展、识别高风险区域,并为现场响应人员提供态势感知。
  • 天气:实时更新可用于跟踪风暴的移动、识别当前危险并提供警告和警报。
  • 环境:实时更新可用于跟踪火山灰和其他污染物的移动、识别环境退化区域以及监测人类活动的影响。

在所有这些情况下,客户都可以将其实时数据 Feed 与 Google 的边界数据相结合,从而快速、轻松地在地图上直观呈现数据,进而释放更多价值。这赋予了他们近乎即时地获取数据洞见的能力,有助于他们做出更明智的决策。

解决方案的架构方法

现在,我们来逐步了解如何使用数据驱动型样式构建地图,以直观呈现动态数据。如前所述,该用例是按邮政编码直观呈现的纽约市出租车数量。这有助于用户了解叫出租车的难易程度。

架构
下面是该方法的应用架构图:
应用架构

动态数据驱动型样式解决方案

现在,我们来逐步了解为数据集实现动态数据驱动型样式分级统计图所需的步骤。

借助此解决方案,您可以直观呈现一个假设数据集,其中包含纽约市周边按邮政编码划分的实时出租车密度。虽然这些数据可能不是真实世界的数据,但它们具有实际应用价值,可让您了解如何通过数据驱动型样式在地图上直观呈现动态数据,以及这种方式的强大功能和优势。

第 1 步:选择要直观呈现并与边界地点 ID 联接的数据

第一步是确定要显示的数据,并确保这些数据可以与 Google 的边界相匹配。您可以在客户端执行此匹配,方法是为每个 postalCode 调用 findPlaceFromQuery 回调方法。请注意,美国的邮政编码具有不同的名称,但其他行政级别没有。如果查询结果可能不明确,您需要确保为查询选择正确的地点 ID。


const request = {
    query: postalCode,
    fields: ['place_id'],
};
 
function findPlaceId() {
   placesService.findPlaceFromQuery(request, function (results, status) {
      if (status === google.maps.places.PlacesServiceStatus.OK) {
         console.log(results[0]);
      }
   });
}

如果您的数据包含经纬度值,您还可以将 Geocoding API 与组件过滤功能搭配使用,将这些经纬度值解析为要设置样式的地图项图层的地点 ID 值。在此示例中,您将为 POSTAL_CODE 地图项图层设置样式。

第 2 步:连接到实时数据

连接到数据源的方式有多种,最佳实现方式取决于您的具体需求和技术基础架构。在本例中,我们假设您的数据位于一个 BigQuery 表中,该表包含两列:“zip_code”和“taxi_count”,您将通过 Firebase Cloud Functions 函数查询该表。

async function queryNycTaxis() {
   // Queries the NYC Taxis dataset.

   // Create a client
   const bigqueryClient = new BigQuery();
  
   // The SQL query to run
   const sqlQuery = 'SELECT zip_code, taxi_count
      FROM \'YOUR_DATASET_ID.TABLE\' LIMIT 100';
      
   const options = {
      query: sqlQuery,
      // Location must match that of the dataset(s)
      // referenced in the query.
      location: 'US',
   };
  
   // Run the query
   const [rows] = await bigqueryClient.query(options);
  
   rows.forEach(row => {
      const postalCode = row['zip_code'];
      const taxiCount = row['taxi_count'];
   });
}

接下来,您需要确保数据始终是最新的。一种方法是使用 Web Worker 调用上述查询,并设置一个计时器,以便使用 setInterval 函数刷新数据。您可以将间隔设置为适当的值,例如每 15 秒刷新一次地图。每当间隔时间过去后,Web Worker 都会请求每个 postalCode 的更新 taxiCount 值。

现在,我们可以查询和刷新数据了,接下来让我们确保地图多边形的外观能够反映这些变化。

第 3 步:使用数据驱动型样式设置地图样式

现在,您已经获得了在 Maps JavaScript 实例中为邮政编码边界创建和应用视觉样式所需的动态数据值(以 JSON 对象的形式),接下来就可以将其样式设置为分级统计图了。

在此示例中,您将根据每个邮政编码区域的出租车数量来设置地图样式,让用户了解其所在区域的出租车密度和可用性。样式会因出租车数量值而异。出租车最少的区域将应用紫色样式,颜色渐变将经过红色、橙色,最后在密度最高的区域呈现纽约市出租车的黄色。对于此配色方案,您需要将这些颜色值应用于 fillColor 和 strokeColor。将 fillOpacity 设置为 0.5 可让用户看到底层地图,将 strokeOpacity 设置为 1.0 可让用户区分同色多边形的边界:


const featureLayer = map.getFeatureLayer(
   google.maps.FeatureType.POSTAL_CODE
);
featureLayer.style = (featureStyleFunctionOptions) => {
   const placeFeature = featureStyleFunctionOptions.feature;
   // taxiCount per (postal_code) PlaceID 
   const taxiCount = zips[placeFeature.placeId];
   let fillColor;
   let strokeColor;
// Apply colors to features based on taxiCount values
if (taxiCount < 8) {
   fillColor = "#571845";  
   strokeColor = "#571845"; 
} else if (taxiCount < 13) {
   fillColor = "#900c3e";
   strokeColor = "#900c3e";
} else if (taxiCount < 21) {
   fillColor = "#c60039"; 
   strokeColor = "#c60039"; 
} else if (taxiCount < 34) {
   fillColor = "#fe5733";
   strokeColor = "#fe5733";
// keep else if or the whole map gets this style with else
} else if (taxiCount >= 34) { 
   fillColor = "#fec30f";
   strokeColor = "#fec30f";
}  
return {
   fillColor,
   strokeColor,
   fillOpacity: 0.5,
   strokeOpacity: 1.0,
};
 

总结

借助 Google 边界的数据驱动型样式,您可以根据自己的数据为地图设置样式,从而在各行各业和细分市场中实现各种应用。连接到实时数据后,您就可以传达正在发生什么、在哪里发生以及何时发生。这项功能有望释放实时数据的价值,并帮助用户在现实世界中实时更好地理解这些数据。

后续操作

贡献者

主要作者:

Jim Leflar | Google Maps Platform 解决方案工程师