村界数据怎么算接壤:12县的邻里图谱实测
技术专栏 · 数据处理 · 2026-11-05
「我们县和哪几个县接壤?边界各有多长?」这类问题看着像查资料就能答,真要做进系统里却需要自己算——现成的邻接表并不多见。其实一份村界数据就够:把临沂市的 7,404 个村级面按县分组溶解,两两比对县轮廓的边,66 个两两组合里算出 24 对接壤、42 对不接壤,连每对之间边界有多长都一并有数。本文把这套算法和结果完整摆出来。
量法:溶解、配对、求和
算法沿用村界系列的老三样(《从村界聚合出乡镇边界:环缝合实测》的无向边配对法):先把每个县的村面溶解成县轮廓,量化登记每条边界边;两个县的轮廓之间如果存在方向相反的同一线段,说明这条边是两县的公共边界,把它兜进「甲—乙」的账上,长度累加。12 个县的溶解共 8.5 秒,两两比对 66 个组合十几秒跑完。
临沂 12 县的邻里图谱
24 对邻接关系按共享边界长度排序,前十名如下:
| 县对 | 共享边界 | 县对 | 共享边界 |
|---|---|---|---|
| 沂南县 — 沂水县 | 267.2 km | 临沭县 — 莒南县 | 129.8 km |
| 平邑县 — 费县 | 247.0 km | 沂南县 — 费县 | 95.5 km |
| 兰陵县 — 费县 | 172.4 km | 沂水县 — 蒙阴县 | 77.3 km |
| 兰山区 — 费县 | 159.7 km | 临沭县 — 郯城县 | 73.2 km |
| 沂南县 — 蒙阴县 | 157.3 km | 蒙阴县 — 费县 | 71.0 km |
每县的「人脉」差异也很大:沂南县邻接 6 个县(全市最多)、总接壤 626.3 公里,是临沂的十字路口;费县接壤总长 745.6 公里居全市之首,邻 5 县;沂水县只有 2 个市内邻居(沂南、蒙阴)——它的北部与东部边界接的是潍坊和日照,出了市的范围。罗庄区 215.5 公里垫底,城区边界本来就短。
数字之外:42 对「不接壤」也要看一眼
66 个组合里 42 对共享边为零。大部分是常识——蒙阴与郯城隔着全市南北距离,本就不挨着;但逐对过一遍也有发现:极短接壤段(河东区—郯城县 18 公里)说明存在「擦边」县对,量化精度稍粗就会漏判;而共享边为零但位置相邻的组合,要警惕飞地或数据缺面。邻接图谱的另一半价值就在这:它既是关系表,也是数据质量的探针——与《边界数据拓扑检查:一段脚本查出缝隙与重叠》配套使用,入库前把两类检查都跑一遍。
脚本:十几行算完 66 个组合
const shared = (edgesA, edgesB) => {
const rev = new Set(edgesA.map(e => key(e[2], e[3], e[0], e[1]))); // 反向边集
let len = 0;
for (const e of edgesB) {
const k = key(e[0], e[1], e[2], e[3]);
if (rev.has(k)) len += e[4]; // 配对成功:累加边长
}
return len; // 共享边界长度(米)
};
// 对 12 个县两两调用 shared(),得到 24 对邻接与 42 对零接壤
量化精度取 1e-6(约 0.1 米)——同一份数据内部的边是精确共点的,粗量化反而会把接壤与不接壤搅在一起。这与《合并京津村界数据:13,868面一条缝》里跨包接缝要放宽到米级的处理正好相反:同一份数据从严,两份数据从宽。
接壤图谱的四种用法
物流分区:相邻县合并成一个配送圈,转运节点放在共享边界的中点附近;应急通报:事件在哪个县发生,按图谱的第一圈邻县逐级通知,顺序不会乱;区域划分:销售大区、医保结算圈这类「连片」要求,用图谱做连通性校验,避免出现不接壤的飞地片区;数据质检:邻接度异常(比如某县孤零零零邻居)几乎必然意味着缺面或错面。四类场景的输入都是同一张表——本文的 24 对邻接清单。
7,404 个村面组成的临沂市包在「村界数据 · 按市」页按市整包出售;只要单县(沂南、费县们都在),「村界数据 · 按区县」页按县计价。换一个城市复算这张图谱,脚本原样能跑。
常见问题
- 怎么判断两个区县是否接壤?
- 把每个县的村级面分别溶解成县轮廓,逐边量化登记;两个县的轮廓之间存在共享边(方向相反的同一线段)即判定接壤,共享边的总长度就是接壤长度。实测临沂 12 县:66 个两两组合里 24 对接壤、42 对不接壤。
- 接壤长度是怎么算出来的?
- 共享边逐段求和:溶解后的县轮廓由村级边界拼成,把甲县轮廓的每条量化边与乙县的反向边配对,配对成功就累加这段边的实际长度。全部 24 对接壤边算完只用了十几秒,最小接壤段也有 18 公里(河东区—郯城县)。
- 为什么用村界算接壤,而不用县界数据?
- 一份村界数据自带全部信息:村级分辨率比简化县界高一两个量级,接壤线不再是一条几公里才一个折点的粗线;而且算完县与县的接壤,还能顺带得到乡镇、村两级的关系。用县界算县界当然也可以,但需要两份数据,而村界一份就够。
- 邻接图谱能用来做什么?
- 四类场景直接可用:物流与配送的分区归属(边界共享长的相邻县合并配送区更顺);应急事件的邻接通报顺序(按图谱逐级通知);区域划分与销售大区设计(避免把不接壤的县划进同一片区);数据质检(邻接度异常的县往往意味着缺面或错面)。
- 42 对不接壤是真实的吗?会不会有飞地误判?
- 以共享边为零判定不接壤,基本可靠;极端情况是两县仅靠一个点或一条极短缝「擦肩」,量化后会漏判。实测临沂 12 县里未发现此类擦肩对——最小接壤段(河东区—郯城县)也有 18 公里,与常识核对一致。严谨场景可把量化精度放宽到 10 米级复查一遍。
- 这份接壤图谱的数据和脚本在哪里能拿到?
- 7,404 个村面组成的临沂市包在「村界数据 · 按市」页按市整包出售;单县取用走「村界数据 · 按区县」页。计算脚本本文已给出,换一份村界数据、改一张县名表就能复算任意城市的接壤图谱。