Bigquery - учитывая географическую точку и расстояние, как обвести многоугольник вокруг него - PullRequest
1 голос
/ 02 апреля 2020

У меня была проблема, чтобы решить, где, учитывая центральную географическую точку и расстояние, мне нужно было выделить вокруг нее многоугольник.

Представьте себе любую географическую точку: скажем: 41.6748248, -83.6882749, и мне нужно, чтобы сказать восьмиугольник вокруг него, используя расстояние 50 метров например,

Отвечая на мой собственный Вопрос, так как я не нашел другого метода, который я мог бы использовать непосредственно в BQ, как есть. (До сих пор в BQ нет встроенной функции для этого.)

1 Ответ

2 голосов
/ 02 апреля 2020
CREATE TEMPORARY FUNCTION get_point_at_a_distance(latitude float64, longitude float64, d int64, brng int64) as (
    (select ST_GEOGPOINT(((longitude* (ACOS(-1)/180)) + atan2(sin(brng* (ACOS(-1)/180))*sin(d/6371000)*cos(latitude* (ACOS(-1)/180)),cos(d/6371000)-sin(latitude* (ACOS(-1)/180))*sin(latitude* (ACOS(-1)/180))))* (180/ACOS(-1)), 
    (asin(sin(latitude* (ACOS(-1)/180))*cos(d/6371000) + cos(latitude* (ACOS(-1)/180))*sin(d/6371000)*cos(brng* (ACOS(-1)/180))))* (180/ACOS(-1))))
); 

CREATE TEMPORARY FUNCTION get_polygon(latitude float64, longitude float64, distance int64) as (

(select ST_MAKEPOLYGON(ST_MAKELINE(ARRAY_AGG(geo_point))) 
from 
(
select get_point_at_a_distance(latitude, longitude, distance, 0) as geo_point union all 
select get_point_at_a_distance(latitude, longitude, distance, 45) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 90) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 135) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 180) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 225) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 270) as geo_point  union all 
select get_point_at_a_distance(latitude, longitude, distance, 315) as geo_point 
)));

select get_polygon(41.6748248, -83.6882749, 50)```


Confirm with: https://www.keene.edu/campus/maps/tool/
Try to plot the output: 
-83.6887005865171, 41.6751427574177
 -83.6888769116458, 41.6748247984293
 -83.6887005865171 ,41.6745068410117
 -83.6882749, 41.674375139197
 -83.6878492134828, 41.6745068410116
 -83.6876728883542, 41.6748247984293
-83.6878492134828, 41.6751427574177
 -83.6882749, 41.675274460803
 -83.6887005865171, 41.6751427574177

...