Cắt raster với lớp vector bằng GDAL


26

Tôi đã cài đặt GDAL bằng trình cài đặt Osgeo. Làm thế nào tôi có thể cắt một lớp raster với một lớp vectơ lập trình? Có API GDAL nào có thể giúp tôi điều này không? Tôi đang sử dụng Python.

Câu trả lời:


13

Tôi không chắc chắn về api gdal, có void* GDALWarpOptions::hCutlinetrong Tùy chọn Warp được tham chiếu từ hướng dẫn API Warp , nhưng không có ví dụ rõ ràng. Bạn có chắc chắn cần một câu trả lời theo chương trình? Các tiện ích dòng lệnh có thể làm điều đó ra khỏi hộp:

  1. tạo một shapefile chỉ chứa diện tích cắt đa giác quan tâm
  2. sử dụng ogrinfođể xác định phạm vi của shapefile cắt
  3. sử dụng gdal_translateđể kẹp vào phạm vi hình dạng
  4. sử dụng gdalwarpvới -cutlinetham số

Bước 2 & 3 là để tối ưu hóa, bạn chỉ có thể thực hiện bằng cách gdalwarp -cutline ....

Xem Clipping raster với GDAL bằng đa giác từ Linfinity cho giải pháp dựa trên linux, tất cả được gói gọn trong một tập lệnh. Một ví dụ khác về đường cắt có thể được nhìn thấy trong hướng dẫn của Michael Corey tạo ra các hình đồi cho Mapnik .


Matt, bạn có thể nhớ lại trac.osgeo.org/gdal/ticket/1599 trông giống như đường cắt hoàn thành điều này
Mike T


10

Có vẻ như chủ đề này luôn luôn quay trở lại. Bản thân tôi không biết rằng GDAL> 1.8 rất tiên tiến nên nó đã cho bạn xử lý dòng lệnh công bằng để thực hiện nhiệm vụ đó.

Nhận xét từ Mike Toews khá hữu ích nhưng bạn có thể chỉ cần làm ví dụ:

gdalwarp -of GTiff -cutline DATA/area_of_interest.shp -cl area_of_interest  -crop_to_cutline DATA/PCE_in_gw.asc  data_masked7.tiff 

Bạn có thể gói lệnh này bên trong một tập lệnh python với mô đun quy trình con tuyệt vời .

Một điều thực sự có vấn đề với tôi là tôi cần cung cấp một giải pháp tối thiểu cho vấn đề đó, nghĩa là đơn giản nhất có thể và không yêu cầu nhiều phụ thuộc bên ngoài. Việc sử dụng Thư viện hình ảnh Python như trong hướng dẫn của Joel Lawhead rất gọn gàng, nhưng tôi đã đưa ra giải pháp sau: sử dụng mảng mặt nạ Numpy.
Tôi không biết liệu nó có tốt hơn không, nhưng đó là những gì tôi biết trở lại hơn (3 năm trước ...).
Ban đầu tôi đã tạo một vùng dữ liệu hợp lệ bên trong raster ban đầu (ví dụ: phạm vi của raster đầu ra giống nhau), nhưng tôi thích ý tưởng làm cho raster cũng nhỏ hơn (ví dụ: -crop_to_cutline), vì vậy tôi đã áp dụng world2Pixeltừ Joel Lawhead. Đây là giải pháp của riêng tôi:

def RasterClipper():
    craster = MaskRaster()
    contraster2 = 'PCE_in_gw.aux'
    craster.reader("DATA/"+contraster2.replace('aux','asc'))
    xres, yres = craster.extent[1], craster.extent[1]
    craster.fillrasterpoints(xres, yres)
    craster.getareaofinterest("DATA/area_of_interest.shp")
    minX, maxX=craster.new_extent [0]-5,craster.new_extent[1]+5
    minY, maxY= craster.new_extent [2]-5,craster.new_extent[3]+5
    ulX, ulY=world2Pixel(craster.extent, minX, maxY)
    lrX, lrY=world2Pixel(craster.extent, maxX, minY)
    craster.getmask(craster.corners)
    craster.mask=np.logical_not(craster.mask)
    craster.mask.resize(craster.Yrange.size,craster.Xrange.size)
    # choose all data points inside the square boundaries of the AOI,
    # replace all other points with NULL
    craster.cdata= np.choose(np.flipud(craster.mask), (craster.data, -9999))
    # resise the data set to be the size of the squared polygon
    craster.ccdata=craster.cdata[ulY:lrY, ulX:lrX]
    craster.writer("ccdata2m.asc",craster.ccdata, (minX+xres*.5, maxY+yres*.5), 10,10,Flip=False)
    # in second step we rechoose all the data points which are inside the
    # bounding vertices of AOI
    # need to re-define our raster points
    craster.xllcorner, craster.yllcorner = minX, minY
    craster.xurcorner, craster.yurcorner = maxX, maxY
    craster.fillrasterpoints(10,10)
    craster.getmask(craster.boundingvertices) # just a wrapper around matplotlib.nxutils.points_in_poly
    craster.data=craster.ccdata
    craster.clip2(new_extent_polygon=craster.boundingvertices)
    craster.data = np.ma.MaskedArray(craster.data, mask=craster.mask)
    craster.data = np.ma.filled(craster.data, fill_value=-9999)
    # write the raster to disk
    craster.writer("ccdata2m_clipped.asc",craster.data, (minX+xres*.5, maxY+yres*.5), 10,10,Flip=False)

để biết mô tả đầy đủ về các class MaskRasterphương thức và nó, hãy xem github của dự án của tôi .

Sử dụng mã này, bạn vẫn sẽ cần sử dụng GDAL. Tuy nhiên, kế hoạch sẽ sử dụng trong Python thuần túy trong tương lai nếu tôi có thể, vì đối tượng dự định của phần mềm của tôi gặp khó khăn với quá nhiều phụ thuộc (tôi sử dụng Debian để phát triển phần mềm và khách hàng sử dụng Windows 7 ...).


Tôi thích ví dụ dòng lệnh bạn đã đưa ra, nhưng bạn có thể giải thích đối số -crop_to_cutline không? Tôi không chắc mục đích của nó được đưa ra là shapefile được chỉ định bởi -cutline.
hendra

1
tùy chọn -cutline kẹp raster vào hộp giới hạn bên trong của lớp đa giác. Ví dụ, nếu nó nhỏ hơn trong phạm vi thì raster đầu ra cũng sẽ nhỏ hơn. Không có điều này, raster đầu ra sẽ có cùng kích thước với bản gốc, nhưng với NULL ở tất cả các điểm nằm ngoài khu vực bạn quan tâm.
Oz123
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.