如果你用某款主流GIS平台做过地形分析、淹没模拟或者选址建模,一定绕不开ArcToolbox里那一排排工具。我这些年做项目,最常被新同事问的不是某个工具怎么点,而是“栅格计算器到底是怎么个原理,为什么一条表达式就把整个区域的结果算出来了”。这篇就拿3D Analyst模块里的栅格计算(一)作为开端,把栅格计算这个概念、背后的代数逻辑以及实操中最容易踩的坑,一次性讲清楚。这篇内容更适合正在学栅格数据处理、搞地形表面分析的人,也适合那些已经把坡度、坡向、山体阴影工具点得滚瓜烂熟,却始终不太敢写复杂表达式的朋友。看完你至少能独立写出第一条有实际意义的栅格计算表达式,并且知道算错了该怎么排查。1. 栅格计算到底是什么,为什么说它是空间分析的“心脏”1.1 从“逐像元运算”理解栅格计算的底层逻辑栅格计算听起来很玄,实际上就是把整个研究区域切成了无数个规则小格子,每个格子(像元)都带着一个数值。比如DEM数据里,每个像元存的是高程;坡度数据里,每个像元存的是该位置的坡度角;降雨量插值结果里,每个像元存的是年降雨量。栅格计算做的事,就是把这些像元数值当成变量,用数学表达式逐个格子的算一遍。你输入的“dem * 2 + 10”,平台会从研究区域的左上角开始,把每一个像元的高程值带入这个公式,算完一个格子再算下一个,直到覆盖整个范围。最后输出一张新栅格,每个像元都对应一个计算结果。这个思想和Excel里做公式填充很像。区别在于Excel的行列是二维表格,而栅格数据的每个像元除了行列位置,还携带真实的地理坐标。所以栅格计算不只是算数,它是在带着空间位置做算数——这也是“地图代数”这个说法的由来。3D Analyst模块里很多工具,比如坡度、坡向、山体阴影,本质上也是在做栅格计算,只是它们的内核更复杂,涉及邻域像元的比较与几何关系解算。而栅格计算器把这种能力开放成一个可以自由写表达式的入口,让你不再受限于预设的工具,可以按自己的业务规则组合、叠加、筛选任意栅格数据。1.2 栅格计算器在ArcToolbox中的位置与适用边界栅格计算器在ArcToolbox里的路径一般是“地图代数”工具集下的“栅格计算器”。3D Analyst扩展模块开启后,很多表面分析工具会出现在3D Analyst工具列表里,但栅格计算器既是3D Analyst的常用搭档,也常被归到地图代数这一组。实际项目里,你往往是这样配合使用的:先用3D Analyst里的“坡度”“坡向”工具从DEM生成基础地形因子,再打开栅格计算器,把这些因子按业务逻辑组合成最终的判断模型。栅格计算器适合解决四类问题:多因子叠加:比如“坡度小于25度且高程低于800米且距道路小于500米”的选址条件;栅格代数运算:比如NDVI、差值计算、归一化等;条件判断与重分类:比如把满足某个阈值的区域提取出来,赋值1,其余赋值0;复杂公式建模:把多个栅格变量和常数组合成自定义公式,模拟某种连续变化过程。但栅格计算器不是万能的。它适合处理离散的数值运算和逻辑判断,如果要做邻域统计、区域统计、焦点分析,应该用专门的工具而不是在表达式中硬凑。有些刚入门的朋友试图在栅格计算器里通过嵌套非常复杂的Con和FocalStatistics来替代“焦点统计”工具,结果是表达式冗长、运行极慢、报错难排查。工具用对地方才叫高效。1.3 什么时候选“栅格计算器”,什么时候选“Spatial Analyst”其他工具很多选择困难来自不明白工具之间的分工。我习惯用一个很简单的判断标准:如果这个操作在ArcToolbox里已经有了现成的工具按钮或菜单项,优先用专门工具;如果现有工具无法表达你的自定义条件或组合逻辑,才用栅格计算器写表达式。举个例子。要把高程大于100米的区域单独提出来,“Spatial Analyst工具-地图代数-栅格计算器”和“Spatial Analyst工具-提取分析-按属性提取”都能做。但前者更灵活,因为表达式里可以直接写“dem > 100”,简单直接。后者适合带属性表的整数栅格做SQL查询。要做“坡度+高程+坡向”三个条件的联合筛选,现成的“按属性提取”一次只能针对一个栅格,这时候栅格计算器几乎是唯一选择。如果只是想看某个栅格的均值、最大值、最小值,应该用“分区统计”或“栅格统计”工具,而不是写表达式。一句话:能用现成工具解决的就别硬写表达式;多个条件叠加、需要自定义公式时,栅格计算器才是正解。2. 动手前必须搞懂的三个底层问题:像元、NoData与坐标系2.1 像元大小不一致时,结果会“缺斤少两”这是实操中最常见也最坑的一个问题。假设你有一份DEM,分辨率是30米,还有一份土地利用分类栅格,分辨率是250米。直接打开栅格计算器写“dem + landuse”,平台不会报错,但它会悄悄把两个数据统一到某种像元大小下再运算。如果统一到30米,250米那一个像元的信息会被重采样到若干个30米像元上,数值被反复填充或插值;如果统一到250米,DEM的细节就丢了。我见过不少新手在算完之后发现结果栅格范围要么变大要么变小,检查半天才发现是分辨率没对齐。解决办法:在写表达式之前,先用“环境设置”指定输出像元大小。最稳妥的设置是把“处理范围”选成与你核心数据一致,“栅格分析”里的“像元大小”设为与被分析数据相同。或者,用“重采样”工具先把所有参与计算的栅格统一到同一分辨率。实操建议:打开栅格计算器前,右键点击输入图层,查看“源属性”里的像元大小和范围;在“环境设置”里,把“处理范围”设为“与图层dem相同”,“栅格分析-像元大小”设为“与图层dem相同”;如果项目里有多个分辨率差异大的数据,先统一分辨率再做计算,不要指望表达式内部自动处理。2.2 NoData不是0,默认忽略与主动处理的区别栅格里的NoData代表“此处无数据”,它和数值0有本质区别。0是一个合法测量值,NoData是缺失。比如某地区的DEM覆盖范围内有一块水域,测量时返回到NoData,如果计算时把它当成0,坡度算出来全是0,后续分析全被打乱。栅格计算器默认行为是:参与计算的任何一个输入的像元值是NoData,输出对应位置就是NoData。这个设计其实是合理的,因为缺失值没法参与可靠运算。但在某些业务场景里,你需要NoData区域也给出一个合理结果,比如把无数据区域当成0参与逻辑判断,这时候就要显式处理。处理方式有两种:用“Con(IsNull("dem"), 0, "dem")”把NoData替换成0;先运行“填充缺失值”相关工具把NoData填上合理数值再计算。我个人的习惯是:如果NoData区域占研究区比例不大,而且它们的值不影响最终判读方向,直接保留默认行为;如果NoData区域会干扰后续统计或可视化,就先用IsNull结合Con处理掉。重要的是心里有数,知道这一步的取舍。2.3 坐标系不一致,算出来的是“张冠李戴”栅格计算并不是简单地把两个栅格丢进表达式就能保证结果的坐标系统一。如果两个输入栅格的坐标系不同,比如一个是CGCS2000投影坐标系,一个是WGS1984地理坐标系,平台会自动做动态投影,但转换误差和性能开销都会增加,严重的甚至会出现偏移。最让人头疼的是,这种偏移在视觉上不一定明显,但做面积统计、距离计算时就会暴露。所以在做栅格计算前,建议先检查所有参与图层的坐标系。如果发现不一致,用“投影栅格”工具先把它们统一到目标坐标系。我一般选项目主导数据的坐标系作为统一基准,这样既保证精度,也方便后续制图。3. 完整实例:用栅格计算完成一个地形条件筛选3.1 案例背景与数据准备为了演示完整流程,我构造一个典型场景:假设手里有一份某山区的DEM数据,分辨率30米,范围大约是一个乡镇的山地。需求是提取“高程大于600米,且坡度小于20度”的区域,作为潜在的建设用地预选范围。这个需求单用“坡度”工具不够,还需要结合高程条件做联合筛选,非常适合用栅格计算器写表达式解决。准备的数据有三份:dem——原始DEM(高程栅格);slope——用3D Analyst的“坡度”工具从dem生成的坡度栅格;可选:landuse——土地利用数据,用于后续剔除水体、林地等,但这一步可以先不加。先把“坡度”工具的结果生成出来。方法是在ArcToolbox中找到3D Analyst工具→栅格表面→坡度,输入dem,输出“slope”。坡度单位选“度”,这样便于直接和20度比较。3.2 逐行拆解栅格计算器表达式打开栅格计算器,输入下面这行表达式:Con("dem" > 600 & "slope" < 20, 1, 0)这行表达式的作用是:如果像元满足“高程大于600米”和“坡度小于20度”两个条件,输出1,否则输出0。参数说明:Con是“条件判断”函数,格式是Con(条件, 条件为真时的值, 条件为假时的值);“dem”和“slope”是当前地图内容里的图层名,必须用双引号括起来;&是逻辑“与”运算符,表示同时满足;也可以写成嵌套形式:Con("dem" > 600, Con("slope" < 20, 1, 0), 0),两者逻辑等价,但单行写法更简洁。写完之后,在“输出栅格”路径里指定保存位置,命名比如“select_zone”,点击“确定”或“运行”。运行过程中可以观察平台底部状态栏,如果表达式里引用的栅格较大,可能需要一些时间。这里有个细节:输入栅格是否已经加载到当前地图,不影响表达式运行,但会影响你写表达式时能不能通过下拉列表选择图层。建议先把dem和slope都加载进来,用下拉选择而不是手敲图层名,避免拼写错误。3.3 结果验证:不是算完就完事计算完成后,第一件事不是急着转矢量,而是验证结果是否符合预期。我把验证分成四步:看直方图。右键打开结果栅格属性,查看直方图,确认存在0和1两类值,且1的占比符合预期。如果全是0,说明条件没匹配上,多半是阈值方向写反了。和原始DEM叠加目视检查。把结果栅格设为半透明叠加在DEM上,随机挑几个满足条件的位置,用“识别”工具检查该像元的DEM高程值和坡度值,确认条件确实满足。检查边界。结果栅格的有效区域应和输入的DEM范围一致,如果出现大面积NoData,通常是输入栅格范围不一致或坐标系没对齐。面积合理性。利用“栅格转面”工具把结果转为矢量面,再统计面积,初步判断输出面积数量级是否合理。比如一个乡镇的山地,如果提取出来的区域占到整个乡镇的90%,多半是坡度阈值写错了。我遇到过一位同学,写的是“dem > 600 & slope > 20”,意思变成了“高程大于600且坡度大于20”,完全把方向搞反了。这种错误视觉上很难一眼发现,只有对比直方图和叠加检查才能抓住。3.4 进阶:把多个因子加权组合成一个连续指数条件筛选只是栅格计算最基础的功能。更常见的场景是做“加权叠加”或“多因子评分”。假设你把地形适宜性分成三个因子:高程评分:高程越低越适宜;坡度评分:坡度越小越适宜;距离道路评分:距道路越近越适宜。每一个因子都可以先通过重分类或栅格计算器规范成0到10的评分。最后用加权表达式组合:"elev_score" * 0.3 + "slope_score" * 0.4 + "road_score" * 0.3这种表达式之所以重要,是因为它把定性判断(高、低、好、差)变成了可量化的空间计算,而且权重一旦确定,结果就是完全可复现的。这正是栅格计算器和普通手工作图的本质区别——用表达式固化规则,规则可审查、结果可追溯。写完这种公式后,建议顺带生成一份权重敏感性分析。简单做法是改几个权重跑两次,比较输出栅格的重叠度,看最终适宜区是否稳定。权重一变结果就剧烈波动,说明因子之间存在共线性,这时候别急着调权重,先检查因子原始数据。4. 栅格计算常见报错与排查思路4.1 表达式里引用了图层名,却提示“无法识别”这是新手最经常遇到的报错。原因通常是图层名里带了空格、特殊字符或者不是当前地图中的图层名。解决方法有三个层次:写表达式时,优先使用“图层列表”下拉框选择,不要手敲;如果图层名确实包含空格(比如“DEM 30m”),必须用双引号包住完整名称,同时注意名称里的空格也要原样输入;如果图层没被加载到当前地图,但名称是已知的,可以在表达式里用完整路径加双引号包围,比如“E:\data\dem30.tif”。我还遇到过一种情况:图层加载了,但名字是中文,表达式也报了错。后来发现是数据格式问题,某些栅格格式的源数据名称不能被正确识别。这种情况下最省事的办法是先右键图层导出成标准TIFF格式,再加载参与计算。4.2 输出结果全黑或全0全黑通常代表值域极窄或者全是NoData。全0则是条件判断没有命中任何像元。排查顺序:检查输入栅格的“属性”里的最小值和最大值,确认数据范围和你的条件阈值是否匹配;检查条件方向,比如需求是“小于20度”,但表达式写成了“大于20度”;检查NoData区域。如果输入栅格大量区域是NoData,Con条件在NoData位置会保留NoData,视觉上可能表现为大片黑色;用“Identify”工具在怀疑有值的区域点一下,看像元实际值是多少,确认表达式条件是否真的被满足。4.3 栅格计算器卡死或提示内存不足大范围、高分辨率栅格参与表达式运算时,对内存的要求比较高。我见过有人拿全省30米分辨率的DEM做栅格计算,结果平台长时间无响应。缓解手段:分块计算。先用“裁剪”工具把研究区切成几块,分别计算,再“镶嵌”合并;降低分辨率。如果精度要求不高,先用“重采样”把像元大小从30米改成90米甚至100米,能大幅减少运算量;清理临时文件。检查系统临时目录里是否有大量残留栅格文件,定期清理;优先输出成Grid或TIFF格式,避免输出到某些网络路径导致读写缓慢。4.4 表达式正确但结果范围偏了一部分如果输出的有效范围比输入小,最可能的原因是参与的栅格之间存在范围不一致。平台默认按所有输入范围的交集来计算。比如一个栅格覆盖全区域,另一个栅格只覆盖了东半边,那么输出只包含东半边。这时需要注意“环境设置”里“处理范围”的值。如果你希望输出范围跟随主数据(比如dem)覆盖全区,在环境设置里把“处理范围”指定为“与图层dem相同”。参与计算的其他栅格超出部分会按NoData处理,结果范围就不缩水了。还有一个容易忽略的细节:输出栅格的范围即使正确,如果坐标原点、像元对齐方式和主数据不一致,结果依然可能出现错位。最稳妥的做法就是在环境设置中把“栅格分析”里的“像元大小”和“对齐栅格”都指定为主数据。5. 我踩过几次坑之后的个人体会栅格计算这个工具,说实话入门门槛不高,但用好的关键不是学会点按更多按钮,而是建立一种“把空间问题翻译成代数表达式”的思维模式。我刚接触的时候,最常犯的毛病是想要什么条件就直接堆表达式,写着写着图层一多,自己都不知道哪一步算的是什么。后来养成一个习惯:每做一次复杂栅格计算,一定分步骤保存中间结果,每一步都用清晰的命名,后面检查、回溯、对结果有信心。另外一个体会是:栅格计算器和3D Analyst里的表面分析工具最好配合使用,而不是互相替代。坡度、坡向、山体阴影这些工具应该先跑完,把中间因子都落盘,然后再用栅格计算器做组合运算。这样既照顾了运算效率,也让每一步数据都可追溯可验证。如果一个表达式里塞了太多中间运算,虽然平台能支持,但排查问题时会非常痛苦。最后分享一个小技巧:表达式写完之后,先别急着全区域运行,用“裁剪”功能切一个小范围进行试算。试算结果确认无误后,再放开全区域跑。这个小习惯给我节省了大量等待时间,也几乎杜绝了“算完才发现表达式写错”的尴尬。栅格计算(一)这篇就先聊到这里,从概念、三个底层问题到完整实例、常见报错,基本覆盖了日常最常用的场景。后续有机会,再展开讲讲多因子加权、条件函数嵌套、以及与3D Analyst其他表面工具的联合建模。
如果你用某款主流GIS平台做过地形分析、淹没模拟或者选址建模,一定绕不开ArcToolbox里那一排排工具。我这些年做项目,最常被新同事问的不是某个工具怎么点,而是“栅格计算器到底是怎么个原理,为什么一条表达式就把整个区域的结果算出来了”。这篇就拿3D Analyst模块里的栅格计算(一)作为开端,把栅格计算这个概念、背后的代数逻辑以及实操中最容易踩的坑,一次性讲清楚。这篇内容更适合正在学栅格数据处理、搞地形表面分析的人,也适合那些已经把坡度、坡向、山体阴影工具点得滚瓜烂熟,却始终不太敢写复杂表达式的朋友。看完你至少能独立写出第一条有实际意义的栅格计算表达式,并且知道算错了该怎么排查。1. 栅格计算到底是什么,为什么说它是空间分析的“心脏”1.1 从“逐像元运算”理解栅格计算的底层逻辑栅格计算听起来很玄,实际上就是把整个研究区域切成了无数个规则小格子,每个格子(像元)都带着一个数值。比如DEM数据里,每个像元存的是高程;坡度数据里,每个像元存的是该位置的坡度角;降雨量插值结果里,每个像元存的是年降雨量。栅格计算做的事,就是把这些像元数值当成变量,用数学表达式逐个格子的算一遍。你输入的“dem * 2 + 10”,平台会从研究区域的左上角开始,把每一个像元的高程值带入这个公式,算完一个格子再算下一个,直到覆盖整个范围。最后输出一张新栅格,每个像元都对应一个计算结果。这个思想和Excel里做公式填充很像。区别在于Excel的行列是二维表格,而栅格数据的每个像元除了行列位置,还携带真实的地理坐标。所以栅格计算不只是算数,它是在带着空间位置做算数——这也是“地图代数”这个说法的由来。3D Analyst模块里很多工具,比如坡度、坡向、山体阴影,本质上也是在做栅格计算,只是它们的内核更复杂,涉及邻域像元的比较与几何关系解算。而栅格计算器把这种能力开放成一个可以自由写表达式的入口,让你不再受限于预设的工具,可以按自己的业务规则组合、叠加、筛选任意栅格数据。1.2 栅格计算器在ArcToolbox中的位置与适用边界栅格计算器在ArcToolbox里的路径一般是“地图代数”工具集下的“栅格计算器”。3D Analyst扩展模块开启后,很多表面分析工具会出现在3D Analyst工具列表里,但栅格计算器既是3D Analyst的常用搭档,也常被归到地图代数这一组。实际项目里,你往往是这样配合使用的:先用3D Analyst里的“坡度”“坡向”工具从DEM生成基础地形因子,再打开栅格计算器,把这些因子按业务逻辑组合成最终的判断模型。栅格计算器适合解决四类问题:多因子叠加:比如“坡度小于25度且高程低于800米且距道路小于500米”的选址条件;栅格代数运算:比如NDVI、差值计算、归一化等;条件判断与重分类:比如把满足某个阈值的区域提取出来,赋值1,其余赋值0;复杂公式建模:把多个栅格变量和常数组合成自定义公式,模拟某种连续变化过程。但栅格计算器不是万能的。它适合处理离散的数值运算和逻辑判断,如果要做邻域统计、区域统计、焦点分析,应该用专门的工具而不是在表达式中硬凑。有些刚入门的朋友试图在栅格计算器里通过嵌套非常复杂的Con和FocalStatistics来替代“焦点统计”工具,结果是表达式冗长、运行极慢、报错难排查。工具用对地方才叫高效。1.3 什么时候选“栅格计算器”,什么时候选“Spatial Analyst”其他工具很多选择困难来自不明白工具之间的分工。我习惯用一个很简单的判断标准:如果这个操作在ArcToolbox里已经有了现成的工具按钮或菜单项,优先用专门工具;如果现有工具无法表达你的自定义条件或组合逻辑,才用栅格计算器写表达式。举个例子。要把高程大于100米的区域单独提出来,“Spatial Analyst工具-地图代数-栅格计算器”和“Spatial Analyst工具-提取分析-按属性提取”都能做。但前者更灵活,因为表达式里可以直接写“dem > 100”,简单直接。后者适合带属性表的整数栅格做SQL查询。要做“坡度+高程+坡向”三个条件的联合筛选,现成的“按属性提取”一次只能针对一个栅格,这时候栅格计算器几乎是唯一选择。如果只是想看某个栅格的均值、最大值、最小值,应该用“分区统计”或“栅格统计”工具,而不是写表达式。一句话:能用现成工具解决的就别硬写表达式;多个条件叠加、需要自定义公式时,栅格计算器才是正解。2. 动手前必须搞懂的三个底层问题:像元、NoData与坐标系2.1 像元大小不一致时,结果会“缺斤少两”这是实操中最常见也最坑的一个问题。假设你有一份DEM,分辨率是30米,还有一份土地利用分类栅格,分辨率是250米。直接打开栅格计算器写“dem + landuse”,平台不会报错,但它会悄悄把两个数据统一到某种像元大小下再运算。如果统一到30米,250米那一个像元的信息会被重采样到若干个30米像元上,数值被反复填充或插值;如果统一到250米,DEM的细节就丢了。我见过不少新手在算完之后发现结果栅格范围要么变大要么变小,检查半天才发现是分辨率没对齐。解决办法:在写表达式之前,先用“环境设置”指定输出像元大小。最稳妥的设置是把“处理范围”选成与你核心数据一致,“栅格分析”里的“像元大小”设为与被分析数据相同。或者,用“重采样”工具先把所有参与计算的栅格统一到同一分辨率。实操建议:打开栅格计算器前,右键点击输入图层,查看“源属性”里的像元大小和范围;在“环境设置”里,把“处理范围”设为“与图层dem相同”,“栅格分析-像元大小”设为“与图层dem相同”;如果项目里有多个分辨率差异大的数据,先统一分辨率再做计算,不要指望表达式内部自动处理。2.2 NoData不是0,默认忽略与主动处理的区别栅格里的NoData代表“此处无数据”,它和数值0有本质区别。0是一个合法测量值,NoData是缺失。比如某地区的DEM覆盖范围内有一块水域,测量时返回到NoData,如果计算时把它当成0,坡度算出来全是0,后续分析全被打乱。栅格计算器默认行为是:参与计算的任何一个输入的像元值是NoData,输出对应位置就是NoData。这个设计其实是合理的,因为缺失值没法参与可靠运算。但在某些业务场景里,你需要NoData区域也给出一个合理结果,比如把无数据区域当成0参与逻辑判断,这时候就要显式处理。处理方式有两种:用“Con(IsNull("dem"), 0, "dem")”把NoData替换成0;先运行“填充缺失值”相关工具把NoData填上合理数值再计算。我个人的习惯是:如果NoData区域占研究区比例不大,而且它们的值不影响最终判读方向,直接保留默认行为;如果NoData区域会干扰后续统计或可视化,就先用IsNull结合Con处理掉。重要的是心里有数,知道这一步的取舍。2.3 坐标系不一致,算出来的是“张冠李戴”栅格计算并不是简单地把两个栅格丢进表达式就能保证结果的坐标系统一。如果两个输入栅格的坐标系不同,比如一个是CGCS2000投影坐标系,一个是WGS1984地理坐标系,平台会自动做动态投影,但转换误差和性能开销都会增加,严重的甚至会出现偏移。最让人头疼的是,这种偏移在视觉上不一定明显,但做面积统计、距离计算时就会暴露。所以在做栅格计算前,建议先检查所有参与图层的坐标系。如果发现不一致,用“投影栅格”工具先把它们统一到目标坐标系。我一般选项目主导数据的坐标系作为统一基准,这样既保证精度,也方便后续制图。3. 完整实例:用栅格计算完成一个地形条件筛选3.1 案例背景与数据准备为了演示完整流程,我构造一个典型场景:假设手里有一份某山区的DEM数据,分辨率30米,范围大约是一个乡镇的山地。需求是提取“高程大于600米,且坡度小于20度”的区域,作为潜在的建设用地预选范围。这个需求单用“坡度”工具不够,还需要结合高程条件做联合筛选,非常适合用栅格计算器写表达式解决。准备的数据有三份:dem——原始DEM(高程栅格);slope——用3D Analyst的“坡度”工具从dem生成的坡度栅格;可选:landuse——土地利用数据,用于后续剔除水体、林地等,但这一步可以先不加。先把“坡度”工具的结果生成出来。方法是在ArcToolbox中找到3D Analyst工具→栅格表面→坡度,输入dem,输出“slope”。坡度单位选“度”,这样便于直接和20度比较。3.2 逐行拆解栅格计算器表达式打开栅格计算器,输入下面这行表达式:Con("dem" > 600 & "slope" < 20, 1, 0)这行表达式的作用是:如果像元满足“高程大于600米”和“坡度小于20度”两个条件,输出1,否则输出0。参数说明:Con是“条件判断”函数,格式是Con(条件, 条件为真时的值, 条件为假时的值);“dem”和“slope”是当前地图内容里的图层名,必须用双引号括起来;&是逻辑“与”运算符,表示同时满足;也可以写成嵌套形式:Con("dem" > 600, Con("slope" < 20, 1, 0), 0),两者逻辑等价,但单行写法更简洁。写完之后,在“输出栅格”路径里指定保存位置,命名比如“select_zone”,点击“确定”或“运行”。运行过程中可以观察平台底部状态栏,如果表达式里引用的栅格较大,可能需要一些时间。这里有个细节:输入栅格是否已经加载到当前地图,不影响表达式运行,但会影响你写表达式时能不能通过下拉列表选择图层。建议先把dem和slope都加载进来,用下拉选择而不是手敲图层名,避免拼写错误。3.3 结果验证:不是算完就完事计算完成后,第一件事不是急着转矢量,而是验证结果是否符合预期。我把验证分成四步:看直方图。右键打开结果栅格属性,查看直方图,确认存在0和1两类值,且1的占比符合预期。如果全是0,说明条件没匹配上,多半是阈值方向写反了。和原始DEM叠加目视检查。把结果栅格设为半透明叠加在DEM上,随机挑几个满足条件的位置,用“识别”工具检查该像元的DEM高程值和坡度值,确认条件确实满足。检查边界。结果栅格的有效区域应和输入的DEM范围一致,如果出现大面积NoData,通常是输入栅格范围不一致或坐标系没对齐。面积合理性。利用“栅格转面”工具把结果转为矢量面,再统计面积,初步判断输出面积数量级是否合理。比如一个乡镇的山地,如果提取出来的区域占到整个乡镇的90%,多半是坡度阈值写错了。我遇到过一位同学,写的是“dem > 600 & slope > 20”,意思变成了“高程大于600且坡度大于20”,完全把方向搞反了。这种错误视觉上很难一眼发现,只有对比直方图和叠加检查才能抓住。3.4 进阶:把多个因子加权组合成一个连续指数条件筛选只是栅格计算最基础的功能。更常见的场景是做“加权叠加”或“多因子评分”。假设你把地形适宜性分成三个因子:高程评分:高程越低越适宜;坡度评分:坡度越小越适宜;距离道路评分:距道路越近越适宜。每一个因子都可以先通过重分类或栅格计算器规范成0到10的评分。最后用加权表达式组合:"elev_score" * 0.3 + "slope_score" * 0.4 + "road_score" * 0.3这种表达式之所以重要,是因为它把定性判断(高、低、好、差)变成了可量化的空间计算,而且权重一旦确定,结果就是完全可复现的。这正是栅格计算器和普通手工作图的本质区别——用表达式固化规则,规则可审查、结果可追溯。写完这种公式后,建议顺带生成一份权重敏感性分析。简单做法是改几个权重跑两次,比较输出栅格的重叠度,看最终适宜区是否稳定。权重一变结果就剧烈波动,说明因子之间存在共线性,这时候别急着调权重,先检查因子原始数据。4. 栅格计算常见报错与排查思路4.1 表达式里引用了图层名,却提示“无法识别”这是新手最经常遇到的报错。原因通常是图层名里带了空格、特殊字符或者不是当前地图中的图层名。解决方法有三个层次:写表达式时,优先使用“图层列表”下拉框选择,不要手敲;如果图层名确实包含空格(比如“DEM 30m”),必须用双引号包住完整名称,同时注意名称里的空格也要原样输入;如果图层没被加载到当前地图,但名称是已知的,可以在表达式里用完整路径加双引号包围,比如“E:\data\dem30.tif”。我还遇到过一种情况:图层加载了,但名字是中文,表达式也报了错。后来发现是数据格式问题,某些栅格格式的源数据名称不能被正确识别。这种情况下最省事的办法是先右键图层导出成标准TIFF格式,再加载参与计算。4.2 输出结果全黑或全0全黑通常代表值域极窄或者全是NoData。全0则是条件判断没有命中任何像元。排查顺序:检查输入栅格的“属性”里的最小值和最大值,确认数据范围和你的条件阈值是否匹配;检查条件方向,比如需求是“小于20度”,但表达式写成了“大于20度”;检查NoData区域。如果输入栅格大量区域是NoData,Con条件在NoData位置会保留NoData,视觉上可能表现为大片黑色;用“Identify”工具在怀疑有值的区域点一下,看像元实际值是多少,确认表达式条件是否真的被满足。4.3 栅格计算器卡死或提示内存不足大范围、高分辨率栅格参与表达式运算时,对内存的要求比较高。我见过有人拿全省30米分辨率的DEM做栅格计算,结果平台长时间无响应。缓解手段:分块计算。先用“裁剪”工具把研究区切成几块,分别计算,再“镶嵌”合并;降低分辨率。如果精度要求不高,先用“重采样”把像元大小从30米改成90米甚至100米,能大幅减少运算量;清理临时文件。检查系统临时目录里是否有大量残留栅格文件,定期清理;优先输出成Grid或TIFF格式,避免输出到某些网络路径导致读写缓慢。4.4 表达式正确但结果范围偏了一部分如果输出的有效范围比输入小,最可能的原因是参与的栅格之间存在范围不一致。平台默认按所有输入范围的交集来计算。比如一个栅格覆盖全区域,另一个栅格只覆盖了东半边,那么输出只包含东半边。这时需要注意“环境设置”里“处理范围”的值。如果你希望输出范围跟随主数据(比如dem)覆盖全区,在环境设置里把“处理范围”指定为“与图层dem相同”。参与计算的其他栅格超出部分会按NoData处理,结果范围就不缩水了。还有一个容易忽略的细节:输出栅格的范围即使正确,如果坐标原点、像元对齐方式和主数据不一致,结果依然可能出现错位。最稳妥的做法就是在环境设置中把“栅格分析”里的“像元大小”和“对齐栅格”都指定为主数据。5. 我踩过几次坑之后的个人体会栅格计算这个工具,说实话入门门槛不高,但用好的关键不是学会点按更多按钮,而是建立一种“把空间问题翻译成代数表达式”的思维模式。我刚接触的时候,最常犯的毛病是想要什么条件就直接堆表达式,写着写着图层一多,自己都不知道哪一步算的是什么。后来养成一个习惯:每做一次复杂栅格计算,一定分步骤保存中间结果,每一步都用清晰的命名,后面检查、回溯、对结果有信心。另外一个体会是:栅格计算器和3D Analyst里的表面分析工具最好配合使用,而不是互相替代。坡度、坡向、山体阴影这些工具应该先跑完,把中间因子都落盘,然后再用栅格计算器做组合运算。这样既照顾了运算效率,也让每一步数据都可追溯可验证。如果一个表达式里塞了太多中间运算,虽然平台能支持,但排查问题时会非常痛苦。最后分享一个小技巧:表达式写完之后,先别急着全区域运行,用“裁剪”功能切一个小范围进行试算。试算结果确认无误后,再放开全区域跑。这个小习惯给我节省了大量等待时间,也几乎杜绝了“算完才发现表达式写错”的尴尬。栅格计算(一)这篇就先聊到这里,从概念、三个底层问题到完整实例、常见报错,基本覆盖了日常最常用的场景。后续有机会,再展开讲讲多因子加权、条件函数嵌套、以及与3D Analyst其他表面工具的联合建模。