from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
from datetime import date
import os,glob,zipfile,rasterio
import rasterio.plot
import numpy as np
from osgeo import gdal, osr, ogr, gdalconst
import matplotlib.pyplot as plt
from PIL import Image
import geopandas as gpd
练习1 哨兵-2号数据获取及处理
1. 数据介绍
哨兵-2号卫星携带一枚多光谱成像仪(MSI),高度为786km,可覆盖13个光谱波段,幅宽达290千米。地面分辨率分别为10m、20m和60m、一颗卫星的重访周期为10天,两颗互补,重访周期为5天。从可见光和近红外到短波红外,具有不同的空间分辨率,在光学数据中,哨兵-2号数据是唯一一个在红边范围含有三个波段的数据,这对监测植被健康信息非常有效。
13个波段中蓝色 (B2)、绿色 (B3)、红色 (B4) 和近红外 (B8) 波段具有 10 米的分辨率;红端(B5)、近红外 NIR(B6、B7 和 B8A)以及短波红外 SWIR(B11和B12)的地面采样距离为20米;沿海大气气溶胶 (B1) 和卷云波段 (B10) 的像素大小为 60 米;
环境要求: * GDAL==2.4.1 * numpy==1.19.5 * scikit-image==0.17.2 * sentinelsat==1.1.1 * zipp==3.6.0
2. 数据下载
- Sentinelsat包提供搜索、下载和检索Sentinel数据的功能
- 数据来源:哥白尼数据开放访问中心
# 输入ESA用户名和密码
= 'chidan'
user_name = 'chidan123!'
password
# 登录ESA API
= SentinelAPI(user_name, password, 'https://apihub.copernicus.eu/apihub')
api
# 检索的地理范围坐标
= "POLYGON((115.5 40.2, 116.0 40.2, 116.0 40.5, 115.5 40.5, 115.5 40.2))" #左上为起始点,顺时针旋转,回到起始点闭合
footprint
# 使用API接口查询,更多接口信息查询https://www.strerr.com/geojson/geojson.html#map=5/31.386/115.329
= api.query(footprint,
products = ('20220801', date(2022,9,1)),
date = 'Sentinel-2',
platformname = "S2MSI2A", #S2MSI1C",# S2MS2Ap
producttype = (0, 1))
cloudcoverpercentage
print(f"一共检索到{len(products)}景符合条件的数据\n")
for i, product in enumerate(products):
= api.get_product_odata(product)
product_info print(product_info['title'])
一共检索到4景符合条件的数据
S2B_MSIL2A_20220825T030519_N0400_R075_T50TLK_20220825T052806
S2B_MSIL2A_20220825T030519_N0400_R075_T50TMK_20220825T052806
S2A_MSIL2A_20220810T030531_N0400_R075_T50TMK_20220810T083201
S2B_MSIL2A_20220805T030529_N0400_R075_T50TMK_20220805T053117
下载数据并解压,只下载一景
# 创建下载路径
= './data/'
save_path if not os.path.exists(save_path):
os.makedirs(save_path)
# 下载检索到的最后一景数据,对于长期存档的数据(3-6个月以上),会出现offline情况,在下载的时候,需要先请求,后台将数据调档至在线,时间大概是半个小时,才能下载
for i, product in enumerate(products):
if i == 1:
break
= api.get_product_odata(product)
product_info # if product_info['title'] == "S2B_MSIL2A_20220805T030529_N0400_R075_T50TMK_20220805T053117":
if product_info['Online']:
print('数据在线,正在下载')
= api.download(product_info['id'],save_path)
file_save_path = file_save_path['path']
sentinel_data_path else:
print('数据未在线,请等待30分钟重试')
数据在线,正在下载
# 解压数据
= zipfile.ZipFile(sentinel_data_path,'r')
f
# 解压到save_path
for file in f.namelist():
file,save_path)
f.extract( f.close()
Sentinel-2产品解压后为SAFE格式,SAFE文件包含以下几个内容: * 一个manifest.safe文件,其中包含 XML 格式的一般产品信息 * JPEG2000 格式的预览图像 * 测量(传感器扫描成像)数据集的子文件夹,包括 GML-JPEG2000 格式的图像数据(颗粒/瓦片) * 数据条级别信息的子文件夹 * 带有辅助数据的子文件夹(例如国际地球自转和参考系统 (IERS) 公告) * HTML 预览
获取数据的信息
获取数据的信息
= sentinel_data_path[:-4] + '.SAFE' + os.sep +'MTD_MSIL2A.xml'
xml_path = gdal.Open(xml_path)
root_ds = root_ds.GetSubDatasets() # 获取子数据集。该数据以数据集形式存储且以子数据集形式组织
ds_list for i in range(len(ds_list)):
= gdal.Open(ds_list[i][0]) # 打开第i个数据子集的路径。ds_list有4个子集,内部前段是路径,后段是数据信息
visual_ds print(ds_list[i][0])
print(f'数据波段为:{ds_list[i][1]}')
print(f'仿射矩阵信息:{visual_ds.GetGeoTransform()}')
print(f'投影信息:{visual_ds.GetProjection()}')
print(f'栅格波段数:{visual_ds.RasterCount}')
print(f'栅格列数(宽度):{visual_ds.RasterXSize} 栅格行数(高度):{visual_ds.RasterYSize}')
print("\n")
SENTINEL2_L2A:data\S2B_MSIL2A_20220825T030519_N0400_R075_T50TLK_20220825T052806.SAFE\MTD_MSIL2A.xml:10m:EPSG_32650
数据波段为:Bands B2, B3, B4, B8 with 10m resolution, UTM 50N
仿射矩阵信息:(300000.0, 10.0, 0.0, 4500000.0, 0.0, -10.0)
投影信息:PROJCS["WGS 84 / UTM zone 50N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32650"]]
栅格波段数:4
栅格列数(宽度):10980 栅格行数(高度):10980
SENTINEL2_L2A:data\S2B_MSIL2A_20220825T030519_N0400_R075_T50TLK_20220825T052806.SAFE\MTD_MSIL2A.xml:20m:EPSG_32650
数据波段为:Bands B5, B6, B7, B8A, B11, B12, AOT, CLD, SCL, SNW, WVP with 20m resolution, UTM 50N
仿射矩阵信息:(300000.0, 20.0, 0.0, 4500000.0, 0.0, -20.0)
投影信息:PROJCS["WGS 84 / UTM zone 50N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32650"]]
栅格波段数:11
栅格列数(宽度):5490 栅格行数(高度):5490
SENTINEL2_L2A:data\S2B_MSIL2A_20220825T030519_N0400_R075_T50TLK_20220825T052806.SAFE\MTD_MSIL2A.xml:60m:EPSG_32650
数据波段为:Bands B1, B9, AOT, CLD, SCL, SNW, WVP with 60m resolution, UTM 50N
仿射矩阵信息:(300000.0, 60.0, 0.0, 4500000.0, 0.0, -60.0)
投影信息:PROJCS["WGS 84 / UTM zone 50N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32650"]]
栅格波段数:7
栅格列数(宽度):1830 栅格行数(高度):1830
SENTINEL2_L2A:data\S2B_MSIL2A_20220825T030519_N0400_R075_T50TLK_20220825T052806.SAFE\MTD_MSIL2A.xml:TCI:EPSG_32650
数据波段为:True color image, UTM 50N
仿射矩阵信息:(300000.0, 10.0, 0.0, 4500000.0, 0.0, -10.0)
投影信息:PROJCS["WGS 84 / UTM zone 50N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32650"]]
栅格波段数:3
栅格列数(宽度):10980 栅格行数(高度):10980
3. 数据格式转换
我们所需要的图像数据储存在IMG_DATA文件夹里,该文件夹内有三个子文件夹,分别存有三种不同分辨率的数据,数据格式为JPEG2000。接下来的任务为:
- 在解压缩后的文件夹查找到jp2数据
- 对各个波段的jp2数据进行解压缩,保存为GeoTiff格式数据
# 检索解压目录下的所有子文件夹,找到IMG_DATA文件夹
for root, _, _ in os.walk(sentinel_data_path[:-4] + '.SAFE'):
if root.endswith("IMG_DATA"):
= root
IMG_DATA_path
def get_image_name(image_directory):
file = image_directory + '\R10m'
= os.listdir(file)[0]
names = names[:22]
img_name return img_name
# 获得文件名
= get_image_name(IMG_DATA_path)
img_identifier
# 拼接成各个波段文件绝对路径
# 20m分辨率数据
= [IMG_DATA_path + os.sep +'R20m\%s_B8A_20m.jp2' %img_identifier ,
jp2_20m_list + os.sep +'R20m\%s_B11_20m.jp2' %img_identifier ,
IMG_DATA_path + os.sep +'R20m\%s_B12_20m.jp2' %img_identifier,
IMG_DATA_path + os.sep +'R20m\%s_B05_20m.jp2' %img_identifier,
IMG_DATA_path + os.sep +'R20m\%s_B06_20m.jp2' %img_identifier,
IMG_DATA_path + os.sep +'R20m\%s_B07_20m.jp2' %img_identifier]
IMG_DATA_path
# 10m分辨率数据
= [IMG_DATA_path + os.sep +'R10m\%s_B02_10m.jp2' %img_identifier,
jp2_10m_list + os.sep +'R10m\%s_B03_10m.jp2' %img_identifier,
IMG_DATA_path + os.sep +'R10m\%s_B04_10m.jp2' %img_identifier,
IMG_DATA_path + os.sep +'R10m\%s_B08_10m.jp2' %img_identifier]
IMG_DATA_path
def jp2Totif(jp2_path,save_path):
"""
格式转换:jp2 转 tif
:param jp2_path: jp2数据地址
:param save_path: 存储路径
:return: 存储地址
"""
= os.path.basename(jp2_path)[:-4]
file_name = os.path.join(save_path,file_name)
save_file = save_file+'.tif'
save_file = gdal.Open(jp2_path)
dataset = dataset.RasterYSize
rows = dataset.RasterXSize
cols = dataset.GetProjection()
projection = dataset.GetGeoTransform()
trans = dataset.ReadAsArray()
data if data.dtype == 'uint16':
= gdal.GetDriverByName('GTiff')
driver = driver.Create(save_file, cols, rows, 1, gdal.GDT_UInt16)
out_dataset
out_dataset.SetProjection(projection)
out_dataset.SetGeoTransform(trans)1).WriteArray(data)
out_dataset.GetRasterBand(1).SetNoDataValue(0)
out_dataset.GetRasterBand(
out_dataset.FlushCache()del dataset, out_dataset
elif data.dtype == 'uint8':
= gdal.GetDriverByName('GTiff')
driver = driver.Create(save_file, cols, rows, 1, gdal.GDT_Byte)
out_dataset
out_dataset.SetProjection(projection)
out_dataset.SetGeoTransform(trans)1).WriteArray(data)
out_dataset.GetRasterBand(1).SetNoDataValue(0)
out_dataset.GetRasterBand(
out_dataset.FlushCache()del dataset, out_dataset
return save_file
仅堆叠可见波段NIR、RE和SWIR1和SWIR2(波段2、3、4、8、8A、11、12)。将20m波段(8A、11和12)重新采样至10m。
# 创建20m分辨率数据存储路径
= ".\\data"+ os.sep + img_identifier+ os.sep+ "20m"
tif_20m_save_path if not os.path.exists(tif_20m_save_path):
os.makedirs(tif_20m_save_path)
# 将20m分辨率数据由jp2格式转换为tif格式,并记录地址到tif_20m_list
= []
tif_20m_list for jp2_path in jp2_20m_list:
= jp2Totif(jp2_path, tif_20m_save_path)
tif_path
tif_20m_list.append(tif_path)
# 创建10m分辨率数据存储路径
= ".\\data"+ os.sep + img_identifier+ os.sep+"10m"
tif_10m_save_path if not os.path.exists(tif_10m_save_path):
os.makedirs(tif_10m_save_path)
# 将10m分辨率数据由jp2格式转换为tif格式,并记录地址到tif_10m_list
= []
tif_10m_list for jp2_path in jp2_10m_list:
= jp2Totif(jp2_path, tif_10m_save_path)
tif_path tif_10m_list.append(tif_path)
4. 数据重采样
将20m分辨率数据重采样至10m分辨率
def ReprojectImages(inputfilePath,outputfilePath,referencefilefilePath):
# 获取输出影像信息
= gdal.Open(inputfilePath, gdal.GA_ReadOnly)
inputrasfile = inputrasfile.GetProjection()
inputProj # 获取参考影像信息
= gdal.Open(referencefilefilePath, gdal.GA_ReadOnly)
referencefile = referencefile.GetProjection()
referencefileProj = referencefile.GetGeoTransform()
referencefileTrans = referencefile.GetRasterBand(1)
bandreferencefile = referencefile.RasterXSize
Width= referencefile.RasterYSize
Height = referencefile.RasterCount
nbands # 创建重采样输出文件(设置投影及六参数)
= gdal.GetDriverByName('GTiff')
driver = driver.Create(outputfilePath, Width,Height, nbands, bandreferencefile.DataType)
output
output.SetGeoTransform(referencefileTrans)
output.SetProjection(referencefileProj)# 参数说明 输入数据集、输出文件、输入投影、参考投影、重采样方法(最邻近内插\双线性内插\三次卷积等)、回调函数
0.0,0.0,) gdal.ReprojectImage(inputrasfile, output, inputProj, referencefileProj, gdalconst.GRA_Bilinear,
# 获取一景10m分辨率影像作为参考影像
= tif_10m_list[0]
reference_tif
# 将20m分辨率数据重采样至10m,并保存至 tif_10m_save_path 路径下
for tif_path in tif_20m_list:
= os.path.basename(tif_path)[:-7]
file_name = tif_10m_save_path + os.sep + file_name +'10m.tif'
save_tif_path ReprojectImages(tif_path, save_tif_path, reference_tif)
5. 波段叠合
- 将多个不同波段的的TIF文件合为一个多波段TIF文件
- 叠合波段为可见波段NIR、RE和SWIR1和SWIR2(波段2、3、4、8、8A、11、12)
# 读图像文件
def read_img(filename):
= gdal.Open(filename) # 打开文件
dataset
= dataset.RasterXSize # 栅格矩阵的列数
im_width = dataset.RasterYSize # 栅格矩阵的行数
im_height # im_bands = dataset.RasterCount # 波段数
= dataset.GetGeoTransform() # 仿射矩阵,左上角像素的大地坐标和像素分辨率
im_geotrans = dataset.GetProjection() # 地图投影信息,字符串表示
im_proj = dataset.ReadAsArray(0, 0, im_width, im_height)
im_data
del dataset #关闭对象dataset,释放内存
# return im_width, im_height, im_proj, im_geotrans, im_data,im_bands
return im_proj, im_geotrans, im_data, im_width,im_height
# 遥感影像的存储
# 写GeoTiff文件
def Write_Tiff(img_arr, geomatrix, projection,path):
# img_bands, img_height, img_width = img_arr.shape
if 'int8' in img_arr.dtype.name:
= gdal.GDT_Byte
datatype elif 'int16' in img_arr.dtype.name:
= gdal.GDT_UInt16
datatype else:
= gdal.GDT_Float32
datatype
if len(img_arr.shape) == 3:
= img_arr.shape
img_bands, img_height, img_width = gdal.GetDriverByName("GTiff")
driver = driver.Create(path, int(img_width), int(img_height), int(img_bands), datatype)
dataset # print(path, int(img_width), int(img_height), int(img_bands), datatype)
if(dataset!= None) and (geomatrix !='') and (projection!=''):
#写入仿射变换参数
dataset.SetGeoTransform(geomatrix) #写入投影
dataset.SetProjection(projection) for i in range(img_bands):
+1).WriteArray(img_arr[i])
dataset.GetRasterBand(idel dataset
elif len(img_arr.shape) == 2:
# img_arr = np.array([img_arr])
= img_arr.shape
img_height, img_width =1
img_bands#创建文件
= gdal.GetDriverByName("GTiff")
driver = driver.Create(path, int(img_width), int(img_height), int(img_bands), datatype)
dataset # print(path, int(img_width), int(img_height), int(img_bands), datatype)
if(dataset!= None):
#写入仿射变换参数
dataset.SetGeoTransform(geomatrix) #写入投影
dataset.SetProjection(projection) 1).WriteArray(img_arr)
dataset.GetRasterBand(del dataset
def merge_tif(tif_path_list, output_tif):
= []
arr_list for tif_path in tif_path_list:
= read_img(tif_path)
proj, geotrans, data, row, column
arr_list.append(data)= np.array(arr_list)
all_arr
Write_Tiff(all_arr,geotrans,proj,output_tif)
筛选数据
= os.listdir(tif_10m_save_path) # 获取所有10m分辨率tif数据的名称
tif_list = [] # 以列表的形式存储各个波段的路径
tif_path_list
= ["B02","B03","B04","B08","B8A","B11","B12"] # 需要堆叠的波段名
band_names
for band_name in band_names:
for tif_name in tif_list:
if band_name == tif_name[-11:-8]:
+ os.sep + tif_name)
tif_path_list.append(tif_10m_save_path
print(tif_path_list)
['.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B02_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B03_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B04_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B08_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B8A_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B11_10m.tif', '.\\data\\T50TLK_20220825T030519\\10m\\T50TLK_20220825T030519_B12_10m.tif']
# 执行叠加函数
=save_path+img_identifier+os.sep+img_identifier+"_merge.tif"
merge_out merge_tif(tif_path_list, merge_out)
6. 真彩色影像可视化
- 对图像进行拉伸显示
- 转换成0-255的快视图并保存
# 显示叠加结果数据信息
# 归一化函数
def stretch(band, lower_percent=2, higher_percent=98): #2和95表示分位数
=np.array(band,dtype=np.float32)
band= np.percentile(band, lower_percent)*1.0
c = np.percentile(band, higher_percent)*1.0
d <c] = c
band[band>d] = d
band[band= (band - c) / (d - c)
out return out.astype(np.float32)
def stretch_n(data, n_band=3): #该操作讲改变原始数据,因此data用.copy,不对原始数据进行更改
=np.array(data,dtype=np.float32)
datafor k in range(n_band):
= stretch(data[:,:,k])
data[:,:,k] return data
def rgb(img_data,iftran=True):
= img_data[:3,:,:] # 取前三个波段 B02,B03,B04
img_data_3b if iftran:
= img_data_3b[::-1,:,:] # 将B02,B03,B04转成B04,B03,B02 (BGR转RGB)
img_data_3b = img_data_3b.transpose(1,2,0) # C,H,W -> H,W,C
img_data return img_data
= read_img(merge_out)
proj, geotrans, img_data, row, column =rgb(img_data) #提取3波段改变rgb顺序和数据维度
img_data_r= np.uint8(stretch_n(img_data_r.copy())*255) # 数据值域缩放至(0~255)
img_data_rgb_s
=(8,8))
plt.figure(figsize
plt.imshow(Image.fromarray(img_data_rgb_s)) plt.show()
仿射矩阵信息:(300000.0, 10.0, 0.0, 4500000.0, 0.0, -10.0)
投影信息:PROJCS["WGS 84 / UTM zone 50N",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",117],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32650"]]
栅格波段数:7
栅格列数(宽度):10980 栅格行数(高度):10980
=save_path+img_identifier+os.sep+img_identifier+"_quickimg.tif"
quickimg 2,0,1),ds.GetGeoTransform(),ds.GetProjection(),quickimg) Write_Tiff(img_data_rgb_s.transpose(
7. 重投影
如果需要对数据进行投影操作,可以利用gdal.warp实现
= gdal.Open(quickimg) # 打开文件
ds =save_path+img_identifier+os.sep+img_identifier+"_projected.tif"
rojectedtmp = gdal.Warp(rojectedtmp, ds, dstSRS='EPSG:4326') # 有投影的需求可以使用warp命令,epsg可以通过https://epsg.io/查询,这里给出的是wgs84 ds
= read_img(rojectedtmp)
proj, geotrans, img_data, row, column
# 显示重投影结果信息
print(f'仿射矩阵信息:{geotrans}',f'投影信息:{proj}')
print("\n")
= img_data.transpose(1,2,0) # C,H,W -> H,W,C
img_data_ plt.imshow(img_data_)
仿射矩阵信息:(114.63531921298156, 0.00010513256977891853, 0.0, 40.64592849014489, 0.0, -0.00010513256977891853) 投影信息:GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]
<matplotlib.image.AxesImage at 0x16971629430>
8. 数据裁剪
- 利用rasterio库更容易将shp与影像进行叠加显示
- 利用gdal.warp实现数据裁剪
= './data/clippolygon.shp'
clip_shp = gpd.read_file(clip_shp)
vector =rasterio.open(quickimg)
img
= plt.subplots(figsize=(5,5))
fig, ax =rasterio.plot.show(img, ax=ax,title='Sentinel 2 image of Guanting Reservoir')
p1 =ax,edgecolor='red', linewidth=1,facecolor = "none") #如果shp与raster坐标投影不一致无法同时显示
vector.plot(ax plt.show()
按矢量轮廓裁剪
# 执行裁剪
=save_path+img_identifier+os.sep+img_identifier+"_clip.tif"
clip_output # 按矢量轮廓裁剪
= clip_shp, format="GTiff", cropToCutline = True) gdal.Warp(clip_output, merge_out, cutlineDSName
<osgeo.gdal.Dataset; proxy of <Swig Object of type 'GDALDatasetShadow *' at 0x00000169B2690810> >
= read_img(clip_output)
proj, geotrans, img_data, row, column =rgb(img_data)
img_data_ plt.imshow(stretch_n(img_data_.copy()))
<matplotlib.image.AxesImage at 0x16971673eb0>
想了解更多请关注[45度科研人]公众号,欢迎给我留言!