Я намагаюся обчислити растрову статистику (хв, макс, середнє) для кожного багатокутника у векторному шарі, використовуючи PostgreSQL / PostGIS.
Ця відповідь GIS.SE описує, як це зробити, обчисливши перетин між полігоном та растром, а потім обчисливши середньозважене значення: https://gis.stackexchange.com/a/19858/12420
Я використовую наступний запит (де dem
мій растр, topo_area_su_region
мій вектор та toid
унікальний ідентифікатор:
SELECT toid, Min((gv).val) As MinElevation, Max((gv).val) As MaxElevation, Sum(ST_Area((gv).geom) * (gv).val) / Sum(ST_Area((gv).geom)) as MeanElevation FROM (SELECT toid, ST_Intersection(rast, geom) AS gv FROM topo_area_su_region,dem WHERE ST_Intersects(rast, geom)) foo GROUP BY toid ORDER BY toid;
Це працює, але це занадто повільно. Мій векторний шар має 2489 тис. Функцій, кожен з яких займає близько 90 мс для обробки - це займе кілька днів, щоб обробити весь шар. Швидкість обчислення не здається значно поліпшеною, якщо я обчислюю лише min та max (що дозволяє уникнути дзвінків на ST_Area).
Якщо я роблю аналогічний розрахунок за допомогою Python (GDAL, NumPy та PIL), я можу значно скоротити кількість часу, необхідного для обробки даних, якщо замість векторизації растра (використовуючи ST_Intersection) я раструю вектор. Дивіться код тут: https://gist.github.com/snorfalorpagus/7320167
Мені не дуже потрібна середньозважена оцінка - підхід "якщо вона торкається, то це" є досить хорошим - і я впевнено впевнений, що це уповільнює справи.
Питання : Чи є спосіб змусити PostGIS вести себе таким чином? тобто повернути значення всіх комірок з растру, до яких дотикується багатокутник, а не точне перетин.
Я дуже новачок у PostgreSQL / PostGIS, тому, можливо, є щось інше, що я не роблю правильно. Я запускаю PostgreSQL 9.3.1 і PostGIS 2.1 для Windows 7 (2.9 ГГц i7, 8 Гб оперативної пам’яті) і налаштував конфігурацію бази даних, як тут запропоновано: http://postgis.net/workshops/postgis-intro/tuning.html