2. 相邻矿体边界重叠区域的检测与分割
问题定位:重叠区不是“错误面”,而是归属未定的公共带
两个相邻矿体面图层(如 orebody_A、orebody_B)在接触带附近常因分别数字化而出现重叠。与自相交不同,重叠区本身是合法的面几何,问题在于同一块空间被两个矿体同时声明。修复目标不是删除重叠,而是沿地质推断的接触线把重叠带切开,分别并入两侧矿体,使修复后 A ∩ B = ∅,且 Area(A) + Area(B) 保持不变。
关键约束有三条:① 分割线必须来自地质推断的接触线(如钻孔控制的岩性界面、剖面解释线),不能随意取重叠区中线;② 分割后重叠带内的面积必须全部归属某一侧,不允许出现新缝隙;③ 总面积守恒,即修复前后两矿体面积之和的偏差应控制在数字化精度允许范围内(示例取 ≤0.01%)。
检测:把重叠带从“面相交”中量化出来
检测的核心是求交并量化,而不是只看两图层是否相交。以 QGIS/PostGIS 或 ArcGIS 均可实现,下面给出 PostGIS 的检测 SQL(示例表名与字段按实际替换)。设两图层几何列均为 geom,坐标系为投影坐标系(单位 m),重叠面积容差取 1.0 m²,用于过滤数字化抖动产生的微小相交。
-- 1) 逐对求交,输出重叠带几何与面积
CREATE TABLE overlap_ab AS
SELECT
a.ore_id AS id_a,
b.ore_id AS id_b,
ST_Intersection(a.geom, b.geom) AS geom_overlap,
ST_Area(ST_Intersection(a.geom, b.geom)) AS area_overlap
FROM orebody_A a
JOIN orebody_B b
ON ST_Intersects(a.geom, b.geom)
WHERE ST_Area(ST_Intersection(a.geom, b.geom)) > 1.0;
-- 2) 统计重叠带宽度,判断是真实重叠还是边界抖动
-- 宽度近似 = 2 * 面积 / 周长
SELECT id_a, id_b, area_overlap,
2 * area_overlap / NULLIF(ST_Perimeter(geom_overlap), 0) AS approx_width
FROM overlap_ab
ORDER BY area_overlap DESC;
判读要点:若 approx_width 只有厘米级且沿整条边界均匀分布,多为两次数字化不一致造成的“薄带”,可用容差吸附处理;若宽度达到米级、局部膨大,则是真实的重叠归属问题,必须走分割流程。本例假设检测出 1 处重叠带,面积约 3 860 m²,近似宽度 12 m,属于需要分割的情形。
分割:用接触线切重叠带并双向归属
分割的本质是:把重叠带 O = A ∩ B 用接触线 L 切成 O_A 与 O_B 两部分,然后 A′ = (A − O) ∪ O_A,B′ = (B − O) ∪ O_B。这样重叠带被完整分配,既不残留也不重复。实现时先把接触线延长到完全穿越重叠带,再执行切割。
-- 3) 接触线穿出重叠带(两端各延长 5 m,确保完全切开)
CREATE TABLE contact_cut AS
SELECT ST_LineSubstring(
ST_LineMerge(geom),
-5.0 / ST_Length(geom),
1.0 + 5.0 / ST_Length(geom)
) AS geom
FROM contact_line
WHERE contact_id = 'C-01';
-- 4) 用接触线切割重叠带,得到两片
CREATE TABLE overlap_split AS
SELECT
o.id_a, o.id_b,
d.path[1] AS side, -- 1 / 2 表示接触线两侧
d.geom AS geom_piece
FROM overlap_ab o
CROSS JOIN LATERAL ST_Dump(
ST_Split(o.geom_overlap, (SELECT geom FROM contact_cut))
) AS d;
-- 5) 按侧别归属:side=1 归 A,side=2 归 B(侧别由接触线方向与地质约定确定)
CREATE TABLE overlap_to_a AS
SELECT id_a, id_b, ST_Union(geom_piece) AS geom FROM overlap_split WHERE side = 1 GROUP BY id_a, id_b;
CREATE TABLE overlap_to_b AS
SELECT id_a, id_b, ST_Union(geom_piece) AS geom FROM overlap_split WHERE side = 2 GROUP BY id_a, id_b;
-- 6) 重建两矿体面:先减去重叠带,再并入各自分得的部分
CREATE TABLE orebody_A_fixed AS
SELECT a.ore_id,
ST_Multi(ST_Union(
ST_Difference(a.geom, o.geom_overlap),
ta.geom
)) AS geom
FROM orebody_A a
JOIN overlap_ab o ON o.id_a = a.ore_id
JOIN overlap_to_a ta ON ta.id_a = a.ore_id
GROUP BY a.ore_id;
CREATE TABLE orebody_B_fixed AS
SELECT b.ore_id,
ST_Multi(ST_Union(
ST_Difference(b.geom, o.geom_overlap),
tb.geom
)) AS geom
FROM orebody_B b
JOIN overlap_ab o ON o.id_b = b.ore_id
JOIN overlap_to_b tb ON tb.id_b = b.ore_id
GROUP BY b.ore_id;
ST_Split 的输出顺序猜测。稳妥做法是取每片重叠带的质心,判断其位于接触线左侧还是右侧(如 ST_LineLocatePoint 结合方位),再与地质约定(例如“接触线东侧归 B”)对齐。示例中约定接触线东侧归 B。验证:三条硬指标同时通过才算修复完成
| 校验项 | 检查方法 | 通过条件(示例) |
|---|---|---|
| 无重叠 | ST_Area(ST_Intersection(A′,B′)) | = 0(或 ≤ 0.01 m² 浮点误差) |
| 无缝隙 | 重叠带内任取点,应落在 A′ 或 B′ 之一 | 重叠带被完全覆盖,无空洞 |
| 面积守恒 | |Area(A′)+Area(B′) − Area(A)−Area(B)| / 原面积和 | ≤ 0.01% |
| 几何有效 | ST_IsValid(A′)、ST_IsValid(B′) | 均为 true |
-- 7) 一次性校验
SELECT
ST_Area(ST_Intersection(a.geom, b.geom)) AS overlap_after,
ST_IsValid(a.geom) AND ST_IsValid(b.geom) AS valid_ok,
(ST_Area(a.geom) + ST_Area(b.geom)) AS area_after,
ABS((ST_Area(a.geom) + ST_Area(b.geom)) - :area_before)
/ :area_before AS area_dev
FROM orebody_A_fixed a, orebody_B_fixed b;
示例数据下,修复前 Area(A)+Area(B) = 1 284 500 m²,修复后应仍为 1 284 500 m²(重叠带被切开后分别计入两侧,总和不变),overlap_after = 0,area_dev 在浮点误差量级。若 overlap_after 不为 0,通常是接触线未完全穿越重叠带,需检查延长长度;若面积偏差超限,多半是 ST_Difference 与 ST_Union 顺序导致重叠带被重复扣除或漏加,应回到第 6 步核对。