利用夜间灯光数据运用阈值法提取城市建成区是相对容易实现一种做法,并且兼具高效、快速等特点,但是当面对大量城市的时候,如何批量提取城市建成区范围显得尤为重要。提取方法有阈值法、突变检测法等等。要实现 ArcGIS 批量利用夜间灯光数据提取城市建成区,核心思路是:
1.批量读取夜间灯光栅格数据(如 NPP/VIIRS 数据);- 2.通过阈值法(最常用、易实现)筛选灯光值高于阈值的栅格(即建成区);
# -*- coding: utf-8 -*-
import arcpy
import os
import sys
# 设置ArcGIS环境(允许覆盖输出、显示进度)
arcpy.env.overwriteOutput = True
arcpy.env.addOutputsToMap = False # 关闭自动加图层,提升批量处理速度
arcpy.CheckOutExtension("Spatial") # 检查并启用空间分析扩展模块
def extract_built_up_area(input_folder, output_folder, threshold):
""" 批量提取城市建成区
:param input_folder: 夜间灯光栅格数据文件夹(仅支持tif格式)
:param output_folder: 结果输出文件夹
:param threshold: 灯光阈值(需根据数据校准,如VIIRS数据常用10-30,DMSP数据常用30-60)
""" # 检查输入输出文件夹是否存在
if not os.path.exists(input_folder):
raise FileNotFoundError(f"输入文件夹不存在:{input_folder}")
if not os.path.exists(output_folder):
os.makedirs(output_folder) # 不存在则创建
# 获取文件夹内所有tif格式的夜间灯光数据
raster_list = [f for f in os.listdir(input_folder) if f.endswith(".tif")]
if not raster_list:
raise ValueError("输入文件夹中未找到tif格式的栅格数据!")
# 批量处理每个栅格
for raster_name in raster_list:
try:
print(f"正在处理:{raster_name}")
# 1. 拼接完整路径
raster_path = os.path.join(input_folder, raster_name)
raster_base_name = os.path.splitext(raster_name)[0] # 去掉后缀的文件名
# 2. 阈值筛选:提取灯光值>阈值的栅格(建成区)
out_threshold_raster = os.path.join(output_folder, f"{raster_base_name}_threshold.tif")
# 构建栅格计算器表达式(Con函数:满足条件赋值1,否则赋值NoData)
calc_expression = f"Con(\"{raster_path}\" > {threshold}, 1)"
arcpy.ia.RasterCalculator(calc_expression, out_threshold_raster)
# 3. 栅格转矢量面(将建成区栅格转为多边形)
out_polygon=os.path.join(output_folder,f{raster_base_name}_built_up.shp")
arcpy.conversion.RasterToPolygon( in_raster=out_threshold_raster,
out_polygon_features=out_polygon,simplify="NO_SIMPLIFY"
# 不简化,保留细节 )
# 4. 删除中间栅格(可选,节省空间)
arcpy.Delete_management(out_threshold_raster)
print(f"✅ {raster_name} 处理完成,结果保存至:{out_polygon}") except Exception as e: print(f"❌ {raster_name} 处理失败:{str(e)}")
continue
if __name__ == "__main__":
# -------------------- 请修改以下参数 -------------------
INPUT_FOLDER = r"E:\night_light_data" # 夜间灯光数据文件夹
OUTPUT_FOLDER = r"E:\built_up_result" # 建成区结果输出文件夹
THRESHOLD = 15 # 灯光阈值(需根据数据类型调整,VIIRS建议10-30,DMSP建议30-60)
# -------------------------------------------------------------------
# 执行批量提取
try:extract_built_up_area(INPUT_FOLDER, OUTPUT_FOLDER, THRESHOLD)
print("\n🎉 所有数据处理完成!")
except Exception as e:
print(f"\n❌ 程序执行失败:{str(e)}")
sys.exit(1)
四、代码关键说明
- 环境设置:
arcpy.CheckOutExtension("Spatial") 必须启用空间分析扩展,否则栅格计算会报错; - 阈值筛选:核心是
Con函数,筛选灯光值大于阈值的栅格(赋值 1),其余为 NoData,这是提取建成区的核心逻辑; - 栅格转矢量:
RasterToPolygon 将栅格转为 shp 矢量面,便于后续的城市边界分析、面积统计等; - 批量处理:通过遍历文件夹内所有 tif 文件,实现自动化批量操作,避免手动逐个处理。
五、前置条件
- 安装 ArcGIS(建议 10.8 及以上版本),并确保 ArcPy 库可用;
- 夜间灯光数据为tif 格式栅格(如 NPP/VIIRS、DMSP/OLS 数据);
- 确保输入文件夹仅存放夜间灯光 tif 数据,避免其他 tif 文件干扰;
- VIIRS 数据(2012 年后):阈值建议 10-30;
- DMSP 数据(1992-2013):阈值建议 30-60;
- 可先通过 ArcGIS 手动试算单个数据的最优阈值,再批量应用。
六、使用步骤
- 修改代码中
INPUT_FOLDER、OUTPUT_FOLDER、THRESHOLD三个参数为实际路径 / 阈值; - 打开 ArcGIS 的 Python 窗口(或 IDLE/VSCode,需配置 ArcPy 环境);