Birden çok çokgen için nokta çokgen algoritması


11

Üzerinde çokgen bulunan bir Google haritam var.

İşte ilgilendiğim bir sorun: Lat, lng noktası göz önüne alındığında, bu noktanın içinde bulunduğu tüm çokgenleri belirlemenin en iyi yolu nedir?

Açık çok yol her poligon için bir "çokgen noktası" algoritması tekrar tekrar çalıştırmaktır, ama özellikle binlerce çokgen varsa bu tür sorguları cevaplamak için etkili bir algoritma olup olmadığını merak ediyordum.


Google Haritalar API'sı hakkında fazla bir şey bilmiyorum, ancak tarayıcı böyle büyük sorgular yapmak için en iyi yer olma eğiliminde değil. PostGIS (ücretsiz), ArcServer veya Oracle Spatial bu gibi istekleri daha iyi ele alma eğilimindedir.
canisrufus

Algoritma ile her şeyden çok ilgileniyorum. BTW, bunu PostGIS'de nasıl yapardınız?
numan

Aşağıdaki url çokgen noktası hakkında konuşuyor .. (ben hiç bu kullanmadım) .. bir deneyin .. biraz ide verebilir. eriestuff.blogspot.com/2008/02/…

3
İşte benim zorunlu yorumum, "çokgen noktasında" bir küre üzerindeki bir nokta için hiçbir anlam ifade etmiyor, çünkü bir küre üzerindeki bir çokgen, küreyi 'iç' olarak adlandırılma hakkına sahip iki parçaya böler. Kuzey veya güney kutbu ekvatoru tanımlayan çokgenin “içinde” midir? Unutmayın, lat-long kartezyen değil ...
Spacedman

4
@Spaced "Polygon" u "polyline" ile karıştırıyorsunuz. Çokgen noktası bir küre üzerinde mükemmel bir anlam ifade eder. Bir çokgen sınırından daha fazlasıdır (kapalı bir çoklu çizgi): iç kısmını içerir. Çokgen bir sınır küreyi bağlı iki bileşene ayırsa da, bunlardan birini çokgenin iç mekanı olarak atamanın birçok yolu vardır, örneğin bir yönlendirme kuralı (örneğin, iç sınırdan geçerken sola uzanır) ) veya bir raster temsili kullanarak.
whuber

Yanıtlar:


12

Hemen hemen tüm bu tür sorularda olduğu gibi , optimal yaklaşım "kullanım örnekleri" ne ve özelliklerin nasıl temsil edildiğine bağlıdır. Kullanım durumları tipik olarak (a) her katmanda birden fazla veya daha az nesne olup olmadığı ve (b) katmanlardan birinin (veya her ikisinin) bazı veri yapılarının önceden hesaplanmasına izin verip vermediği; yani bunlardan birinin veya her ikisinin ön hesaplama yatırımını değerli kılmak için yeterince durağan ve değişmez olup olmadığı.

Mevcut durumda, bu aşağıdaki senaryoları verir. Normalde noktalar dinamiktir: yani önceden verilmezler. (Önceden veya çok büyük gruplarda mevcutlarsa, bunları sıralamaya dayalı bazı optimizasyonlar kullanılabilir olacaktır.) Q , sorgu noktası sayısı ve P , çokgen köşe sayısı sayısı olsun .

Vektör çokgen verileri

(1) Az puan, birkaç Poligon köşeleri toto . Klasik çizgi bıçaklama algoritması gibi bir kaba kuvvet prosedürü kullanın . İyi bir yöntem için maliyet O (P * Q) 'dur, çünkü bir noktayı bir poligon kenarıyla karşılaştırmak O (1) zamanına mal olur ve bu tür tüm karşılaştırmalar yapılmalıdır.

(2) Muhtemelen birçok çokgen köşesi vardır, ancak dinamiktirler: sorguda her nokta kullanıldığında, çokgenlerin hepsi değişmiş olabilir. Tekrar kaba kuvvet algoritması kullanın. Maliyet hala O (P * Q), bu da büyük olacak, çünkü P büyük olacak, ancak buna yardımcı olmuyor. Değişiklikler küçükse veya kontrol edilirse ( örneğin , çokgenler hafifçe değişiyorsa veya sadece yavaşça hareket ediyorsa) bir sonraki çözümün bir sürümünü kullanabilir ve çokgenler değiştikçe veri yapılarını güncellemenin etkili bir yolunu bulabilirsiniz. Bu muhtemelen orijinal araştırma için bir sorun olacaktır.

(3) Birçok çokgen köşesi ve statik çokgen (yani, çokgen katmanı nadiren değişir). Aramayı desteklemek için bir veri yapısını önceden hesaplayın (bir satır taramasına veya dörtlü bir algoritmaya dayalı olabilir ). Bu algoritmalar için ön hesaplama maliyeti O (P * log (P)) 'dir, ancak sorguların maliyeti O (Q * log (P)) olur, bu nedenle toplam maliyet O ((P + Q) * log ( p)).

Bazı özel durumlarda ,

(a) Tüm çokgenler dışbükeydir ( çokgenlerin önişlenmesi daha hızlı yapılabilir ),

(b) Tüm çokgen iç kısımları ayrıktır , bu durumda birliklerini tek bir çokgen olarak düşünebilirsiniz (bu, üçgenleme tabanlı olanlar gibi doğrudan etkili algoritmalara izin verir ve

(c) Çoğu çokgenler çok kıvrımlı değildir - yani sınırlayıcı kutularının büyük bölümlerini işgal ederler - bu durumda sadece sınırlayıcı kutulara dayalı bir ilk test yapabilir ve ardından bu çözümü geliştirebilirsiniz. Bu popüler bir optimizasyon.

(d) Puan sayısı fazladır. Bunları sıralamak zamanlamayı iyileştirebilir. Örneğin, bir soldan sağa çizgi çokgen noktasında tarama algoritması uygularken, ilk koordinatlarındaki noktaları sıralayarak çokgen kenarlarını süpürürken aynı zamanda noktaları süpürmenize izin verirsiniz. Böyle bir optimizasyonun yayınlandığının farkında değilim. Bununla birlikte, yayınlanan bir nokta, tüm noktaların ve çokgen köşelerinin birliğinin sınırlandırılmış bir üçgenlemesini yapmaktır : bu üçgenleme tamamlandığında, iç noktaların belirlenmesi hızlı olmalıdır. Hesaplama maliyeti O (Q * log (Q) + (P + Q) * log (P + Q)) olarak ölçeklenir.

Raster çokgen verileri

Bu inanılmaz derecede kolaydır: Çokgen katmanını ikili gösterge raster olarak görüntüleyin (1 = bir çokgenin içinde, 0 = dış). (Bu, raster değerlerini iç / dış göstergelere dönüştürmek için bir arama tablosu gerektirebilir.) Her nokta probu şimdi raster hücresini indekslemek ve değerini okumak için O (1) çaba gerektirir. Toplam çaba O (Q).

Genel olarak

Güzel bir melez çözümbirçok statik vektör çokgeninin olması durumunda (yukarıdaki vektör örneği 3) başlangıçta çokgenleri, belki de kaba bir çözünürlükle bile rasterleştirmektir, bu kez çokgen sınırının herhangi bir bölümünü kesen hücreleri ayırt etmek (onlara 2 değerini vermek, demek) . Raster prob kullanılması (maliyet: O (1)) tipik olarak kesin bir cevap verir (noktanın içte veya dışta olduğu bilinir), ancak bazen belirsiz bir cevapla sonuçlanır (nokta, en az bir kenarın bulunduğu bir hücreye düşer bu durumda daha pahalı O (log (P)) vektör sorgusu yapılır. Bu yöntem, raster için ekstra depolama maliyetine neden olur, ancak çoğu durumda küçük bir raster (bir MB, 2000'den 2000'e kadar olan bir raster için izin verir, bu da {0,1,2, null} değerlerini saklar) hesaplama zamanında büyük avantajlar sağlayabilir. . Asymptotik,


7

Çokgen sınırlayıcı kutuları dörtlü ağaç gibi bir şeyde sakladıysanız, hangi poligonları kontrol edeceğinizi hızlı bir şekilde belirlemek için bunu kullanabilirsiniz. En azından noktanın, her çokgen için çokgende bir tam nokta yapmak yerine her bir çokgen sınırlayıcı kutunun içinde olup olmadığını görebilirsiniz. Şahsen ben bellekte çokgenleri önbellek ve kavşak sorgusu yapmak için JTS veya NetTopology paketi gibi bir şey kullanmak bir web hizmeti kurmak.


1

Postgis'te ST_Intersects , önce noktanın çokgenin sınırlayıcı kutusunun içinde olup olmadığını bulmak için dizinleri kullanır ve daha sonra gerçekten çokgenin içinde olup olmadığını görmek için bir yeniden kontrol yapar. Bu hızlı, genellikle çok hızlı.

Verilerinizi PostGIS'de sakladıysanız, veritabanının hesaplamayı yapmak için doğru yer olduğuna şüphe olmamalıdır. Diğer durumlarda, çokgenlerinizi bazı orta veya istemci programlarına göndermeniz gerekir. Bu, kendi başına hesaplamaları yapmaktan çok daha fazla zaman alacak ve sadece ilgili çokgenleri alacaktır.

/ Nicklas

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.