跳转到内容
AI Agent
QGIS
教程

QGIS 字段计算器教程:24 个实测表达式与常见陷阱

发布于

要在 QGIS 中计算一列,打开图层的属性表,点击 Field Calculator(字段计算器)图标(Ctrl+I),选择新字段或现有字段,输入表达式,然后点 OK。这一步很快。难的是表达式没有报错,却写入了 NULL、平方度或错误的分类。

2026 年 11 月 7 日,我在印度班加罗尔 Indiranagar 及周边选区的真实 OpenStreetMap 图层上(8,709 栋建筑、854 条道路、35 所学校、37 个公交站、10 个选区)运行了 24 个字段计算器表达式,并在旁边运行了每个表达式的常见错误写法。下面是这份速查手册,包括精确的输出值、以椭球参考测得的隐蔽陷阱,以及我把其中最难的三个交给 QGIS 里的 AI agent 后发生了什么。

什么是 QGIS 字段计算器?

QGIS 字段计算器是内置工具,用 QGIS 表达式创建或更新属性表中的列。它可以计算面积、长度、坐标等几何值,改写文本,用 CASE WHEN 给行分类,还能从项目中的其他图层提取计数或距离。

QGIS 其实提供了四个地方来运行同样的表达式,选错地方是丢失工作的第一种方式:

  • Field Calculator 对话框 (Ctrl+I):直接编辑图层。你可以新建一列或覆盖现有列,作用于全部要素或仅选中的要素。修改会留在编辑缓冲区,直到你保存编辑。
  • 虚拟字段(对话框里的复选框):每次打开表格或绘制地图时实时计算表达式。我把测试图层中建筑 fid 27 的轮廓放大一倍后,它的普通面积列仍是 197.355,而虚拟字段更新为 789.418。问题在于虚拟字段保存在 .qgs 项目文件里,而不是 GeoPackage 或 Shapefile 里。在新项目中打开这个文件,这一列就没了。
  • Processing 中的 "Field calculator" 工具 (native:fieldcalculator):生成一个全新的输出图层,原图层保持不变。在模型中使用,或不想直接编辑原图层时用它。注意 @row_number 在这里从 0 开始,在对话框里从 1 开始。
  • 属性表顶部的快速计算栏:不打开完整对话框就能更新现有列,已经处于编辑模式时适合快速写一行表达式。

如何一步步计算字段

打开字段计算器

右键点击图层,选择 Open Attribute Table,然后点击属性表工具栏里的算盘图标。在图层面板中选中该图层后,按 Ctrl+I 可以直接打开 Field Calculator。

检查选择状态和字段设置

如果地图上选中了任何要素,Only update N selected feature(s) 默认会被勾选。如果要计算整个图层,请取消勾选。选择 Create a new field(或 Update existing field),填写 Output field name,并选择 Output field type(带小数的面积和长度用 Decimal number (real),整数计数用 Integer,标签和分类用 Text (string))。

编写表达式并查看 Preview

在左侧编辑器中输入表达式,或在中间的函数列表中搜索并双击插入。点 OK 之前,一定要看编辑器下方的 Preview 行。如果显示错误、NULL,或像 0.0000003 这样的数字,先修好表达式,再把它写进 8,000 行。

点击 OK 并保存编辑

点击 OK。如果图层不在编辑模式,QGIS 会提示它将自动开启编辑模式。计算完成后,点击属性表工具栏里的 Save Edits 软盘图标,把这一列写入磁盘。

下面是道路图层上的对话框,准备写入道路等级:

班加罗尔道路图层上的 QGIS 字段计算器对话框,勾选了 Only update 39 selected features,新建名为 road_rank 的 Text 字段,CASE WHEN 表达式把 primary 和 secondary 道路归为 arterial,Preview 显示 arterial。
QGIS 3.44 中的字段计算器对话框。注意左上角的复选框:因为画布上选中了 39 条道路,只会计算这 39 行。

不知道函数名时,用中间一栏上方的搜索框。它会筛选函数树,并在右侧打开文档,包括参数顺序和示例。

选区图层上的 QGIS 字段计算器表达式构建器,在函数列表中搜索 overlay_contains,右侧面板显示 overlay_contains 的语法和参数,预览返回 18。
在函数列表中搜索 overlay_contains。运行计算之前,底部的 Preview 就显示所选选区内有 18 所学校。

实测表达式速查手册

下面每个表达式都于 2026 年 11 月 7 日在 QGIS 3.44.15 中,在我们的班加罗尔 OpenStreetMap 图层上运行过(存储为 EPSG:4326,项目椭球为 WGS 84)。如果你需要自己区域的测试数据,我们的 如何在 QGIS 中下载 OpenStreetMap 数据 指南讲解了如何干净地获取建筑、道路和点数据。

下面的建筑样例输出来自建筑 fid 27、28、30、60 和 62(有地址和楼层数),以及 fid 1、2 和 3(两者都没有)。

面积、长度、周长和坐标

你想要的可粘贴的表达式样例实测结果常见错误写法(及其后果)
建筑面积,单位 m²(椭球)$area197.35, 110.86, 141.11, 219.71, 318.83area($geometry) 返回 0.0(约 3e-7 平方度),不报错
建筑面积,单位 m²(投影到 UTM 43N)area(transform($geometry, 'EPSG:4326', 'EPSG:32643'))197.60, 110.99, 141.29, 219.98, 319.22转换到 'EPSG:3857'(Web Mercator)后,这里的面积偏大 +5.95%
道路长度,单位米(椭球)$length616.34, 7.99, 1104.32, 9.14, 72.24length($geometry) 返回 0.005681、0.000074(度),不报错
道路长度,单位米(投影到 UTM 43N)length(transform($geometry, 'EPSG:4326', 'EPSG:32643'))616.72, 7.99, 1105.01, 9.14, 72.29转换到 'EPSG:3857' 后,道路长度中位数偏大 +3.03%
建筑周长,单位米$perimeter56.72, 44.97, 48.60, 61.54, 72.69perimeter($geometry) 在 EPSG:4326 图层上返回度
多边形质心 X(东坐标,单位米)x(centroid(transform($geometry, 'EPSG:4326', 'EPSG:32643')))786714.46, 786437.79, 786237.28在多边形上用 $x 返回 NULL,不报错;x_at($geometry, 0) 返回第一个顶点(77.642744),不是中心
多边形质心 Y(北坐标,单位米)y(centroid(transform($geometry, 'EPSG:4326', 'EPSG:32643')))1435359.45, 1435116.32, 1436699.32图层为 EPSG:4326 时,y(centroid($geometry)) 返回度(12.97...)
行号或要素 ID@row_number 或 $id1, 2, 3, 4(对话框),fid 27 的 $id 为 27@row_number 在图形界面对话框中从 1 开始,在 Processing native:fieldcalculator 中从 0 开始

如果把 $area 写进 Integer 输出字段而不是 Decimal number (real)(用 Processing 的 Field calculator 测试),QGIS 会四舍五入到最接近的整数(197.35 变成 197,110.86 变成 111),而不是截断。

条件分类(CASE WHEN 与 NULL 处理)

你想要的可粘贴的表达式样例实测结果常见错误写法(及其后果)
按面积分大小等级CASE WHEN $area < 100 THEN 'small' WHEN $area < 250 THEN 'medium' ELSE 'large' ENDmedium, medium, medium, medium, large未测试
用默认整数替换 NULL 楼层数coalesce(to_int("building:levels"), 1)4, 4, 2, 4, 3(楼层数为 NULL 时为 1)"building:levels" + 'a' 返回 '4a',因为 OSM 标签以文本字符串存储
高度分级,NULL 单独归类CASE WHEN to_int("building:levels") IS NULL THEN 'unknown' WHEN to_int("building:levels") <= 2 THEN 'low' WHEN to_int("building:levels") <= 4 THEN 'mid' ELSE 'high' ENDmid, mid, low, mid, mid(fid 1 为 unknown)省略 WHEN ... IS NULL 会让所有空行进入 ELSE,把 7,636 栋未标注的建筑标成 'high'

文本清理、格式化和日期

你想要的可粘贴的表达式样例实测结果常见错误写法(及其后果)
安全拼接门牌号和街道concat("addr:housenumber", ' ', "addr:street")'594 12th Main Road', '83/4 13th Main Road'(两者都为 NULL 时为 ' ')"addr:housenumber" || ' ' || "addr:street" 在任一列为 NULL 时返回 NULL
去掉道路名称的后缀(Road、Main、Cross)regexp_replace("name", '\\s+(Road|Main|Cross)$', '')'Chinmaya Mission Hospital', '13th Main', '12th Main'只写一个反斜杠 \s+ 会失败,报 Invalid regular expression '?+(Road|Main|Cross)$'
把 ID 补零到 12 位lpad(to_string("osm_id"), 12, '0')'000313829229', '000313835091'未测试
格式化数字用于显示format_number($area, 1)'197,4', '110,9'(在逗号区域设置的 Mac 上,3958.7 显示为 '3 958,7')输出是遵循操作系统区域设置的文本(小数逗号和窄不换行空格),之后无法再做数学运算
两个日期之间的天数day(age(to_date('2026-11-07'), to_date('2019-03-15')))2794单独用 age(...) 返回 QgsInterval 对象;to_date('07/11/2026') 会失败,除非第二个参数传入 'dd/MM/yyyy'

把文本写入 GeoPackage 或 Shapefile 时,还要注意输出字段长度。我在 Processing 中把 concat("addr:housenumber", ' ', "addr:street") 写入长度为 40 的文本字段时,整个运行中止,没有任何输出,因为有一条道路(" 80 Feet Road(Sir C.V. Raman Hospital Road)")长 43 个字符。

跨图层的空间计数、求和与最近距离

这些表达式让一个图层直接查询项目中的另一个图层,不必单独做一次 QGIS 空间连接。

你想要的可粘贴的表达式样例实测结果常见错误写法(及其后果)
统计与每个选区相交的建筑数aggregate('buildings', 'count', "osm_id", filter:=intersects($geometry, geometry(@parent)))4, 1552, 336, 3141, 79, 402, 1179, 348, 1539, 139忘记 filter:=... 会让每个选区都得到整个图层的总数(8709),不报错
每个选区的建筑总面积,单位公顷round(aggregate('buildings', 'sum', $area, filter:=intersects($geometry, geometry(@parent))) / 10000, 3)0.565, 20.292, 5.605, 59.116, 1.037, 14.094, 16.646, 7.991, 21.39, 1.7会把与选区边界相交的完整轮廓都加进来,所以边界上的建筑会在两个选区各算一次
统计每个选区内的学校数array_length(overlay_contains('schools', "osm_id"))0, 2, 3, 18, 0, 0, 7, 3, 2, 0(合计:35)不带第二个参数的 overlay_contains('schools') 返回 true 或 false,不是计数
到最近公交站的距离,单位米distance(transform($geometry, 'EPSG:4326', 'EPSG:32643'), transform(array_first(overlay_nearest('bus_stops', $geometry)), 'EPSG:4326', 'EPSG:32643'))125.17, 49.39, 199.59, 158.39, 187.97, 74.67, 123.00, 226.61distance($geometry, array_first(overlay_nearest('bus_stops', $geometry))) 返回 0.001142(度)
统计建筑 300 米内的公交站数aggregate('bus_stops', 'count', "osm_id", filter:=distance(transform($geometry, 'EPSG:4326', 'EPSG:32643'), transform(geometry(@parent), 'EPSG:4326', 'EPSG:32643')) <= 300)1, 1, 4, 2, 2, 6, 7, 7array_length(overlay_nearest('bus_stops', $id, max_distance:=300, limit:=-1)) 返回 37(所有站点),因为 300 被当成 300 度

五个不报错的字段计算器陷阱

我读了 YouTube 上 QGIS 教程下的 70 条求助评论:48 条是关于编写表达式的真实问题,其中 8 条是表达式无效、返回 NULL 或什么都没选中。更糟的是没人问的情况,因为表达式运行成功,还写入了看似合理的数字。下面是我们在班加罗尔数据上测出的五个陷阱。

1. $area 与 area($geometry),以及项目椭球的作用

$area 和 area($geometry) 做的不是同一种计算,至少有一篇 2026 年的教程说 $area 在地理坐标系中返回平方度。在我们测试的两种项目设置下,它都没有。2026 年 11 月 7 日,我们在 EPSG:4326 班加罗尔图层的前 200 栋建筑和前 200 条道路上测量了这两者以及 transform(),并以椭球 WGS 84 参考(QgsDistanceArea)作对比。

  • $area 和 $length 使用项目椭球(在 Project > Properties > General > Measurements 中设置)。当椭球为 WGS 84 时,即使图层和项目都以度为单位(EPSG:4326),$area 也返回准确的平方米。
  • 当项目椭球设为 None / Planimetric 时,$area 在我们的 EPSG:4326 图层上仍然没有返回平方度。在 QGIS 3.44.15 中,它返回的平方米在这 200 栋建筑上 偏大 +3.24%。
  • area($geometry) 和 length($geometry) 始终在图层自身的 CRS 中做平面计算。 在 EPSG:4326 图层上,area($geometry) 返回平方度(一栋房子约 0.0000003),在标准小数列中会四舍五入为 0.0。
  • 在 area() 之前转换到 Web Mercator(EPSG:3857)会让每栋建筑偏大 +5.95%,即使在班加罗尔的纬度(北纬 13°)也是如此,道路长度偏大 +3.03%。转换到当地 UTM 带(EPSG:32643)与椭球面积的误差保持在 +0.12% 以内。
在 EPSG:4326 图层上的表达式(n = 200 栋建筑,200 条道路)相对 WGS 84 椭球的误差中位数最大误差
$area(项目椭球 WGS 84)0.00%0.00%
$area(项目椭球 None)+3.24%+3.25%
$perimeter(项目椭球 None)+1.72%+2.25%
道路上的 $length(项目椭球 None)+1.31%+2.61%
area($geometry)-100.00%(平方度)-100.00%
道路上的 length($geometry)-100.00%(度)-100.00%
area(transform($geometry, 'EPSG:4326', 'EPSG:32643'))+0.12%+0.12%
道路上的 length(transform($geometry, 'EPSG:4326', 'EPSG:32643'))+0.06%+0.06%
area(transform($geometry, 'EPSG:4326', 'EPSG:3857'))+5.95%+5.96%
道路上的 length(transform($geometry, 'EPSG:4326', 'EPSG:3857'))+3.03%+3.26%

如果不清楚 EPSG:4326、EPSG:3857 和 UTM 带为什么表现差别这么大,请阅读我们的解释文章 QGIS 中的 CRS 是什么。

2. overlay_nearest 按图层单位读取 max_distance,不是米

overlay_nearest 函数很快,因为它使用空间索引,还有一个方便的 max_distance 参数。但 max_distance 始终以图层的坐标单位计量。

当我们的建筑和公交站都是 EPSG:4326(度),而你写 array_length(overlay_nearest('bus_stops', $id, max_distance:=300, limit:=-1)) 时,QGIS 会查找 300 度以内的公交站。这覆盖了整个地球,所以每栋建筑都得到 37(图层中全部 37 个公交站)。把 300 米估算成 max_distance:=0.003 也不太行,因为一度经度和一度纬度对应的米数并不相同:在建筑 fid 62 上,0.003 返回了 8 个站点,而真实值是 7。要么先把两个图层都重投影到 UTM,要么使用上面空间表格最后一行的 aggregate(..., filter:=distance(transform(...))) 写法。

3. NULL 行会直接落入 CASE WHEN 的 ELSE 分支

在我们的班加罗尔数据集中,8,709 栋建筑里只有 1,073 栋(12.3%)有 building:levels 标签。其余 7,636 栋为 NULL。

如果你写 CASE WHEN to_int("building:levels") <= 2 THEN 'low' WHEN to_int("building:levels") <= 4 THEN 'mid' ELSE 'high' END,两个 <= 比较在 NULL 行上都得出未知,这一行就会落入 ELSE。最后你会把 7,636 栋未标注的建筑归为高层塔楼,而且没有任何警告。数据有缺失时,一定要把 WHEN "field" IS NULL THEN 'unknown' 放在第一个分支(或者不写 ELSE,让不匹配的行保持 NULL)。

4. "Only update selected features" 会让这一列的其余部分保持 NULL

只要地图画布上选中了哪怕一个要素,字段计算器就会自动勾选 Only update N selected feature(s)。

我选中班加罗尔的 39 条 primary 道路,把 CASE WHEN "highway" IN ('primary', 'secondary') THEN 'arterial' ELSE 'local' END 写入新字段 road_rank 后,QGIS 给这 39 行写入了 'arterial',其余 815 条道路保持 NULL(包括表达式明确写到的全部 28 条 secondary 道路)。

选中 39 条 primary 道路后运行字段计算器,道路图层的 QGIS 属性表:primary 行的 road_rank 显示 arterial,secondary 和 residential 行显示 NULL,row_n 列由 @row_number 显示 1、2、3。
因为打开对话框时选中了 39 条 primary 道路,28 条 secondary 道路和 787 条普通道路都得到 NULL,尽管 CASE 表达式已经处理了它们。

5. 双引号与单引号(为什么 "building" = "yes" 返回 NULL)

在 QGIS 表达式中,双引号 " " 表示字段名,单引号 ' ' 表示文本值。

如果你输入 "building" = "yes",QGIS 会找一个叫 building 的列,把它和另一个叫 yes 的列比较。因为没有叫 yes 的列,表达式结果为 NULL(底层的 QgsExpression 解析器会报 Field 'yes' not found)。同样,如果列名含有冒号,比如 OpenStreetMap 的 building:levels,不加双引号会失败,报 syntax error, unexpected Unknown_CHARACTER。在 Fields and Values 列表中双击字段名,每次都会插入正确的引号。

跳过语法:用 AI agent 完成同样的计算

手写 $area 很快。手写一个嵌套的 aggregate(),里面有两个 transform() 调用、一个 @parent 几何引用和一个距离过滤条件,这才是大家最后跑去 Stack Exchange 提问的地方。

我们开发了 AI Agent,一个停靠在 QGIS 里的聊天面板,所以这一节讲的是我们自己的工具。因为它运行在你打开的 QGIS 项目里,它会先查看你的图层名、字段类型、CRS 和唯一值,再替你运行 Field Calculator 或 Processing 工具。

2026 年 11 月 7 日,我把测试计划中三个多步骤计算交给 AI Agent(v1.9.4,Medium effort,Balanced permissions),每个聊天一句话,使用完全相同的五个 EPSG:4326 班加罗尔图层。

任务发送的原始提示词Agent 用时与我们独立核对的结果对比
A. 邻近计数"Add a field called bus_stops_300m to the buildings layer with the number of bus stops within 300 metres of each building."39 秒通过。创建了 Integer 字段,8,709 栋建筑全部填写,与我们在 EPSG:32643 中按轮廓到站点计算的结果相比 0 处不一致(范围 0 到 8)。
B. 分类 + 样式"Class the buildings into low (1 or 2 levels), mid (3 or 4) and high (5 or more) from the building:levels field, store the class in a new field called height_class, and style the buildings by that class."18 秒通过。563 栋 low,442 栋 mid,68 栋 high(1,073 栋全部符合我们的规则)。7,636 栋没有楼层数的行保持 NULL,并以第四个灰色类别 "Unknown levels" 显示。
C. 每个选区的学校数和建筑面积"For each ward, add the number of schools and the total building area in hectares."37 秒通过(方法有差异)。school_count 在 10/10 个选区一致(合计 35)。building_ha 在 10/10 个选区与裁剪后的轮廓面积一致(合计 148.25 公顷)。

在任务 A 中,agent 没有掉进 300 度的 overlay_nearest 陷阱。它的工具日志显示,它查看了两个图层,检查了 CRS,以米制单位从建筑轮廓(不是质心,用质心会让 667 栋建筑的结果不同)进行计算,并在回答前核对了最小值和最大值。

QGIS 中的 AI Agent 面板,为 8,709 栋班加罗尔建筑添加 bus_stops_300m 字段后,报告计数范围 0 到 8,没有缺失值,并说明是从每栋建筑轮廓到 37 个站点的直线距离。
AI Agent 中的任务 A:在 EPSG:4326 项目中用 39 秒算出 8,709 栋建筑 300 米内的公交站数,没有掉进度数陷阱。

在任务 B 中,它先检查了 building:levels 的唯一值,发现 8,709 栋建筑中有 7,636 栋没有楼层数,于是在 height_class 中让这些行保持 NULL,而不是让它们落入 high,并在地图上应用了 4 类分类样式。

AI Agent 面板和 QGIS 图层面板,显示 height_class 字段分为 low、mid、high 和 Unknown levels,回答列出 563 栋 low、442 栋 mid、68 栋 high 和 7,636 栋未知建筑。
任务 B:agent 先检查了这一列,让 7,636 栋未标注的建筑不进入 ELSE 分支,并为全部四组设置了样式。

看渲染出的地图就能明白,为什么在 OpenStreetMap 数据上检查 NULL 很重要:灰色建筑就是没有记录 building:levels 标签的那 87.7%。

班加罗尔 Indiranagar 中心区的 QGIS 渲染地图,建筑按楼层着色:浅黄为 low,橙色为 mid,深红为 high,灰色为未知楼层,叠加了道路和表示公交站的黑点。
按 height_class 着色的 Indiranagar 中心区:563 栋 low(黄色),442 栋 mid(橙色),68 栋 high(红色),7,636 栋在 OSM 中没有楼层标签(灰色)。

在任务 C 中,agent 的 building_ha 数值与速查手册中每个选区公顷数那一行略有不同:New Thippasandra 为 20.151 ha,而不是 20.292 ha(-0.69%),Jeevan Bhimanagar 为 -0.14%,Indiranagar 为 -0.06%。我查了原因,发现 agent 其实用了比我的 intersects() 过滤更严格的几何方法:它先在选区边界处裁剪建筑多边形,再求面积之和,所以跨越边界的建筑不会在两个选区重复计算,它也在回复中说明了这一点。它确实让选区图层停留在编辑模式,留有未提交的编辑,并在回答中告诉我这些编辑尚未保存。

QGIS 中的 AI Agent 面板,报告班加罗尔 10 个选区各自的 school_count 和 building_ha,说明轮廓已按选区边界裁剪,且编辑尚未保存。
任务 C:agent 在汇总公顷数前,把跨边界的建筑按选区边界裁剪,并说明图层编辑尚未提交。

下面是提交这些编辑后选区图层的属性表:

班加罗尔 10 个选区的 QGIS 属性表,显示新增的 school_count 整数列和 building_ha 小数列,旁边是 Domlur、Indiranagar、New Thippasandra 和 Ulsoor 等选区名称。
10 个选区新增了 school_count(合计 35)和 building_ha(合计 148.25 公顷)。

三个任务是很小的样本(n = 3),而且我给出的提示词很清楚,写明了字段和分类界限,所以请把它看作演示,而不是基准测试。对于 $area 或 concat() 这样的简单公式,字段计算器对话框比输入一条聊天消息更快。agent 真正有用的地方,是需要跨图层聚合、CRS 转换或多步骤 Processing 链的时候,或者你本来要写 PyQGIS 脚本 的时候。你也可以在我们的 QGIS AI 汇总页 比较其他助手。

我们如何测量。 所有测试于 2026 年 11 月 7 日在 macOS 上的 QGIS 3.44.15-Solothurn 中进行,使用班加罗尔 Indiranagar 的 OpenStreetMap 数据(边界框 12.968, 77.634, 12.986, 77.656,ODbL),项目 CRS 为 EPSG:4326。每个速查表达式都在相同要素 ID 上,用独立的 Python 或 QgsDistanceArea 计算核对过。面积和长度误差在按 fid 排序的前 200 栋建筑和前 200 条道路上测量,以使用 WGS 84 椭球(EPSG:7030)的 QgsDistanceArea 为参考。AI Agent 1.9.4 以 Medium effort 和 Balanced permissions 运行,每个任务使用一个新聊天。YouTube 问题数来自 59 个视频下的 70 条求助评论,这些评论从 25,276 条评论的语料中筛选得出。

常见问题

为什么我在 QGIS 中计算的 $area 不对或返回 0?

先检查你是不是输入了 area($geometry) 而不是 $area。在以度存储的图层(EPSG:4326)上,area($geometry) 返回平方度(一栋房子约 0.0000003),在小数字段中会四舍五入为 0.0。使用 $area,并在 Project > Properties > General > Measurements 中把项目椭球设为 WGS 84;或者在表达式中用当地 UTM 带重投影几何:area(transform($geometry, 'EPSG:4326', 'EPSG:32643'))。避免使用 EPSG:3857(Web Mercator),在我们的测试中,即使在北纬 13°,它也让建筑面积偏大 +5.95%。

如何在 QGIS 字段计算器中写 IF 或 CASE 语句?

两种结果时,用 if(condition, value_if_true, value_if_false),例如 if($area < 100, 'small', 'large')。三个或更多类别时,用 CASE WHEN ... THEN ... ELSE ... END:

CASE WHEN to_int("building:levels") IS NULL THEN 'unknown' WHEN to_int("building:levels") <= 2 THEN 'low' WHEN to_int("building:levels") <= 4 THEN 'mid' ELSE 'high' END

把 IS NULL 检查放在最前面。否则每个空值行都会落入 ELSE。

为什么字段计算器在全部或大部分行中返回 NULL?

四个常见原因:

  1. 地图上选中了要素,所以 Only update N selected feature(s) 被勾选,所有未选中的行都保持 NULL。
  2. 你用 || 拼接文本(比如 "addr:housenumber" || ' ' || "addr:street"),只要有一个输入为 NULL,整个结果就是 NULL。请改用 concat()。
  3. 你给文本值加了双引号("building" = "yes"),这会让 QGIS 去找名为 yes 的列。值要用单引号("building" = 'yes')。
  4. 你在多边形或线图层上用了 $x 或 $y。$x 只适用于点;多边形请用 x(centroid($geometry))。

如何在 QGIS 字段计算器中按公顷计算面积?

把 Output field type 设为 Decimal number (real),把 Precision 设为 2 或 3,然后输入 $area / 10000(前提是项目面积单位为平方米,且已在 Project > Properties > General 中设置项目椭球)。如果要把存储的值本身四舍五入到 3 位小数,用 round($area / 10000, 3)。

如何在字段计算器中只更新选中的要素?

先在地图画布或属性表中选中要素,再打开字段计算器(Ctrl+I)。左上角的 Only update N selected feature(s) 复选框会自动勾选。选择 Update existing field,从下拉列表中选择列,输入表达式,然后点击 OK。

免费试用 AI Agent

在 QGIS 里,说一句就能完成

AI Agent 会在你自己的 QGIS 项目中,完成你描述的任务。免费使用,无需绑卡。

免费试用 AI Agent
由以下作者撰写Yvann Barbot
·10 min read