У меня есть таблица с тремя столбцами, как показано ниже:
Часовой пояс_имя | Долгота | Широта |
---|---|---|
Америка/Чикаго | 151.2095611 | -31.8862892 |
Америка/Чикаго | 152.2095611 | -32.8862892 |
Америка/Канкун | 150.2095611 | -34.8862892 |
Америка/Канкун | 149.2095611 | -35.8862892 |
Решение проблемы
Итак, есть кое-что важное, на что следует обратить внимание: для многоугольника порядок точек имеет значение, и здесь мы можем видеть, что у двух поколений были разные порядки, И первая точка должна быть последней точкой, так что цикл замыкается..
Поэтому, если вы используете «квадратные» углы, вы можете построить действительный многоугольник, например, я изменил ваши данные в соответствии с моими демонстрационными потребностями, потому что при преобразовании ваших данных в это было больше боли, чем мне нужно.
with data(tz_name, lon1, lat1, lon2, lat2) as (
select * from values
('America/Chicago', '151.2095611', '-31.8862892', '152.2095611', '-32.8862892'),
('America/Cancun', '150.2095611', '-34.8862892', '149.2095611', '-35.8862892')
)
select tz_name
,'LINESTRING('||lon1||' '||lat1||', '||lon2||' '||lat1||', '||lon2||' '||lat2||', '||lon1||' '||lat2||', '||lon1||' '||lat1||')' as line_str
,to_geography(line_str) as g_ls
,st_makepolygon(g_ls) as poly
from data;
Если у вас есть вершины порядка вашего полигона, но набор не замкнут, вы можете взять последнюю и поместить ее первой, например:
with data(tz_name, _order, lon, lat) as (
select * from values
('America/Chicago', 1, '151.2095611', '-31.8862892'),
('America/Chicago', 2, '152.2095611', '-31.8862892'),
('America/Chicago', 3, '152.2095611', '-32.8862892'),
('America/Chicago', 4, '151.2095611', '-32.8862892')
)
select
tz_name
,listagg(part,', ') within group (order by _order) as p_str
,'LINESTRING('||p_str||')' as line_str
,to_geography(line_str) as g_ls
,st_makepolygon(g_ls) as poly
from (
select
tz_name,
_order,
lon,
lat,
last_value(lon)over(partition by tz_name order by _order) as l_lon,
last_value(lat)over(partition by tz_name order by _order) as l_lat,
iff(_order = 1, l_lon ||' '|| l_lat ||', '|| lon ||' '|| lat, lon ||' '|| lat) as part
from data
)
group by 1
Комментариев нет:
Отправить комментарий