Jak uzyskać środek ciężkości zestawu punktów w PostGIS?

16

Używam PostgreSQL z rozszerzeniem PostGIS.

Mam zestaw punktów w the_geomkolumnie z tabeli myschema.myobjects. Chcę utworzyć instrukcję select, aby uzyskać środek ciężkości tego klastra, więc z instrukcji select takiej jak to:

SELECT the_geom FROM myschema.myobjects

Muszę znaleźć poprawną składnię dla instrukcji takiej jak:

SELECT ST_AsText(ST_Centroid( (SELECT the_geom FROM myshema.myobjects) ));
Rémi B.
źródło

Odpowiedzi:

21

musisz użyć funkcji unii w ten sposób

SELECT att1, st_centroid(st_union(geom)) as geom
FROM schema.table
GROUP BY att1;

dzięki czemu można uzyskać środek ciężkości punktu, który ma ten sam atrybut.

Sergio
źródło
6

PostGIS ma dwie funkcje do łączenia wielu geometrii w jedną geometrię, której można użyć jako danych wejściowych ST_Centroid.

ST_Collect po prostu łączy zestaw geometrii bez ich modyfikacji.

Alternatywa ST_Union„rozpuści” wiele geometrii i usunie zbędne komponenty. Prawdopodobnie nie jest to, co chcesz dla tej aplikacji.

Aby zobaczyć różnicę, porównaj:

 SELECT ST_AsText(ST_Centroid(ST_Union(geom))) FROM 
 (VALUES ('POINT (0 0)'), ('POINT (2 2)'), ('POINT (2 2)')) sq (geom);

 -- POINT(1 1)

i

 SELECT ST_AsText(ST_Centroid(ST_Collect(geom))) FROM 
 (VALUES ('POINT (0 0)'), ('POINT (2 2)'), ('POINT (2 2)')) sq (geom);

 -- POINT(1.33333333333333 1.33333333333333)

W takim przypadku ST_Unionusunął zduplikowany punkt, ST_Collectzachowując go.

dbaston
źródło
4

Jeśli szukasz wydajności, skorzystaj z tego zapytania:

SELECT avg(ST_X(the_geom)) as lon, avg(ST_Y(the_geom)) as lat FROM table

daje mniej więcej taką samą wydajność jak:

SELECT ST_AsText(ST_Centroid(ST_Collect(the_geom))) FROM table

jak w odpowiedzi @dbaston, ale jest szybszy i nie zużywa tyle pamięci.

gemo1011
źródło