使用 BigQuery 和 Datasets API 直观呈现数据

本文档提供了一个参考架构和示例,介绍了如何在 Google Cloud Platform BigQueryGoogle Maps Platform Datasets API 中使用位置数据创建地图数据可视化内容,例如分析公开的市政数据、制作电信覆盖范围地图,或直观呈现移动车队移动的轨迹。

地图数据可视化是一款强大的工具,有助于吸引用户和发掘位置数据中的空间数据洞见。位置数据是包含点、线或多边形地图项的数据。例如,天气图可帮助消费者了解和规划行程,并为风暴做好准备;商业智能地图可帮助用户从数据分析中发掘洞见,而电信地图可帮助用户了解其提供商的特定服务区域的覆盖范围和质量

然而,对于应用开发者来说,要实现性能出色并提供出色的用户体验的大型地图数据可视化非常困难。大量数据必须加载到内存客户端,导致首次地图加载时间较长。视觉效果必须在所有设备(包括内存和 GPU 受限的低端手机)上表现出出色的性能。最后,开发者需要选择一个可移植、可靠且性能出色的大型数据渲染库,用于处理大数据。

参考架构

开发具有大型数据可视化功能的应用需要两个主要组件。

  1. 客户后端 - 所有后端应用数据和处理和存储等服务。
  2. 客户客户端 - 包含地图可视化组件的应用界面。

下面的系统示意图展示了这两个组件如何与应用用户、Google Cloud 和 Google Maps Platform 进行交互,从而创建大型数据可视化应用。

架构图

<ph type="x-smartling-placeholder">

设计考虑事项

要使用 Google Cloud 和 Google Maps Platform 打造高性能的数据可视化效果,需要遵循一些设计注意事项。

  1. 源数据大小和更新频率
    1. 如果 GeoJSON 格式的源数据小于 5 MB 或更新非常频繁,例如实时天气雷达预报,不妨考虑在应用中以 GeoJSON 对象客户端的形式提供数据,并使用 deck.gl 图层进行渲染。
    2. 如果您的数据超过 5MB,且每小时更新一次,请考虑使用本文档中的 Datasets API 架构。
      1. 数据集支持的文件最大为 350 MB
      2. 如果您的数据大于 350MB,请考虑先剪除或简化源文件中的几何图形数据,然后再传递到数据集(请参阅下面的“数据剪枝”)。
  2. 架构和格式 <ph type="x-smartling-placeholder">
      </ph>
    1. 确保数据中每项特征的全局唯一 ID 属性。借助唯一 ID,您可以选择特定地图项并为其设置样式,或者将数据与地图项联接以直观呈现,例如针对“点击”用户事件设置所选地图项的样式。
    2. 根据 Datasets API 规范,将数据的格式设置为 CSVGeoJSON,其中包含有效的列名称、数据类型和 GeoJSON 对象类型。
    3. 为了便于从 BigQuery 创建数据集,请在 SQL CSV 导出文件中创建一个名为 wkt 的列。数据集支持从名为 wkt 的列中导入采用已知文本 (WKT) 格式的 CSV 格式的几何图形。
    4. 请检查您的数据是否为有效的几何图形和数据类型。例如,GeoJSON 必须采用 WGS84 坐标系、几何图形环绕顺序等。
    5. 使用 geojson-validate 等工具确保源文件中的所有几何图形均有效,或使用 ogr2ogr 等工具在格式或坐标系之间转换源文件。
  3. 数据剪枝 <ph type="x-smartling-placeholder">
      </ph>
    1. 尽可能减少地图项的属性数量。您可以在运行时利用唯一标识符键将其他属性与功能联接起来(示例)。
    2. 尽可能为属性对象使用整数数据类型,以最大限度减少功能块存储空间,使功能块能够在客户端应用中通过 HTTPS 加载。
    3. 简化和/或聚合非常复杂的地图项几何图形;可以考虑对复杂的多边形几何图形使用 ST_Simplify 等 BigQuery 函数,以缩减源文件大小并提高地图性能。
  4. 平铺 <ph type="x-smartling-placeholder">
      </ph>
    1. Google Maps Datasets API 会根据您的源数据文件创建地图图块,以用于 Web 或移动 Maps SDK。
    2. 地图图块是一种基于缩放的索引系统,可让您以更高效的方式将数据加载到可视化应用中。
    3. 地图图块可能会在较低的缩放级别放置密集或复杂的地图项。当用户缩小到某个州或国家/地区(例如 z5-z12)时,其效果可能与放大到城市或街区(例如 z13-z18)时看起来不同。

示例 - 伦敦的铁路

在此示例中,我们将运用参考架构,借助 GCP 和 Google 地图创建 Web 应用,从而根据 Open Street Map (OSM) 数据直观呈现伦敦的所有铁路。

前提条件

  1. 访问 BigQuery SandboxCloud 控制台
  2. 确保您已设置 GCP 项目和结算账号。

第 1 步 - 在 BigQuery 中查询数据

前往 BigQuery 公共数据集。数据集“bigquery-public-data”表 geo_openstreetmap.planet_features 包含全球的 Open Street Map (OSM) 数据,包括所有可能的地图项。了解可在 OSM Wiki 中查询的所有功能,包括 amenityroadlanduse

通过 Cloud Shell 或 BigQuery Cloud 控制台(https://console.cloud.google.com) 使用 SQL 查询表。下面的代码段使用了 bq query 命令,通过边界框和 ST_Intersects() 函数查询过滤出伦敦的所有铁路。

如需通过 Cloud Shell 执行此查询,请运行以下代码段,更新您的环境的项目 ID、数据集和表名称。

bq query --use_legacy_sql=false \
--destination_table PROJECTID:DATASET.TABLENAME \
--replace \
'SELECT
osm_id, 
feature_type,
(SELECT value
         FROM   unnest(all_tags)
         WHERE  KEY = "name") AS name,
(SELECT value
         FROM   unnest(all_tags)
         WHERE  KEY = "railway") AS railway,
geometry as wkt
FROM   bigquery-public-data.geo_openstreetmap.planet_features
WHERE ("railway") IN (SELECT key FROM unnest(all_tags)) 
    AND ST_Intersects(
    geometry,
ST_MakePolygon(ST_MakeLine(
      [ST_GeogPoint(-0.549370, 51.725346),
      ST_GeogPoint(-0.549370, 51.2529407),
      ST_GeogPoint(0.3110581, 51.25294),
      ST_GeogPoint(0.3110581, 51.725346),
      ST_GeogPoint(-0.549370, 51.725346)]
    ))
   )' 

查询会返回以下内容:

  1. 每个地图项的唯一标识符 osm_id
  2. feature_type,例如点、线等
  3. 特征的 name,例如Paddington Station
  4. railway 类型,例如主要、旅游、军事等
  5. 地图项的 wkt - 点、线或多边形几何图形,采用 WKT 格式。WKT 是 BigQuery 地理位置列在查询中返回的标准数据格式。

注意 - 如需在创建数据集之前直观地验证查询结果,您可以使用 Looker Studio 在 BigQuery 的信息中心内快速直观呈现数据。

如需将表导出为 Google Cloud Storage 存储分区中的 CSV 文件,请在 Cloud Shell 中使用 bq extract 命令:

bq extract \
--destination_format "CSV" \
--field_delimiter "," \
--print_header=true \
PROJECTID:DATASET.TABLENAME \
gs://BUCKET/FILENAME.csv

注意:您可以使用 Cloud Scheduler 自动执行每个步骤,以定期更新数据。

第 2 步 - 基于 CSV 文件创建数据集

接下来,根据 Google Cloud Storage (GCS) 上的查询输出创建 Google Maps Platform 数据集。使用 Datasets API,您可以创建数据集,然后从 GCS 上托管的文件将数据上传到您的数据集

首先,请在您的 GCP 项目上启用 Maps Datasets API,并查看 API 文档。有 PythonNode.js 客户端库,可通过应用后端的逻辑调用 Datasets API。此外,Cloud 控制台还提供数据集 GUI,可用于在 Cloud 控制台中手动创建数据集。

数据集上传完成后,您可以在数据集 GUI 中预览数据集。

数据集预览

第 4 步 - 将您的数据集与地图 ID 相关联

创建数据集后,您可以使用关联的地图样式创建地图 ID。在地图样式编辑器中,您可以将 mapId 和样式与数据集相关联。您还可以在此处应用云端地图样式设置来自定义地图的外观和风格。

第 5 步 - 创建客户端应用地图可视化

最后,您可以使用 Maps JS API 将数据集添加到客户端数据可视化应用。使用与上一步中的数据集关联的 mapID 初始化您的地图对象。然后,设置数据集图层的样式和互动性。如需了解更多详情,请参阅完整的“使用数据集设置数据驱动型样式”指南

您可以使用 Maps JS API 自定义样式、添加用于动态更改样式的事件处理脚本等。请参阅文档中的示例。下面,我们将定义一个 setStyle 函数,用于根据“feature_type”属性为此示例创建点和线地图项样式。

function setStyle(params) {
  const map.getDatasetFeatureLayer("your-dataset-id");
  const datasetFeature = params.feature;
  const type = datasetFeature.datasetAttributes["feature_type"];
if (type == "lines") {
           return {
             fillColor: "blue",
             strokeColor: "blue",
             fillOpacity: 0.5,
             strokeWeight: 1,
           }
         } else if (type == "points") {
           return {
             fillColor: "black",
             strokeColor: "black",
             strokeOpacity: 0.5,
             pointRadius: 2,
             fillOpacity: 0.5,
             strokeWeight: 1,
           }
     }
}

注意 - 请务必始终将数据集的提供方说明添加到地图应用中。要添加 OSM 归因,请按照符合 OSM 指南文档中的归因代码示例操作。

上述代码在单页 Web 应用中初始化时会生成以下地图数据可视化内容:

伦敦铁路地图

在这里,您可以通过添加逻辑来过滤地图项、添加基于用户互动的样式,以及与应用的其余部分互动,在 setStyle() 函数中扩展您的地图可视化。

总结

在本文中,我们讨论了使用 Google Cloud 和 Google Maps Platform 的大型数据可视化应用的参考架构和示例实现。借助此参考架构,您可以使用 Google Maps Datasets API,基于 GCP BigQuery 中的任何数据创建在任何设备上都能正常运行的位置数据可视化应用。

后续操作

补充阅读材料:

贡献者

主要作者:

  • Ryan Baumann,Google Maps Platform 解决方案工程经理