PostGIS에서 POINT를 생성하는 기능은 무엇입니까? PostGIS에서 포인트를 정의

PostGIS에서 포인트를 정의 할 때 다음 중 어느 것을 사용하기로 결정합니까?

  • ST_SetSRID(ST_MakePoint(lon,lat),4326)
  • ST_SetSRID(ST_Point(long,lat),4326)
  • ST_SetSRID(ST_GeomFromText('POINT(lon lat)',4326)
  • ST_GeomFromEWKT('SRID=4326;POINT(lon lat)')

본질적으로 성능의 차이가 있다면 어느 것이 가장 빠릅니까?



답변

내 생각 엔 ST_MakePoint가장 빠르지 만 100k 랜덤 포인트로 벤치마킹하기에 충분합니다.

\timing

WITH test AS (
  SELECT <POINT CONSTRUCTOR METHOD>
  FROM generate_series(1,100000)
)
SELECT count(*) FROM test;

그리고 PostgreSQL 9.1, x64 Debian의 PostGIS 2.1 (트렁크) 결과는 다음과 같습니다. 나는 대략적인 평균을 얻기 위해 몇 번이나 했어요. <POINT CONSTRUCTOR METHOD>가장 빠른 것부터 가장 느린 것까지 순서 는 다음과 같습니다 .

  1. ST_SetSRID(ST_MakePoint(random(), random()), 4326)
    • 평균 160ms
    • 훨씬 빠른 속도로 더블 포인트 정밀도 유지 (무손실)
    • 숫자 좌표 데이터로 매개 변수화 된 쿼리를 작성하는 가장 쉬운 방법
  2. ST_GeomFromText('POINT(' || random()::text || ' ' || random()::text || ')', 4326)
    • 평균 760ms
    • 숫자가 텍스트로 캐스트되면 문자열이 함께 조각화되고 PostGIS는 숫자를 찾기 위해 구문 분석해야합니다.
    • 숫자-> 텍스트-> 숫자 변환으로 인해 손실
  3. ST_GeomFromEWKT('SRID=4326;POINT(' || random()::text || ' ' || random()::text || ')')
    • 평균 810ms
    • 가장 느리다. 왜 느리다. ST_GeomFromText

마지막으로 위의 방법을 사용하여 손실이없는 / 손실이있는 변환의 차이점에 대한 각주. ST_MakePoint이진 부동 소수점 정밀도 데이터 만 유지하며 텍스트 변환은 데이터의 아주 작은 부분을 잘라냅니다. 두 점이 WKB에서 볼 수있는 이진 차이를 가질 수 있지만 항상 공간적으로 동일해야합니다. 거리 차이는 본질적으로 배정도를위한 기계 엡실론입니다 .

SELECT
  (geom_text = geom_binary) AS spatially_equal,
  (geom_text::text = geom_binary::text) AS binary_equal,
  (ST_AsText(geom_text) = ST_AsText(geom_binary)) AS wkt_equal,
  ST_Distance(geom_text, geom_binary)
FROM (
  SELECT x, y,
    ST_GeomFromText('POINT(' || x::text || ' ' || y::text || ')') AS geom_text,
    ST_MakePoint(x, y) AS geom_binary
  FROM (SELECT random()::float8 as x, random()::float8 as y) AS f1
) AS f2;

 spatially_equal | binary_equal | wkt_equal |     st_distance
-----------------+--------------+-----------+----------------------
 t               | f            | t         | 1.38777878078145e-16


답변

ST_MakePoint와 ST_Point는 동일합니다. 둘 다 LWGEOM_makepoint를 호출합니다 (소스 코드의 postgis / postgis.sql.in 파일에서 확인할 수 있음). ST_MakePoint를 사용합니다. 텍스트 변환 루틴은 동일한 결과를 생성하지만 필요한 구문 분석 양으로 인해 속도가 느려집니다.


답변

SRID 4326 및 형상

MikeT의 우수하고 포괄적이며 최신 답변에 대한 참고 사항 입니다. 많은 사람들이 POINT 열에 SRID를 설정하려고하기 때문에이 질문을하는 것 같습니다.

CREATE TABLE foo ( geom geometry(Point,4326) );

그러나 그들이 할 때 그들은 포인트를 만드는 가장 좋은 방법처럼 보이는 것에 문제가 생겼지 만, 아쉽게도 문제가 발생합니다.

INSERT INTO foo (geom) VALUES ( ST_MakePoint(1,2) );
ERROR:  Geometry SRID (0) does not match column SRID (4326);

거기에서 그들은 두 가지 옵션이 있다고 생각합니다.

  • SRID를 수동으로 설정하십시오.이 ST_SetSRID( ST_MakePoint(1,2) )방법은 가장 옳은 방법이지만 잔인합니다. 또는
  • 를 사용하여 텍스트로 구성하면 ST_GeomFromText논리적으로 느리고 벤치 마크가 필요하지 않습니다. PostgreSQL은 텍스트에서 생성자의 인수를 구문 분석해야합니다. 또한 그 자체가 매우 추악합니다.

아아, 다른 방법이 있습니다.

지리 유형

의 기본 SRID geography는 4326입니다. 처음 사용하는 경우 다음을 사용하는 것이 좋습니다.geography 대신을 하는geometry . 실제로, 일반적으로 원하는 차이를 모르는 경우 geography. 열을 매우 쉽게 전환 할 수 있습니다.

BEGIN;
  ALTER TABLE foo ADD COLUMN geog geography(point,4326);
  UPDATE foo SET geog = geom::geography;
  ALTER TABLE foo DROP COLUMN geom;
COMMIT;

유형이 이미 기본적으로 SRID 4326과 연관되어 있기 때문에 삽입이 더 쉬워졌습니다. 이제 명시 적으로에 캐스트 geography하거나 내재 된 캐스트를 작동시킬 수 있습니다.

ST_MakePoint(x,y)                     -- implicit cast and srid
ST_MakePoint(x,y)::geography          -- explicit cast, implicit srid
ST_SetSRID( ST_MakePoint(3,4), 4326 ) -- explicit cast and srid

이것은 다음과 같습니다 (모두 같은 것을 삽입합니다)

INSERT INTO foo (geog) VALUES
  -- implicit cast and SRID
  ( ST_MakePoint(1,2) ),

  -- explicit cast, implicit SRID
  ( ST_MakePoint(1,2)::geography ),

   -- explicit cast and SRID
  ( ST_SetSRID( ST_MakePoint(3,4), 4326 )::geography );

텍스트로 변환 한 다음 PostgreSQL에서 텍스트를 구문 분석 ST_GeomFromText하거나 강제로
ST_GeogFromText느리게합니다.


답변