나는 래스터 (USGS DEM)를 가지고 있으며 아래 그림과 같이 작은 덩어리로 나눠야합니다. 이는 Split Raster 도구를 사용하여 ArcGIS 10.0에서 수행되었습니다. 이를 위해 FOSS 방법을 원합니다. GDAL을 살펴 보았지만 (gdal_translate를 사용하여) 확실히 할 것이라고 생각했지만 아무것도 찾을 수 없었습니다. 궁극적으로 래스터를 가져 와서 얼마나 큰지 (4KM x 4KM 청크)로 나누고 싶습니다.
나는 래스터 (USGS DEM)를 가지고 있으며 아래 그림과 같이 작은 덩어리로 나눠야합니다. 이는 Split Raster 도구를 사용하여 ArcGIS 10.0에서 수행되었습니다. 이를 위해 FOSS 방법을 원합니다. GDAL을 살펴 보았지만 (gdal_translate를 사용하여) 확실히 할 것이라고 생각했지만 아무것도 찾을 수 없었습니다. 궁극적으로 래스터를 가져 와서 얼마나 큰지 (4KM x 4KM 청크)로 나누고 싶습니다.
답변:
gdal_translate 는 -srcwin 또는 -projwin 옵션을 사용하여 작동합니다.
-srcwin xoff yoff xsize ysize : 소스 이미지에서 픽셀 / 라인 위치를 기준으로 복사 할 하위 창을 선택합니다.
-projwin ulx uly lrx lry : 복사 할 소스 이미지에서 -srcwin과 같은 서브 윈도우를 선택하지만 모서리는 지리 참조 좌표로 제공됩니다.
픽셀 / 라인 위치 또는 코너 좌표를 찾은 다음 gdal_translate를 사용하여 값을 반복해야합니다. 픽셀 값을 사용하고 -srcwin이 적합한 경우 아래의 빠르고 더러운 파이썬과 같은 것이 작동합니다. 좌표로 정렬하는 것이 조금 더 많은 작업입니다.
import os, gdal
from gdalconst import *
width = 512
height = 512
tilesize = 64
for i in range(0, width, tilesize):
for j in range(0, height, tilesize):
gdaltranString = "gdal_translate -of GTIFF -srcwin "+str(i)+", "+str(j)+", "+str(tilesize)+", " \
+str(tilesize)+" utm.tif utm_"+str(i)+"_"+str(j)+".tif"
os.system(gdaltranString)
@wwnick의 솔루션을 기반으로 한 내 솔루션은 파일 자체에서 래스터 크기를 읽고 필요한 경우 가장자리 타일을 작게 만들어 전체 이미지를 덮습니다.
import os, sys
from osgeo import gdal
dset = gdal.Open(sys.argv[1])
width = dset.RasterXSize
height = dset.RasterYSize
print width, 'x', height
tilesize = 5000
for i in range(0, width, tilesize):
for j in range(0, height, tilesize):
w = min(i+tilesize, width) - i
h = min(j+tilesize, height) - j
gdaltranString = "gdal_translate -of GTIFF -srcwin "+str(i)+", "+str(j)+", "+str(w)+", " \
+str(h)+" " + sys.argv[1] + " " + sys.argv[2] + "_"+str(i)+"_"+str(j)+".tif"
os.system(gdaltranString)
래스터를 줄이기 위해 번들로 제공되는 번들 파이썬 스크립트 gdal_retile이 있습니다 .
gdal_retile.py [-v] [-co NAME=VALUE]* [-of out_format] [-ps pixelWidth pixelHeight]
[-overlap val_in_pixel]
[-ot {Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/
CInt16/CInt32/CFloat32/CFloat64}]'
[ -tileIndex tileIndexName [-tileIndexField tileIndexFieldName]]
[ -csv fileName [-csvDelim delimiter]]
[-s_srs srs_def] [-pyramidOnly]
[-r {near/bilinear/cubic/cubicspline/lanczos}]
-levels numberoflevels
[-useDirForEachRow]
-targetDir TileDirectory input_files
예 :
gdal_retile.py -ps 512 512 -targetDir C:\example\dir some_dem.tif
@Aaron은 다음과 같이 물었습니다.
향상된 멀티 코어 및 멀티 스레드 작업을 위해 -multi 옵션을 사용하는 @wwnick의 대답에 대한 gdalwarp 버전을 찾고 싶습니다.
약간의 부인
gdalwarp
비록 성능이 많이 나올 것이라고 확신하지는 않지만을 사용합니다 . 지금까지 나는 I / O 바인딩되었습니다.이 스크립트를 큰 래스터에서 많은 작은 부분으로 자르는 것은 CPU를 많이 사용하지 않는 것처럼 보이므로 병목 현상이 디스크에 기록되고 있다고 가정합니다. 타일 또는 이와 유사한 것을 동시에 다시 투영하려는 경우 변경 될 수 있습니다. 튜닝 팁이 있습니다 . 간단한 플레이는 나에게 아무런 개선을 가져 오지 않았으며 CPU는 결코 제한 요소가 아닌 것으로 보였습니다.
면책 조항을 제외 gdalwarp
하고 래스터를 여러 개의 작은 타일로 분할하는 데 사용되는 스크립트가 있습니다 . 바닥 구분으로 인해 약간의 손실이있을 수 있지만 원하는 타일 수를 선택하여 처리 할 수 있습니다. 그것은 될 것입니다 n+1
곳 n
얻가 당신에 의해 분할 개수 tile_width
와 tile_height
변수.
import subprocess
import gdal
import sys
def gdalwarp(*args):
return subprocess.check_call(['gdalwarp'] + list(args))
src_path = sys.argv[1]
ds = gdal.Open(src_path)
try:
out_base = sys.argv[2]
except IndexError:
out_base = '/tmp/test_'
gt = ds.GetGeoTransform()
width_px = ds.RasterXSize
height_px = ds.RasterYSize
# Get coords for lower left corner
xmin = int(gt[0])
xmax = int(gt[0] + (gt[1] * width_px))
# get coords for upper right corner
if gt[5] > 0:
ymin = int(gt[3] - (gt[5] * height_px))
else:
ymin = int(gt[3] + (gt[5] * height_px))
ymax = int(gt[3])
# split height and width into four - i.e. this will produce 25 tiles
tile_width = (xmax - xmin) // 4
tile_height = (ymax - ymin) // 4
for x in range(xmin, xmax, tile_width):
for y in range(ymin, ymax, tile_height):
gdalwarp('-te', str(x), str(y), str(x + tile_width),
str(y + tile_height), '-multi', '-wo', 'NUM_THREADS=ALL_CPUS',
'-wm', '500', src_path, out_base + '{}_{}.tif'.format(x, y))
GRASS GIS의 r.tile 을 사용할 수 있습니다 . r.tile은 사용자 정의 접두사를 기반으로 번호가 매겨진 맵 이름을 가진 각 타일에 대해 별도의 래스터 맵을 생성합니다. 타일 너비 (열) 및 타일 높이 (행)를 정의 할 수 있습니다.
풀 세션 Python API를 사용하면 외부에서 r.tile 기능을 호출하는 데 (예 : 독립형 스크립트 작성) 몇 줄의 Python 코드 만 필요합니다. r.external 및 r.external.out을 사용 하면 GRASS GIS 처리 단계 중에 데이터 중복이 발생하지 않습니다.
의사 코드 :