在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的Django框架中编写错误提示页面
Jul 22 Python
Python随手笔记之标准类型内建函数
Dec 02 Python
python3如何将docx转换成pdf文件
Mar 23 Python
python 信息同时输出到控制台与文件的实例讲解
May 11 Python
小白入门篇使用Python搭建点击率预估模型
Oct 12 Python
详解如何用django实现redirect的几种方法总结
Nov 22 Python
Python3.5常见内置方法参数用法实例详解
Apr 29 Python
基于python3抓取pinpoint应用信息入库
Jan 08 Python
Python3标准库之functools管理函数的工具详解
Feb 27 Python
解决django 向mysql中写入中文字符出错的问题
May 18 Python
用python进行视频剪辑
Nov 02 Python
Python快速优雅的批量修改Word文档样式
May 20 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
PHP7+Nginx的配置与安装教程详解
2016/05/10 PHP
JS模拟多线程
2007/02/07 Javascript
Tab页界面,用jQuery及Ajax技术实现
2009/09/21 Javascript
js解决弹窗问题实现班级跳转DIV示例
2014/01/06 Javascript
如何用jquery控制表格奇偶行及活动行颜色
2014/04/20 Javascript
JavaScript设计模式之适配器模式介绍
2014/12/28 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
2015/01/08 Javascript
通过伪协议解决父页面与iframe页面通信的问题
2015/04/05 Javascript
Javascript进制转换实例分析
2015/05/14 Javascript
JavaScript中的数组遍历forEach()与map()方法以及兼容写法介绍
2016/05/19 Javascript
JS 实现可停顿的垂直滚动实例代码
2016/11/23 Javascript
js正则相关知识点专题
2018/05/10 Javascript
详解Vue Elementui中的Tag与页面其它元素相互交互的两三事
2018/09/25 Javascript
原生JS 实现的input输入时表格过滤操作示例
2019/08/03 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
Js实现复选框的全选、全不选反选功能代码实例
2020/02/28 Javascript
jquery插件实现轮播图效果
2020/10/19 jQuery
详解Vue3.0 + TypeScript + Vite初体验
2021/02/22 Vue.js
[01:20:37]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
在Python上基于Markov链生成伪随机文本的教程
2015/04/17 Python
python3使用SMTP发送HTML格式邮件
2018/06/19 Python
Python下opencv图像阈值处理的使用笔记
2019/08/04 Python
Python实现快速排序的方法详解
2019/10/25 Python
PyQt5 closeEvent关闭事件退出提示框原理解析
2020/01/08 Python
详解Anaconda 的安装教程
2020/09/23 Python
Django Model层F,Q对象和聚合函数原理解析
2020/11/12 Python
Selenium 安装和简单使用的实现
2020/12/04 Python
python集合的新增元素方法整理
2020/12/07 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
丝芙兰美国官网:SEPHORA美国
2016/08/03 全球购物
旅游管理实习自我鉴定
2013/09/29 职场文书
2015年科学教研组工作总结
2015/07/22 职场文书
礼仪培训心得体会
2016/01/22 职场文书
陶瓷类经典广告语集锦
2019/10/25 职场文书
Python移位密码、仿射变换解密实例代码
2021/06/27 Python
React四级菜单的实现
2022/04/08 Javascript