QGIS 空间连接教程:按位置、最近邻与 AI
发布于

空间连接根据要素所在的位置,而不是共同的 ID,把一个图层的字段复制到另一个图层上。 在 QGIS 中,打开 Vector > Data Management Tools > Join Attributes by Location…,选好要接收新字段的图层、提供字段的图层和一条规则(例如 "intersect"),然后运行。遇到"哪个最近"这类问题,改用 Join Attributes by Nearest,也可以直接用一句话把整个任务告诉 AI Agent。
| 你想做什么 | 工具 | 实测耗时 |
|---|---|---|
| 让每个点获得它所在区域的名称 | Join Attributes by Location | 0.21 s,382 所学校 |
| 同样的事,用一句话完成 | AI Agent | 22 s,统计和最近邻一起完成 |
| 按区域统计点的数量或求和 | Join Attributes by Location (Summary) | 0.02 s,9 个区 |
| 找出最近的要素和距离 | Join Attributes by Nearest | 0.06 s,382 所学校 |
测试数据
本文的每个数字都来自 2026 年 10 月 15 日在法国里昂真实开放数据上的一次运行:
- OpenStreetMap 的 9 个 arrondissement(城市的行政区)和 382 所学校。
- OpenStreetMap 的 106 个有轨电车站。
- 法国国家地形数据库 IGN BD TOPO 的 103,910 栋建筑。
所有图层都使用 Lambert-93(EPSG:2154),这是一个以米为单位的投影坐标系。耗时来自 MacBook Air M4 上的 QGIS 3.44。
方法 1:Join attributes by location
这是最经典的空间连接。这里,每所学校都会得到所属 arrondissement 的名称。
打开工具
Vector > Data Management Tools > Join Attributes by Location…。你也可以在 Processing Toolbox(处理工具箱,Ctrl+Alt+T)中搜索 "join attributes"。
选择两个图层
Join to features in 是接收新字段的图层,这里是 schools。By comparing to 是提供字段的图层,这里是 arrondissements。
勾选空间谓词
对于点落在多边形内的情况,intersect 是安全的默认选项。下面的章节会说明每个选项的含义。
选择字段和连接类型
在 Fields to add 中只保留需要的字段,这里是 name。把 Join type 设为 one-to-one,并加上 arr_ 这样的前缀,方便一眼找到新字段。
运行
先让 Joined layer 保持为临时图层,检查结果后再保存为 GeoPackage。

只有想丢掉没连上的记录时,才勾选 Discard records which could not be joined。一开始先不要勾选:空行能告诉你哪里出了问题。
适用情况: 你想从要素所在或接触的对象上取一个或几个字段。
不适用情况: 要素之间从不接触,例如学校和电车站。这种情况用方法 4。
方法 2:用一句话请 AI Agent 完成
AI Agent 是我们的 QGIS 插件,可以根据你输入的请求执行任务。它会读取图层名和字段,选择工具,并在你的项目中运行。
我们在加载了同样的里昂图层后,向它输入了下面这句话(英文原文):
Count the schools in each arrondissement, then give every school the name of its nearest tram stop and the distance to it in metres.
意思是:统计每个 arrondissement 的学校数量,然后给每所学校加上最近电车站的名称和到该站的距离(单位为米)。
它先运行了两个 QGIS 处理工具,再用一小段 Python 把两个新字段写入学校图层。面板显示 "Worked for 22 s"。它只请求过一次许可,因为它要修改磁盘上的 GeoPackage。它的统计结果与我们手动运行的结果完全一致:共 382 所学校,从第 2 区和第 4 区的 27 所,到第 5 区的 56 所。

适用情况: 你知道要问什么,但不清楚四个连接工具里该用哪个,或者需要串联多个步骤。
不适用情况: 你每周都要运行同一个连接。把它保存成模型或 Python 脚本一次就够了。
价格: 免费版,无需绑卡。Pro 版每月 €49,不含增值税。
方法 3:用空间连接统计和汇总
方法 1 让每所学校得到所属的区。反过来的问题,即每个区有多少所学校,需要用汇总版本。
在 Processing Toolbox 中搜索 Join attributes by location (summary)。把多边形放进 Join to features in,把点放进 By comparing to,然后在 Summaries to calculate 中选择统计量:计数、求和、平均值、中位数、最小值、最大值等。QGIS 会为每个统计量新增一个字段,命名类似 osm_id_count。

它也可以对数值求和。在 IGN 建筑数据上,一次运行就给出了每个 arrondissement 的建筑数量和其中登记的住宅套数:第 3 区的建筑数(9,474 栋)和住宅套数(51,743 套)都是最多的。
只想做简单计数的话,Vector > Analysis Tools > Count Points in Polygon… 设置更少,结果相同。
适用情况: 你要的答案是每个区域的一个数字:数量、总和、平均值。
不适用情况: 你需要匹配结果的明细列表。请用方法 1,并选择 one-to-many。
方法 4:Join attributes by nearest
要素之间从不接触时,可以按距离连接。在 Processing Toolbox 中搜索 Join attributes by nearest。
把 Input layer 设为 schools,Input layer 2 设为 tram_stops,Maximum nearest neighbors 设为 1。QGIS 会加上电车站的字段和一个 distance 字段,还有两端的坐标。

有两个设置会改变结果:
- Maximum distance(最大距离)。 设为 300 m 时,只有 86 所学校找到了车站。其余 296 所留在输出里,字段为空,除非你勾选 Discard records which could not be joined。
- Maximum nearest neighbors(最大近邻数)。 设为 3 时,382 所学校变成了 1,146 行,每所学校和每个车站各一行。距离完全相同的并列情况也会多出一行:在 103,910 栋 IGN 建筑上,我们得到了 103,911 行。
这里的距离是直线距离,不是沿街道的步行距离。
适用情况: 你要问"哪个最近"和"有多远"。
不适用情况: 你需要出行距离。请用 Processing Toolbox 中的 Network analysis 工具。
该勾选哪个空间谓词
空间谓词是决定是否匹配的空间规则。QGIS 把它理解为"图层 A [谓词] 图层 B",其中 A 是接收字段的图层。

三条规则能应对大部分工作:
- 点落在多边形内,以及只需要接触的情况,用 intersect。它也会匹配位于边界上的要素。
- 要素必须整个落在内部时,用 are within。在我们的建筑数据中,与里昂相交的建筑里有 112 栋并不完全位于某一个 arrondissement 内:108 栋跨过了市界,4 栋跨过了内部边界。
- 反方向,即多边形包含点时,用 contain。
你可以同时勾选多个选项。只要其中任何一个成立,要素就算匹配。
One-to-one、one-to-many 还是 largest overlap
位于边界上的建筑会同时接触两个区。Join type 决定如何处理它。以下是与里昂相交的 46,250 栋 IGN 建筑的结果:
| 连接类型 | 输出行数 | 耗时 |
|---|---|---|
| One-to-many(每个匹配一个要素) | 46,254 | 1.13 s |
| 只取第一个匹配要素(one-to-one) | 46,250 | 0.99 s |
| 只取重叠最大的(one-to-one) | 46,250 | 9.62 s |
One-to-many 把跨内部边界的 4 栋建筑复制了一份。做匹配列表时这样没问题,但做任何求和都是错的:这些建筑会被算两次。
"First matching" 保留 QGIS 先遇到的那个匹配,所以边界上的建筑可能落入任意一个区。"Largest overlap" 选择包含它最多部分的区,这是更合理的答案,但这里耗时是前者的十倍。
坐标参考系(CRS)的陷阱
错误的坐标参考系很少让连接直接失败,它只会悄悄改变结果。
- 位置连接可以混用不同的 CRS。 我们把学校留在 WGS 84(EPSG:4326),把各区留在 Lambert-93。QGIS 即时重投影,382 所学校全部匹配。
- 距离的单位跟随输入图层。 对 WGS 84 文件运行 Join by nearest,距离的中位数是 0.0071。这是度,不是米。请先用
Vector > Data Management Tools > Reproject Layer…把两个图层都重投影到以米为单位的投影坐标参考系。 - Maximum distance 使用同样的单位。 以度为单位的 300 可以覆盖整个地球。
我们的指南 什么是 CRS 解释了度和米的区别,以及如何修复位置错误的图层。
大图层的速度
QGIS 处理城市规模的连接只需几秒。在 103,910 栋 IGN 建筑上:
- 与 9 个区做 one-to-one 连接:从 GeoPackage 读取只需 0.97 s。
- 同一图层存成 Shapefile:1.69 s。执行
Vector > Data Management Tools > Create Spatial Index…之后是 1.04 s。 - 为每栋建筑找最近的电车站:3.5 s。
- Largest overlap:9.62 s,是最慢的选项。
四个习惯能让大型连接保持快速:
- 使用 GeoPackage。 它自带空间索引。Shapefile 需要
.qix文件,Create Spatial Index 会生成它。 - 只要必要的字段。 填写 Fields to add,不要复制全部字段。
- 避免 largest overlap,除非边界上的要素确实重要。
- 先修复几何。 无效的多边形会让运行中止,并提示 "has invalid geometry"。Processing Toolbox 中的 Fix geometries 工具可以修复。你也可以修改输入图层旁扳手图标下的 Invalid feature filtering。
也要检查点的位置。382 个学校点中,只有 211 个落在 IGN 建筑内。其余的标在操场和院子里,所以"学校在建筑内"这个条件会漏掉 171 所学校。
要点回顾
用 Join Attributes by Location 加 intersect,让点获得所在区域的名称。
要按区域计数或求和,用 Summary 版本;要找最近的要素和距离,用 Join Attributes by Nearest。
要算总数,选 one-to-one;需要每一个匹配时,选 one-to-many。
做任何距离计算之前,先重投影到以米为单位的 CRS。
如果不确定哪个工具合适,就把你想要的结果告诉 AI Agent,再检查它做了什么。
常见问题
QGIS 中的空间连接是什么?
空间连接根据位置(在内部、接触或最近)把一个图层的字段加到另一个图层上。在 QGIS 中,主要工具有 Join Attributes by Location、用于计数和统计的 Summary 版本,以及用于距离的 Join Attributes by Nearest。
如何在 QGIS 中按位置连接属性?
打开 Vector > Data Management Tools > Join Attributes by Location…。在 Join to features in 中设置接收字段的图层,在 By comparing to 中设置来源图层,勾选 intersect,选择字段和 one-to-one 连接类型,然后运行。
按位置连接和按最近邻连接有什么区别?
按位置连接要求要素按你勾选的空间谓词相互接触或重叠。按最近邻连接不需要接触:它找出最近的要素并添加距离字段,单位取决于输入图层 CRS 的单位。
为什么我的空间连接返回的字段是空的?
通常是要素不满足空间谓词:点刚好落在多边形外面、谓词过严(例如 "are within"),或者几何无效。在地图上检查两个图层,试试 "intersect",并运行 Fix Geometries。如果某个图层缺少 CRS,它的位置也会出错。
AI 可以在 QGIS 中做空间连接吗?
可以。AI Agent 根据输入的请求运行 QGIS 工具。在我们的里昂测试中,它用一句话在 22 秒内完成了按区统计和最近邻连接,结果与手动运行完全一致。
中,打开 

