ST_DEm medidores de calcário - transformar ou converter?

9

Eu quero usar ST_DWithin em dados armazenados na geometria SRID de 4326 e usar metros como parâmetro de distância. É mais eficiente fazer uma conversão (por exemplo, data.geom :: geography) ou uma transformação em um SRID com unidades de metros (por exemplo, ST_Transform (geom, 3857)?

kingzing1
fonte
Qual a extensão espacial dos seus dados?
amigos estão dizendo sobre dps
Os dados abrangem todo o país.
kingzing1
Se os dados indexado não é a geografia, em seguida, você seria melhor fora de aproximação com formação em ST_DWithin, em seguida, usando um elenco com ST_Distance ..
Vince
Eu tentaria me transformar em Albers Equal Area Conic para o Continential USA, que acredito estar em metros (metros?) ... experimentá-lo em alguns recursos primeiro ... é aí que eu começaria ...
DPSSpatial
que tal "apenas tentar o que é mais rápido"?
Stophface

Respostas:

14

Conforme descrito, a resposta é "nenhum", pelos seguintes motivos:

  • Pegue uma tabela espacial em 4326. Crie um índice espacial nela. O índice espacial é um índice planar, consistindo nos limites 2D dos recursos, em 4326, classificados em uma estrutura em árvore.
  • (a) execute uma consulta de filtro de distância usando uma conversão, como ST_DWithin(geom::geography, %anothergeom, %radius). Como a geografia está envolvida, o sistema procurará um índice geográfico (construído em uma esfera, não em um plano) e não o encontrará. Como não possui índice, ele realizará a junção usando varreduras completas das tabelas. Vai ser lento.
  • (b) execute uma consulta de filtro de distância usando uma transformação, como ST_DWithin(ST_Transform(geom, 2163), %anothergeom, %radius). Seus testes não são contra a coluna indexada (geom), mas contra uma função aplicada à coluna ( ST_Transform(geom,2163)) e, novamente, seu índice espacial não será usado. Vai ser lento.

Você precisa que sua consulta e seu índice se harmonizem. Se você não deseja alterar a projeção de seus dados, será necessário usar um índice funcional; por exemplo, se você criar um índice de geografia de função, poderá usar uma consulta baseada em geografia:

CREATE INDEX mytable_geog_x 
  ON mytable USING GIST (geography(geom));

SELECT * 
  FROM mytable 
  WHERE ST_DWithin(geography(geom), %anothergeography, %radius);

Ou, no caso de transformação:

CREATE INDEX mytable_geog_x 
  ON mytable USING GIST (ST_Transform(geom, 2163));

SELECT * 
  FROM mytable 
  WHERE ST_DWithin(ST_Transform(geom, 2163), %another2163geometry, %radius);

O desempenho mais rápido absoluto será se você converter os dados da sua tabela em uma projeção plana (como EPSG: 2163 ), criar um índice espacial e depois usá-lo ST_DWithin()no resultado.

ALTER TABLE mytable 
  ALTER COLUMN geom 
  TYPE Geometry(Point, 2163) 
  USING ST_Transform(geom, 2163);

CREATE INDEX mytable_geom_x ON mytable USING GIST (geom);

SELECT * 
  FROM mytable
  WHERE ST_DWithin(geom, %some2163geom, %radius)
Paul Ramsey
fonte
Obrigado por este Paul. Muito útil - acelera drasticamente o tempo de processamento.
kingzing1
Mas as duas últimas consultas não diferem da primeira, na qual as últimas calculam distâncias planares e as anteriores, geodésicas?
Andre Silva
Essa é uma ótima resposta, mas o que me confunde é que parece contradizer os documentos: postgis.net/docs/manual-dev/PostGIS_FAQ.html#idm1363 Os documentos estão incorretos ou os estou interpretando mal?
Olshansk