fromosgeoimportgdalimportsysgdal.UseExceptions()defmain(band_num,input_file):src_ds=gdal.Open(input_file)try:srcband=src_ds.GetRasterBand(band_num)exceptRuntimeErrorase: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()ifctableisNone:print('No ColorTable found')sys.exit(1)print("[ COLOR TABLE COUNT ] = ",ctable.GetCount())foriinrange(0,ctable.GetCount()):entry=ctable.GetColorEntry(i)ifnotentry:continueprint("[ COLOR ENTRY RGB ] = ",ctable.GetColorEntryAsRGB(i,entry))main(1,"merge.tif")
fromosgeoimportgdal,gdalnumeric,ogr,osrfromPILimportImage,ImageDrawimportos,sysgdal.UseExceptions()defimageToArray(i):""" Image转换为数组. """a=gdalnumeric.fromstring(i.tostring(),'b')a.shape=i.im.size[1],i.im.size[0]returnadefarrayToImage(a):""" 数组转换为Image. """i=Image.fromstring('L',(a.shape[1],a.shape[0]),(a.astype('b')).tostring())returnidefworld2Pixel(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)## EDIT: this is basically an overloaded# version of the gdal_array.OpenArray passing in xoff, yoff explicitly# so we can pass these params off to CopyDatasetInfo#defOpenArray(array,prototype_ds=None,xoff=0,yoff=0):ds=gdal.Open(gdalnumeric.GetArrayFilename(array))ifdsisnotNoneandprototype_dsisnotNone:iftype(prototype_ds).__name__=='str':prototype_ds=gdal.Open(prototype_ds)ifprototype_dsisnotNone:gdalnumeric.CopyDatasetInfo(prototype_ds,ds,xoff=xoff,yoff=yoff)returndsdefhistogram(a,bins=range(0,256)):""" Histogram function for multi-dimensional array. a = array bins = range of numbers to match """fa=a.flatn=gdalnumeric.searchsorted(gdalnumeric.sort(fa),bins)n=gdalnumeric.concatenate([n,[len(fa)]])hist=n[1:]-n[:-1]returnhistdefstretch(a):""" Performs a histogram stretch on a gdalnumeric array image. """hist=histogram(a)im=arrayToImage(a)lut=[]forbinrange(0,len(hist),256):# step sizestep=reduce(operator.add,hist[b:b+256])/255# create equalization lookup tablen=0foriinrange(256):lut.append(n/step)n=n+hist[i+b]im=im.point(lut)returnimageToArray(im)defmain(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=ulXyoffset=ulYprint("Xoffset, Yoffset = ( %f, %f )"%(xoffset,yoffset))# 创建新的仿射变换geoTrans=list(geoTrans)geoTrans[0]=minXgeoTrans[3]=maxY# Map points to pixels for drawing the# boundary on a blank 8-bit,# black and white, mask image.points=[]pixels=[]geom=poly.GetGeometryRef()pts=geom.GetGeometryRef(0)forpinrange(pts.GetPointCount()):points.append((pts.GetX(p),pts.GetY(p)))forpinpoints: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 the image using the maskclip=gdalnumeric.choose(mask, \
(clip,0)).astype(gdalnumeric.uint8)# This image has 3 bands so we stretch each one to make them# visually brighterforiinrange(3):clip[i,:,:]=stretch(clip[i,:,:])# Save new tiff## EDIT: instead of SaveArray, let's break all the# SaveArray steps out more explicity so# we can overwrite the offset of the destination# raster#### the old way using SaveArray## gdalnumeric.SaveArray(clip, "OUTPUT.tif", format="GTiff", prototype=raster_path)#####gtiffDriver=gdal.GetDriverByName('GTiff')ifgtiffDriverisNone:raiseValueError("Can't find GeoTiff Driver")gtiffDriver.CreateCopy("OUTPUT.tif",OpenArray(clip,prototype_ds=raster_path,xoff=xoffset,yoff=yoffset))# Save as an 8-bit jpeg for an easy, quick previewclip=clip.astype(gdalnumeric.uint8)gdalnumeric.SaveArray(clip,"OUTPUT.jpg",format="JPEG")gdal.ErrorReset()if__name__=='__main__':## example run : $ python clip.py /<full-path>/<shapefile-name>.shp /<full-path>/<raster-name>.tif#iflen(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])
importgdal,ogr,osr,numpyimportsysdefzonal_stats(feat,input_zone_polygon,input_value_raster):# Open dataraster=gdal.Open(input_value_raster)shp=ogr.Open(input_zone_polygon)lyr=shp.GetLayer()# Get raster georeference infotransform=raster.GetGeoTransform()xOrigin=transform[0]yOrigin=transform[3]pixelWidth=transform[1]pixelHeight=transform[5]# Reproject vector geometry to same projection as rastersourceSR=lyr.GetSpatialRef()targetSR=osr.SpatialReference()targetSR.ImportFromWkt(raster.GetProjectionRef())coordTrans=osr.CoordinateTransformation(sourceSR,targetSR)feat=lyr.GetNextFeature()geom=feat.GetGeometryRef()geom.Transform(coordTrans)# Get extent of featgeom=feat.GetGeometryRef()if(geom.GetGeometryName()=='MULTIPOLYGON'):count=0pointsX=[];pointsY=[]forpolygoningeom:geomInner=geom.GetGeometryRef(count)ring=geomInner.GetGeometryRef(0)numpoints=ring.GetPointCount()forpinrange(numpoints):lon,lat,z=ring.GetPoint(p)pointsX.append(lon)pointsY.append(lat)count+=1elif(geom.GetGeometryName()=='POLYGON'):ring=geom.GetGeometryRef(0)numpoints=ring.GetPointCount()pointsX=[];pointsY=[]forpinrange(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)# Specify offset and rows and columns to readxoff=int((xmin-xOrigin)/pixelWidth)yoff=int((yOrigin-ymax)/pixelWidth)xcount=int((xmax-xmin)/pixelWidth)+1ycount=int((ymax-ymin)/pixelWidth)+1# Create memory target rastertarget_ds=gdal.GetDriverByName('MEM').Create('',xcount,ycount,1,gdal.GDT_Byte)target_ds.SetGeoTransform((xmin,pixelWidth,0,ymax,0,pixelHeight,))# Create for target raster the same projection as for the value rasterraster_srs=osr.SpatialReference()raster_srs.ImportFromWkt(raster.GetProjectionRef())target_ds.SetProjection(raster_srs.ExportToWkt())# Rasterize zone polygon to rastergdal.RasterizeLayer(target_ds,[1],lyr,burn_values=[1])# Read raster as arraysbanddataraster=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)# Mask zone of rasterzoneraster=numpy.ma.masked_array(dataraster,numpy.logical_not(datamask))# Calculate statistics of zonal rasterreturnnumpy.average(zoneraster),numpy.mean(zoneraster),numpy.median(zoneraster),numpy.std(zoneraster),numpy.var(zoneraster)defloop_zonal_stats(input_zone_polygon,input_value_raster):shp=ogr.Open(input_zone_polygon)lyr=shp.GetLayer()featList=range(lyr.GetFeatureCount())statDict={}forFIDinfeatList:feat=lyr.GetFeature(FID)meanValue=zonal_stats(feat,input_zone_polygon,input_value_raster)statDict[FID]=meanValuereturnstatDictdefmain(input_zone_polygon,input_value_raster):returnloop_zonal_stats(input_zone_polygon,input_value_raster)if__name__=="__main__":## Returns for each feature a dictionary item (FID) with the statistical values in the following order: Average, Mean, Medain, Standard Deviation, Variance## example run : $ python grid.py <full-path><output-shapefile-name>.shp xmin xmax ymin ymax gridHeight gridWidth#iflen(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'printmain(sys.argv[1],sys.argv[2])