- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
好吧,经过一番摆弄之后,我从第二个评论行中的站点超链接调整了一个脚本。该脚本的目的是使用具有多个多边形(每个都有一个“名称”记录)的 Shapefile 以 GTiff 格式剪辑/屏蔽一个大栅格(即不能适应 32 位 Python 2.7.5 应用程序)并保存将栅格剪切到“剪辑”子目录中,其中每个蒙版网格都以每个多边形的“名称”命名。与原始脚本一样,它假定 GTiff 和 shapefile 在同一投影中并正确重叠,并且它处理 ~100 掩码/秒。但是,我将该脚本修改为 1) 使用浮点值高程网格,2) 仅将较大网格的窗口加载到以当前多边形为界的内存中(即减少内存负载),2) 导出具有正确(即未移动)地理位置和值(value)的 GTiff。
但是,我遇到了麻烦,因为每个蒙版网格都有一个我称之为“右侧阴影”的东西。也就是说,对于多边形中的每条垂直线,其中该线的右侧位于给定多边形之外,掩膜网格将在该多边形侧的右侧包含一个栅格单元。
因此,我的问题是,我做错了什么使蒙版网格具有右阴影?
我将尝试弄清楚如何发布示例 shapefile 和 tif,以便其他人可以重现。下面的代码还有整数值卫星图像的注释行(例如,在 geospatialpython.com 的原始代码中)。
# RasterClipper.py - clip a geospatial image using a shapefile
# http://geospatialpython.com/2011/02/clip-raster-using-shapefile.html
# http://gis.stackexchange.com/questions/57005/python-gdal-write-new-raster-using-projection-from-old
import os, sys, time, Tkinter as Tk, tkFileDialog
import operator
from osgeo import gdal, gdalnumeric, ogr, osr
import Image, ImageDraw
def SelectFile(req = 'Please select a file:', ft='txt'):
""" Customizable file-selection dialogue window, returns list() = [full path, root path, and filename]. """
try: # Try to select a csv dataset
foptions = dict(filetypes=[(ft+' file','*.'+ft)], defaultextension='.'+ft)
root = Tk.Tk(); root.withdraw(); fname = tkFileDialog.askopenfilename(title=req, **foptions); root.destroy()
return [fname]+list(os.path.split(fname))
except: print "Error: {0}".format(sys.exc_info()[1]); time.sleep(5); sys.exit()
def rnd(v, N): return int(round(v/float(N))*N)
def rnd2(v): return int(round(v))
# Raster image to clip
rname = SelectFile('Please select your TIF DEM:',ft='tif')
raster = rname[2]
print 'DEM:', raster
os.chdir(rname[1])
# Polygon shapefile used to clip
shp = SelectFile('Please select your shapefile of catchments (requires Name field):',ft='shp')[2]
print 'shp:', shp
qs = raw_input('Do you want to stretch the image? (y/n)')
qs = True if qs == 'y' else False
# Name of base clip raster file(s)
if not os.path.exists('./clip/'): os.mkdir('./clip/')
output = "/clip/clip"
# 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.tostring(),'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.fromstring('L',(a.shape[1],a.shape[0]), (a.astype('b')).tostring())
return i
def world2Pixel(geoMatrix, x, y, N= 5, r=True):
"""
Uses a gdal geomatrix (gdal.GetGeoTransform()) to calculate
the pixel location of a geospatial coordinate
"""
ulX = geoMatrix[0]
ulY = geoMatrix[3]
xDist = geoMatrix[1]
yDist = geoMatrix[5]
rtnX = geoMatrix[2]
rtnY = geoMatrix[4]
if r:
pixel = int(round(x - ulX) / xDist)
line = int(round(ulY - y) / xDist)
else:
pixel = int(rnd(x - ulX, N) / xDist)
line = int(rnd(ulY - y, N) / xDist)
return (pixel, line)
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)
# Also load as a gdal image to get geotransform
# (world file) info
srcImage = gdal.Open(raster)
geoTrans_src = srcImage.GetGeoTransform()
#print geoTrans_src
pxs = int(geoTrans_src[1])
srcband = srcImage.GetRasterBand(1)
ndv = -9999.0
#ndv = 0
# Create an OGR layer from a boundary shapefile
shapef = ogr.Open(shp)
lyr = shapef.GetLayer()
minXl, maxXl, minYl, maxYl = lyr.GetExtent()
ulXl, ulYl = world2Pixel(geoTrans_src, minXl, maxYl)
lrXl, lrYl = world2Pixel(geoTrans_src, maxXl, minYl)
#poly = lyr.GetNextFeature()
for poly in lyr:
pnm = poly.GetField("Name")
# Convert the layer extent to image pixel coordinates
geom = poly.GetGeometryRef()
#print geom.GetEnvelope()
minX, maxX, minY, maxY = geom.GetEnvelope()
geoTrans = geoTrans_src
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)
# Load the source data as a gdalnumeric array
#srcArray = gdalnumeric.LoadFile(raster)
clip = gdalnumeric.BandReadAsArray(srcband, xoff=ulX, yoff=ulY, win_xsize=pxWidth, win_ysize=pxHeight)
#clip = srcArray[:, ulY:lrY, ulX:lrX]
# 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)
clip = gdalnumeric.choose(mask, (clip, ndv)).astype(gdalnumeric.numpy.float)
# 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,:,:])
if qs: clip[:,:] = stretch(clip[:,:])
# Save ndvi as tiff
outputi = rname[1]+output+'_'+pnm+'.tif'
#gdalnumeric.SaveArray(clip, outputi, format="GTiff", prototype=srcImage)
driver = gdal.GetDriverByName('GTiff')
DataSet = driver.Create(outputi, pxWidth, pxHeight, 1, gdal.GDT_Float64)
#DataSet = driver.Create(outputi, pxWidth, pxHeight, 1, gdal.GDT_Int32)
DataSet.SetGeoTransform(geoTrans)
Projection = osr.SpatialReference()
Projection.ImportFromWkt(srcImage.GetProjectionRef())
DataSet.SetProjection(Projection.ExportToWkt())
# Write the array
DataSet.GetRasterBand(1).WriteArray(clip)
DataSet.GetRasterBand(1).SetNoDataValue(ndv)
# Save ndvi as an 8-bit jpeg for an easy, quick preview
#clip = clip.astype(gdalnumeric.uint8)
#gdalnumeric.SaveArray(clip, rname[1]+outputi+'.jpg', format="JPEG")
#print '\t\tSaved:', outputi, '-.tif, -.jpg'
print 'Saved:', outputi
del mask, clip, geom
del driver, DataSet
del shapef, srcImage, srcband
最佳答案
此功能已合并到 gdal 命令行实用程序中。鉴于你的情况,我看不出你想用 Python 自己做这件事的任何理由。
您可以使用 OGR 循环遍历几何图形,并使用适当的参数为每个调用 gdalwarp
。
import ogr
import subprocess
inraster = 'NE1_HR_LC_SR_W_DR\NE1_HR_LC_SR_W_DR.tif'
inshape = '110m_cultural\ne_110m_admin_0_countries_lakes.shp'
ds = ogr.Open(inshape)
lyr = ds.GetLayer(0)
lyr.ResetReading()
ft = lyr.GetNextFeature()
while ft:
country_name = ft.GetFieldAsString('admin')
outraster = inraster.replace('.tif', '_%s.tif' % country_name.replace(' ', '_'))
subprocess.call(['gdalwarp', inraster, outraster, '-cutline', inshape,
'-crop_to_cutline', '-cwhere', "'admin'='%s'" % country_name])
ft = lyr.GetNextFeature()
ds = None
我在上面的示例中使用了来自 Natural Earth 的一些示例数据,对于巴西,剪切图如下所示:
如果您只想将图像裁剪到多边形区域并且不遮盖任何外部区域,您可以转换 Shapefile,使其包含多边形的包络。或者简单地松开 shapefile 并使用 -projwin
调用 gdal_translate
以指定感兴趣的区域。
关于python - 带有 gdal、ogr 等的 python 中带有 shapefile 的 GTiff 掩码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23769531/
我想为 H3 生成 shapefile特定地理区域的六边形。特别是,我对分辨率为 6、7 和 9 的湾区感兴趣。如何为覆盖该区域的六边形创建 shapefile? 我是 shapefile 或任何其他
我有一个形状文件 (Sample.shp) 以及其他两个文件(Sample.shx 和 Sample.dbf),其中为孟买的 15 个 pincode 定义了几何图形(多边形)。 我可以使用快速入门教
我已经在这方面工作了一段时间并且取得了一些成功,但是在重写文件时,我没有。 我正在使用的 shapefile 是都市和小都市地区的多边形形状文件,但我对小都市地区不感兴趣,所以我正在使用 R 中的 s
我下载了波士顿的 shapefile,并想使用下面的代码将其绘制出来。然而它给了我一个错误 ValueError: lat_0 必须在 -90.000000 和 90.000000 度之间 原来coo
我正在使用 {raster} 来根据不规则形状文件(亚马逊生物群落)剪辑(或裁剪)栅格,但输出始终具有矩形范围。但是,我需要形状文件的完全相同的几何形状的输出。有小费吗?干杯。 library(ras
在 fiona 1.5.0 上(我很困惑为什么各种文件(例如 .dbf 和 .gdb)不打印我的“不是 Shapefile!”(这是我想要的文件不是 . shp) 退出前警告。 import fion
我正在尝试使用 python 中的 matplotlib 在世界地图上绘制国家/地区的填充多边形。 我有一个包含每个国家/地区边界坐标的 shapefile。现在,我想使用 matplotlib 将这
我使用 postgresql 9.1,postgis 2.0.1。为了将 shapefile 导入我的数据库,我使用 shp2pgsql。我尝试了很多导入这些 shapefile 的方法(shp2pg
有没有办法读取具有特定字符编码的形状文件?我正在尝试读取在某些名称中包含特殊(法语)字符的加拿大 shapefile。我可以手动转换它们,但如果我对某处的设置一无所知,我宁愿不这样做。 # manua
已结束。此问题正在寻求书籍、工具、软件库等的推荐。它不满足Stack Overflow guidelines 。目前不接受答案。 我们不允许提出寻求书籍、工具、软件库等推荐的问题。您可以编辑问题,以便
library(raster) admin <- getData('GADM', country='FRA', level=2) set.seed(123) id <- data.frame(ID_2
我目前有一个英国的 shapefile,并绘制了英国不同地区的物种种群。到目前为止,我刚刚绘制了 3 个物种种群水平,并将它们着色为红色 = 高、橙色 = 中、绿色 = 低。但我想做的是有一个渐变图,
Facebook 构建了它所谓的 relative wealth index适用于全局 > 1900 万个微型区域(2.4 公里网格单元)。他们已经 shared the data ( zip ) 在
在阅读了大量帖子和网站后,我无法找到如何从我的经纬度数据表中创建多边形 shapefile。我想创建这样的 map 。 我的csv数据文件包含地中海1000个点的经度、纬度和属性。我想按属性创建 sh
你好我尝试实现传单插入,以显示本地托管的 shapefile。 shapefile 的显示有效,但我想添加一个图层控件(用于切换 shapefile 图层)。插件链接:https://github.c
使用下面的代码,我可以创建一条折线并将其写入形状文件。但我也想读取Polyline类型的形状文件并将Point转换为x:f64和y:f64。 use shapefile::{Point, Polyli
我有一个包含亚马逊大河的 shapefile。仅 shapefile 就有 37.9 MB,连同属性表高达 42.1 MB。我正在生成所有巴西亚马逊的 PNG 图像,每个 1260x940 像素,sh
我正在尝试导入这样的形状文件: fn <- "Proj1" my_shp <- readShapeSpatial(fn) 在 Windows 计算机(32 位)上它工作正常,但是当我在 Ubuntu
我有一个导出 ArcGIS map 点的应用程序。 Spring MVC Controller 中的接收点。 我的指针有一个可变的属性列表。属性是具有两个值(名称和值)的字符串列表。代码: publi
我正在编写一个 map 应用程序,用于导入人口普查和 USGS 信息并将其显示为 Google map 上的叠加层。我想导出这些项目的混搭并导出为 Shapefile . 我使用 geotools 库
我是一名优秀的程序员,十分优秀!