PostGIS'e ek geometri sütunu eklensin mi?


11

PostGIS'e birçok coğrafi veri seti alıyorum ve farklı SRID' sları var . (Bazıları EPSG:3857, bazıları EPSG:4326, bazıları başka bir şeye sahiptir).

Ek bir tane oluşturmak istiyorum geometry column, örn. the_geom_mercatorile SRID EPSG:3857ve ayrıca orijinal tutmak geomne olursa olsun sütunu SRIDo geldi.

PostGIS işleviyle bunu nasıl yapabilirim?

Yanıtlar:


19

Varolan bir tabloya sütun eklemek için ALTER TABLE DDL'yi kullanın , örn:

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

aşağıdakileri kullanarak başka bir sütundan (the_geom) doldurulabilir:

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

(üçüncü satır FROM spatial_ref_sys ...gerekli değildir, ancak bilinmeyen veya geçersiz projeksiyonlarla dönüşüm girişimlerini korur ve bu da hataları artırır).

Bu tablo korunacaksa (eklenecek / güncellenecekse), the_geom_mercator'ı güncellemek için bir tetikleyici işlevi kullanabilirsiniz, örneğin:

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'un hataları yakalaması ve bir uyarı göstermesi gerektiğini unutmayın, örneğin:

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

Harika bir cevap için teşekkürler. Tetikleyicileri kullanmak gerçekten temiz, bunu yapmaya başlayacağım. Bu tetikleyiciyi veritabanına ekleyebilir miyim, böylece her yeni tablo için bu tetikleyiciyi eklemek zorunda kalmam?
knutole

Ben postgis ile veri ekliyorum ve piped shp2psqlzaman tablo oluşturulur psql. Yani tablo var olmadan gerçekten bir tetikleyici ekleyemiyorum?
knutole

1
Shp2pgsql kullanıyorsanız, bir güncelleme ifadesi kullanın, yukarıya bakın. Tetikleyici, bir tabloyu korumanız gerekiyorsa, ancak yükleme için kullanmamanız durumunda faydalıdır.
Mike T

2

Öncelikle, zaten sahip olduğunuz normal bir uzamsal olmayan tablo oluşturun. İkinci olarak, OpenGIS "AddGeometryColumn" işlevini kullanarak tabloya bir uzamsal sütun ekleyin.

Misal:

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

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

1

Yerel formu tutmak için kısıtlanmamış bir SRID geometri sütunu oluşturabilir ve sonra var olana dönüştürebilirsiniz. Aşama tablosundan kopyaladığınız çokgenlere sahip olduğunuzu varsayarak, karışık bir şekilde, türü geometriye, örneğin geometriye ayarlayabilirsiniz (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;

Cevabınız için teşekkürler. Bunu zaten var olan tablolarda yapmanın bir yolu var mı (örn. Aşama tabloları kullanmadan)? Diyelim ki zaten bir geomsütun içeren bir tablom var ve sadece başka bir the_geom_webmercatorsütun eklemek istiyorum . Bunu nasıl yaparım?
knutole
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.