PostGis--更多连接以及有效性

55 阅读4分钟

1、简介

PostGIS的空间连接和有效性检查是空间数据处理中的重要技术。这次将介绍多边形连接中的重复统计问题及其解决方案,介绍了如何处理大半径距离连接时的数据去重。同时讲解空间数据的有效性概念,包括多边形的闭合性、自相交检查等规则,并提供了实用的验证和修复方法。这些技术对于确保空间数据分析的准确性和提高查询效率至关重要。

2、更多连接

2.1 多边形/多边形连接

我们使用 ST_Intersects(geometry_a, geometry_b) 函数来确定要包含在每个邻域摘要中的人口普查区域面。这就引出了一个问题:如果一块土地落在两个社区之间的边界上怎么办?它将与两者相交,因此将包含在两者的汇总统计中。(重复统计)

  • 简单的方法是确保每个区域仅位于一个汇总区域(使用 ST_Centroid(几何))
  • 复杂的方法是在边界处划分交叉区域(使用ST_Intersection(几何,几何))

2.2 大半径距离连接

举个例子,比如问题:地铁站附近(500米以内)的人的通勤时间与远离地铁站的人的通勤时间有何不同?

-- 人口距离地铁站不到 500 米:
-- 错误方法:
SELECT Sum(popn_total)
FROM nyc_census_blocks census
JOIN nyc_subway_stations subway
ON ST_DWithin(census.geom, subway.geom, 500);
-- 会发现很多都重复计算了!!!
-- 比如一个户口距离两个地铁站都不到500米,则会重复计算

-- 正确方法:
WITH distinct_blocks AS (
  SELECT DISTINCT ON (blkid) popn_total	-- 每个街区去重
  FROM nyc_census_blocks census
  JOIN nyc_subway_stations subway
  ON ST_DWithin(census.geom, subway.geom, 500)
)
SELECT Sum(popn_total)
FROM distinct_blocks;

3、有效性

3.1 什么是有效性?

PostGIS中多边形的有效性遵循一些基本规则,这些规则确保多边形的几何结构是正确的,可以进行空间分析和操作。以下是一些关键的有效性规则:

  • 闭合环:多边形的边界必须形成一个闭合环,即多边形的起点和终点必须相同。
  • 非自相交:多边形的边界不应自相交。一个有效的多边形边界在任何点上都不会与自身相交,除了起点和终点。
  • 环的方向:在某些情况下,多边形的外环和内环(洞)的方向(顺时针或逆时针)可能会影响其有效性。通常,外环应该是顺时针,而内环(如果有的话)应该是逆时针。
  • 内环与外环的关系:如果多边形包含一个或多个内环(洞),则每个内环都必须完全位于外环内部,并且内环之间不能相交或重叠。
  • 无重叠边:多边形的边不应重叠。每条边应该只与其两个端点相连的两条边相交。
  • 无悬挂点:多边形的边界上不应有悬挂点,即边界上的点不应只连接一条边。
    在这里插入图片描述 为了检查多边形的有效性,PostGIS提供了ST_IsValid函数,它可以用来检查一个几何对象是否符合上述规则。如果几何对象无效,ST_IsValidReason函数可以用来返回无效的原因。以下是如何使用这些函数的示例:
-- 检查多边形是否有效
SELECT ST_IsValid(geom) FROM your_polygon_table;

-- 获取无效多边形的原因
SELECT ST_IsValidReason(geom) FROM your_polygon_table WHERE NOT ST_IsValid(geom);

确保多边形的有效性对于避免在空间分析和操作中出现错误非常重要

3.2 修复无效性

在这里插入图片描述 批量修复:

-- Column for old invalid form
ALTER TABLE nyc_neighborhoods
  ADD COLUMN geom_invalid geometry
  DEFAULT NULL;

-- Fix invalid and save the original
UPDATE nyc_neighborhoods
  SET geom = ST_MakeValid(geom),
      geom_invalid = geom
  WHERE NOT ST_IsValid(geom);

-- Review the invalid cases
SELECT geom, ST_IsValidReason(geom_invalid)
  FROM nyc_neighborhoods
  WHERE geom_invalid IS NOT NULL;

PS:

大家好,我是小健,Java开发工程师一枚,我会持续发一些技术推文,偶尔也会发些工作求职,互联网热点的事情,希望各位小伙伴多多支持,如果觉得本篇文章对您有所帮助,记得点赞关注收藏喔~