Eu criei essas duas funções e quero saber se existe uma maneira melhor de converter matrizes json em polígonos sem precisar instalar a extensão PostGIS.
Tipo bruto:
((-34.888733,-57.956764),(-34.92303,-57.99367),(-34.953579,-57.95255))
polígono_para_json:
["-34.888733,-57.956764","-34.92303,-57.99367","-34.953579,-57.95255"]
json_to_polígono:
((-34.888733,-57.956764),(-34.92303,-57.99367),(-34.953579,-57.95255))
create or replace function json_to_polygon(p_poly json, out p_out polygon) returns polygon
parallel safe
returns null on null input
immutable
language plpgsql
as $$
begin
if(p_poly is null) then
return;
end if;
select
polygon(concat('((', string_agg(x, '),('), '))'))
from
json_array_elements_text(p_poly) x
into
p_out;
end;
$$;
create or replace function polygon_to_json(p_poly polygon) returns json
parallel safe
returns null on null input
immutable
language plpgsql
as $$
begin
if(p_poly is null) then
return null;
end if;
return to_json(string_to_array(replace(replace(p_poly::text, '((', ''), '))', ''), '),('));
end;
$$;
Sim, existe uma maneira melhor:
violino
Eu uso a variante de sintaxe para funções padrão SQL (adicionada com Postgres 14. Veja:
Obviamente, como ambas as funções são declaradas
STRICT
( =RETURNS NULL ON NULL INPUT
), não precisamos verificar se há entrada nula.As funções simples podem ser
LANGUAGE sql
, portanto podem ser incorporadas. Ver:concat()
for onlySTABLE
, notIMMUTABLE
, use oIMMUTABLE
operador de concatenação||
. Então, declarar que a funçãoIMMUTABLE
está correta e também não atrapalhará o inlining da função. Ver:Um terceiro
replace()
deve ser mais rápido do que puxarstring_to_array()
.Por fim, faço
json_to_polygon()
exatamente o inverso depolygon_to_json()
, que novamente deve ser mais rápido e mais fácil de ler e manter.Dito isso, o PostGIS tem algumas funções para ajudar nisso...