PostGIS kullanarak çokgenli bir raster ile kesişme - artefakt hatası


15

Bazı raster / çokgen kavşakları yapmak için PostGIS2.0 kullanıyorum . Hangi işlemi kullanmam gerektiğini ve bunu gerçekleştirmenin en hızlı yolunun ne olduğunu anlamakta güçlük çekiyorum. Benim sorunum şöyle:

  • Çokgenim ve rasterim var
  • Çokgene düşen tüm pikselleri bulmak ve piksel değerinin toplamını almak istiyorum
  • Ve (güncellenmiş sorun): Sorguyu gerçekleştirdiğimde orijinal taramada bulunmayan bazı pikseller için büyük değerler alıyorum

Ben kullanması gerekip gerekmediğini anlamakta güçlük yaşıyorum ST_Intersects()ya ST_Intersection(). Piksellerimi toplamak için en iyi yaklaşımın ne olduğunu da bilmiyorum. İşte denediğim ilk yaklaşım (# 1):

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

Bu rast, ne yapacağımdan emin olmadığım bir değer listesi döndürür . Özet istatistiklerini kullanarak hesaplamayı denedim ST_SummaryStats()ama bu çokgen içinde yatan tüm piksellerin ağırlıklı toplamı olup olmadığından emin değilim.

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

Denediğim diğer yaklaşım (# 2) ST_Intersection()şunları kullanır :

 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;

Bu, daha fazla analiz ettiğim geometrilerin bir listesini döndürür, ancak bunun daha az verimli olduğunu varsayıyorum.

Hangi operasyonun en hızlı sırası olduğu konusunda net değilim. Hep seçmeliyim raster, polygonya polygon, raster, ya da böylece bir raster içine çokgen dönüştürmek raster, raster?

EDIT: # 2 yaklaşımının R.K.bağlantısından bazı ayrıntılarla güncelledim .

Yaklaşım # 2'yi kullanarak, çıktıda anlamadığım nedenin bir parçası olan sonuçlarda aşağıdaki hatayı fark ettim. İşte orijinal rasterimin görüntüsü ve kesişmek için kullanılan çokgenin bir taslağı, üstüne yerleştirilmiş:

resim açıklamasını buraya girin

Ve işte PostGIS kullanarak kesişimin sonucu:

resim açıklamasını buraya girin

Sonuçtaki sorun, orijinal rasterde olmayan 21474836 değerlerinin döndürülmesidir. Bunun neden olduğu hakkında hiçbir fikrim yok. Bunun bir yerlerde küçük sayılarla (neredeyse 0'a bölünerek) ilgili olduğundan şüpheleniyorum, ancak yanlış sonucu döndürüyor.


İkinci nokta ile ilgili olarak, çokgene kesişen piksellerin değerlerinin toplamını mı almak istiyorsunuz?
RK

Evet, ST_SummaryStats()# 1 için kullandım , ancak # 2 için nasıl yapılacağından emin değilim.
djq

Bir referans bağlantısı yayınladı. Umarım bu yardımcı olur.
RK

2
Haritanızdaki ölçeğin maksimum değeri, 32 bit işaretli tam sayıdır. Sizin durumunuzda bunun ne anlama geldiğini bilmiyorum, ama NA değerleri ile ilgili olabilir. Sorgunuzdaki aralıkta düzgün işlenmeyen boş değerler olabilir. en.wikipedia.org/wiki/2147483647#2147483647_in_computing
yellowcap

6
FWIW, 21474836, 32 bit işaretli bir int'nin maksimum değeri değildir . Bununla birlikte, ^ 31-1 = 2147483647 2 olduğu maksimum ve bildirim 21474836 = 2147483647/100 (tamsayı bölme) olup. Bu, dahili olarak bazı NA'ların üretildiğini (belki de sınır hücreleri boyunca), 2 ^ 31-1 olarak temsil edildiğini ve daha sonra bunların "NA olduğunu" kodladığını ve (belki de bir yeniden örnekleme işleminde?) Bunları 100'e böldüğünü ima eder.
whuber

Yanıtlar:


6

PostGIS WKT Raster kullanarak geniş bir raster kapsama alanına sahip kesişen vektör çokgenleri hakkında bir eğitim buldum . Aradığınız cevaplara sahip olabilirsiniz.

Öğretici çokgenler ve bir dizi 13 SRTM yükseklik raster üretmek için tamponlanmış bir nokta şekli dosyası olan iki veri kümesi kullandı. Aralarında çok fazla adım vardı, ancak raster ve vektör ile kesişmek için kullanılan sorgu şöyle görünüyordu:

 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;

Değerler daha sonra aşağıdakiler kullanılarak özetlendi:

 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;

Bunu açıklamak için yeterince PostGIS bilmiyorum ama başaramaya çalıştığınız gibi görünüyor. Öğretici ara adımlara ışık tutmalıdır. İyi şanslar :)


Teşekkürler @RK Ben bu öğretici aracılığıyla okudum. Hesaplamamın daha basit olduğunu düşünüyorum, ancak yine de bu temel adımı anlıyorum!
djq

2

Orijinal sorudaki 2. nokta ile ilgili olarak - postgis 2.0 geliştirme sürümlerinin birçoğu GDAL kütüphanesinin ints'a yüzen bir versiyonunu kullandı. Rasterinizde kayan değerler varsa ve 1.9.0'dan daha düşük bir GDAL sürümü veya GDALFPolygonize () öğesini düzgün şekilde çağırmayan bir PostGIS 2.0 ön sürüm sürümü kullanıyorsanız, bu hatayla karşılaşıyor olabilirsiniz. PostGIS ve GDAL hata izleyicilerindeki biletler açıldı ve kapatıldı. Bu hata, orijinal sorunun olduğu sırada aktifti.

Performans açısından, kullanmanın kullanmaktan ST_Intersects(raster, geom)çok daha hızlı olduğunu göreceksiniz ST_Intersects(geom, raster). İlk versiyon geometriyi rasterleştirir ve raster-boşluk kesişimi yapar. İkinci versiyon geometriyi vektörleştirir ve çok daha pahalı bir işlem olabilecek bir vektör-uzay kavşağı yapar.


0

Ben de kullanarak garip sorunları olmamdı ST_SummaryStatsile ST_Clip. Verileri farklı şekilde sorgulamak, ST_SummaryStatsrasterimin min değerinin 32 olduğunu ve daha sonra maksimum 300 olduğunu söyledi, ancak hedef poligonumdaki piksel değerleri için -32700 döndürüyordu.

Ben sorunu etrafında kesmek kadar sona erdi:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.