【Python实例】获取指定经纬度范围内的栅格数据(tif)


在地理信息系统(GIS)中,经纬度是一种常用的坐标系统,用于在地球上定位位置。在许多应用中,我们可能需要根据给定的经纬度范围获取特定区域内的栅格位置。本文将介绍如何使用Python来实现这一目标(类似于GIS中的掩膜提取)。

数据准备

确定经纬度范围

首先,我们需要确定所需区域的经纬度范围。经度表示东西方向上的位置,介于-180到180之间,其中0代表本初子午线。纬度表示南北方向上的位置,介于-90到90之间,其中0代表赤道。
例如,我们希望获取北纬30度到40度,东经100度到110度范围内的栅格位置。

安装必要的库

在开始编写代码之前,我们需要安装一些Python库来处理地理空间数据。其中最常用的是GeoPandas和Shapely。

可以使用以下命令来安装它们:

pip install geopandas shapely

基于Python获取指定区域内栅格数据(Mask)

指定经纬度范围内

代码功能:根据全球不透水面积裁剪得到指定经纬度范围内的栅格数据

图形如下:
在这里插入图片描述
Python代码如下:

# 设置要裁剪的经纬度范围
min_lon = 102.0  # 最小经度
max_lon = 123.0  # 最大经度
min_lat = 14.0   # 最小纬度
max_lat = 33.0   # 最大纬度

# 导入重采样后的不透水面积数据
ISA_resampled_file = "D:/0 DataBase/5 Imperious surface area/ISA_resampled_500m.tif"
ISA_dataset = gdal.Open(ISA_resampled_file, gdal.GA_ReadOnly)

if ISA_dataset is None:
    raise Exception(f"Unable to open file+{ISA_resampled_file}")

# 获取数据的地理变换参数
geo_transform = ISA_dataset.GetGeoTransform()
top_left_x = geo_transform[0]
pixel_width = geo_transform[1]
top_left_y = geo_transform[3]
pixel_height = geo_transform[5]

# 计算裁剪区域的像素范围
# 计算左上角和右下角的像素位置
ul_x = int((min_lon - top_left_x) / pixel_width)
ul_y = int((top_left_y - max_lat) / abs(pixel_height))
lr_x = int((max_lon - top_left_x) / pixel_width)
lr_y = int((top_left_y - min_lat) / abs(pixel_height))

# 使用 gdal.Translate 裁剪数据
ISA_clipped_file = "D:/0 DataBase/5 Imperious surface area/ISA_clipped.tif"
gdal.Translate(
    ISA_clipped_file,
    ISA_dataset,
    srcWin=[ul_x, ul_y, lr_x - ul_x, lr_y - ul_y]  # 裁剪区域的像素范围
)

# 读取裁剪后的数据
ISA_clipped_dataset = gdal.Open(ISA_clipped_file, gdal.GA_ReadOnly)
band = ISA_clipped_dataset.GetRasterBand(1)
ISA_clipped_data = band.ReadAsArray()

# 打印裁剪后的数据大小
print("裁剪后的不透水面积数据大小:", ISA_clipped_data.shape)

指定研究区(其他tif文件)

Python代码如下:

# 导入重采样后的不透水面积数据
ISA_resampled_file = "D:/0 DataBase/5 Imperious surface area/ISA_resampled_500m.tif"
ISA_dataset = gdal.Open(ISA_resampled_file, gdal.GA_ReadOnly)

if ISA_dataset is None:
    raise Exception(f"Unable to open file+{ISA_resampled_file}")

# 计算不透水面积数据的地理变换参数
ISA_geo_transform = ISA_dataset.GetGeoTransform()
ISA_top_left_x = ISA_geo_transform[0]
ISA_pixel_width = ISA_geo_transform[1]
ISA_top_left_y = ISA_geo_transform[3]
ISA_pixel_height = ISA_geo_transform[5]

# 计算裁剪区域的左上角和右下角经纬度
min_lon = top_left_x
max_lon = top_left_x + (LUCC_width * pixel_width)
max_lat = top_left_y
min_lat = top_left_y + (LUCC_height * pixel_height)

# 计算裁剪区域的像素范围
ul_x = int((min_lon - ISA_top_left_x) / ISA_pixel_width)
ul_y = int((ISA_top_left_y - max_lat) / abs(ISA_pixel_height))
lr_x = int((max_lon - ISA_top_left_x) / ISA_pixel_width)
lr_y = int((ISA_top_left_y - min_lat) / abs(ISA_pixel_height))

# 计算对齐的左上角坐标
aligned_top_left_x = top_left_x
aligned_top_left_y = top_left_y

# 进行裁剪和对齐
ISA_clipped_file = "D:/0 DataBase/5 Imperious surface area/ISA_clipped_aligned.tif"

gdal.Warp(
    ISA_clipped_file,
    ISA_dataset,
    width=LUCC_width,  # 输出与 LUCC 数据相同的宽度
    height=LUCC_height,  # 输出与 LUCC 数据相同的高度
    outputType=gdal.GDT_Float32,  # 输出数据类型
    xRes=pixel_width,  # 与 LUCC 相同的分辨率
    yRes=abs(pixel_height),  # 与 LUCC 相同的分辨率
    dstSRS=LUCC_dataset.GetProjection(),  # 使用 LUCC 数据的投影
    outputBounds=[aligned_top_left_x, aligned_top_left_y + LUCC_height * pixel_height,
                  aligned_top_left_x + LUCC_width * pixel_width, aligned_top_left_y],  # 输出边界
    resampleAlg=gdal.GRA_Bilinear  # 使用双线性插值
)

# 读取裁剪和对齐后的数据
ISA_clipped_dataset = gdal.Open(ISA_clipped_file, gdal.GA_ReadOnly)
band = ISA_clipped_dataset.GetRasterBand(1)
ISA_clipped_data = band.ReadAsArray()

# 打印裁剪和对齐后的数据大小
print("裁剪和对齐后的不透水面积数据大小:", ISA_clipped_data.shape)

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WW、forever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值