探索地理时空Flux

导航至

Flux最近增加了地理时空功能,我一直在探索如何有效地使用这种时序和地理位置数据的新组合。为了帮助您开始,我们将介绍地理时空概述,然后探讨一些示例。

如果您想使用InfluxDB 2.0 OSS(开源)或InfluxDB Cloud进行操作,请部署此AWS Lambda以从美国地质调查局(USGS)收集每小时地震数据。

地理时空Flux:概述

Flux的地理时空能力来源于一个Golang S2几何库。S2基于球面几何,非常适合回答地理位置问题。

S2有很多细节,但与Flux相关的主要概念是S2单元及其级别(从0到30)。S2单元由四个球面测地线所界定。在级别0时,一个S2单元大约代表85M km²,随着级别的增加,S2单元被细分为更小的区域。在级别30时,单个细分区域代表略小于1 cm²的面积。

技术上,Flux中的地理时空分析只需要纬度和经度。然而,使用S2单元标识符(ID)标记数据有助于在规模上高效地分析数据。S2单元ID有时也称为S2单元令牌,可以唯一标识指定级别的S2单元。要使用S2单元ID,您可以在查询时计算它们,也可以在将数据写入InfluxDB时计算。

在查询时计算使用Flux 计算S2单元ID。每次查询都计算S2单元ID会花费时间,并且当在相同的数据集上执行多个查询时效率低下。相比之下,在数据摄取时准备S2单元ID,虽然会增加基数,但可以避免查询时的计算。对于使用Telegraf进行数据收集的用户,有一个S2 Geo处理器插件,允许您计算并将S2单元ID添加到纬度和经度数据中。

如果您决定在摄取时添加S2单元格ID,请考虑您地理时间计算的精度基数,并相应地调整您的S2级别。例如,在级别0时,六个S2单元格ID代表地球,但在级别16时,需要超过250亿个。当然,如果您只是跟踪陆地上的某物的移动,这可以显著减少所需的S2单元格数量;这意味着您可能会提高精度——假设您捕获的纬度和经度数据也有足够的精度。

地震Lambda在摄取时是否使用地球计算并标记地震的9级S2单元格ID?在级别9,每个S2单元格ID大约12英里(19.31公里)宽,地球上大约有150万个可能的S2单元格ID。对于分析地震数据,这在粒度和基数之间提供了一个很好的平衡。对于您的用例,您可能需要一个更高或更低的精度级别。

地理时间Flux示例

让我们深入分析美国地质调查局地震数据的一个实时分析。这个初始示例找到在过去24小时内发生在美国大陆西海岸大致区域的地震。

import "experimental/geo"

from(bucket: "Earthquake")
  |> range(start: -24h)
  |> filter(fn: (r) => r["_measurement"] == "geo")
  |> filter(fn: (r) => r["_field"] == "lat" or r["_field"] == "lon")
  |> geo.filterRows(
    region: {
      minLat: 32.245914,
      maxLat: 49.259394,
      minLon: -126.860380,
      maxLon: -114.715901
    }
  )

我们定义了一个矩形框,具有最大和最小的纬度和经度,并且地理函数确保只提供那些边界内的地震列表。

对于简单矩形框不适合您的用例的情况,Flux提供了圆圈和一般多边形。例如,这里我调查了在过去7天内,我经常旅行的旧金山湾区五个县(旧金山、马林、阿拉米达、康特拉科斯塔和圣马特奥县)内地震的数量。

import "experimental/geo"

from(bucket: "Earthquake")
  |> range(start: -7d)
  |> filter(fn: (r) => r["_measurement"] == "geo")
  |> filter(fn: (r) => r["_field"] == "lat" or r["_field"] == "lon")
  |> geo.filterRows(
    region: {
        points: [
        {lat: 38.296395, lon: -123.022551}, {lat: 38.320102, lon: -122.879729}, {lat: 38.190695, lon: -122.580351}, {lat: 38.060455, lon: -122.394375},
        {lat: 38.043152, lon: -121.751675}, {lat: 38.112338, lon: -121.581387}, {lat: 37.825442, lon: -121.536068}, {lat: 37.546042, lon: -121.552121},
        {lat: 37.482863, lon: -121.466977}, {lat: 37.451254, lon: -121.931149}, {lat: 37.454980, lon: -122.112390}, {lat: 37.214760, lon: -122.148095},
        {lat: 37.054918, lon: -122.406274}, {lat: 37.990496, lon: -123.027002}
        ]
    }
  )

尽管如此,如果您住在湾区,最好不要长时间关注这些结果。

最后一个示例展示了通过首先找到美国地质调查局在过去24小时内观察到的全球最强地震,然后我们查看过去7天,并计算在该事件200公里范围内发生的地震数量。

import "experimental/geo"

max_eq = 
   from(bucket:"Earthquake")
       |> range(start: -24h)
       |> filter(fn: (r) => r._measurement == "geo")
       |> geo.toRows()
       |> group()
       |> max(column: "mag")
       |> findRecord(fn: (key) => true, idx: 0)

from(bucket:"Earthquake")
    |> range(start: -7d)
    |> geo.filterRows(region: {lat: max_eq.lat, lon: max_eq.lon, radius: 200.0}, strict: false)
    |> group()
    |> count(column: "mag")

接下来是什么?

要探索更多InfluxDB的地理时间功能,请查看Tim Hall的InfluxDays路线图演示。Tim讨论了我们关于地理时间数据收集、查询和可视化的更多工作。我将继续发布探索Flux高级地理时间功能的新的博客。

想今天分析自己的数据吗?请查看InfluxDB Cloud 2.0InfluxDB Enterprise 1.8InfluxDB OSS 2.0中的Flux地理时间功能。

一如既往,如果您有任何问题或反馈,请在我们的社区论坛加入我们的Slack中告诉我们!