今天分享的是
1992年-2022年 ESA CCI土地覆盖
数据已经处理好,结尾链接可获取哦~
01 数据介绍
1. 数据简介:
欧洲航天局气候变化倡议(ESA Climate Change Initiative, CCI)项目提供1992-2015年(2.0.7版)、 2016 至 2022 年(2.1 版)的全球土地覆盖(LC)地图,其空间分辨率为 0.002778°(在赤道附近约为 300 米)。全球土地覆盖数据库所使用的坐标参考系统(CRS)是基于世界大地测量系统 84 (WGS84) 参考椭球体的地理坐标系统(GCS)。
2.土地覆盖分类图例:
3.网页可视化链接:
ESA提供ESA_CCI数据的网页端可视化内容
https://maps.elie.ucl.ac.be/CCI/viewer/
02 1992-2015年数据下载
v.2.0.7
📌下载链接:
https://data.ceda.ac.uk/neodc/esacci/land_cover/data/land_cover_maps
03 v.2.1.1 2016-2020年下载
v2.1.1(v2.0.7 的延续)——2016 年至 2020 年每年 300 米空间分辨率的全球土地覆盖图,与欧洲航天局 (ESA) 气候变化倡议 (CCI) 制作的 1992 年至 2015 年全球年度 LC 地图系列一致。
📌下载链接:
https://cds.climate.copernicus.eu/datasets/satellite-land-cover?tab=overview
04 nc转tif处理
1.单个数据转tif
import xarray as xr
import rasterio
from rasterio.transform import from_origin
import numpy as np
import os
# 1. 读取 NetCDF 文件
ORIGINAL_DATA_DIR = "E:/你的原始数据路径"
PROCESSED_DATA_DIR = "E:/你的保存路径"
nc_path = os.path.join(ORIGINAL_DATA_DIR, "ESA_CCI", "C3S-LC-L4-LCCS-Map-300m-P1Y-2020-v2.1.1.nc")
tif_path = os.path.join(PROCESSED_DATA_DIR, "lccs_class_2020.tif")
os.makedirs(os.path.dirname(tif_path), exist_ok=True)
ds = xr.open_dataset(nc_path)
# 2. 提取变量(只取第一个时间片)
data = ds['lccs_class'].isel(time=0)
# 3. 转换为 numpy 数组
array = data.values.astype(np.uint8)
# 4. 获取空间信息
lat = ds['lat'].values
lon = ds['lon'].values
res_lat = abs(lat[1] - lat[0])
res_lon = abs(lon[1] - lon[0])
# 注意 lat 是从北到南,所以起点是左上角
transform = from_origin(west=lon[0], north=lat[0], xsize=res_lon, ysize=res_lat)
with rasterio.open(
tif_path,
'w',
driver='GTiff',
height=array.shape[0],
width=array.shape[1],
count=1,
dtype=array.dtype,
crs="EPSG:4326", # 通常地理坐标使用这个
transform=transform,
) as dst:
dst.write(array, 1)
print(f"✅ 成功保存为: {tif_path}")
2.批量处理nc转tif
import xarray as xr
import rasterio
from rasterio.transform import from_origin
import numpy as np
import os
# 设置原始数据路径和保存路径
ORIGINAL_DATA_DIR = "E:/你的原始数据路径"
PROCESSED_DATA_DIR = "E:/你的保存路径"
# 创建保存路径
os.makedirs(PROCESSED_DATA_DIR, exist_ok=True)
# 获取所有 NetCDF 文件
nc_files = [f for f in os.listdir(os.path.join(ORIGINAL_DATA_DIR, "ESA_CCI")) if f.endswith('.nc')]
for nc_file in nc_files:
# 从文件名中提取年份
year = nc_file.split('-')[3] # 提取年份部分(例如 "2020")
# 构造输入文件路径和输出文件路径
nc_path = os.path.join(ORIGINAL_DATA_DIR, "ESA_CCI", nc_file)
tif_filename = f"{year}.tif" # 使用年份作为输出文件名
tif_path = os.path.join(PROCESSED_DATA_DIR, tif_filename)
# 创建保存路径的文件夹
os.makedirs(os.path.dirname(tif_path), exist_ok=True)
# 打开 NetCDF 数据集
ds = xr.open_dataset(nc_path)
# 2. 提取变量(只取第一个时间片)
data = ds['lccs_class'].isel(time=0)
# 3. 转换为 numpy 数组
array = data.values.astype(np.uint8)
# 4. 获取空间信息
lat = ds['lat'].values
lon = ds['lon'].values
res_lat = abs(lat[1] - lat[0])
res_lon = abs(lon[1] - lon[0])
# 注意 lat 是从北到南,所以起点是左上角
transform = from_origin(west=lon[0], north=lat[0], xsize=res_lon, ysize=res_lat)
# 5. 保存为 GeoTIFF 文件
with rasterio.open(
tif_path,
'w',
driver='GTiff',
height=array.shape[0],
width=array.shape[1],
count=1,
dtype=array.dtype,
crs="EPSG:4326", # 通常地理坐标使用这个
transform=transform,
) as dst:
dst.write(array, 1)
print(f"✅ 成功保存为: {tif_path}")
05 保存部分分类数据
很多时候我们的研究只需要其中的部分分类内容(如:草地,森林,灌木等),这时候就需要我们从原始的土地覆盖数据中提取出我们需要的内容,以下代码可以帮助我们直接提取,保存需要的分类部分,并输出为新的tif文件。
import os
import numpy as np
import rasterio
import geopandas as gpd
from rasterio.features import shapes
from shapely.geometry import shape
from multiprocessing import Pool
ORIGINAL_DATA_DIR = "E:/你的原始数据路径"
PROCESSED_DATA_DIR = "E:/你的保存路径"
# 输入和输出路径
input_tif = os.path.join(PROCESSED_DATA_DIR, "lccs_class_2020.tif")
output_tif = os.path.join(PROCESSED_DATA_DIR, 'LUCC', "lccs_class_2020_mask.tif")
# 打开原始 TIF 文件
with rasterio.open(input_tif) as src:
data = src.read(1) # 读取第一个波段(假设是单波段分类图)
profile = src.profile # 获取元信息
# 创建掩码:保留值在10到130之间,其余设为 nodata (255)
filtered_data = np.where(((data >= 10) & (data <= 130) & (data != 20)), data, 255)
# 更新元信息,设置 nodata 为 255
profile.update(dtype=rasterio.uint8, nodata=255)
# 注释掉生成新的 TIF 文件的部分
with rasterio.open(output_tif, 'w', **profile) as dst:
dst.write(filtered_data, 1)
print("✔ 新的 TIF 文件已保存:", output_tif)
修改这一句就可以直接保存你需要的内容
如:需要分类数据大于10,小于130且不等于20的部分,nodata设置为255
# 创建掩码:保留值在10到130之间,其余设为 nodata (255)
filtered_data = np.where(((data >= 10) & (data <= 130) & (data != 20)), data, 255)
# 更新元信息,设置 nodata 为 255
profile.update(dtype=rasterio.uint8, nodata=255)
❤
欢迎大家交流学习
我们一起成长进步
~后台回复003获取数据链接~
点击关注遥感代码星球