☰
夜间灯光强度计算:ArcGIS掩膜提取与分区统计全流程解析
2026/10/14 7:50:32 网站建设 项目流程

简介:在GIS遥感分析中,夜间灯光数据常用于评估城市化程度、人口分布和经济发展差异。面向使用ArcGIS处理夜间灯光影像的初学者和科研人员,这份资料提供了从数据准备到结果可视化的完整操作指引。内容涵盖VIIRS/DMSP-OLS栅格数据与行政边界数据的获取,利用按属性选择完成区域范围提取,通过按掩膜提取裁剪出目标夜间灯光影像,并借助Spatial Analyst工具下的以表格显示分区统计计算各区域灯光强度,再结合字段连接与分级色彩进行专题制图,还可继续添加图名、图例、比例尺等地图整饰要素。资源为单个docx文档,约6.52MB,文档中列出每一步的工具位置、参数设置和导出建议,便于对照实操,也可作为后续同类遥感任务的参考模板。已有3651人次学习下载,适用于城市规划、区域发展比较、生态环境监测等场景,能帮助用户系统掌握夜光遥感分析的高效工作流,并理解从原始影像到统计成果的完整链路。

1. 夜间灯光的提取与强度计算:ArcGIS掩膜与分区统计一条链路走通

夜间灯光提取和强度计算在 GIS 实务里是一对固定搭配:前者用行政区边界把卫星灯光栅格“切”出研究范围,后者用分区统计把切出来的像元值汇总成能写进报告的数字。这套流程在 ArcGIS 里跑一遍并不复杂,但真正动手的人里,七成左右会卡在坐标系不一致、NoData 被当成 0、连接字段类型对不上这类细节上。这篇笔记把整条链路拆开来讲,适合正在做城市夜间灯光分析、经济活跃度评估或环境监测的从业者,也适合刚接触 ArcGIS 空间分析的学生。看完你能拿着矢量边界和灯光 tif,自己从属性选择一路做到分区统计和出图。

2. 数据准备:坐标系统一与两类灯光数据的选型细节

2.1 灯光数据源差异:VIIRS 与 DMSP/OLS 怎么选

夜间灯光栅格数据本质是一张单波段影像,每个像元记录的是该位置的灯光亮度值,单位是辐射亮度或数字量化值。不同传感器产出的数据在空间分辨率、时间跨度和数值意义上差别很大,选错数据源会直接导致后续统计结果不可比。

VIIRS 传感器提供的合成产品是当前最常用的选择,空间分辨率约 500 米,数值是去除火光、气体燃烧等杂散光源后的平均灯光辐射值,适合做年度或月度对比。DMSP/OLS 系列是更早的稳定灯光合成数据,分辨率约 1 公里,时间覆盖从 1992 年到 2013 年左右,适合做长时序的城市扩张回溯分析。两类数据在 ArcGIS 里都能直接加载,但要注意:DMSP/OLS 的像元值是 0 到 63 的整数档位,VIIRS 是浮点型的辐射值,二者不能混在同一张统计表里。

对比项DMSP/OLSVIIRS
空间分辨率约 1000 米约 500 米
数值类型0~63 整数档位浮点辐射亮度值
适用场景长时序城市扩张分析近期灯光强度、经济活跃度评估
拼接处理需逐年校准官方已做合成处理,可直接用

实际项目里,我一般默认优先拿 VIIRS 月度合成数据,如果只是做某一年的截面分析,直接用对应年份的年度合成 tif 就够了。下载时留意文件命名里的年份标记,避免把不同年份的影像叠在一起统计。

2.2 坐标系为什么是第一步:栅格与矢量必须坐在同一张“底图”上

坐标系不统一是这条链路里翻车率最高的环节,而且它翻得很隐蔽:ArcGIS 打开两个图层时,软件会动态投影让它俩看起来是重合的,但按掩膜提取工具执行时,底层会按严格的坐标值做空间计算。如果灯光栅格是地理坐标系(WGS84 经纬度),行政边界是投影坐标系(比如 CGCS2000 投影),两者即便视觉上重叠,实际参与计算的坐标基准不同,结果要么是范围偏移,要么是输出一张看着正常但统计值全是零的废栅格。

判断坐标系是否一致,最快的方式是分别打开两个图层的属性——源选项卡里看“空间参考”。栅格数据一般在元数据里带着坐标系信息,矢量 shp 的坐标系则写在同目录的 .prj 文件里。如果 shp 文件旁边没有 .prj 文件,ArcGIS 会默认当成未知坐标系,这时候必须先给定坐标系,否则后面所有分析都建立在错误假设上。

我一般会先做一次“图层右键—属性—源”检查,把两个数据的空间参考名称记下来。理想状态下,栅格和矢量都使用同一投影坐标系,比如 CGCS2000_3_Degree_GK_CM_114E,因为投影坐标系的单位是米,分区统计的面积和强度字段直接与面积挂钩,不用做单位换算。

2.3 统一坐标系的操作路径:先看元数据再动手

如果发现坐标系不一致,优先改矢量,不要轻易重投影栅格。栅格重投影涉及像元重采样,每重采样一次就相当于给数据做一次插值,灯光亮度值会被平滑,后续统计结果会失真。矢量 shp 的坐标系换起来要安全得多,工具路径是 ArcToolbox—数据管理工具—投影和变换—要素—投影。

操作时注意勾选“输出坐标系”为与灯光栅格一致的坐标系。如果矢量本身没有定义坐标系,先使用“定义投影”工具补一个正确坐标系,再执行“投影”工具完成转换。定义投影和投影工具是两个容易混淆的操作:定义投影是告诉软件这个数据是什么坐标系,投影才是实际转换坐标值。

工具路径:ArcToolbox → 数据管理工具 → 投影和变换 → 要素 → 投影 关键参数: - 输入数据集或要素类:选择行政 shp - 输出数据集或要素类:命名如 admin_Projected.shp - 输出坐标系:选择与灯光 tif 一致的空间参考

投影工具执行完成后,把输出的新 shp 加载进地图,右键查看源空间参考。确认与灯光栅格完全一致后,再进入属性选择和掩膜提取环节。整套流程里这一步最枯燥,但省掉它的代价就是后面所有输出都可能作废。

3. 行政区提取与按掩膜提取:属性选择的 SQL 写法与三入参对齐

3.1 按属性选择区域:name 字段的唯一值获取与 Or 连接

拿到行政矢量后,第一步是从整层数据里挑出研究区范围。ArcGIS 的“按属性选择”工具在图层右键菜单里,也可以从“选择—按属性选择”打开。操作顺序是:在字段列表里双击 name 字段,点击“获取唯一值”,这时下方会列出该字段的全部取值,直接双击需要的区域名即可拼进表达式。

只选一个区域时,表达式就是"name" = 'A市',点击应用确定就能看到地图上高亮出该区域。需要选多个区域时,用 Or 连接多个条件。这里有一个新手很容易忽略的点:当条件比较多时,必须用括号把多个 Or 条件包起来,否则如果后面还要 And 别的条件,逻辑会错乱。例如"name" = 'A市' Or "name" = 'B县' Or "name" = 'C区'是没问题的,但如果想表达“属于这几个区域且面积大于多少”,必须写成("name" = 'A市' Or "name" = 'B县') And "area" > 100。

多区域连接时可以换用 SQL 的 IN 写法,表达式更简洁:"name" IN ('A市', 'B县', 'C区')。ArcGIS 的标准 SQL 方言对 IN 支持良好,尤其适合候选区域列表很长的情况。唯一要注意的是字段值里的中文引号必须用英文单引号,别用中文引号,否则表达式会直接报错。

3.2 导出要素并只显示目标图层:别把整层数据带进掩膜

选中的区域仍然属于原始 shp 图层,如果直接拿它去做掩膜,掩膜范围会临时按当前选择集计算,虽然也能跑,但后续一旦清除选择集或重新打开工程,这个掩膜图层就失效了。稳妥的做法是把选中的区域导出成独立 shp 文件。

右键图层名,选“数据—导出数据”,在导出对话框里“导出”选项默认是“所选要素”,确认无误后设置输出路径和文件名。注意这里导出的是要素类,不是图层,路径里不能包含中文目录,文件名最好用拼音或英文,否则部分 ArcGIS 版本会出现数据源无法加载的问题。

导出完成后,把原始行政图层前面的勾去掉,地图里只保留新导出的研究区图层。这一步的价值在于:后续每一次掩膜提取和分区统计都使用同一份边界数据,不会因为选择集状态变化导致结果前后不一致。按属性选择这套操作在项目里往往要重复多次,每提取一次研究范围就导出一次,保持数据链条干净。

3.3 按掩膜提取参数对照:输入栅格、掩膜、输出位置的三个坑

按掩膜提取工具位于 Spatial Analyst 工具—提取分析下,三个输入参数看起来简单,实际操作时最容易出问题的反而是环境设置。

输入栅格选择夜间灯光 tif,注意这里要选真实栅格文件,而不是图层符号化后的对象。掩膜数据选择上一节导出的研究区 shp。输出栅格命名后,还要检查一个关键环境参数:地理处理环境的“处理范围”和“掩膜”设置。如果环境里的范围仍保持默认,输出的栅格会保留灯光影像的原始范围,掩膜以外的区域会被填成 NoData,栅格文件尺寸巨大,加载和后续统计都会变慢。

注意:掩膜提取输出栅格的 NoData 区域不等于 0 值。在分区统计时,NoData 像元默认不参与统计,但如果后续做栅格计算器或转成整型,NoData 很容易被转成 0,导致灯光暗区被当成无灯光区混入统计。

正确做法是在执行工具前,打开“地理处理—环境”,把“处理范围”设为与掩膜相同,“栅格分析”里的掩膜也设为研究区 shp。这样输出的 tif 范围与行政边界完全一致,几乎所有后续操作都会更快更稳。

工具路径:ArcToolbox → Spatial Analyst 工具 → 提取分析 → 按掩膜提取 参数设置: - 输入栅格:夜间灯光 tif - 输入栅格数据或要素掩膜数据:行政研究区 shp - 输出栅格:以英文命名,如 night_light_extract.tif - 环境设置:处理范围 → 与掩膜相同;栅格分析掩膜 → 研究区 shp

掩膜提取完成后,建议先看一眼输出栅格的直方图。灯光数据有一定数量的 0 值像元属于正常现象,但如果直方图在最大值位置出现一个突兀的尖峰,多半是边界处存在异常高亮像元,需要回到原始数据检查是否是传感器异常值。

4. 强度计算与可视化:分区统计的统计类型选择与连接回图

4.1 分区统计的统计语义:均值、总和与夜间灯光强度的真实含义

夜间灯光强度计算不是直接拿栅格里的像元值填个颜色就完了,它需要把研究区边界内的所有灯光像元汇总成有业务含义的数字。ArcGIS 里对应的工具是“以表格显示分区统计”(Zonal Statistics as Table),位于 Spatial Analyst 工具—区域分析下。

分区统计的输入有四个关键项:区域数据(行政区 shp)、区域字段(用于唯一标识每个面的字段,比如 name)、赋值栅格(掩膜提取后的灯光 tif)以及输出表。统计类型这个参数决定了输出字段的语义,可选项包括 MIN、MAX、MEAN、SUM、STD、RANGE 等。在夜间灯光分析里,业务上常用的是 SUM 和 MEAN。

SUM 表示区域内所有灯光像元值和,可以理解为该区域的灯光总能量,适合衡量城市经济规模总量。MEAN 表示平均灯光强度,消除面积差异后适合比较不同区域的发展密度。如果只按默认值跑而不选统计类型,工具默认输出的是所有统计字段,表格会非常宽,后续连接查看也不方便。

统计类型输出字段含义适用业务场景
SUM区域灯光总值城市规模比较、经济总量估算
MEAN区域平均灯光强度单位面积灯光密度、城市化水平
MAX区域内最大像元值检查是否存在异常高亮像元
STD灯光值离散程度分析灯光分布集中度

执行分区统计时,还有一个容易忽略的选项是“忽略 NoData”。默认情况下 NoData 像元会被忽略,不参与计算,这个默认行为是正确的。但如果掩膜提取时没有清理干净边界,面积很小的狭长像元可能因为 NoData 不参与统计而输出空值,需要回到掩膜提取环节重新处理。

4.2 连接回图前的字段预处理:类型不一致会静默失败

分区统计输出的是一张独立表格(dbf),里面有一列是区域字段的值,后面跟着各统计类型的计算结果。要把这张表挂回行政区的属性表,用的是“连接和关联”功能。右键行政区图层,选“连接和关联—连接”,在连接对话框中分别指定要连接的字段和外部表格的连接字段。

这里最常见的坑是字段类型不一致。比如行政区属性表里的 name 字段是文本型,分区统计输出表里的同名区域字段也是文本型,ArcGIS 才能正确匹配。如果区域字段在统计表里被识别成数值型,哪怕显示的内容看起来一样,连接后结果字段会全是空值。判断方法很简单:连接完成后立刻打开行政区属性表,向右滑动看最后几列,如果灯光强度字段全为空,基本就是字段类型或字段值不匹配。

解决方式有两种。一是连接时换一个字段:很多 shp 文件的属性表自带 FID 或 ObjectID 字段,分区统计表也保留了这个字段,用整数型字段连接要比用 name 文本字段更可靠。二是如果必须用 name 字段连接,先在两个表里分别给该字段做一次“字段计算器”,把值统一前后去空格,再新建一个文本字段复制一遍,确保类型完全一致。

连接是动态关联,原表更新后连接字段就可能失效。做成图后如果需要把统计结果固化下来,可以右键图层“数据—导出数据”,把连接结果导成一份新 shp 或要素类。这一步输出的是带灯光强度字段的最终版行政图,后续所有制图都基于这份数据。

4.3 分级色彩与布局元素:从统计表到可交付专题图

统计结果挂回属性表后,就可以做符号化了。右键图层—属性—符号系统,选择“数量—分级色彩”,字段下拉里选刚才连接的灯光强度字段(例如 SUM 或 MEAN 对应的列),配色方案按数据类型选择合适的渐变。这里有一个出图经验:如果数据偏态严重(少数城市核心区亮度极高、外围大量低值区域),建议用“几何间隔”分类而不是“相等间隔”,后者会把大部分区域归入最小的一档,专题图看起来像一张深色底图。

分级数量设置在 5 到 7 类之间比较均衡,太少区分度不够,太多图例冗长。分类完成后,进入布局视图做最终出图:视图—布局视图,然后通过“插入”菜单依次加入图名、图例、比例尺和指北针。图名直接写“某研究区夜间灯光强度分布”这类业务标题,图例只保留灯光强度分级字段,别把 name 字段也带进图例。

插入比例尺时注意设置合适的单位,如果行政范围不大,比例尺单位选公里更直观。指北针类型选带 N 标记的简洁样式即可,不要用花哨的航海风格,保持专题图的信息密度。所有元素放好后,导出为 JPG 或 PDF 前,先切到布局视图预览一下,确认图例没有压住主体图斑,比例尺长度合理,再输出。

5. 问题排查:坐标系、NoData、连接字段五个典型翻车点

5.1 高频问题速查表

做夜间灯光提取与强度计算的过程中,下面的问题我基本每次处理新数据都会至少遇到一次,列出来方便你对号入座。

现象原因修复方式
掩膜提取后影像范围还是原始全图环境设置没有指定处理范围地理处理环境里把范围设为与掩膜相同
分区统计结果全为 0 或极小值栅格与矢量坐标系不一致先统一坐标系,再重跑分区统计
连接后灯光字段全为空连接字段类型或值不匹配改用 FID/ObjectID 连接或统一字段类型
统计结果与目视判读明显不符统计类型选错(选了 FIRST 或含末位字段)业务分析使用 SUM 或 MEAN 统计
多区域选择漏掉部分区域Or 表达式里中文引号或条件间没加括号改用 IN 写法并检查引号格式

5.2 逐条拆解:五处最影响结果的细节

第一条掩膜范围问题,我在前期接触这个流程时踩得很深。当时按掩膜提取跑完,输出 tif 加载进来看着是正常的,但一做分区统计,输出表里的像元数量比行政区内像元数量多了近十倍。原因是环境处理范围没设,整个城市的灯光影像全被保留,行政边界外的 NoData 黑边在栅格计算时还是占着位置。从那以后我把“处理范围与掩膜一致”当成掩膜提取的必选项,跑完后看一眼属性里的范围描述,确认输出范围与研究区一致再往下走。

第二条坐标系问题,最典型的特征是灯光图层和行政图层在地图上叠得严丝合缝,但分区统计输出全是 0 或极小值。因为 ArcMap 的动态投影让视觉重叠,实际参与计算的栅格像元和区域数据在真实坐标空间里错位,绝大多数像元落在行政面之外。修复方法是在分区统计前,单独检查两个数据源的“源”选项卡,确保投影坐标系 ID 一致。

第三条连接字段为空,这是动态连接最容易踩的暗坑。上次处理某区县数据时,连接完字段在属性表里完全显示,但导出后再打开新图层却全空了,原因是连接依赖原始表格路径,文件移动导致连接失效。解决方式是在导出前把连接结果“物化”成新要素类,不要带着动态连接到处转移。

第四条统计类型要选对语义。如果只是想把各区的灯光总量对比一下,用 SUM;如果要比较单位面积灯光密度,必须用 MEAN 再结合面积字段做二次计算。有人会误用统计表里的 FIRST 或 LAST 字段,这两个字段返回的是该区域内第一个或最后一个被访问的像元值,带有随机性,完全不能代表区域灯光强度。

第五条多区域选取时,经常出现在区域列表特别长时,手工点选会漏掉某个区县。检查方法是导出后打开研究区属性表,统计要素数量是否与计划一致。不一致时直接重做按属性选择,表达式里用 IN 比一长串 Or 更不容易出错。

6. 进阶用法:arcpy 把“提取+统计+出表”串成半自动流程

如果只是单次分析,ArcGIS 菜单点击完全够用。但实际项目里往往要处理多个年份、多个研究区,每次都重复点同一套工具会非常浪费时间,而且手动操作容易漏改参数。arcpy 可以把掩膜提取、分区统计、连接结果一次跑完,脚本化之后换数据只需改路径。

下面的脚本适合在 ArcGIS Pro 的 Python 窗口或独立 IDE 里运行,核心逻辑是先设置环境掩膜,再依次执行提取和分区统计。注意脚本里所有路径都用原始字符串写法,避免转义问题。

import arcpy from arcpy.sa import * # 统一管理路径,换数据时只需改这三处 arcpy.env.workspace = r"D:\nightlight_data" arcpy.env.overwriteOutput = True light_tif = r"D:\nightlight_data\light_2024.tif" admin_shp = r"D:\nightlight_data\admin_q.shp" extract_path = r"D:\nightlight_data\light_extract.tif" stats_table = r"D:\nightlight_data\light_stats.dbf" # 关键一步:环境掩膜直接指定为行政边界 arcpy.env.mask = admin_shp arcpy.env.snapRaster = light_tif # 执行按掩膜提取,输出范围自动与掩膜一致 extract_obj = ExtractByMask(light_tif, admin_shp) extract_obj.save(extract_path) print("掩膜提取完成:", extract_path) # 分区统计,区域字段用行政区属性表里的名称字段 zone_field = "name" stat_result = ZonalStatisticsAsTable( admin_shp, zone_field, extract_path, stats_table, "DATA", "MEAN" ) print("分区统计完成:", stats_table) # 把统计表连接回行政要素并输出带字段的新shp joined_shp = r"D:\nightlight_data\admin_q_light.shp" arcpy.management.CopyFeatures(admin_shp, joined_shp) arcpy.management.JoinField( joined_shp, zone_field, stats_table, zone_field, ["MEAN"] ) print("最终结果:", joined_shp)

脚本里需要注意三个细节:一是环境掩膜必须在 ExtractByMask 前设置,否则输出范围仍是原栅格范围;二是 ZonalStatisticsAsTable 的第五个参数 "DATA" 表示 NoData 不参与计算,这是夜间灯光统计的正确语义;三是 JoinField 连接字段的名称必须与区域数据里的字段一致,这里用的是 name。

脚本跑完后,拿输出 shp 的属性表与手动操作结果对比一下。一个可靠的验证方法是:在 ArcGIS 里手动选一个面积较小的县区,用“按属性选择”单独提取后做一次分区统计,手动记录 MEAN 值,再和脚本输出表里的同名记录对比。数值一致说明链路完整,不一致就优先检查坐标系和字段类型。

从那以后,我每次拿到新增年份的灯光数据,都强制把路径换掉后重跑一遍这套脚本。脚本输出的结果表再进 ArcGIS 做专题图,整个流程从一小时缩短到五分钟。希望这篇笔记能把你在夜间灯光提取和强度计算上的弯路省下来。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询