在 BigQuery 中假设我有一个 GEOPOINT 数据类型。例如
ST_GEOGPOINT(-122, 37)
我怎样才能找到 10 个地理点来构成半径为 100 公里的外圆。
要求是 Looker 仪表板,我在其中拥有最低级别的设备 GPS 数据,并且我们正在跟踪它的活动。
现在我们将在城市级别创建一个聚合表,作为以下数据
ST_CENTROID_AGG
函数计算活动存储桶下所有设备的聚合中心 GPS 点城市 | 年龄桶 | 中央地理点 | 设备数量 |
---|---|---|---|
美国德克萨斯州 | 1 天 | ST_GEOGPOINT(31, 99) | 100 |
美国德克萨斯州 | 1 周 | ST_GEOGPOINT(31, 99) | 10 |
美国德克萨斯州 | 1个月 | ST_GEOGPOINT(31, 99) | 10 |
美国德克萨斯州 | 2个月 | ST_GEOGPOINT(31, 99) | 10 |
美国德克萨斯州 | 4个月 | ST_GEOGPOINT(31, 99) | 10 |
美国德克萨斯州 | 6 个月 | ST_GEOGPOINT(31, 99) | 10 |
美国德克萨斯州 | 10 个月 | ST_GEOGPOINT(31, 99) | 100 |
美国佛罗里达州 | 1 天 | ST_GEOGPOINT(27, 81) | 100 |
美国佛罗里达州 | 2周 | ST_GEOGPOINT(27, 81) | 10 |
美国佛罗里达州 | 3个月 | ST_GEOGPOINT(27, 81) | 10 |
美国佛罗里达州 | 5个月 | ST_GEOGPOINT(27, 81) | 10 |
美国佛罗里达州 | 6 个月 | ST_GEOGPOINT(27, 81) | 10 |
美国佛罗里达州 | 9个月 | ST_GEOGPOINT(27, 81) | 10 |
美国佛罗里达州 | 10 个月 | ST_GEOGPOINT(27, 81) | 100 |
在绘图时,我希望看到所有佛罗里达州都绘制在中心点,周围有同心圆。 对于美国德克萨斯州来说,这里需要外圈6分 美国佛罗里达这里需要外圈7分
我们如何拥有一个 BigQuery 函数,让我可以获取这些地理点(在聚合表中预先计算或作为运行时函数)以更好的方式进行绘制
我厌倦了阅读下面的文章
https://towardsdatascience.com/spatial-binning-with-google-bigquery-d118afba6273
并且可以获得一些近似的圆圈,由于纬度和经度在地图中的显示方式,这些圆圈看起来是椭圆形的,并且在北极或南极处倾斜
--
-- Table Function to Generate Circular Points for an input (Will be Oval in Shape)
--
CREATE OR REPLACE TABLE FUNCTION looker_iot_model.approx_circle_points(
latitude FLOAT64, longitude FLOAT64, circle FLOAT64, points INTEGER)
AS (
SELECT
seq,
ST_GEOGPOINT(longitude + ((SIN(ACOS(-1)*seq/points))*circle/9), latitude + ((COS(ACOS(-1)*seq/points))*circle/10)) AS geo_point
FROM UNNEST(GENERATE_ARRAY(-1*(points-1),(points-1),2)) as seq
);
现在如果我跑步
select * FROM looker_iot_model.approx_circle_points(37.7749, -122.4194, 12, 12)
select * FROM looker_iot_model.approx_circle_points(71, 42, 12, 12)
ST_Buffer(central_point, 100*1000, 10/4)
围绕中心点构建一个多边形环。第二个参数是半径(以米为单位),第三个参数是每季度的点数。它返回具有 10 个顶点的 POLYGON(由于第一个和最后一个顶点在 POLYGON 循环中重复,因此看起来像 11)
要将其转换为点列表,我们需要
ST_DumpPoints
,这在 BigQuery 中不可用,让我们使用文本操作构建它的穷人版本:
select st_geogfromtext(concat("POINT(", p, ")")) AS point
from unnest(split(
trim(
st_astext(st_buffer(ST_GEOGPOINT(-122, 37), 100e3,
num_seg_quarter_circle => 10/4)),
"POLYGON()"),
",")) p with offset o
where o <> 0;
这会构建一个缓冲区,将其转换为文本,剥离“多边形((..))”包装,分割剩余的点,并将它们转换回省略第一个点(在多边形定义末尾重复)的地理区域。
另请考虑以下方法
WITH your_table AS (
SELECT 1 id, ST_GEOGPOINT(-122, 37) point, 10 points UNION ALL
SELECT 2, ST_GEOGPOINT(-118, 34), 16
)
SELECT id, ST_UNION_AGG(ST_POINTN(ring, index)) outer_points,
ANY_VALUE(point) point, ANY_VALUE(points) points
FROM your_table,
UNNEST([ST_EXTERIORRING(ST_BUFFER(point, 100e3, num_seg_quarter_circle => points /4))]) ring,
UNNEST(GENERATE_ARRAY(1, ST_NUMPOINTS(ring) - 1)) index
GROUP BY id
有输出
最终得到以下可视化结果
和