ST_D Dentro de los medidores de Calc: ¿transformar o lanzar?

9

Quiero usar ST_DWithin en los datos que se almacenan en la geometría SRID de 4326 y usar metros como parámetro de distancia. ¿Es más eficiente hacer un lanzamiento (por ejemplo, data.geom :: geography) o una transformación a un SRID con unidades de metros (por ejemplo, ST_Transform (geom, 3857)? ¿O ninguno?

kingzing1
fuente
¿Qué extensión espacial tienen sus datos?
DPSEspacial
Los datos cubren la totalidad de los Estados Unidos.
Kingzing1
Si los datos indexados no son geografía, entonces sería mejor aproximarse con grados en ST_DWithin, luego usar un yeso con ST_Distance ..
Vince
Intentaría transformarme en Albers Equal Area Conic para los EE. UU. Continentales, que creo que está en metros (¿metros?) ... pruébalo primero en algunas características ... ahí es donde comenzaría ...
DPSSpatial
¿Qué pasa con "solo intentar cuál es más rápido"?
Stophface

Respuestas:

14

Como se describe, la respuesta es "ninguna", por las siguientes razones:

  • Tome una tabla espacial en 4326. Cree un índice espacial sobre ella. El índice espacial es un índice plano, que consiste en los límites 2D de las características, en 4326, ordenados en una estructura de árbol.
  • (a) ejecute una consulta de filtro de distancia utilizando un reparto, como ST_DWithin(geom::geography, %anothergeom, %radius). Debido a que la geografía está involucrada, el sistema buscará un índice de geografía (que se basa en una esfera, no en un plano) y no encontrará ninguno. Como no tiene índice, realizará la unión usando escaneos completos de las tablas. Será lento
  • (b) ejecute una consulta de filtro de distancia utilizando una transformación, como ST_DWithin(ST_Transform(geom, 2163), %anothergeom, %radius). Sus pruebas no están en contra de la columna indexada (geom), sino contra una función aplicada a la columna ( ST_Transform(geom,2163)) y, de nuevo, su índice espacial no se utilizará. Será lento

Necesita que su consulta y su índice se armonicen. Si no desea cambiar la proyección de sus datos, deberá usar un índice funcional, por ejemplo, si crea un índice de geografía de función, puede usar una consulta basada en geografía:

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

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

O, en el caso de transformación:

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);

El rendimiento más rápido absoluto será si convierte los datos de su tabla en una proyección plana (como EPSG: 2163 ), crea un índice espacial y luego lo utiliza ST_DWithin()en el 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
fuente
Gracias por esto Paul. Muy útil: acelera drásticamente el tiempo de procesamiento.
kingzing1
¿Pero las dos últimas consultas no diferirán de la primera en la que la última calcula las distancias planas y las anteriores geodésicas?
Andre Silva
Esta es una gran respuesta, pero lo que me confunde es que parece que está contradiciendo los documentos: postgis.net/docs/manual-dev/PostGIS_FAQ.html#idm1363 ¿Son incorrectos los documentos o los estoy leyendo mal?
Olshansk