在Python中用GDAL实现矢量对栅格的切割实例


Posted in Python onMarch 11, 2020

概述:

本文讲述如何在Python中用GDAL实现根据输入矢量边界对栅格数据的裁剪。

效果:

在Python中用GDAL实现矢量对栅格的切割实例

裁剪前

在Python中用GDAL实现矢量对栅格的切割实例

矢量边界

在Python中用GDAL实现矢量对栅格的切割实例

裁剪后

实现代码:

# -*- coding: utf-8 -*-
"""
@author lzugis
@date 2017-06-02
@brief 利用shp裁剪影像
"""
 
from osgeo import gdal, gdalnumeric, ogr
from PIL import Image, ImageDraw
import os
import operator
 
gdal.UseExceptions()
 
# This function will convert the rasterized clipper shapefile
# to a mask for use within GDAL.
def imageToArray(i):
 """
 Converts a Python Imaging Library array to a
 gdalnumeric image.
 """
 a=gdalnumeric.fromstring(i.tobytes(),'b')
 a.shape=i.im.size[1], i.im.size[0]
 return a
 
def arrayToImage(a):
 """
 Converts a gdalnumeric array to a
 Python Imaging Library Image.
 """
 i=Image.frombytes('L',(a.shape[1],a.shape[0]),
   (a.astype('b')).tobytes())
 return i
 
def world2Pixel(geoMatrix, x, y):
 """
 Uses a gdal geomatrix (gdal.GetGeoTransform()) to calculate
 the pixel location of a geospatial coordinate
 """
 ulX = geoMatrix[0]
 ulY = geoMatrix[3]
 xDist = geoMatrix[1]
 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
#
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 size
  step = reduce(operator.add, hist[b:b+256]) / 255
  # create equalization lookup table
  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 ):
 # Load the source data as a gdalnumeric array
 srcArray = gdalnumeric.LoadFile(raster_path)
 
 # Also load as a gdal image to get geotransform
 # (world file) info
 srcImage = gdal.Open(raster_path)
 geoTrans = srcImage.GetGeoTransform()
 
 # Create an OGR layer from a boundary shapefile
 shapef = ogr.Open(shapefile_path)
 lyr = shapef.GetLayer( os.path.split( os.path.splitext( shapefile_path )[0] )[1] )
 poly = lyr.GetNextFeature()
 
 # Convert the layer extent to image pixel coordinates
 minX, maxX, minY, maxY = lyr.GetExtent()
 ulX, ulY = world2Pixel(geoTrans, minX, maxY)
 lrX, lrY = world2Pixel(geoTrans, maxX, minY)
 
 # Calculate the pixel size of the new image
 pxWidth = int(lrX - ulX)
 pxHeight = int(lrY - ulY)
 
 clip = srcArray[:, ulY:lrY, ulX:lrX]
 
 #
 # EDIT: create pixel offset to pass to new image Projection info
 #
 xoffset = ulX
 yoffset = ulY
 print "Xoffset, Yoffset = ( %f, %f )" % ( xoffset, yoffset )
 
 # Create a new geomatrix for the image
 geoTrans = list(geoTrans)
 geoTrans[0] = minX
 geoTrans[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)
 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 the image using the mask
 clip = gdalnumeric.choose(mask, \
  (clip, 0)).astype(gdalnumeric.uint8)
 
 # This image has 3 bands so we stretch each one to make them
 # visually brighter
 for i in range(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' )
 if gtiffDriver is None:
  raise ValueError("Can't find GeoTiff Driver")
 gtiffDriver.CreateCopy( "beijing.tif",
  OpenArray( clip, prototype_ds=raster_path, xoff=xoffset, yoff=yoffset )
 )
 
 # Save as an 8-bit jpeg for an easy, quick preview
 clip = clip.astype(gdalnumeric.uint8)
 gdalnumeric.SaveArray(clip, "beijing.jpg", format="JPEG")
 
 gdal.ErrorReset()
 
 
if __name__ == '__main__':
 #shapefile_path, raster_path
 shapefile_path = 'beijing.shp'
 raster_path = 'world.tif'
 main( shapefile_path, raster_path )

补充知识:Python+GDAL | 读取矢量并写出txt

这篇文章主要描述了如何使用GDAL/OGR打开矢量文件、读取属性表,并将部分属性写出至txt。

代码

import ogr,sys,os
import numpy as np

os.chdir(r'E:\')

#设置driver,并打开矢量文件
driver = ogr.GetDriverByName('ESRI Shapefile')
ds = driver.Open('sites.shp', 0)
if ds is None:
  print("Could not open", 'sites.shp')
  sys.exit(1)
#获取图册
layer = ds.GetLayer()

#要素数量
numFeatures = layer.GetFeatureCount()
print("Feature count: "+str(numFeatures))

#获取范围
extent = layer.GetExtent()
print("Extent:", extent)
print("UL:", extent[0],extent[3])
print("LR:", extent[1],extent[2])

#获取要素
feature = layer.GetNextFeature()
ids = []
xs = []
ys = []
covers = []
#循环每个要素属性
while feature:
  #获取字段“id”的属性
  id = feature.GetField('id')
  #获取空间属性
  geometry = feature.GetGeometryRef()
  x = geometry.GetX()
  y = geometry.GetY()
  cover = feature.GetField('cover')
  ids.append(id)
  xs.append(x)
  ys.append(y)
  covers.append(cover)
  feature = layer.GetNextFeature()

data = [ids, xs, ys, covers]
data = np.array(data)
data = data.transpose()

#写出致txt
np.savetxt('myfile.txt',data, fmt='%s %s %s %s')
np.savetxt('myfile.csv',data, fmt='%s %s %s %s')

#释放文件空间
layer.ResetReading()
feature.Destroy()
ds.Destroy()

以上这篇在Python中用GDAL实现矢量对栅格的切割实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享
Jul 09 Python
Python中用pycurl监控http响应时间脚本分享
Feb 02 Python
Python使用cx_Freeze库生成msi格式安装文件的方法
Jul 10 Python
使用sklearn之LabelEncoder将Label标准化的方法
Jul 11 Python
用Python逐行分析文件方法
Jan 28 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
May 13 Python
python实现比对美团接口返回数据和本地mongo数据是否一致示例
Aug 09 Python
Python3变量与基本数据类型用法实例分析
Feb 14 Python
python 实现读取csv数据,分类求和 再写进 csv
May 18 Python
什么是python的列表推导式
May 26 Python
五分钟带你搞懂python 迭代器与生成器
Aug 30 Python
FP-growth算法发现频繁项集——发现频繁项集
Jun 24 Python
将 Ubuntu 16 和 18 上的 python 升级到最新 python3.8 的方法教程
Mar 11 #Python
利用Python裁切tiff图像且读取tiff,shp文件的实例
Mar 10 #Python
GDAL 矢量属性数据修改方式(python)
Mar 10 #Python
使用Python开发个京东上抢口罩的小实例(仅作技术研究学习使用)
Mar 10 #Python
python 获取当前目录下的文件目录和文件名实例代码详解
Mar 10 #Python
python爬虫开发之使用Python爬虫库requests多线程抓取猫眼电影TOP100实例
Mar 10 #Python
Django 404、500页面全局配置知识点详解
Mar 10 #Python
You might like
PHP错误Warning: Cannot modify header information - headers already sent by解决方法
2014/09/27 PHP
PHP实现获取客户端IP并获取IP信息
2015/03/17 PHP
php计算年龄精准到年月日
2015/11/17 PHP
php生成验证码,缩略图及水印图的类分享
2016/04/07 PHP
Yii+MYSQL锁表防止并发情况下重复数据的方法
2016/07/14 PHP
PHP swoole和redis异步任务实现方法分析
2019/08/12 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
原生Js实现按的数据源均分时间点幻灯片效果(已封装)
2010/12/28 Javascript
Jquery加载时从后台读取数据绑定到dropdownList实例
2013/06/09 Javascript
jquery div拖动效果示例代码
2013/12/08 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
javascript感应鼠标图片透明度显示的方法
2015/02/24 Javascript
深入分析JSON编码格式提交表单数据
2015/06/25 Javascript
JavaScript+html5 canvas制作的圆中圆效果实例
2016/01/27 Javascript
JS创建Tag标签的方法详解
2017/06/09 Javascript
Thinkjs3新手入门之添加一个新的页面
2017/12/06 Javascript
javascript获取图片的top N主色值方法详解
2018/01/26 Javascript
vue-cli初始化项目中使用less的方法
2018/08/09 Javascript
Vue中使用方法、计算属性或观察者的方法实例详解
2018/10/31 Javascript
vue中根据时间戳判断对应的时间(今天 昨天 前天)
2019/12/20 Javascript
jquery检测上传文件大小示例
2020/04/26 jQuery
浅谈Vue 自动化部署打包上线
2020/06/14 Javascript
Node 使用express-http-proxy 做api网关的实现
2020/10/15 Javascript
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
使用Python和OpenCV检测图像中的物体并将物体裁剪下来
2019/10/30 Python
html5 canvas绘制网络字体的常用方法
2019/08/26 HTML / CSS
俄罗斯化妆品和香水网上商店:Iledebeaute
2019/01/03 全球购物
注塑工厂厂长岗位职责
2013/12/02 职场文书
平面设计岗位职责
2013/12/14 职场文书
端午节活动总结
2014/08/26 职场文书
公安机关纪律作风整顿个人剖析材料材料
2014/10/10 职场文书
活动费用申请报告
2015/05/15 职场文书
2015年财务个人工作总结范文
2015/05/22 职场文书
费城故事观后感
2015/06/10 职场文书
简历上的自我评价,该怎么写呢?
2019/06/13 职场文书
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android