ArcGIS夜间灯光分析全流程:从栅格提取到分区统计与出图
简介:这份资源面向GIS初学者与遥感分析入门者,围绕夜间灯光数据的提取与强度计算展开,帮助读者掌握从行政矢量范围筛选到栅格裁剪、分区统计的完整分析思路,可应用于城市规划、环境监测与区域经济评估等场景。压缩包共1个文件,为docx格式文档,大小约6.52MB,以图文步骤形式组织内容,便于对照ArcGIS界面逐步操作。目前已有3662人学习下载,说明其在同类实操教程中具有一定参考价值。文档重点讲解按属性选择提取目标行政区、按掩膜提取裁剪夜间灯光栅格、以表格显示分区统计计算区域灯光强度,以及通过连接关联与分级色彩完成结果可视化,并附有图名、图例、比例尺等制图要素的添加方法。读者可据此独立完成一套夜间灯光分析流程,理解栅格与矢量数据配合使用的关键环节,为后续遥感定量分析与专题制图打下基础。
1. 夜间灯光提取与强度计算:从一张 tif 到能出图的分区统计表
手里有一份夜间灯光栅格 tif,领导要的是「每个区县的平均灯光强度」和一张能放进报告的分级设色图。听起来两步就能搞定,真上手才发现坐标系对不上、掩膜提取报错、分区统计表连不回属性表,一个环节卡住后面全白干。这套流程在 GIS 圈里属于遥感分析的常规操作,ArcGIS 的 Spatial Analyst 工具箱就能全程跑通,不需要写一行代码。它解决的核心问题是:把覆盖大范围的灯光栅格,按行政边界裁剪、统计、可视化,最终落到「哪个区域亮、亮多少」这个可比较的数字上。适合做城市规划、区域经济评估、建成区识别的从业者,也适合刚接触栅格分析、想拿一个完整案例练手的人。下面按我实际跑通的顺序拆,参数和坑都写清楚。
2. 数据准备与坐标系对齐:掩膜提取能不能跑通全看这一步
夜间灯光分析的第一个翻车点几乎都出在数据上,而不是工具上。灯光栅格和行政矢量来自两个渠道,坐标系、范围、分辨率各不相同,直接拿去做掩膜提取,轻则结果偏移,重则工具直接报错。这一章把数据选型和对齐讲透,后面两步才有意义。
2.1 灯光栅格与行政矢量的选型理由
夜间灯光数据常见的有两类:一类是老一代的 DMSP/OLS 稳定灯光产品,空间分辨率约 1km,时间跨度长但存在像元饱和问题,城市核心区亮度容易「顶格」;另一类是 VIIRS 夜间灯光产品,分辨率提升到约 500m,动态范围更宽,饱和现象缓解不少。做区域强度对比,我一般优先用 VIIRS 类产品,因为它的 DN 值(像元亮度值)分布更接近真实的光照差异,算出来的平均值区分度更好。如果研究需要长时序,才回头考虑 DMSP/OLS,并且要接受它饱和带来的偏差。
行政矢量就是标准的 shp 面文件,关键看两点:属性表里有没有可用的区域名称或编码字段,以及它的坐标系是什么。灯光栅格通常是地理坐标系(经纬度),行政矢量如果是投影坐标系(比如某种高斯投影),两者单位不一致,掩膜提取时边界会对不齐。常见做法是统一到同一个坐标系,我一般把矢量投影到与栅格一致的地理坐标系,或者反过来把栅格投影到矢量的投影坐标系,二选一,但必须统一。
| 数据 | 常见格式 | 关键检查项 | 处理动作 |
|---|---|---|---|
| 夜间灯光栅格 | tif | 坐标系、像元大小、NoData 值 | 记录坐标系,确认 NoData |
| 行政矢量 | shp | 坐标系、名称字段、面是否闭合 | 投影到与栅格一致 |
提示:下载数据时就把坐标系记在便签上,别等打开 ArcGIS 再回头查,这一步省下来的时间后面会加倍还回去。
2.2 用按属性选择筛出目标区域并导出
拿到行政矢量后,先别急着裁剪。如果研究区只是某几个区县,直接在属性表里筛出来单独导出,比拿整个省的面去做掩膜干净得多,也避免掩膜范围过大导致输出栅格冗余。
操作路径是:把 shp 拖进 ArcGIS,右键图层打开属性表,点「按属性选择」。在表达式框里双击字段名(比如区域名称字段),点等号,再点「获取唯一值」,从列表里双击目标区域名。只要一个区域,点应用、确定即可;要多个区域,在第一个条件后点「Or」,重复上面的字段、等号、取值操作,把所有目标区域串起来,最后应用、确定。
-- 按属性选择的表达式形态(以名称字段为例) "NAME" = '区域A' OR "NAME" = '区域B' OR "NAME" = '区域C'这段表达式的逻辑很直白:每个"NAME" = '区域X'是一个筛选条件,OR表示满足任意一个就选中。字段名和取值要用你数据里真实存在的,字符串用单引号包裹。选完之后,右键图层 → 数据 → 导出数据,浏览到存放位置、改好名称、保存,导出时勾选「所选要素」,这样新 shp 里就只有目标区域。导出后只显示这个新图层,确认范围没问题再往下走。
2.3 按掩膜提取:把灯光栅格裁到行政边界内
掩膜提取是整个流程的核心裁剪动作,工具位置在 ArcToolbox → Spatial Analyst 工具 → 提取分析 → 按掩膜提取。三个输入要填对:输入栅格选夜间灯光 tif;输入栅格数据或要素掩膜数据选上一步导出的目标区域 shp;输出栅格指定路径和名称。点确定后,输出就是只保留目标区域范围的灯光栅格。
这里有个容易被忽略的点:掩膜提取默认会把掩膜范围外的像元设为 NoData,而不是删掉。所以输出栅格的矩形范围可能还是原图那么大,只是边界外全是空值。做后续分区统计时这没问题,但如果要算整幅图的统计量,记得排除 NoData,否则平均值会被拉低。提取完成后,在内容列表里只勾选输出栅格,肉眼确认边界贴合、没有明显错位,再进入统计环节。
# 用 ArcPy 复现掩膜提取,便于批量处理多个区域 import arcpy from arcpy.sa import ExtractByMask arcpy.CheckOutExtension("Spatial") in_raster = r"D:\data\nightlight.tif" # 夜间灯光栅格 in_mask = r"D:\data\region_A.shp" # 目标区域矢量 out_raster = r"D:\data\nightlight_mask.tif" # 输出裁剪结果 ExtractByMask(in_raster, in_mask).save(out_raster) arcpy.CheckInExtension("Spatial")这段脚本和手动操作等价,ExtractByMask的两个必填参数就是输入栅格和掩膜要素,.save()写出结果。批量处理多个区域时,把in_mask换成循环里的每个 shp 路径即可,省去一次次点对话框。注意先CheckOutExtension("Spatial")拿到扩展许可,跑完再还回去,否则在部分许可环境下会直接抛错。
3. 分区统计与表格连接:把亮度变成一个能比较的数字
裁剪出来的栅格是一张图,不是一张表。要让「每个区域亮多少」变成可排序、可比较的数值,得靠分区统计把栅格值按区域聚合,再把结果连回矢量属性表。这一步的坑集中在字段选择和连接键上。
3.1 以表格显示分区统计的参数怎么设
工具在 Spatial Analyst 工具 → 区域分析 → 以表格显示分区统计。输入栅格数据或要素区域数据选目标区域 shp;区域字段选能唯一标识每个区域的字段,通常是区域编码或名称,别选那种有重复值的字段,否则统计会合并出错;输入赋值栅格选上一步裁剪出的灯光栅格;输出表指定路径和名称;统计类型按需求选,平均值看整体亮度水平,总和看总光量,最大值看峰值。
| 参数 | 建议取值 | 说明 |
|---|---|---|
| 区域字段 | 区域编码/名称 | 必须唯一标识区域 |
| 赋值栅格 | 裁剪后灯光 tif | 与区域范围一致 |
| 统计类型 | MEAN / SUM / MAX | 按分析目的选 |
| 输出表 | 地理数据库表或 dbf | 便于后续连接 |
统计类型里 MEAN 是最常用的,它反映区域平均亮度,受面积影响小,适合横向比较;SUM 适合衡量区域总光量,但面积大的区域天然占优,比较时要心里有数。我一般先跑 MEAN,需要总量再补一列 SUM。输出表里会带上区域字段和统计值字段,字段名类似MEAN、SUM,记下这个字段名,下一步连接要用。
3.2 连接字段与分级设色的完整操作
统计表出来后,右键目标区域矢量图层 → 连接和关联 → 连接。在弹出的对话框里,第一个下拉选矢量图层里用来匹配的字段(比如区域编码),第二个下拉选统计表里对应的区域字段,两者必须是同一套编码,否则连出来全是空值。连接基于字段值相等,选错字段是这一步最常见的失败原因。
连接成功后,右键图层 → 属性 → 符号系统 → 数量 → 分级色彩,字段选刚才统计出来的MEAN字段,选一个合适的色带,类别数按数据分布定,5 到 7 类比较常见。点确定后,地图上每个区域就按平均灯光强度着色,颜色越亮代表强度越高。这时候打开属性表,能看到统计值已经挂在每个区域记录上,可以直接读数和导出。
# 用 ArcPy 做分区统计并连接,避免手动点选 import arcpy from arcpy.sa import ZonalStatisticsAsTable arcpy.CheckOutExtension("Spatial") zone_data = r"D:\data\region_A.shp" zone_field = "REGION_CODE" # 唯一标识字段 value_raster = r"D:\data\nightlight_mask.tif" out_table = r"D:\data\zonal_stat.dbf" ZonalStatisticsAsTable(zone_data, zone_field, value_raster, out_table, "DATA", "MEAN") arcpy.JoinField_management(zone_data, zone_field, out_table, zone_field, ["MEAN"]) arcpy.CheckInExtension("Spatial")ZonalStatisticsAsTable的第四个参数"DATA"表示只统计有效像元、忽略 NoData,第五个"MEAN"指定统计类型。JoinField_management把统计表的MEAN字段按REGION_CODE连回矢量,连接键两边必须同名同类型。跑完这一步,矢量属性表里就多了MEAN列,后续设色和出图都基于它。
3.3 布局视图出图:图名、图例、比例尺、指北针
数据对了,图还得能看。切到视图 → 布局视图,先调整页面和地图框比例,让研究区铺满又不裁边。然后插入 → 图名,写清楚分析对象和时间;插入 → 图例,在图例属性里删掉不需要的图层项,只保留分级设色的区域图层;插入 → 比例尺和指北针,位置放在图框角落不压数据的地方。图例的类别标签建议手动改成「低—高」或具体数值区间,比默认的字段名可读性强得多。
出图前再检查一遍:分级色彩的字段是不是MEAN,图例类别和地图颜色是否一一对应,比例尺单位是否和坐标系匹配。这几项对不上,图看着没问题,实际是错的。导出时选合适的分辨率,报告用图 300dpi 起步。
4. 避坑与排查:五个真实翻车点及处理办法
这套流程我跑过不止一次,每次卡住的地方都差不多。下面五条按「现象 → 原因 → 解决」写,照着排查能省不少时间。
现象一:按掩膜提取报错「输入不符合预期」或输出全空。原因多半是栅格和矢量坐标系不一致,或者矢量范围根本不在栅格覆盖范围内。解决:先用图层属性确认两者坐标系,不一致就投影统一;再把两个图层叠在一起看范围是否重叠,不重叠说明数据下错了区域。
现象二:分区统计表连回矢量后全是空值。原因是连接时两边字段选错,或者字段类型不一致(一边是文本一边是数值)。解决:打开两张表对比连接字段的值,确认编码格式完全一致;类型不同时先新建一个同类型字段做转换再连接。
现象三:统计出来的平均值明显偏低。原因是掩膜提取后范围外是 NoData,统计时如果没排除 NoData,或者赋值栅格选成了未裁剪的原图,平均值会被大片空值拉低。解决:确认赋值栅格是裁剪后的结果,分区统计的忽略 NoData 选项保持默认开启。
现象四:分级设色后颜色分布一边倒,看不出差异。原因是灯光 DN 值分布右偏,少数高值区把分级区间拉得很开。解决:在符号系统里改用手动分级或分位数分级,让类别按数据分布切分,而不是等间距切分。
现象五:多个区域用 OR 选择时漏选或错选。原因是表达式里引号、括号或 Or 的位置写错,或者区域名里有特殊字符。解决:每加一个条件就点一次「应用」验证选中数量,区域名带空格或符号时确认引号包裹正确,选完在属性表里核对记录数。
注意:所有中间结果都单独存文件,别覆盖原始数据。掩膜提取、分区统计各留一份,出错时能快速回退,不用从头再来。
5. 进阶技巧:批量统计与结果校验的固定动作
单个区域跑通之后,真正费时的是几十上百个区县的批量处理。手动一个个选、裁、统计,不仅慢,还容易漏。我的做法是把第 2、3 章的 ArcPy 脚本串成一个循环:读一个区域列表,逐个按名称筛选导出、掩膜提取、分区统计,最后把所有统计表合并成一张总表。这样一次跑完,结果格式统一,后续做对比分析直接可用。
批量跑之前有个校验习惯值得养成:随机抽两三个区域,用手动流程的结果和脚本结果对一遍MEAN值,差异应该在浮点误差范围内。对不上就说明循环里某个参数串了,比如掩膜路径没跟着区域变,或者统计表被后一个区域覆盖。这个抽查动作花不了几分钟,但能挡住整批结果作废的风险。
| 校验项 | 方法 | 合格标准 |
|---|---|---|
| 坐标系一致性 | 图层属性对比 | 两者坐标系相同 |
| 裁剪边界贴合 | 叠加目视 | 无明显偏移 |
| 统计值合理性 | 抽样手算对比 | 差异在误差内 |
| 连接完整性 | 属性表查空值 | 无大面积空值 |
还有一个细节:批量输出的统计表字段名可能因工具版本略有差异,合并前先统一字段名,否则拼出来的总表列对不齐。我一般用字段映射或重命名先把MEAN统一,再合并。
从那以后我每次跑夜间灯光分析,都强制先做坐标系核对和单区域试跑这两步,确认无误再上批量。这套流程本身不复杂,翻车基本都翻在数据对齐和字段连接上,把这两处盯死,剩下的就是点按钮的事。希望帮到你。
本文还有配套的精品资源,点击获取