Перетинання растра з багатокутником за допомогою PostGIS - помилка артефакту


15

Я використовую PostGIS2.0, щоб зробити кілька растрових / багатокутних перетинів. Мені важко зрозуміти, яку операцію я повинен використовувати, і який найшвидший спосіб виконання цього. Моя проблема полягає в наступному:

  • У мене є багатокутник і растр
  • Я хочу знайти всі пікселі, які потрапляють у полігон, і отримати суму значення пікселя
  • І (оновлена ​​проблема): я отримую масові значення для деяких пікселів, які не існують у вихідному растрі, коли я виконую запит

У мене важко зрозуміти , чи повинен я використовувати ST_Intersects()або ST_Intersection(). Я також не знаю, який найкращий підхід для підсумовування пікселів. Ось перший підхід, який я спробував (№1):

SELECT 
    r.rast 
FROM
    raster as r, 
    polygon as p
WHERE
    ST_Intersects(r.rast, p.geom)

Це повертає список rastзначень, з якими я не впевнений, що з цим робити. Я спробував обчислити підсумкову статистику, ST_SummaryStats()але я не впевнений, чи це зважена сума всіх пікселів, що лежать у полігоні.

SELECT  
        (result).count,
        (result).sum    
FROM (  
         SELECT 
            ST_SummaryStats(r.rast) As result
         FROM
            raster As r, 
            polygon As p
         WHERE
            ST_Intersects(r.rast, p.geom)    
    ) As tmp

Інший підхід, який я спробував (№2), використовує ST_Intersection():

 SELECT
        (gv).geom,         
        (gv).val
 FROM 
 (
    SELECT 
        ST_Intersection(r.rast, p.geom) AS gv
    FROM 
        raster as r, 
        polygon as p           
    WHERE 
        ST_Intersects(r.rast, p.geom)

      ) as foo;

Це повертає список геометрій, які я аналізую далі, але я вважаю, що це менш ефективно.

Мені незрозуміло, за яким також є найшвидший порядок роботи. Чи слід завжди вибирати raster, polygonчи polygon, rasterперетворювати багатокутник у растр так, щоб він був raster, raster?

EDIT: Я оновив підхід №2 з деякими деталями із R.K.посилання 's.

Використовуючи підхід №2, я помітив наступну помилку в результатах, яка є частиною причини, чому я не зрозумів вихід. Ось зображення мого оригінального растру та контур багатокутника, який використовується для його перетину, накладений зверху:

введіть тут опис зображення

І ось результат перехрестя за допомогою PostGIS:

введіть тут опис зображення

Проблема з результатом полягає в тому, що є значення 21474836, які повертаються, яких немає в початковому растрі. Я не знаю, чому це відбувається. Я підозрюю, що він десь пов'язаний з невеликою кількістю (ділиться майже на 0), але це повертає неправильний результат.


Щодо точки другої, ви хочете отримати суму значень пікселів, які перетинаються багатокутник?
РК

Так, я використовував ST_SummaryStats()для №1, але не знаю, як це зробити для №2.
djq

Опублікував посилання на посилання. Я сподіваюся, що це допомагає.
РК

2
Максимальне значення масштабу на карті - це максимум 32-бітного цілого числа, підписаного. Я не знаю, що це означає у вашому випадку, але це може стосуватися значень NA. Діапазон у вашому запиті може мати нульові значення, які неправильно обробляються. en.wikipedia.org/wiki/2147483647#2147483647_in_computing
yellowcap

6
FWIW, 21474836 - не максимальне значення 32-бітного підписаного int. Однак 2 ^ 31-1 = 2147483647 - макс., І зауважте, що 21474836 = 2147483647/100 (ціле ділення). Це натякає на те, що всередині НС генеруються деякі (можливо, уздовж прикордонних комірок), вони представляються як 2 ^ 31-1, і тоді код «забуває» це NA та (можливо, в процесі перекомпонування?) Ділить їх на 100.
whuber

Відповіді:


6

Я знайшов підручник з пересічних векторних багатокутників з великим растровим покриттям за допомогою PostGIS WKT Raster . Можливо, відповіді ви шукаєте.

У навчальному посібнику було використано два набори даних, файл у формі точки, який був забудований для отримання полігонів та серію з 13 растрових висот SRTM. Між ними було багато кроків, але запит, що використовується для перетину растру та вектора, виглядав так:

 CREATE TABLE caribou_srtm_inter AS
 SELECT id, 
        (gv).geom AS the_geom, 
        (gv).val
 FROM (SELECT id, 
              ST_Intersection(rast, the_geom) AS gv
       FROM srtm_tiled,
            cariboupoint_buffers_wgs
       WHERE ST_Intersects(rast, the_geom)
      ) foo;

Потім значення підсумовували за допомогою наступного:

 CREATE TABLE result01 AS
 SELECT id, 
        sum(ST_Area(ST_Transform(the_geom, 32198)) * val) / 
        sum(ST_Area(ST_Transform(the_geom, 32198))) AS meanelev
 FROM caribou_srtm_inter
 GROUP BY id
 ORDER BY id;

Я насправді не знаю достатньо PostGIS, щоб пояснити це, але це впевнено звучить як те, що ви намагалися досягти. Підручник повинен пролити світло на проміжні щаблі. Удачі :)


Дякую @RK, я прочитав цей підручник. Я думаю, що мій розрахунок є більш базовим, але я все-таки з'ясовую цей основний крок!
djq

2

Що стосується пункту 2 в первинному запитанні - в декількох версіях розробки версій Postgis 2.0 використовується версія бібліотеки GDAL, яка передає плавки до ints. Якщо ваш растр має в ньому плавні значення, і ви використовували версію GDAL, нижчу за 1.9.0, або версію попереднього випуску PostGIS 2.0, яка неправильно викликала GDALFPolygonize (), можливо, ви зіткнулися з цією помилкою. Квитки в трекерах про помилки PostGIS та GDAL були подані та закриті. Ця помилка була активною під час первинного запитання.

З точки зору продуктивності ви побачите, що використання ST_Intersects(raster, geom)набагато швидше, ніж використання ST_Intersects(geom, raster). Перша версія растерізує геометрію і робить растрово-космічний перетин. Друга версія веризує геометрію і робить перетин вектор-простір, що може бути набагато дорожчим процесом.


0

Я також мають дивні питання , використовуючи ST_SummaryStatsз ST_Clip. Запитуючи дані по-різному, мені сказали, що мінімальне значення мого растра становило 32, а потім макс 300, але ST_SummaryStatsповертало -32700 для піксельних значень у моєму цільовому багатокутнику.

Я закінчила злом навколо проблеми так:

WITH first AS (
   SELECT id, (ST_Intersection(geom, rast)).val
   FROM raster_table
   INNER JOIN vector_table ON ST_Intersects(rast, geom)
)
SELECT id, COUNT(val), SUM(val), AVG(val), stddev(val), MIN(val), MAX(val)
FROM first
GROUP BY id
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.