在PostGIS中添加其他几何列?


10

我正在将许多地理数据集导入PostGIS,而它们具有不同SRID的。(有些有EPSG:3857,有些EPSG:4326,有些其他)。

我想另外创建一个geometry column,例如。the_geom_mercator使用SRID EPSG:3857,并将原始geom列保留SRID在其中。

如何使用PostGIS功能做到这一点?

Answers:


18

要将列添加到现有表中,请使用ALTER TABLE DDL,例如:

ALTER TABLE my_table
  ADD COLUMN the_geom_mercator
    geometry(Geometry,3857);

可以使用以下命令从另一列(the_geom)填充:

UPDATE my_table SET
  the_geom_mercator = ST_Transform(the_geom, 3857)
FROM spatial_ref_sys
WHERE ST_SRID(the_geom) = srid;

(第三行FROM spatial_ref_sys ...不是必需的,但它可以保护具有未知或无效投影的转换尝试,从而引发错误)。

如果要维护(添加/更新)该表,则可以使用触发函数来更新the_geom_mercator,例如:

CREATE OR REPLACE FUNCTION my_table_tg_fn() RETURNS trigger AS
$BODY$BEGIN
  IF TG_OP = 'INSERT' AND NEW.the_geom ISNULL THEN
    RETURN NEW; -- no new geometry
  ELSIF TG_OP = 'UPDATE' THEN
    IF NEW.the_geom IS NOT DISTINCT FROM OLD.the_geom THEN
      RETURN NEW; -- same old geometry
    END IF;
  END IF;
  -- Attempt to transform a geometry
  BEGIN
    NEW.the_geom_mercator := ST_Transform(NEW.the_geom, 3857);
  EXCEPTION WHEN SQLSTATE 'XX000' THEN
    RAISE WARNING 'the_geom_mercator not updated: %', SQLERRM;
  END;
  RETURN NEW;
END;$BODY$ LANGUAGE plpgsql;

CREATE TRIGGER my_table_tg BEFORE INSERT OR UPDATE
   ON my_table FOR EACH ROW
   EXECUTE PROCEDURE my_table_tg_fn();

请注意,ST_Transform应该捕获错误并显示警告,例如:

postgis=# INSERT INTO my_table(the_geom)
postgis-# VALUES (ST_SetSRID(ST_MakePoint(0,1), 123))
postgis-# RETURNING the_geom, the_geom_mercator;
WARNING:  the_geom_mercator not updated: GetProj4StringSPI: Cannot find SRID (123) in spatial_ref_sys
-[ RECORD 1 ]-----+---------------------------------------------------
the_geom          | 01010000207B0000000000000000000000000000000000F03F
the_geom_mercator |

INSERT 0 1

感谢您的答复。使用触发器真的很巧妙,我将开始这样做。我可以将该触发器添加到数据库中,这样就不必为每个新表添加此触发器了吗?
knutole

我将数据添加到postgis中,shp2psql并且通过管道创建表psql。所以我真的不能在表存在之前添加触发器吗?
knutole

1
如果您使用的是shp2pgsql,请使用更新语句,请参见上文。如果您需要维护表而不是用于加载,则触发器非常有用。
Mike T

2

首先创建一个普通的非空间表,该表已经存在。其次,使用OpenGIS的“ AddGeometryColumn”功能将空间列添加到表中。

例:

CREATE TABLE terrain_points ( 
ogc_fid serial NOT NULL, 
elevation double precision,
);

SELECT AddGeometryColumn('terrain_points', 'wkb_geometry', 3725, 'POINT', 3 );

1

您可以创建一个不受约束的SRID几何列以保存本机表单,然后转换为现有表单。这是一个人为的示例,假设您要从登台表中复制多边形(如果已混合,则可以将类型设置为几何,例如geometry(Geometry,3857):

CREATE TABLE poi(gid serial primary key, 
   geom_native geometry(POLYGON),  
   geom_mercator geometry(POLYGON,3857) );

INSERT INTO TABLE poi(geom_native, geom_mercator)
SELECT geom, ST_Transform(geom, 3857)
   FROM staging.imported_poly;

感谢您的回答。有什么方法可以在已经存在的表上执行此操作(即不使用暂存表)?假设我已经有一个带有geom列的表,而我只想添加另一the_geom_webmercator列。我该怎么办?
knutole
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.