5.2 叠加六式:几何与属性的六种相遇 本节摘要:矢量叠加的核心是裁剪、相交、联合、擦除、标识、空间连接六个算子——前四个做几何集合运算并决定属性如何携带,标识为输入补充叠加层信息,空间连接按空间关系挂接属性而几乎不动几何。本节用两个图层的同一场实验逐一对比六式输出,给出按问题选算子的决策规则与输出净化要点。 六种对话方式 把问题抽象到最简:图层 A(耕地图斑)与图层 B(河流缓冲区)叠在同一坐标系里,空间上无非四种关系——只属 A、只属 B、两者交集、两者并集。六式就是对这几种关系做不同取舍,并决定每种取舍下属性表怎么合并。 裁剪(Clip):像用 B 当模具切 A——几何上取交集,但只保留 A 的属性。问"缓冲区内的耕地长什么样、归谁管",用裁剪。
本节摘要:矢量叠加的核心是裁剪、相交、联合、擦除、标识、空间连接六个算子——前四个做几何集合运算并决定属性如何携带,标识为输入补充叠加层信息,空间连接按空间关系挂接属性而几乎不动几何。本节用两个图层的同一场实验逐一对比六式输出,给出按问题选算子的决策规则与输出净化要点。
把问题抽象到最简:图层 A(耕地图斑)与图层 B(河流缓冲区)叠在同一坐标系里,空间上无非四种关系——只属 A、只属 B、两者交集、两者并集。六式就是对这几种关系做不同取舍,并决定每种取舍下属性表怎么合并。
裁剪(Clip):像用 B 当模具切 A——几何上取交集,但只保留 A 的属性。问"缓冲区内的耕地长什么样、归谁管",用裁剪。
相交(Intersect):同样取交集,但双方属性都保留。输出图斑既有耕地属性又有缓冲区属性。问"哪些地块既是耕地又在淹没范围内",用相交。
联合(Union):取并集,全区域都保留,落在交集的部分带双方属性,单侧部分另一侧字段为空。问"全县每个角落处于什么状态(纯耕地、纯缓冲区、两者兼有)",用联合。
擦除(Erase):从 A 里抠掉 B 覆盖的部分,保留差集与 A 的属性。问"离河超过 500 米的耕地有哪些",用擦除。
标识(Identity):以 A 为主体,在 A 的范围内叠加 B 的属性;A 未被 B 覆盖的部分保留、B 字段为空。问"给每块耕地标注是否在淹没区内",用标识——它像是"保留全部 A 的相交"。
空间连接(Spatial Join):几何几乎不动 A 一根毫毛,只按空间关系(相交、包含、最近)把 B 的属性挂到 A 的字段上。问"每个行政村包含多少个排污口",用空间连接——几何保持村界,属性表多出一列计数。
前五式改几何,第六式改属性;前四式是集合运算的变奏,第五式是信息标注,第六式是关系查询。这套分类记住了,选算子就从背参数变成查语义。

光看图不过瘾,用真实数据把六式各跑一遍,观察输出数量与字段构成:
import arcpy arcpy.env.workspace = r"K:/gisdata/overlay_lab.gdb" A, B = "parcels", "river_buffer" # 耕地图斑 与 河流500米缓冲 # 四个几何算子 for tool, out in [("Clip", "r_clip"), ("Intersect", "r_intersect"), ("Erase", "r_erase"), ("Identity", "r_identity")]: if tool == "Clip": arcpy.analysis.Clip(A, B, out) elif tool == "Intersect": arcpy.analysis.Intersect([A, B], out) elif tool == "Erase": arcpy.analysis.Erase(A, B, out) else: arcpy.analysis.Identity(A, B, out) n = int(arcpy.management.GetCount(out).getOutput(0)) flds = len(arcpy.ListFields(out)) print(f"{tool:10s} -> {out:12s} {n:5d} 要素 {flds} 字段") # 输出示例: # Clip -> r_clip 487 要素 14 字段 # Intersect -> r_intersect 487 要素 21 字段 # Erase -> r_erase 1532 要素 14 字段 # Identity -> r_identity 2019 要素 21 字段
输出透露了三件事:裁剪与相交要素数相同(同一交集)但字段差 7 个(相交携带 B 的字段);擦除保留了缓冲区外的 1532 块耕地;标识 2019 等于擦除加相交——A 的全部范围被"交集区加非交集区"划分,且统一带 B 字段(非交集区为空值)。数字之间的关系就是算子之间的代数关系。
空间连接单独做一组实验,体会"属性聚合":
import arcpy arcpy.env.workspace = r"K:/gisdata/overlay_lab.gdb" # 给每个行政村统计:辖区内排污口数量 与 最近河流距离 arcpy.analysis.SpatialJoin( target_features="villages", # 目标:村界(几何保持不动) join_features="outlets", # 挂接:排污口点 out_feature_class="villages_stats", join_operation="JOIN_ONE_TO_ONE", # 一村一行,多点聚合成统计 field_mapping='outlets "排污口数量" true true false 0 Long 0 0,Count,#,outlets,IDENTITY,0,0', match_option="INTERSECT") # 再挂一列最近河流距离 arcpy.analysis.SpatialJoin("villages_stats", "rivers", "villages_stats2", join_operation="JOIN_ONE_TO_ONE", field_mapping='rivers "最近河流名" true true false 0 Text 255,First,#,rivers,NAME,0,0', match_option="CLOSEST") with arcpy.da.SearchCursor("villages_stats2", ["村名", "排污口数量", "最近河流名"]) as cur: for row in cur: print(row) # 输出示例: # ('李家坳村', 4, '东干渠') # ('沙河村', 11, '沙河') # ('白云村', 2, '白云河')
两次连接把"数量"与"最近者"分别聚合进村界属性表——几何还是那 187 个村界多边形,一行没变,但每行现在能回答两个空间问题。这就是空间连接被称为"属性层面的叠加"的原因。
叠加输出常带三类副产品,直接使用会污染统计。碎片要素:边界几乎重合处切出的毫米级小面,属性无意义,按最小面积(如 10 平方米)筛选删除或并入邻斑。属性重复:相交后同一名目字段出现 A、B 两份(如两个图层都有"面积"),改名区分再使用。空值陷阱:标识与联合输出中,未覆盖侧字段为空,统计前先按空值分组看清规模,避免均值被空值拖偏。
净化本身也是一条工具链:按属性选择小面积、删除、字段改名、空值统计。老练的分析师交付的是净化后的图层,并把净化规则写进元数据——又回到第 3 章的档案纪律。
把六式收进一张问题对照表,实战中按问题直查:
| 你要回答的问题 | 用哪式 | 关键参数 |
|---|---|---|
| 范围内有什么(保留主体属性) | 裁剪 | 模具图层 B |
| 同时满足两个图层条件的地块 | 相交 | join_attributes 默认全保留 |
| 全区域每处属于什么状态 | 联合 | 注意空值处理 |
| 排除某区域的要素 | 擦除 | 擦除层 B |
| 给主体补充环境信息 | 标识 | 主体在前 |
| 数一数、找最近、算总和 | 空间连接 | 聚合方式与匹配选项 |
⚠️ 常见坑:把相交当万能叠加。两张大图斑密集的图层直接相交,输出要素数可能呈乘性膨胀,几千对几十万。先用处理范围与属性选择收窄输入,或考虑用空间连接替代几何求交——很多时候你要的只是属性,不是切割后的几何。
💡 关键直觉:六式是同一枚硬币的六面。几何上它们都在 A 与 B 的关系四分天下里取舍,属性上它们只是决定"带谁的字段"。想清楚要几何还是要属性、要交集还是差集,算子自动浮现。
六式解决"在不在、是不是"的问题,下一节给分析链加一把距离尺——缓冲区、近邻与服务区。