Thêm cột hình học bổ sung trong PostGIS?


10

Tôi đang nhập nhiều bộ geodata vào PostGIS và chúng có các bộ khác nhau SRID. (Một số có EPSG:3857, một số EPSG:4326, một số thứ khác).

Tôi muốn tạo thêm geometry column, vd. the_geom_mercatorvới SRID EPSG:3857, và cũng giữ geomcột ban đầu trong bất cứ điều gì SRIDnó đến.

Làm thế nào tôi có thể làm điều này với chức năng PostGIS?

Câu trả lời:


18

Để thêm một cột vào bảng hiện có, hãy sử dụng ALTER TABLE DDL , ví dụ:

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

có thể được điền từ một cột khác (the_geom) bằng cách sử dụng:

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

(dòng thứ ba FROM spatial_ref_sys ...không cần thiết, nhưng nó bảo vệ chuyển đổi các nỗ lực với các phép chiếu không xác định hoặc không hợp lệ, gây ra lỗi).

Và nếu bảng này được duy trì (thêm / cập nhật), bạn có thể sử dụng chức năng kích hoạt để cập nhật_geom_mercator, ví dụ:

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

Lưu ý rằng ST_Transform nên bẫy lỗi và hiển thị cảnh báo, ví dụ:

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

Cảm ơn cho một câu trả lời tuyệt vời. Thật sự gọn gàng khi sử dụng kích hoạt, tôi sẽ bắt đầu làm như vậy. Tôi có thể thêm trình kích hoạt đó vào cơ sở dữ liệu thay vào đó để tôi không phải thêm trình kích hoạt này cho mỗi bảng mới không?
knutole 21/07/2015

Tôi đang thêm dữ liệu vào postgis shp2psqlvà bảng được tạo khi được dẫn qua psql. Vì vậy, tôi thực sự không thể thêm một kích hoạt trước khi bảng tồn tại?
knutole 21/07/2015

1
Nếu bạn đang sử dụng shp2pgsql, hãy sử dụng câu lệnh cập nhật, xem bên trên. Một kích hoạt là hữu ích nếu bạn cần duy trì một bảng, nhưng không phải để tải.
Mike T

2

Đầu tiên tạo một bảng không gian bình thường, mà bạn đã có. Thứ hai thêm một cột không gian vào bảng bằng hàm "AddGeometryColumn" của OpenGIS.

Thí dụ:

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

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

1

Bạn có thể tạo một cột hình học SRID không giới hạn để giữ biểu mẫu gốc và sau đó chuyển đổi thành hiện có. Dưới đây là một ví dụ giả định rằng bạn có đa giác mà bạn đang sao chép từ một bảng phân tầng (nếu bạn đã trộn, bạn có thể đặt loại thành hình học, ví dụ như hình học (Hình học, 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;

Cảm ơn câu trả lời của bạn. Có cách nào để làm điều này trên các bảng đã có sẵn (tức là không sử dụng bảng phân tầng) không? Giả sử tôi đã có một bảng, với một geomcột và tôi chỉ muốn thêm một the_geom_webmercatorcột khác . Làm thế nào tôi có thể làm điều đó?
knutole
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.