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

基于PostGIS的省域空间相邻检索实践

目录

前言

一、相关空间检索函数

1、ST_touches函数

2、ST_Intersects函数

3、ST_Relate函数

4、区别于对比

二、空间相邻检索实践

1、省域表相关介绍

2、相关省域相邻查询

3、全国各省份邻居排名

三、总结


前言

        在当今数字化时代,地理空间数据的高效管理和精准分析对于众多领域的发展具有至关重要的作用。省域作为国家行政区域的重要组成部分,其内部的空间关系复杂多样,尤其是空间相邻关系,对于区域规划、交通布局、生态研究等诸多方面都有着深远的影响。准确、快速地检索出省域内各地理要素之间的相邻情况,能够为各项决策提供有力支持,从而优化资源配置,推动区域协调发展。

        PostGIS作为一款功能强大的开源对象关系型空间数据库扩展,以其卓越的空间数据存储、管理和分析能力,在地理信息系统(GIS)领域得到了广泛应用。它能够高效地处理各种空间数据类型,支持复杂的空间查询和分析操作,为解决地理空间问题提供了强大的技术支持。基于PostGIS开展省域空间相邻检索实践,不仅可以充分利用其强大的空间分析功能,还能够结合省域丰富的地理空间数据资源,实现高效、精准的空间相邻关系检索。

        本次实践旨在探索如何利用PostGIS高效地实现省域空间相邻检索,通过深入研究PostGIS的空间数据模型、空间查询函数以及相关算法,结合省域实际地理空间数据,构建一套高效、准确、可扩展的空间相邻检索系统。这将为省域空间规划、资源管理、生态保护等众多领域提供有力的技术支撑,同时也为地理空间数据的深度挖掘和应用提供新的思路和方法。通过对实践过程的详细记录和分析,希望能够为相关领域的研究人员和从业者提供有益的参考和借鉴,推动地理空间数据应用的进一步发展。

一、相关空间检索函数

        通常省域的边界信息都是面数据,因此这里的数据类型是两个面数据的相邻求解,即Polygon的相邻计算。在之前的博客中我们曾经介绍了两种空间函数,原文地址如下:基于SpringBoot和PostGIS的世界各国邻国可视化实践 和 基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战。在博客中也曾对st_touches和距离求解的方式进行计算,st_touches本文还会深入介绍,距离的计算也是比较直接简单的。就是根据距离的阈值来确定是否相邻的关系。本节将介绍其它的空间相邻检索函数如st_touches、st_intersects、st_relate函数,介绍其原理和使用场景。

1、ST_touches函数

        首先介绍第一个相邻检索函数,boolean ST_Touches(geometry A, geometry B);

        如果 A 和 B 相交,但它们的内部不相交,则返回 TRUE。 等价地,A和B至少有一个公共点,并且公共点至少位于一个边界内。 对于点/点输入,关系始终为 FALSE,因为点没有边界。在数学术语中:ST_Touches(A, B) ⇔ (Int(A) ⋂ Int(B) = ∅) ∧ (A ⋂ B ≠ ∅)。该函数在以下场景的检索中会返回true。

         使用st_touches函数的空间对象,可以作用于点、线、面以及他们的各种组合中的查询与检索。 如果两个几何图形的边界相交,或者只有一个几何图形的内部与另一个几何图形的边界相交,则ST_Touches(geometry A, geometry B)将返回TRUE。我们可以在PostGIS中来查看一下其函数的定义:

CREATE OR REPLACE FUNCTION "public"."_st_touches"("geom1" "public"."geometry", "geom2" "public"."geometry")
  RETURNS "pg_catalog"."bool" AS '$libdir/postgis-3', 'touches'
  LANGUAGE c IMMUTABLE STRICT
  COST 10000

2、ST_Intersects函数

        第二个相邻查询函数是相交,boolean ST_Intersects( geometry geomA , geometry geomB );

        对于空间对象而言,面对象也是可以进行相交计算的。 在一些边界没有很好的处理的情况下,比如在使用OSM国界数据与我们的省份信息进行空间相邻分析时,就会出现这种问题。比如全球的国界与云南省的相邻数据,使用st_touches函数是很难进行空间检索的。如果使用st_touches则会返回false,因此在这种情况下,通常我们是采用相交函数来进行空间求解。请注意:ST_Overlaps、ST_Touches、ST_In都隐含着空间交集。如果上述任一项返回TRUE,则这些几何图形在空间上也相交。对于空间相交,不相交意味着FALSE。来看下在PostGIS时空数据库中如何定义相交函数的。

CREATE OR REPLACE FUNCTION "public"."_st_intersects"("geom1" "public"."geometry", "geom2" "public"."geometry")
  RETURNS "pg_catalog"."bool" AS '$libdir/postgis-3', 'ST_Intersects'
  LANGUAGE c IMMUTABLE STRICT
  COST 10000

3、ST_Relate函数

        想介绍的第三种空间相邻计算函数是:boolean ST_Relate(geometry geomA, geometry geomB, text intersectionMatrixPattern);与前两个函数不太一样的是,在参数的入参中不仅有两个空间对比对象,同时还有一个相交模式参数,即大名鼎鼎的九交参数模型。关于九交参数模型,这里不深入讲解和探讨,感兴趣的大家可以去看看。后续再深入讲解九交模型。

        简单的来介绍这个函数就是,函数允许测试和评估两个几何图形之间的空间(拓扑)关系,如维度扩展 九交模型 (DE-9IM) 所定义。DE-9IM 被指定为 9 元素矩阵,指示两个几何图形的内部、边界和外部之间相交的维度。 它由使用符号“F”、“0”、“1”、“2”的 9 个字符文本字符串表示(例如“FF1FF0102”)。可以通过将相交矩阵与相交矩阵模式进行匹配来测试特定类型的空间关系。 模式可以包含附加符号“T”(表示“交集非空”)和“*”(表示“任何值”)。 常见空间关系由命名函数 ST_Contains、ST_ContainsProperly、ST_Covers、ST_CoveredBy、ST_Crosses、ST_Disjoint、ST_Equals、ST_Intersects、ST_Overlaps、ST_Touches和 ST_Within 提供。 使用显式模式可以一步测试相交、交叉等多种条件。 它还允许测试没有命名空间关系函数的空间关系。 例如,关系“Interior-Intersects”具有 DE-9IM 模式 T********,该模式不由任何命名谓词求值。

        因此可以看到,之前提供了一些简单的空间相邻函数的处理,不同的空间函数只能检索指定的空间关系,如果有更复杂的空间查询要求,那么使用包含九交模型的St_Relate函数将能实现最大的灵活性。

CREATE OR REPLACE FUNCTION "public"."st_relate"("geom1" "public"."geometry", "geom2" "public"."geometry", text)
  RETURNS "pg_catalog"."bool" AS '$libdir/postgis-3', 'relate_pattern'
  LANGUAGE c IMMUTABLE STRICT
  COST 10000

4、区别于对比

        在实际工作中,ST_TouchesST_Intersects 的主要区别在于它们判断几何对象空间关系的严格程度和应用场景。以下是两者的详细对比和具体应用场景:

        ST_Touches

  • 功能:判断两个几何对象是否至少有一个共同点,但它们的内部不相交。

    • 两个几何对象仅在边界上接触,但内部没有重叠。

    • 对于点/点输入,关系始终为 FALSE,因为点没有边界。

  • 应用场景

    • 用于判断两个几何对象是否相邻,但不重叠。例如,判断两个多边形是否仅在边界上接触。

    • 适用于需要严格区分边界接触和内部重叠的场景,如地理分区的边界分析。

  • 数学定义

    • ST_Touches(A, B) ⇔ (Int(A) ⋂ Int(B) = ∅) ∧ (A ⋂ B ≠ ∅)

    • 即两个几何对象的内部不相交,但它们至少有一个公共点。

        ST_Intersects

  • 功能:判断两个几何对象是否相交,即它们至少有一个共同点。

    • 包括边界和内部的相交,只要两个几何对象有重叠或接触的部分,就会返回 TRUE

  • 应用场景

    • 用于判断两个几何对象是否有任何重叠或接触的部分,包括边界和内部的相交。

    • 适用于需要判断两个几何对象是否重叠或接触的场景,如空间查询和空间分析。

  • 数学定义

    • 只要两个几何对象的边界或内部有重叠或接触的部分,就会返回 TRUE

        具体区别

  • 严格程度

    • ST_Touches 更严格,仅当两个几何对象在边界上接触且内部不相交时返回 TRUE

    • ST_Intersects 更宽松,只要两个几何对象有重叠或接触的部分,无论是边界还是内部,都会返回 TRUE

  • 应用场景

    • ST_Touches 适用于需要严格区分边界接触和内部重叠的场景,如地理分区的边界分析。

    • ST_Intersects 适用于需要判断两个几何对象是否有任何重叠或接触的部分的场景,如空间查询和空间分析。

二、空间相邻检索实践

        在了解了以上的空间相邻检索函数之后,本节将结合一个实际的例子来对空间相邻检索进行使用查询实践,让大家直观的看到不同的查询情况的展示。

1、省域表相关介绍

        作为数据查询的重要空间表,省域表的设计非常重要,这里将分享省域表的逻辑结构,如下所示:

        其对应的数据库物理表结构如下:

 

CREATE TABLE "biz_province" (
  "id" int8 NOT NULL,
  "code" varchar(16) COLLATE "pg_catalog"."default" NOT NULL,
  "name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
  "type" varchar(32) COLLATE "pg_catalog"."default",
  "geom" "geometry",
  CONSTRAINT "pk_biz_province" PRIMARY KEY ("id")
);

CREATE INDEX "idx_biz_province_code" ON "public"."biz_province" USING btree (
  "code" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
CREATE INDEX "idx_biz_province_geom" ON "public"."biz_province" USING gist (
  "geom" "public"."gist_geometry_ops_2d"
);
COMMENT ON COLUMN "public"."biz_province"."id" IS '主键ID';
COMMENT ON COLUMN "public"."biz_province"."code" IS '省份编码,对应行政区划编码';
COMMENT ON COLUMN "public"."biz_province"."name" IS '省份名称';
COMMENT ON COLUMN "public"."biz_province"."type" IS '类型';
COMMENT ON COLUMN "public"."biz_province"."geom" IS 'geom';

        这里将存储我国所有的省份信息,在navicat或者pgadmin中执行以下的查询条件可以看到以下返回结果集:

2、相关省域相邻查询

        在掌握了以上的空间物理表设计之后,下面我们来看一下如何使用上面的三种方法来进行省域的空间相邻表的检索实现。

        ST_Touches检索(下面以上海市的相邻省份检索)SQL如下:

select * from biz_province where name = '上海市'
union
select t.* from biz_province s,biz_province t where s.name= '上海市'
and ST_Touches(s.geom,t.geom);

        需要说明的是,为了能展示当前省份的信息,因此使用Union查询将本省的信息进行合并。同时为了可以直接看到查询结果,这里以PgAdmin终端为例,展示查询的结果:

        然后点击geometry字段的预览按钮可以预览空间数据:

         ST_Intersects检索(下面以内蒙古自治区的相邻省份检索)SQL如下:

select * from biz_province where name = '内蒙古自治区'
union
select t.* from biz_province s,biz_province t where s.name= '内蒙古自治区'
and ST_Intersects(s.geom,t.geom);

         相交的实例我们以我国最狭长的内蒙古自治区为例,看看它的相邻省份有哪些呢?一共是有8个,下面来看一下空间位置:

        可以看到,内蒙古自治区在空间上与东三省、河北、山西、山西、宁夏、甘肃,确实是一个狭长的省份。 

        ST_Relate检索(下面以四川省的相邻省份检索)SQL如下:

select * from biz_province where name = '四川省'
union
select t.* from biz_province s,biz_province t where s.name = '四川省'
and (ST_Relate(s.geom,t.geom, 'FT*******') 
	or ST_Relate(s.geom,t.geom, 'F**T*****') 
	or ST_Relate(s.geom,t.geom, 'F***T****') 
);

        关于九交模型的参数,这里不进行太多深入的说明,以免绕晕。 可以在地图上看到四川省的邻省也是比较多的。

         天府之国,果然名不虚传。大四川的邻居也是非常多的。足足有7个,仅次于内蒙古自治区和陕西省。

3、全国各省份邻居排名

        为了看看我国各省份的邻居排名,我们使用空间函数来进行一次排名,排名的sql语句如下:

select max(s.code) 编码,max(s.name) 名称,count(1) from biz_province s,biz_province t where 
ST_Touches(s.geom,t.geom) group by s.id order by count desc;

        执行之后可以看到以下查询结果:

 编码    名称    count
150000    内蒙古自治区    8
610000    陕西省    8
510000    四川省    7
130000    河北省    7
360000    江西省    6
340000    安徽省    6
620000    甘肃省    6
410000    河南省    6
420000    湖北省    6
430000    湖南省    6
440000    广东省    6
500000    重庆市    5
520000    贵州省    5
330000    浙江省    5
530000    云南省    4
540000    西藏自治区    4
140000    山西省    4
630000    青海省    4
370000    山东省    4
450000    广西壮族自治区    4
320000    江苏省    4
640000    宁夏回族自治区    3
210000    辽宁省    3
220000    吉林省    3
650000    新疆维吾尔自治区    3
350000    福建省    3
110000    北京市    2
120000    天津市    2
230000    黑龙江省    2
310000    上海市    2
810000    香港特别行政区    1
820000    澳门特别行政区    1

        从以上的查询结果可以看到,内蒙古和陕西的邻居最多,其次是四川和河北。邻居最少的是香港和澳门特别行政区,他们都与广东省相邻。

三、总结

        以上就是本文的主要内容,本次实践旨在探索如何利用PostGIS高效地实现省域空间相邻检索,通过深入研究PostGIS的空间数据模型、空间查询函数以及相关算法,结合省域实际地理空间数据,构建一套高效、准确、可扩展的空间相邻检索系统。通过详细讲解St_touches、st_intersects和St_relate函数,让大家对省域的空间相邻有了更深入的认识。行文仓促,定有许多不足,欢迎各位专家朋友在评论区留言批评指正,不甚荣幸。

        只有站在巨人的肩膀上才能看得更远,博文也参考了其它网友的智慧。原文地址参考如下:

        1、【PostGIS入门】三、空间关系与空间连接。

        2、PostGIS教程九:空间关系。

        3、ST_Touches。

        4、ST_Intersects。


http://www.kler.cn/a/533692.html

相关文章:

  • crewai框架第三方API使用官方RAG工具(pdf,csv,json)
  • 【C++】STL——list底层实现
  • k8m 是一款轻量级、跨平台的 Kubernetes 仪表板
  • 如何优化垃圾回收机制?
  • openai agent第二弹:deepresearch原理介绍
  • 2025年2月4日--2月9日(ue4.0shader抄写+ue5肉鸽独立游戏视频)
  • C语言程序设计P6-3【应用指针进行程序设计 | 第三节】——知识要点:指针与数组
  • 【大数据技术】搭建完全分布式高可用大数据集群(Scala+Spark)
  • LLM推理--vLLM解读
  • 代码讲解系列-CV(二)——卷积神经网络
  • 动态图推理问答算法
  • 动态规划练习八(01背包问题)
  • 用 Python 绘制爱心形状的简单教程
  • 企业百科和品牌百科创建技巧
  • 【CSS】谈谈你对BFC的理解
  • 开源数据分析工具 RapidMiner
  • YK人工智能(五)——万字长文学会torch模型微调
  • 不同数据库与 WebGL 集成
  • ES6中的map和原生的对象有什么区别?
  • 信息学奥赛一本通 2089:【22CSPJ普及组】上升点列(point) | 洛谷 P8816 [CSP-J 2022] 上升点列
  • 题解:洛谷 P1608 路径统计
  • 2.5寒假作业
  • springboot校园数字化图书馆系统设计与实现
  • 数据结构【链式队列】
  • DeepSeek本地部署及其他应用接入
  • 【TensorFlow】T1:实现mnist手写数字识别