跳转到内容
AI Agent
QGIS
Tutorial

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

发布于

里昂第 8 区的街道地图,红色的学校点各自用一条黑线连到最近的蓝色有轨电车站,图上写着 710 m,里昂学校到电车站的距离中位数。

空间连接根据要素所在的位置,而不是共同的 ID,把一个图层的字段复制到另一个图层上。 在 QGIS 中,打开 Vector > Data Management Tools > Join Attributes by Location…,选好要接收新字段的图层、提供字段的图层和一条规则(例如 "intersect"),然后运行。遇到"哪个最近"这类问题,改用 Join Attributes by Nearest,也可以直接用一句话把整个任务告诉 AI Agent。

你想做什么工具实测耗时
让每个点获得它所在区域的名称Join Attributes by Location0.21 s,382 所学校
同样的事,用一句话完成AI Agent22 s,统计和最近邻一起完成
按区域统计点的数量或求和Join Attributes by Location (Summary)0.02 s,9 个区
找出最近的要素和距离Join Attributes by Nearest0.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。

QGIS 的 Join attributes by location 对话框。Join to features in:schools。空间谓词:已勾选 intersect。By comparing to:arrondissements。Fields to add:name。Join type:Take attributes of the first matching feature only (one-to-one)。Joined field prefix:arr_。
我们运行的这次连接:学校获得所在 arrondissement 的名称。382 所学校全部匹配,耗时 0.21 秒。

只有想丢掉没连上的记录时,才勾选 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 所。

QGIS 中填充为橙色的里昂各 arrondissement 和学校点,右侧是 AI Agent 面板。请求内容是: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 的数量,共 382 所学校,并说明所有学校都获得了 nearest_tram 和 tram_distance_m,距离从 49.6 到 4,949.2 m。
同样的两次连接,一句话完成。回答里带有新图层的链接,并列出了改动内容。

适用情况: 你知道要问什么,但不清楚四个连接工具里该用哪个,或者需要串联多个步骤。

不适用情况: 你每周都要运行同一个连接。把它保存成模型或 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。

里昂 9 个 arrondissement 的地图,按学校数量从浅黄到深橙着色,并逐个标注:9e 38、4e 27、1e 33、6e 41、5e 56、2e 27、3e 54、7e 53、8e 53。红点表示学校。
一次汇总连接得到每个 arrondissement 的学校数量:0.02 秒。

它也可以对数值求和。在 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 字段,还有两端的坐标。

里昂第 8 区的街道地图。红色的学校点各自用一条黑线连到最近的蓝色电车站。有几所学校共用同一个车站。
每所学校连到最近的电车站。整个里昂的中位数是 710 m,382 所学校中有 86 所在 300 m 以内。

有两个设置会改变结果:

  • 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 是接收字段的图层。

红色形状 A 与蓝色形状 B 之间八种空间关系的示意图:intersect,二者有任何共同部分;contain,A 包含整个 B;are within,A 位于 B 内部;equal,几何完全相同;touch,只共享边界;overlap,同类型且有部分重叠;cross,线穿过另一个要素;no match(disjoint),没有任何连接。
红色是接收字段的图层,蓝色是用来比较的图层。

三条规则能应对大部分工作:

  • 点落在多边形内,以及只需要接触的情况,用 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,2541.13 s
只取第一个匹配要素(one-to-one)46,2500.99 s
只取重叠最大的(one-to-one)46,2509.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 秒内完成了按区统计和最近邻连接,结果与手动运行完全一致。

在 QGIS 中免费试用 AI Agent,无需绑卡

由以下作者撰写TerraLab
·6 min read
联系