Додавання додаткової колонки геометрії в PostGIS?


11

Я імпортую багато наборів геоданих у PostGIS, і вони мають різні SRID. (Деякі мають EPSG:3857, деякі EPSG:4326, деякі щось інше).

Я хотів би створити додатковий geometry column, напр. the_geom_mercatorз SRID EPSG:3857, а також зберігати оригінальний geomстовпець у тому, до чого SRIDвін увійшов.

Як я можу це зробити за допомогою функції PostGIS?

Відповіді:


19

Щоб додати стовпець до наявної таблиці, використовуйте ПІДГОТОВЛЕННУ ТАБЛИЦЮ 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 ...не потрібен, але він захищає спроби перетворення з невідомими або недійсними проекціями, які викликають помилки).

І якщо ця таблиця має бути збережена (додана / оновлена), ви можете використовувати тригерну функцію для оновлення_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

Дякую за чудову відповідь. Справді акуратно використовувати тригери, я почну це робити. Чи можу я замість цього додати цей тригер до бази даних, щоб мені не довелося додавати цей тригер для кожної нової таблиці?
кнутоле

Я додаю дані в postgis за допомогою, shp2psqlа таблиця створюється при проходженні через psql. Тож я не можу реально додати тригер до існування таблиці?
кнутоле

1
Якщо ви використовуєте shp2pgsql, використовуйте оператор оновлення, див. Вище. Тригер корисний, якщо вам потрібно підтримувати таблицю, але не для завантаження.
Майк Т

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, 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стовпець. Як би я це зробив?
кнутоле
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.