# #python #google-bigquery #geospatial #geo #spatial-query
Вопрос:
У меня есть координаты точки WGS 84, и мне нужно создать «квадратный» многоугольник с центром в указанной выше точке. Вершины, определенные следующим образом:
a N a
W *--------- ---------* E
|
|a
|
X
|
|a
|
W *--------- ---------* E
a S a
X
является отправной точкой и a
представляет собой заданное расстояние в метрах.
- Поскольку координаты точек хранятся в BigQuery вместе с другими географическими данными, предпочтительно вычислять эти полигоны в запросе. Могу ли я сгенерировать их с помощью функций географии BigQuery? (Я не нашел способа вычислить координаты точки X метров до N/E/S/W от начальной точки).
- Если #1 невозможно, какие библиотеки и методы Python я могу использовать для этого?
Ответ №1:
Ну, это не совсем квадрат, из-за сферического искажения расстояние между двумя верхними углами будет короче 2a
и отличаться от расстояния между двумя нижними углами, а также отличаться от расстояния между боковыми углами. Но если a
он достаточно мал, он достаточно близок к квадрату, и с разумной погрешностью вы можете это сделать. Я думаю, что самый простой способ сделать это в BigQuery и избежать явной тригонометрии-сделать небольшое смещение, измерить расстояние и пропорционально увеличить смещение:
-- computes distance in degrees along parallel at specified latitude
create temp function _to_lng_degrees(lat FLOAT64, a FLOAT64) AS
(
a / ST_Distance(ST_GeogPoint(0, lat), ST_GeogPoint(1, lat))
);
-- computes distance in degrees along meridian
create temp function _to_lat_degrees(a FLOAT64) AS
(
a / ST_Distance(ST_GeogPoint(0, 0), ST_GeogPoint(0, 1))
);
create temp function rect(point GEOGRAPHY, a FLOAT64) AS
((
SELECT ST_MakePolygon(ST_MakeLine(
[ST_GeogPoint(x - dx, y - dy), ST_GeogPoint(x dx, y - dy),
ST_GeogPoint(x dx, y dy), ST_GeogPoint(x - dx, y dy),
ST_GeogPoint(x - dx, y - dy)]))
FROM (
SELECT ST_X(point) x, _to_lng_degrees(ST_Y(point), a) dx,
ST_Y(point) y, _to_lat_degrees(a) dy)
));
select rect(ST_GeogPoint(-122.1555771, 47.6858382), 1000)
Комментарии:
1. О, это очень умно. Я сделал это вручную, рассчитав отношение метра к градусу, но теперь я вижу, как я мог бы рассчитать его с помощью
ST_Distance()
. Кстати,_to_lat_degrees()
кажется, это постоянно.