PostGIS'de en yakın Geometri'yi bulma


16

PostGIS "API" fonksiyonlarını inceledim ve çoğunun karşılaştırmak için iki öğe aldığını fark ettim. Örneğin, ST_Distance işlevi mesafeyi bulmak için iki geometri / coğrafya öğesi alır.

"G geometrisi verildiğinde bana Tablo T'de en yakın geometri GClosest'i verin, burada G.id <> GClosest.id" ifadesini kullanın.

Ben tablo üzerinde yineleme ve her öğe üzerinde ST_Distance aramak için bir PL / PgSQL işlevi yazabilirim farkında, ama daha iyi, daha verimli bir çözüm var umuyorum.


1
En yakın geometriye olan mesafeyle ilgileniyorsanız, gis.stackexchange.com/questions/11979/…
underdark

doğru anladıysam bana haber ver ... en yakın mesafeyle aynı mesafeye sahip bir sonraki özelliği mi istiyorsun?
falcacibar

Yanıtlar:


7

Sorunuz ayrıca, tüm kaydı ve referans geometriye olan mesafeyi döndüren aşağıdaki gibi tek (karmaşık da olsa) bir sorgu ile yanıtlanabilir. Birden fazla kayıt minimum mesafeyle eşleşirse bunların hepsinin döndürüldüğünü lütfen unutmayın .

SELECT 
  i.*,
  md.min_distance
FROM
  address AS i, 
  (SELECT 
     ga.address_geom,
     min( ST_Distance(
            ga.address_geom,
            gb.address_geom)
        ) AS min_distance
   FROM
     address AS ga,
     address AS gb 
   WHERE 
     ga.id <> gb.id 
   AND 
     ga.id = 3
   GROUP BY 
     ga.address_geom
  ) AS md 
WHERE 
  ST_Distance( i.address_geom, md.address_geom) = md.min_distance;

Bu sorgu adresler tablosunda test ettik ve çalışıyor. Yukarıdaki sorguda ben id = 3 ile en yakın noktayı arıyorum.


Bu iyi bir bilgidir - teşekkür ederim ... min (..) toplama işlevini tanım gereği anlıyorum, ancak örneğinizde nasıl kullanıldığı konusunda kafam karıştı. st_distance (X, Y) iki geometri türü alır ve aralarındaki mesafeyi döndürür, bu da tek bir değerdir. O zaman neden bu tek değer sonucu üzerinde bir toplama işlevi çağırıyorsunuz? Belki içerideki seçme ifadesini yanlış yorumluyorum ...
Jmoney38

Gruplama grubu, sonuç kümesinin tamamı için bir sabit olan ga geometrisi üzerindedir ( ga'nın id = 3 ile seçildiğini unutmayın ), böylece temelde hiçbir şey yapmaz. Bu sadece dış sorgunun st_distance'ında ga geometrisinin tabloya iki kez katılmadan kullanılabilmesi için bir hiledir . Bugün belki bölüm sorgusunu kullanarak içsel sorgudan tamamen kurtulabileceğimi düşünüyordum . Bu aynı zamanda performansı da arttırmalıdır. Bir deneyeceğim ve size bildireceğim.
unicoletti

Ne yazık ki pencere fonksiyonları 8.4'te tanıtıldı ve şimdi hem postgis hem de bu sürümü olan bir sunucuya erişimim yok, bu yüzden partion yan tümcesiyle yeniden yazılmış bir sorguyu test edemiyorum.
unicoletti

7

George MacKerron, oldukça kullanışlı bulduğum basit bir En Yakın Komşu işlevi yazdı . Bu işlev, verilen bir özelliğe en yakın komşunun kimliğini döndürür:

create or replace function 
  nn(nearTo                   geometry
   , initialDistance          real
   , distanceMultiplier       real 
   , maxPower                 integer
   , nearThings               text
   , nearThingsIdField        text
   , nearThingsGeometryField  text)
 returns integer as $$
declare 
  sql     text;
  result  integer;
begin
  sql := ' select ' || quote_ident(nearThingsIdField) 
      || ' from '   || quote_ident(nearThings)
      || ' where st_dwithin($1, ' 
      ||   quote_ident(nearThingsGeometryField) || ', $2 * ($3 ^ $4))'
      || ' order by st_distance($1, ' || quote_ident(nearThingsGeometryField) || ')'
      || ' limit 1';
  for i in 0..maxPower loop
     execute sql into result using nearTo              -- $1
                                , initialDistance     -- $2
                                , distanceMultiplier  -- $3
                                , i;                  -- $4
    if result is not null then return result; end if;
  end loop;
  return null;
end
$$ language 'plpgsql' stable;

Kullanım örneği:

SELECT id, nn(pt_geom,0.00001,2,100,'nw_node','node_id','node_geom') FROM my_point_table;

... my_point_table içindeki her giriş için nw_node tablosundaki en yakın düğümü seçer.

Boston GIS sitesinde daha genel bir işlev de var .


Daha genel anlamda sorgu 1: N sorgularının nasıl oluşturulacağı ile daha fazla ilgileniyorum. Örneğin, G geometrisine en yakın elemanı bulmak yerine, G ile çakışan ilk elemanı bulmak isteyebilirim. Boston CBS bağlantısı çok faydalı oldu! Hile sayfalarından bazılarını zaten yazdırdım :-)
Jmoney38

Belki sorunuzu biraz daha açıklığa kavuşturabilirsiniz, @ Jmoney48. Yani özellikle en yakın komşu sorunuyla ilgilenmiyorsunuz, daha ziyade bir geometrinin bir tablodaki tüm geometrilerle nasıl karşılaştırılacağıyla ilgileniyor musunuz?
underdark

DAİMA Boston GIS sitesinin genel işlevini kullanın, basit olan büyük tablolar için inanılmaz derecede yavaştır ve uygulama çabası daha büyük değildir.
Vladtn
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.