Próbuję obliczyć statystyki rastrowe (min., Maks., Średnia) dla każdego wielokąta w warstwie wektorowej przy użyciu PostgreSQL / PostGIS.
W odpowiedzi GIS.SE opisano, jak to zrobić, obliczając przecięcie wielokąta i rastra, a następnie obliczając średnią ważoną: https://gis.stackexchange.com/a/19858/12420
Korzystam z następującego zapytania (gdzie dem
jest moim rastrem, topo_area_su_region
jest moim wektorem i toid
jest unikalnym identyfikatorem:
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;
To działa, ale jest zbyt wolne. Moja warstwa wektorowa ma 2489 tys. Funkcji, z których każda zajmuje około 90 ms - przetworzenie całej warstwy zajęłoby dni . Szybkość obliczeń nie wydaje się znacznie poprawiona, jeśli obliczę tylko min i max (co pozwala uniknąć wywołań ST_Area).
Jeśli wykonam podobne obliczenia przy użyciu Pythona (GDAL, NumPy i PIL), mogę znacznie skrócić czas przetwarzania danych, jeśli zamiast wektoryzacji rastra (używając ST_Intersection) rasteryzuję wektor. Zobacz kod tutaj: https://gist.github.com/snorfalorpagus/7320167
Naprawdę nie potrzebuję średniej ważonej - podejście „jeśli dotyka, jest w” jest wystarczająco dobre - i jestem całkiem pewien, że właśnie to spowalnia.
Pytanie : Czy istnieje sposób, aby PostGIS zachowywał się w ten sposób? tzn. aby zwrócić wartości wszystkich komórek z rastra, którego dotyka wielokąt, zamiast dokładnego przecięcia.
Jestem bardzo nowy w PostgreSQL / PostGIS, więc może coś jest nie tak. Korzystam z PostgreSQL 9.3.1 i PostGIS 2.1 w systemie Windows 7 (2,9 GHz i7, 8 GB pamięci RAM) i poprawiłem konfigurację bazy danych zgodnie z sugestią tutaj: http://postgis.net/workshop/postgis-intro/tuning.html