Відсікання растрових з векторним шаром за допомогою GDAL


26

Я встановив GDAL за допомогою програми установки Osgeo. Як я можу програматично зафіксувати растровий шар із векторним шаром? Чи є доступний GDAL API, який може мені допомогти у цьому? Я використовую Python.

Відповіді:


13

Я не впевнений у gdal api, void* GDALWarpOptions::hCutlineу параметрі Warp, на які посилається посібник з Warp API , немає, але явних прикладів немає. Ви впевнені, що вам потрібна програмна відповідь? Утиліти командного рядка можуть робити це з поля:

  1. створити файл форми, що містить просто цікаву область відсікання багатокутника
  2. використовувати ogrinfoдля визначення ступеня обрізного файлу відсікання
  3. використовувати gdal_translateдля притиску до розширень форми
  4. використання gdalwarpз -cutlineпараметром

Кроки 2 і 3 призначені для оптимізації, яку можна було б обійти просто gdalwarp -cutline ....

Див. Розділ " Відсікання" растрових файлів за допомогою GDAL, використовуючи полігони від Linfinity для рішення на базі Linux, усі в одному сценарії. Інший приклад вирізання можна побачити в навчальному посібнику Майкла Корі, який створює схили для Mapnik .


Метт, ти можеш згадати trac.osgeo.org/gdal/ticket/1599, схоже, що ця лінія виконує це
Майк Т

10

Joel Lawhead з GeospatialPython має повний приклад python у растрові Clip, використовуючи shapefile , добре написаний підручник. Вам знадобиться встановити бібліотеку зображень Python (PIL), яка не включена до Osgeo4W (для чого, можливо, вам потрібно буде додати o4w python до реєстру Windows, щоб змусити програму встановлення працювати).


10

Здається, що ця тема завжди повертається. Я сам не знав, що GDAL> 1.8 настільки вдосконалений, він вже дає вам чесне управління командним рядком для виконання цього завдання.

Коментар Майка Тоувса досить корисний, але ви можете просто зробити це, наприклад:

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

Ви можете зафіксувати цю команду всередині сценарію python із чудовим модулем підпроцесу .

Одне, що було для мене справді проблематичним, - це те, що мені потрібно було забезпечити мінімальне рішення цієї проблеми, що означає максимально просте і не потребує багатьох зовнішніх залежностей. Використання бібліотеки зображень Python, як у підручнику Джоела Лоухеда, є акуратним, але я придумав таке рішення: використання масивів маскування Numpy.
Я не знаю, чи краще, але це я знав ще, ніж (3 роки тому ...).
Спочатку я створив дійсну область даних всередині оригінального растру (наприклад, розмір вихідного растру, де такий самий), але мені сподобалася ідея зробити растр також меншим (наприклад, -crop_to_cutline), тому я прийняв world2Pixelвід Джоела Лоухеда. Ось моє власне рішення:

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)

Повний опис class MaskRasterметодів та його методів див. у github мого проекту .

Використовуючи цей код, вам все одно потрібно буде використовувати GDAL. Однак в майбутньому планується використовувати чистий Python, де я можу, оскільки передбачувана аудиторія мого програмного забезпечення має труднощі із занадто великою кількістю залежностей (я використовую Debian для розробки програмного забезпечення, а клієнти використовують Windows 7 ...).


Мені подобається приклад командного рядка, який ви подали, але чи можете ви пояснити, що робить аргумент -crop_to_cutline? Я не впевнений, якою метою присвоєно формат відсікання.
гендра

1
параметр -розріз притискає растр до внутрішнього обмежувального поля шару полігону. Наприклад, якщо він менший у розширеннях, растровий сигнал також буде меншим. Без цього растровий вихід буде мати той самий розмір, що і оригінальний, але з NULL у всіх точках поза зоною, що вас цікавить.
Oz123
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.