为什么 ST_MakeValid() 从已定义的几何图形中剥离 SRID?

Bil*_*ris 5 postgresql postgis

我正在尝试ST_MakeValid()在一系列大多数同心等距的多边形上使用 PostGIS函数。. .

在此处输入图片说明

. . . 它们用明确的几何类型和 SRID 定义(虽然它们可能不是完全有效,但仍然足以在 QGIS 中呈现,如上所示):

trade=# \d tmp1
                           Table "public.tmp1"
  Column   |            Type             | Collation | Nullable | Default 
-----------+-----------------------------+-----------+----------+---------
 the_geom  | geometry(MultiPolygon,4326) |           |          | 
Run Code Online (Sandbox Code Playgroud)

不幸的是,ST_MakeValid()当我使用它来创建新表时,该函数正在剥离 SRID 和几何类型:

trade=# CREATE TABLE tmp2 AS (SELECT ST_MakeValid(the_geom) AS the_geom_valid FROM tmp1);
SELECT 25
trade=# \d tmp2
                    Table "public.tmp2"
     Column     |   Type   | Collation | Nullable | Default 
----------------+----------+-----------+----------+---------
 the_geom_valid | geometry |           |          | 

Run Code Online (Sandbox Code Playgroud)

. . . 并且ST_SetSRID()无法通过创建新表来解决它:

trade=# CREATE TABLE tmp3 AS (SELECT ST_SetSRID(the_geom_valid,4326) AS the_geom_srid FROM tmp2);
SELECT 25
trade=# \d tmp3
                    Table "public.tmp3"
    Column     |   Type   | Collation | Nullable | Default 
---------------+----------+-----------+----------+---------
 the_geom_srid | geometry |           |          | 

Run Code Online (Sandbox Code Playgroud)

. . . 或通过嵌套函数:

trade=# CREATE TABLE tmp4 AS (SELECT ST_SetSRID(ST_MakeValid(the_geom),4326) AS the_geom_all FROM tmp1);
SELECT 25
trade=# \d tmp4
                    Table "public.tmp4"
     Column    |   Type   | Collation | Nullable | Default 
 --------------+----------+-----------+----------+---------
  the_geom_all | geometry |           |          | 
Run Code Online (Sandbox Code Playgroud)

. . . 甚至通过使用每个人最喜欢的ST_MakeValid()半替代品,ST_Buffer()

trade=# CREATE TABLE tmp5 AS (SELECT ST_Buffer(the_geom,0) AS the_geom_buffer FROM tmp1);
SELECT 25
trade=# \d tmp5;
                     Table "public.tmp5"
     Column      |   Type   | Collation | Nullable | Default 
-----------------+----------+-----------+----------+---------
 the_geom_buffer | geometry |           |          | 
Run Code Online (Sandbox Code Playgroud)

我找不到任何文档表明这是使用时的预期行为ST_MakeValid()- 如何在不丢失几何类型和 SRID 的情况下创建有效的几何图形?

Dar*_*man 4

SRID正在保留。例如,试试这个:

\n\n
SELECT st_srid(the_geom_buffer) FROM tmp2 LIMIT 1;\n
Run Code Online (Sandbox Code Playgroud)\n\n

你应该看到类似的东西:

\n\n
\xe2\x94\x8c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x90\n\xe2\x94\x82 st_srid \xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\xa4\n\xe2\x94\x82    4326 \xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x98\n
Run Code Online (Sandbox Code Playgroud)\n\n

原因是 ST_MakeValid() 可以返回多种类型中的任何一种,但无法提前知道它们是什么。从文档中:

\n\n
\n

在全维度或部分维度崩溃的情况下,输出几何图形可以是较低维度至等维度几何图形的集合或较低维度的几何图形。

\n
\n\n

因此唯一的选择是返回通用几何图形。

\n\n

但是,如果您确信这种情况不会发生,您可以使用强制转换(或事后 ALTER 语句)来强制执行:

\n\n
CREATE TABLE tmp2 AS \n  SELECT \n    ST_MakeValid(the_geom)::geometry(MultiPolygon, 4326) AS the_geom_valid\n  FROM tmp1;\n
Run Code Online (Sandbox Code Playgroud)\n