探索地理时空Flux
作者:Nate Isley / 用例,开发者,产品
2020年7月1日
导航至
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.0、InfluxDB Enterprise 1.8和InfluxDB OSS 2.0中的Flux地理时间功能。