Fork me on GitHub

GDAL笔记--chapter10

1.为栅格数据添加地面控制点

 

import shutil
from osgeo import gdal
orig_fn = r''
shutil.copy(orig_fn, fn)   #因为要更新,所以需要对文件做个备份
ds = gdal.Open(fn, gdal.GA_Update)
sr = osr.SpatialReference()
sr = osr.SetWellKnownGeogCS('WGS84')  #WGS84基准
gcps = [gdal.GCP(-111.93, 41.74, 0, 1078, 648),
        gdal.GCP(-111.90, 41.75, 0, 3531, 295)]

ds.SetGCPS(gcps, sr.ExportToWkt())  #将地面控制点附加到数据集
ds = None

#如果要使用一阶变换来创建地理变换,将地面控制点列表传递给GCPsToGeotransform,确保在数据集上设置了地理变换和投影信息
ds.SetProjection(sr.ExportToWkt())
ds.SetGeoTransform(gdal.GCPsToGeotransform(gcps)) #从地面控制点中创建地理变换,并设置在数据集上

 

2.栅格图像镶嵌

def get_extent(fn):
    ds = gdal.Open(fn)
    gt = ds.GetGeoTransform()
    return (gt[0], gt[3], gt[0]+gt[1]*ds.RasterXSize,
            gt[3]+gt[5]*ds.GetRasterYsize)

#将多幅影像镶嵌在一起
#Transform类可以帮助在真实世界坐标和图像坐标之间转换
#还可以在两个不同的栅格之间进行像素偏移
import os
import glob
import math
os.chdir(r'')
in_files = glob.glob('o*.tif')
min_x, max_y, max_x, min_y = get_extent(in_files[0])
for fn in in_files[1:]:
    minx, maxy, maxx, miny = get_extent(fn)
    min_x = min(min_x, minx)
    max_y = max(max_y, maxy)
    max_x = max(max_x, maxx)
    min_y = min(min_y, miny)

in_ds = gdal.Open(in_files[0])
gt = in_ds.GetGeoTransform()  #这里每幅图的分辨率都是一样的
rows = math.ceil((max_y-min_y)/-gt[5]) #计算镶嵌后的行列数
columns = math.ceil((max_x-min_x)/gt[1])

driver = gdal.GetDriverByName('gtiff')
out_ds = driver.Create('mosaic.tif', columns, rows)
out_ds.SetProjection(in_ds.GetProjection())
out_band = out_ds.GetRasterBand(1)

gt = list(in_ds.GetGeoTransform())
gt[0], gt[3] = min_x, max_y  #设置新的起始点坐标
out_ds.SetGeoTransform(gt)

for fn in  in_files:
    in_ds = gdal.Open(fn)
    trans = gdal.Transformer(in_ds, out_ds, []) #第三个参数设置转换器选项,这里不需要
    #False表示计算从源栅格到目标栅格的偏移
    success, xyz = trans.TransformPoint(False, 0, 0)  #这里转换的是图像的左上角行列号坐标,大图将会从x,y处开始读取数据,所以输入应该是(0,0)
    x, y, z = map(int, xyz)
    data = in_ds.GetRasterBand(1).ReadAsArray()
    out_band.WriteArray(data, x, y)

del in_ds, out_band, out_ds

#将图像坐标转换成现实世界坐标,这里out_ds是输入吧?
trans = gdal.Transformer(out_ds, None, [])
success, xyz = trans.TransformPoint(0, 1078, 648)

3.为栅格数据添加颜色映射

#为栅格数据添加颜色映射
import os
from osgeo import gdal
os.chdir('E:\桌面文件保存路径\gdal\osgeopy-data\osgeopy-data\Switzerland')
original_ds = gdal.Open('dem_class.tif')
driver = gdal.GetDriverByName('gtiff')
ds = driver.CreateCopy('dem_class2.tif', original_ds)
#备份文件
band = ds.GetRasterBand(1)
colors = gdal.ColorTable()
colors.SetColorEntry(1, (112, 153, 89))  #第一个参数是value,第二个是RGB分量
colors.SetColorEntry(2, (242, 238, 162))
colors.SetColorEntry(3, (242, 206, 133))
colors.SetColorEntry(4, (194, 140, 124))
colors.SetColorEntry(5, (214, 193, 156))

band.SetRasterColorTable(colors) 
#把颜色映射添加到波段
band.SetRasterColorInterpretation(gdal.FCI_PaletteIndex)
#将颜色解译为调色板
del band, ds

#颜色表的更改
ds = gdal.Open('')
band = ds.GetRasterBand(1)
colors = band.GetRasterColorTable()  #获取颜色表
colors.SetColorEntry(5, (250, 250, 250))  #更改颜色
band.SetRasterColorTable(colors)  #添加到颜色表
del band, ds


#alpha代表不透明度,在创建时需要指定第二个波段是一个alpha波段
#第一个波段存储像素值,第二个是透明度
ds = driver.Create('dem_class4.tif', original_ds.RasterXSize, 
                    original_ds.RasterYSize, 2 , gdal.GDT_Byte, ['ALPHA=YES'])
#像素为5透明度65,其余为255,写入band2,最后解译透明度波段
import numpy as np
data = band1.ReadAsArray()
data = np.where(data==5, 65, 255)
band2.WriteAsArray(data)
band2.SetRasterColorInterpretation(gdal.GCI_AlphaBand)

4.GetHistogram函数

 

import os
from osgeo import gdal
os.chdir('E:\桌面文件保存路径\gdal\osgeopy-data\osgeopy-data\Switzerland')
ds = gdal.Open('dem_class2.tif')
band = ds.GetRasterBand(1)
approximate_hist = band.GetHistogram()
exact_hist = band.GetHistogram(approx_ok=False)
print('Approximate:', approximate_hist[:7], sum(approximate_hist))
print('Exact:', exact_hist[:7], sum(exact_hist))

hist = band.GetHistogtam(0.5, 6.5, 3, approx_ok=False)
band.SetDefaultHistogram(1, 6, hist)  #用最小像素值、最大像素值和计数列表设置默认直方图
min_val, max_val, n, hist = band.GetDefaultHistogram() #返回最小像素、最大像素、组距数、一个计数列表的元组
print(hist)

 

5.为栅格数据添加属性表

 

#为栅格数据添加属性表
os.chdir('')
ds = gdal.Open('dem_class2.tif')
band = ds.GetRasterBand(1)
band.SetNoDataValue(-1)  #不存在的值设置为nodata

rat = gdal.RasterAttributeTable()   #创建属性表
rat.CreateColumn(                  #创建列
    'Value', gdal.GFT_Integer, gdal.GFU_Name     #表示含像素值的列
)
rat.CreateColumn(
    'Count', gdal.GFT_Integer, gdal.GFU_PixelCount  #表示直方图计数
)
rat.CreateColumn(
    'Elevation', gdal.GFT_String, gdal.GFU_Generic  #表示描述信息
)
rat.SetRowCount(6)   #创建行

rat.WriteArray(range(6), 0)   #第一列,012345
rat.WriteArray(band.GetHistogram(-0.5, 5.5, 6, False, False), 1)  #第二列,直方图计数Count
rat.SetValueAsString(1, 2, '0-800')   #第三列elevation
rat.SetValueAsString(2, 2, '800-1300')
rat.SetValueAsString(3, 2, '1300-2000')
rat.SetValueAsString(4, 2, '2000-2600')
rat.SetValueAsString(5, 2, '2600+')

band.SetDefaultRAT(rat)  #添加属性表到波段
band.SetNoDataValue(0)  #恢复nodata
del band, ds

 

6.使用xml定义有一个波段的VRT数据集

 

<VRTDataset rasterXSize='8849' rasterYSize='8023'>
    <SRS>
        PROJCS['WGS 84 /UTM zone 10N', GEOGCS['WGS 84',DATUM['WGS_1984'...]
    </SRS>
    <GeoTransform>343724.25,28.5,0,5369585.25,0,-28.5</Geotransform>
    <VRTRasterBand dataType='Byte' band='1'>
        <SimpleSource>
            <SourceFileName relativeToVRT='1'>
                nat_color.tif
            </SourceFilename>
            <SourceBand3>3</SourceBand>
            <SourceProperties RasterXSize='8849' RasterYSize='8023'
                DataType='Byte' BlockXSize='8849' BlockYSize='1'/>
        </SimpleSource>
    </VRTRasterBand>
</VRTDataset>

 

7.VRT创建

#VRT
from osgeo import gdal
import os
os.chdir('')
tmp_ds = gdal.Open('')
driver = gdal.GetDriverByName('vrt')
ds = driver.Create('nat_color.vrt', tmp_ds.RasterXSize, tmp_ds.RasterYSize, 3)
ds.SetProjection(tmp_ds.GetProjection())
ds.SetGeoTransform(tmp_ds.GetGeoTransform())

#将链接添加到栅格。创建键值source_0,包含文件名的xml字符串
metadata = {'source_0':xml.format('....tif')}
ds.GetRasterBand(1).SetMetadata(metadata, 'vrt_sources')

metadata = {'source_0':xml.format('....tif')}
ds.GetRasterBand(2).SetMetadata(metadata, 'vrt_sources')

metadata = {'source_0':xml.format('....tif')}
ds.GetRasterBand(3).SetMetadata(metadata, 'vrt_sources')

8.VRT裁剪影像

#VRT影像裁剪
import os
from osgeo import gdal

os.chdir('')
tmp_ds = gdal.Open('')
tmp_gt = tmp_ds.GetGeoTransform()
inv_gt = gdal.InvGeoTransform(tmp_gt)
if gdal.VersionInfo()[0]=='1':
    if inv_gt[0]==1:
        inv_gt = inv_gt[1]
    else:
        raise RuntimeError('Inverse geotransform failed')
elif inv_gt is None:
    raise RuntimeError('failed')

vashon_ul = (532000, 5262600)
vashon_lr = (548500, 5241500)
ulx, uly = map(int, gdal.ApplyGeoTransform(inv_gt, *vashon_ul))   #计算裁剪部分左上角图像坐标
lrx, lry = map(int, gdal.ApplyGeoTransform(inv_gt, *vashon_lr))   #裁剪部分右下角
rows = lry - uly
columns = lrx - ulx
gt = list(tmp_gt)
gt[0] += gt[1]*ulx  #原gt[0]是原图的左上角,计算后为裁剪的左上角
gt[3] += gt[5]*uly  #裁剪的右下角

ds = gdal.GetDriverByName('vrt').Create('vashon.vrt', columns, rows, 3)
ds.SetProjection(tmp_ds.GetProjection())
ds.SetGeoTransform(tmp_ds.GetGeoTransform())  #地理变换为裁剪对象的地理变换

xml=''             #描述波段的xml文件
<SimpleSource>
    <SourceFilename relativeToVRT='1'>{fn}</SourceFilename>
    <SourceBand>{band}</SourceBand>
    <SrcRect xOff='{xoff}' yOff='{yoff}'
            xSize='{cols}' ySize='{rows}'/>
    <DstRect xOff='0' yOff='0'
            xSize='{cols}' ySize='{rows}'/>
</SimpleSource>

data = {'fn':'nat_color.tif', 'band':1,   #将数据插入到xml文件
        'xoff':ulx, 'yoff':uly,
        'cols':columns, 'rows':rows}

meta = {'source_0': xml.format(**data)}   #波段1插入到VRT
ds.GetRasterBand(1).SetMetadata(meta, 'vrt_sources')

data['band'] = 2
meta = {'source_0': xml.format(**data)}
ds.GetRasterBand(2).SetMetadata(meta, 'vrt_sources')

data['band'] = 3
meta = {'source_0': xml.format(**data)}
ds.GetRasterBand(3).data(meta, 'vrt_sources')

del ds, tmp_ds

9.创建问题格式

#创建问题格式
ds = gdal.Open('vashon.vrt')
gdal.GetDriverByName('jpeg').CreateCopy('vashon.jpg', ds)

10.栅格数据重投影

#栅格数据的像元易弯曲和移动,通常使用最近领域插值法、双线性插值和三次卷积插值
#方法1.gdalwarp 2.AutoCreateWarpedVRT
srs = osr.SpatialReference()
srs.SetWellKnownGeogCS('WGS84')
#目标srs是WGS84基准的地理坐标系,即未投影。将把UTM投影转换为地理坐标系
old_ds = gdal.Open('nat_color.tif')
vrt_ds = gdal.AutoCreateWarpedVRT(old_ds, None, srs.ExportToWkt(),
    gdal.GRA_Bilinear)
#没有在磁盘上创建VRT文件,而是返回一个数据集对象,可以用CreateCopy保存为其他格式
gdal.GetDriverByName('gtiff').CreateCopy('nat_color_wgs84.tif', vrt_ds)

11.回调函数

import sys
def my_progress(complete, message, progressArg=0.02):
    if not hasattr(my_progress, 'last_progress'):
        sys.stdout.write(message)
        my_progress.last_progress=0
    if complete >= 1:
        sys.stdout.write('done/n')
        del my_progress.last_progress
    else:
        progress = divmod(complete, progressArg)[0]
        while my_progress.last_progress < progress:
            sys.stdout.write('.')
            sys.stdout.flush()
            my_progress.last_progress += 1

 

 

 

 

 

 

posted @ 2020-04-01 21:51  Rser_ljw  阅读(1348)  评论(0编辑  收藏  举报