当前位置: 首页 > ds >正文

PostgreSQL(PostGIS)触发器+坐标转换案例

需求,只录入一份坐标参考为4326的数据,但是发布的数据要求坐标必须是3857

对这种需求可以利用数据库触发器实现数据的同步

步骤:

1. 使用ArcGIS Pro创建一个名字为testfc_4326的图层,坐标参考为4326

2. 使用Pro再创建一个名字为testfc_3857,坐标参考为3857

3. 对两个图层分别开启Global ID功能

4. 图层的字段如下:

lftest_postgis=# \d testfc_4326Table "sde.testfc_4326"Column       |          Type          | Collation | Nullable |                           Default
-------------------+------------------------+-----------+----------+-------------------------------------------------------------objectid          | integer                |           | not null |gdb_geomattr_data | bytea                  |           |          |shape             | geometry               |           |          |field1            | character varying(255) |           |          |globalid          | character varying(38)  |           | not null | '{00000000-0000-0000-0000-000000000000}'::character varying
Indexes:"r387_sde_rowid_uk" UNIQUE, btree (objectid) WITH (fillfactor='75')"uuid_387" UNIQUE, btree (globalid) WITH (fillfactor='75')"a362_ix1" gist (shape)
Check constraints:"enforce_srid_shape" CHECK (st_srid(shape) = 4326)lftest_postgis=# \d testfc_3857Table "sde.testfc_3857"Column       |          Type          | Collation | Nullable |                           Default
-------------------+------------------------+-----------+----------+-------------------------------------------------------------objectid          | integer                |           | not null |gdb_geomattr_data | bytea                  |           |          |shape             | geometry               |           |          |field1            | character varying(255) |           |          |globalid          | character varying(38)  |           | not null | '{00000000-0000-0000-0000-000000000000}'::character varying
Indexes:"r388_sde_rowid_uk" UNIQUE, btree (objectid) WITH (fillfactor='75')"uuid_388" UNIQUE, btree (globalid) WITH (fillfactor='75')"a363_ix1" gist (shape)
Check constraints:"enforce_srid_shape" CHECK (st_srid(shape) = 3857)

  5. 同步触发器

CREATE OR REPLACE FUNCTION sync_4326_to_3857()RETURNS TRIGGER AS $$BEGINif pg_trigger_depth() < 2 then
IF TG_OP = 'INSERT' THENINSERT INTO testfc_3857(objectid, gdb_geomattr_data, field1,shape,globalid)VALUES (sde.next_rowid('sde','testfc_3857'), NEW.gdb_geomattr_data, NEW.field1,st_transform(NEW.shape,3857),NEW.globalid);RETURN NEW;ELSIF TG_OP = 'UPDATE' THENupdate testfc_3857 set gdb_geomattr_data=NEW.gdb_geomattr_data,field1=NEW.field1,globalid=NEW.globalid,shape=st_transform(NEW.shape,3857) where globalid=NEW.globalid;RETURN NEW;ELSIF TG_OP = 'DELETE' THENdelete from testfc_3857 where globalid=OLD.globalid;RETURN OLD;END IF;
END IF;RETURN NULL; -- 通常不会执行到这里END;$$ LANGUAGE plpgsql;
;
CREATE TRIGGER trg_sync_4326_3857AFTER INSERT OR UPDATE OR DELETE ON testfc_4326FOR EACH ROWEXECUTE FUNCTION sync_4326_to_3857();CREATE OR REPLACE FUNCTION sync_3857_to_4326()RETURNS TRIGGER AS $$BEGINif pg_trigger_depth() < 2 then
IF TG_OP = 'INSERT' THENINSERT INTO testfc_4326(objectid, gdb_geomattr_data, field1,shape,globalid)VALUES (sde.next_rowid('sde','testfc_4326'), NEW.gdb_geomattr_data, NEW.field1,st_transform(NEW.shape,4326),NEW.globalid);RETURN NEW;ELSIF TG_OP = 'UPDATE' THENupdate testfc_4326 set gdb_geomattr_data=NEW.gdb_geomattr_data,field1=NEW.field1,globalid=NEW.globalid,shape=st_transform(NEW.shape,4326) where globalid=NEW.globalid;RETURN NEW;ELSIF TG_OP = 'DELETE' THENdelete from testfc_4326 where globalid=OLD.globalid;RETURN OLD;END IF;
END IF;RETURN NULL; -- 通常不会执行到这里END;$$ LANGUAGE plpgsql;CREATE TRIGGER trg_sync_3857_4326AFTER INSERT OR UPDATE OR DELETE ON testfc_3857FOR EACH ROWEXECUTE FUNCTION sync_3857_to_4326();

6.使用Pro在testfc_4326插入一条记录后,使用sql查询如下,确实同步过来了


lftest_postgis=# select st_astext(shape) from testfc_3857;st_astext--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------POLYGON((1810836.61422326 1835666.21123957,5215209.44908767 -2293311.99894363,1593536.22052983 -6351863.96575071,-4418441.33887841 -5205160.20034392,1810836.61422326 1835666.2
1123957))
(1 row)lftest_postgis=# select st_astext(shape) from testfc_4326;st_astext
-------------------------------------------------------------------------------------------------------------------------------------------------POLYGON((16.267022076 16.267022076,46.84902358 -20.171107375,14.314979427 -49.451747112,-39.691533867 -42.294257399,16.267022076 16.267022076))

7. 使用pro编辑和删除数据后,都会同步过去。

8. 同理pro编辑testfc_3857也会同步到testfc_4326中。

8. 注意

我测试数据为4326到3857互转换,该转换为公开算法,因此可以使用postgis自带的st_transform实现,但是很多时候进行转换的都是cgcs2000到地方坐标,只有甲方有相关算法,并且再使用国产数据库的时候,st_transform的代码在数据库厂商手中,因此需要甲方和数据库厂商配合,甲方提供转换的函数或者动态库给数据库厂商来修改st_transform函数。

http://www.xdnf.cn/news/12157.html

相关文章:

  • 网络爬虫一课一得
  • OD 算法题 B卷【DNA序列】
  • 解决:如何在Windows adb使用dmesg | grep检查内核日志
  • 关于udp——mqtt运行注意事项
  • CSP is what?
  • SVM超详细原理总结
  • C语言数组初始化方法大全(附带实例)
  • 服务器--宝塔命令
  • 83.部署解析文件模型
  • 多模态大语言模型arxiv论文略读(106)
  • AlexNet,VGG,Inceptions, ResNet, MobileNet对比
  • Mysql的B-树和B+树的区别总结
  • 【知识点】第6章:组合数据类型
  • 【DVWA系列】——Brute Force(暴力破解)——low
  • 面试题:N叉数的最大深度
  • 软件功能鉴定需要注意哪些内容?
  • NLP学习路线图(二十四):门控循环单元(GRU)
  • 深度学习之路——CNN卷积神经网络详解
  • Python 运算符详解
  • 【Markdown 中定义函数和变量】
  • 创新驱动产业升级,国际数字影像产业园绘就文创发展新蓝图
  • Python多线程编程:从GIL锁到实战优化
  • 【openssl】升级为3.3.1,避免安全漏洞
  • 大模型高效提示词Prompt编写指南
  • Fullstack 面试复习笔记:项目梳理总结
  • 施耐德特价型号伺服电机VIA0703D31A1022、常见故障
  • 硬件学习笔记--66 MCU的DMA简介
  • unix/linux,sudo,一个强大且灵活的工具,允许一个被授权的用户以另一个用户(通常是root,即超级用户)的身份来执行命令
  • VSCode 工作区配置文件通用模板创建脚本
  • 循序渐进kubernetes之Lens