栅格图层¶
关闭栅格数据¶
from osgeo import gdal
ds = gdal.Open('test.tif')
ds = None
获取元数据¶
from osgeo import gdal
gtif = gdal.Open( "merge.tif" )
print (gtif.GetMetadata())
波段融合¶
from osgeo import gdal
ds1=gdal.Open("LM51130321998341HAJ00_B1.TIF")
ds2=gdal.Open("LM51130321998341HAJ00_B2.TIF")
ds3=gdal.Open("LM51130321998341HAJ00_B3.TIF")
ds4=gdal.Open("LM51130321998341HAJ00_B4.TIF")
b1=ds1.GetRasterBand(1)
b2=ds1.GetRasterBand(1)
b3=ds1.GetRasterBand(1)
b4=ds1.GetRasterBand(1)
driver=gdal.GetDriverByName("GTiff")
out_ds=driver.Create('merge.tif',ds1.RasterXSize,ds1.RasterYSize,4,gdal.GDT_Byte)
out_ds.SetGeoTransform(ds1.GetGeoTransform())
out_ds.SetProjection(ds1.GetProjection())
ob1=out_ds.GetRasterBand(1)
ob2=out_ds.GetRasterBand(2)
ob3=out_ds.GetRasterBand(3)
ob4=out_ds.GetRasterBand(4)
ob1.WriteArray(b1.ReadAsArray())
ob2.WriteArray(b2.ReadAsArray())
ob3.WriteArray(b3.ReadAsArray())
ob4.WriteArray(b4.ReadAsArray())
out_ds=None
获取波段¶
from osgeo import gdal
import sys
gdal.UseExceptions()
try:
src_ds = gdal.Open( "merge.tif" )
except RuntimeError as e:
print(e)
sys.exit(1)
try:
srcband = src_ds.GetRasterBand(1)
except RuntimeError as e:
print(e)
sys.exit(1)
遍历波段¶
from osgeo import gdal
import sys
src_ds = gdal.Open( "merge.tif" )
print ("波段个数: ", src_ds.RasterCount)
for band in range( src_ds.RasterCount ):
band += 1
print ("获取波段: ", band)
srcband = src_ds.GetRasterBand(band)
if srcband is None:
continue
stats = srcband.GetStatistics( True, True )
if stats is None:
continue
print ("[ STATS ] = Minimum=%.3f, Maximum=%.3f, Mean=%.3f, StdDev=%.3f" % ( \
stats[0], stats[1], stats[2], stats[3] ))
获取波段信息¶
from osgeo import gdal
import sys
gdal.UseExceptions()
def main( band_num, input_file ):
src_ds = gdal.Open( input_file )
try:
srcband = src_ds.GetRasterBand(band_num)
except RuntimeError as e:
print( e)
sys.exit(1)
print ("[ NO DATA VALUE ] = ", srcband.GetNoDataValue())
print ("[ MIN ] = ", srcband.GetMinimum())
print ("[ MAX ] = ", srcband.GetMaximum())
print ("[ SCALE ] = ", srcband.GetScale())
print( "[ UNIT TYPE ] = ", srcband.GetUnitType())
ctable = srcband.GetColorTable()
if ctable is None:
print ('No ColorTable found')
sys.exit(1)
print ("[ COLOR TABLE COUNT ] = ", ctable.GetCount())
for i in range( 0, ctable.GetCount() ):
entry = ctable.GetColorEntry( i )
if not entry:
continue
print ("[ COLOR ENTRY RGB ] = ", ctable.GetColorEntryAsRGB( i, entry ))
main( 1,"merge.tif" )
多边形化栅格波段¶
from osgeo import gdal, ogr
import sys
gdal.UseExceptions()
src_ds = gdal.Open( "test.tif" )
srcband = src_ds.GetRasterBand(3)
dst_layername = "POLYGONIZED_STUFF"
drv = ogr.GetDriverByName("ESRI Shapefile")
dst_ds = drv.CreateDataSource( dst_layername + ".shp" )
dst_layer = dst_ds.CreateLayer(dst_layername, srs = None )
gdal.Polygonize( srcband, None, dst_layer, -1, [], callback=None )
栅格化矢量数据¶
from osgeo import gdal, ogr
pixel_size = 25
NoData_value = -9999
vector_fn = 'test.shp'
raster_fn = 'test.tif'
source_ds = ogr.Open(vector_fn)
source_layer = source_ds.GetLayer()
x_min, x_max, y_min, y_max = source_layer.GetExtent()
x_res = int((x_max - x_min) / pixel_size)
y_res = int((y_max - y_min) / pixel_size)
target_ds = gdal.GetDriverByName('GTiff').Create(raster_fn, x_res, y_res, 1, gdal.GDT_Byte)
target_ds.SetGeoTransform((x_min, pixel_size, 0, y_max, 0, -pixel_size))
band = target_ds.GetRasterBand(1)
band.SetNoDataValue(NoData_value)
gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[0])
用shapefile裁剪栅格¶
from osgeo import gdal, gdalnumeric, ogr, osr
from PIL import Image, ImageDraw
import os, sys
gdal.UseExceptions()
def imageToArray(i):
"""
Image转换为数组.
"""
a=gdalnumeric.fromstring(i.tostring(),'b')
a.shape=i.im.size[1], i.im.size[0]
return a
def arrayToImage(a):
"""
数组转换为Image.
"""
i=Image.fromstring('L',(a.shape[1],a.shape[0]),
(a.astype('b')).tostring())
return i
def world2Pixel(geoMatrix, x, y):
"""
用地理仿射变换计算像素坐标
"""
ulX = geoMatrix[0]
ulY = geoMatrix[3]
xDist = geoMatrix[1]
yDist = geoMatrix[5]
rtnX = geoMatrix[2]
rtnY = geoMatrix[4]
pixel = int((x - ulX) / xDist)
line = int((ulY - y) / xDist)
return (pixel, line)
def OpenArray( array, prototype_ds = None, xoff=0, yoff=0 ):
ds = gdal.Open( gdalnumeric.GetArrayFilename(array) )
if ds is not None and prototype_ds is not None:
if type(prototype_ds).__name__ == 'str':
prototype_ds = gdal.Open( prototype_ds )
if prototype_ds is not None:
gdalnumeric.CopyDatasetInfo( prototype_ds, ds, xoff=xoff, yoff=yoff )
return ds
def histogram(a, bins=range(0,256)):
"""
Histogram function for multi-dimensional array.
a = array
bins = range of numbers to match
"""
fa = a.flat
n = gdalnumeric.searchsorted(gdalnumeric.sort(fa), bins)
n = gdalnumeric.concatenate([n, [len(fa)]])
hist = n[1:]-n[:-1]
return hist
def stretch(a):
"""
Performs a histogram stretch on a gdalnumeric array image.
"""
hist = histogram(a)
im = arrayToImage(a)
lut = []
for b in range(0, len(hist), 256):
step = reduce(operator.add, hist[b:b+256]) / 255
n = 0
for i in range(256):
lut.append(n / step)
n = n + hist[i+b]
im = im.point(lut)
return imageToArray(im)
def main( shapefile_path, raster_path ):
srcArray = gdalnumeric.LoadFile(raster_path)
srcImage = gdal.Open(raster_path)
geoTrans = srcImage.GetGeoTransform()
shapef = ogr.Open(shapefile_path)
lyr = shapef.GetLayer( os.path.split( os.path.splitext( shapefile_path )[0] )[1] )
poly = lyr.GetNextFeature()
minX, maxX, minY, maxY = lyr.GetExtent()
ulX, ulY = world2Pixel(geoTrans, minX, maxY)
lrX, lrY = world2Pixel(geoTrans, maxX, minY)
pxWidth = int(lrX - ulX)
pxHeight = int(lrY - ulY)
clip = srcArray[:, ulY:lrY, ulX:lrX]
xoffset = ulX
yoffset = ulY
print ("Xoffset, Yoffset = ( %f, %f )" % ( xoffset, yoffset ))
geoTrans = list(geoTrans)
geoTrans[0] = minX
geoTrans[3] = maxY
points = []
pixels = []
geom = poly.GetGeometryRef()
pts = geom.GetGeometryRef(0)
for p in range(pts.GetPointCount()):
points.append((pts.GetX(p), pts.GetY(p)))
for p in points:
pixels.append(world2Pixel(geoTrans, p[0], p[1]))
rasterPoly = Image.new("L", (pxWidth, pxHeight), 1)
rasterize = ImageDraw.Draw(rasterPoly)
rasterize.polygon(pixels, 0)
mask = imageToArray(rasterPoly)
clip = gdalnumeric.choose(mask, \
(clip, 0)).astype(gdalnumeric.uint8)
for i in range(3):
clip[i,:,:] = stretch(clip[i,:,:])
gtiffDriver = gdal.GetDriverByName( 'GTiff' )
if gtiffDriver is None:
raise ValueError("Can't find GeoTiff Driver")
gtiffDriver.CreateCopy( "OUTPUT.tif",
OpenArray( clip, prototype_ds=raster_path, xoff=xoffset, yoff=yoffset )
)
clip = clip.astype(gdalnumeric.uint8)
gdalnumeric.SaveArray(clip, "OUTPUT.jpg", format="JPEG")
gdal.ErrorReset()
if __name__ == '__main__':
if len( sys.argv ) < 2:
print "[ ERROR ] you must two args. 1) the full shapefile path and 2) the full raster path"
sys.exit( 1 )
main( sys.argv[1], sys.argv[2] )
区域统计¶
import gdal, ogr, osr, numpy
import sys
def zonal_stats(feat, input_zone_polygon, input_value_raster):
raster = gdal.Open(input_value_raster)
shp = ogr.Open(input_zone_polygon)
lyr = shp.GetLayer()
transform = raster.GetGeoTransform()
xOrigin = transform[0]
yOrigin = transform[3]
pixelWidth = transform[1]
pixelHeight = transform[5]
sourceSR = lyr.GetSpatialRef()
targetSR = osr.SpatialReference()
targetSR.ImportFromWkt(raster.GetProjectionRef())
coordTrans = osr.CoordinateTransformation(sourceSR,targetSR)
feat = lyr.GetNextFeature()
geom = feat.GetGeometryRef()
geom.Transform(coordTrans)
geom = feat.GetGeometryRef()
if (geom.GetGeometryName() == 'MULTIPOLYGON'):
count = 0
pointsX = []
for polygon in geom:
geomInner = geom.GetGeometryRef(count)
ring = geomInner.GetGeometryRef(0)
numpoints = ring.GetPointCount()
for p in range(numpoints):
lon, lat, z = ring.GetPoint(p)
pointsX.append(lon)
pointsY.append(lat)
count += 1
elif (geom.GetGeometryName() == 'POLYGON'):
ring = geom.GetGeometryRef(0)
numpoints = ring.GetPointCount()
pointsX = []
for p in range(numpoints):
lon, lat, z = ring.GetPoint(p)
pointsX.append(lon)
pointsY.append(lat)
else:
sys.exit("ERROR: Geometry needs to be either Polygon or Multipolygon")
xmin = min(pointsX)
xmax = max(pointsX)
ymin = min(pointsY)
ymax = max(pointsY)
xoff = int((xmin - xOrigin)/pixelWidth)
yoff = int((yOrigin - ymax)/pixelWidth)
xcount = int((xmax - xmin)/pixelWidth)+1
ycount = int((ymax - ymin)/pixelWidth)+1
target_ds = gdal.GetDriverByName('MEM').Create('', xcount, ycount, 1, gdal.GDT_Byte)
target_ds.SetGeoTransform((
xmin, pixelWidth, 0,
ymax, 0, pixelHeight,
))
raster_srs = osr.SpatialReference()
raster_srs.ImportFromWkt(raster.GetProjectionRef())
target_ds.SetProjection(raster_srs.ExportToWkt())
gdal.RasterizeLayer(target_ds, [1], lyr, burn_values=[1])
banddataraster = raster.GetRasterBand(1)
dataraster = banddataraster.ReadAsArray(xoff, yoff, xcount, ycount).astype(numpy.float)
bandmask = target_ds.GetRasterBand(1)
datamask = bandmask.ReadAsArray(0, 0, xcount, ycount).astype(numpy.float)
zoneraster = numpy.ma.masked_array(dataraster, numpy.logical_not(datamask))
return numpy.average(zoneraster),numpy.mean(zoneraster),numpy.median(zoneraster),numpy.std(zoneraster),numpy.var(zoneraster)
def loop_zonal_stats(input_zone_polygon, input_value_raster):
shp = ogr.Open(input_zone_polygon)
lyr = shp.GetLayer()
featList = range(lyr.GetFeatureCount())
statDict = {}
for FID in featList:
feat = lyr.GetFeature(FID)
meanValue = zonal_stats(feat, input_zone_polygon, input_value_raster)
statDict[FID] = meanValue
return statDict
def main(input_zone_polygon, input_value_raster):
return loop_zonal_stats(input_zone_polygon, input_value_raster)
if __name__ == "__main__":
if len( sys.argv ) != 3:
print "[ ERROR ] you must supply two arguments: input-zone-shapefile-name.shp input-value-raster-name.tif "
sys.exit( 1 )
print 'Returns for each feature a dictionary item (FID) with the statistical values in the following order: Average, Mean, Medain, Standard Deviation, Variance'
print main( sys.argv[1], sys.argv[2] )
从数组创建栅格¶
import gdal, ogr, os, osr
import numpy as np
def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
cols = array.shape[1]
rows = array.shape[0]
originX = rasterOrigin[0]
originY = rasterOrigin[1]
driver = gdal.GetDriverByName('GTiff')
outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Byte)
outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
outband = outRaster.GetRasterBand(1)
outband.WriteArray(array)
outRasterSRS = osr.SpatialReference()
outRasterSRS.ImportFromEPSG(4326)
outRaster.SetProjection(outRasterSRS.ExportToWkt())
outband.FlushCache()
def main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
reversed_arr = array[::-1]
array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,reversed_arr)
if __name__ == "__main__":
rasterOrigin = (-123.25745,45.43013)
pixelWidth = 10
pixelHeight = 10
newRasterfn = 'test.tif'
array = np.array([[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
[ 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
[ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array)
替换无效值¶
import gdal, ogr, osr, os
import numpy as np
def raster2array(rasterfn):
raster = gdal.Open(rasterfn)
band = raster.GetRasterBand(1)
return band.ReadAsArray()
def getNoDataValue(rasterfn):
raster = gdal.Open(rasterfn)
band = raster.GetRasterBand(1)
return band.GetNoDataValue()
def array2raster(rasterfn,newRasterfn,array):
raster = gdal.Open(rasterfn)
geotransform = raster.GetGeoTransform()
originX = geotransform[0]
originY = geotransform[3]
pixelWidth = geotransform[1]
pixelHeight = geotransform[5]
cols = raster.RasterXSize
rows = raster.RasterYSize
driver = gdal.GetDriverByName('GTiff')
outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Float32)
outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
outband = outRaster.GetRasterBand(1)
outband.WriteArray(array)
outRasterSRS = osr.SpatialReference()
outRasterSRS.ImportFromWkt(raster.GetProjectionRef())
outRaster.SetProjection(outRasterSRS.ExportToWkt())
outband.FlushCache()
rasterfn = 'test.tif'
newValue = 0
newRasterfn = 'testNew.tif'
rasterArray = raster2array(rasterfn)
noDataValue = getNoDataValue(rasterfn)
rasterArray[rasterArray == noDataValue] = newValue
array2raster(rasterfn,newRasterfn,rasterArray)