Ulaşılabilir bir alan üzerinde çokgen oluşturma


10

Şu anda isochrones ve temel algoritmalar alanında çalışıyorum. Şimdi sorunlara neden olan şey, izokronun kendisinin hesaplanması değil, sonuçların görselleştirilmesidir.
İzokron algoritmamın sonucu noktalar ve kenarlardır. Aslında çalışan bir çözümüm var, ancak 3873 kenarlar ve 1529 düğümler için işler sonsuza dek sürecek gibi görünüyor (2015 Core i7 CPU ve oldukça hızlı bir SSD içeren Lenovo T440s dizüstü bilgisayarımda yaklaşık 2.0 saniye). Saniyeler yerine msec gibi bir şey istiyorum :-).

Belki biri ulaşılabilir alanları görselleştiren çokgenler oluşturmak için gereken hesaplama süresini azaltmama yardımcı olabilir.

Ama bekleyin ... ilk önce!
İşte benim izokron benim hesaplama sonucu olan kenarların bir görselleştirme: İzokron hesaplama sonucu (iskeletlerin mevcut iskeleti) Bu kenarlar bir PostGIS veritabanı tablosunda depolanır ve basit linestrings vardır.

Kullanıcıya göstermek istediğim şudur: resim açıklamasını buraya girin Resmin en güneyindeki ve doğusundaki bağlantısız alanlara dikkat edin. Bunlar ayrı alanlar olarak çizilmelidir (bu nedenle burada birleştirmeye izin verilmez :-))

Şu anda bu sorguyu kullanıyorum:

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_MakePolygon(ST_ExteriorRing(ST_GeometryN(segments, generate_series(1, ST_NumGeometries(segments))))) AS polygons FROM (
        SELECT ST_Union(ST_Buffer("GEOMETRY", 20, 'quad_segs=2')) AS segments FROM my_edges AS a
    ) AS b
) AS c

Zaten bazı deneyler yaptım ve çok fazla belge okudum, ancak daha iyi bir çözüm bulamıyorum.
Benim gözümde en büyük sorun ST_Union kullanımıdır (dokümanda belirtildiği gibi bu fonksiyon yavaş olabilir). En ilginç şey, ST_Collect ile değiştirilmesinin ST_Buffer hesaplamasını yavaşlatması gibi görünüyor, böylece kenarlar arasındaki alanları doldurmasa da (yalnızca satırların etrafında bir tampon oluşturur) ):

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_Buffer(ST_Collect(ST_LineMerge("GEOMETRY")), 20, 'quad_segs=2') AS polygons FROM my_edges AS a
) AS b

Bu benim sistemimde yaklaşık 3.8 saniye sürüyor (yani neredeyse iki katı). Bu küçük ölçütten ilk sonucum, ST_Buffer'ın MultiLineStrings söz konusu olduğunda beklenmedik bir şekilde yavaşladığı (her satır için tampon oluştururken ve tamponları birleştirirken - hatta gözlerim sadece garip) -

Ben de (pgRouting uygulama kullanarak) alfa-şekiller kullanmaya çalıştım, ama ayarlamak için alfa değeri olmadığından (ve aslında ben gerçekten böyle bir değeri ayarlamak için hangi değere değil) Ben sadece bir büyük çokgen ( bu yüzden çok güney ve doğudaki bölgeleri ayrı bölgeler olarak kaybederdim ki istediğim bu değil).
Ayrıca ST_Polygonize (aklıma gelen ilk şeydi) herhangi bir kullanılabilir sonuç vermedi, ama belki burada bir şey kaçırdım ...

PostGIS'te gösterilen alanı oluşturmanın daha iyi bir yolu var mı? Belki de java kodu (jts) veya istemci tarafı javascript kodu (jsts) kullanarak? Aslında, sonuçta gösterilen alanlar ayrı kaldıkça ve hesaplama (çok) daha hızlı hale geldiği sürece biraz ayrıntı kaybederek yaşayabilirdim.


Sadece ST_Exteriorring (ST_Dump (ST_Union (ST_Buffer (geom, ....))). Bir arabellekten sonra bazen ST_Union'dan kaynaklanan ancak ST_GeometryType (geom) ile kolay olan Linestrings'i test etmeniz gerekebilir.Java veya jsts kullanımı söz konusu olduğunda, bunu yapabilirsiniz, ancak daha hızlı olması olası değildir. Postgis (GEOS) işlevlerinin büyük kısmı JTS'nin C / C ++ bağlantı noktalarıdır
John Powell

Haklısın, bu işe yarıyor, ama aslında daha hızlı değil (GeometryN'yi kullanırken ~ 3.1sn sürer, 2sn alır). Kullandığım şey: SELECT ST_AsGeoJson (ST_Transform (ST_Exteriorring ((ST_Dump (ST_Union (ST_Buffer ("GEOMETRY", 20)))). Geom), 4326)) FROM my_edges;
Nikolaus Krismer

@ john-barça: Oh .. Yaklaşırken quad_segs = 2 parçasını ST_Buffer'da sisliyorum ... bu değişiklikle birlikte sorgular bile (her ikisi de yaklaşık 2sn). Ancak, bu hala çok yavaş (gözlerimde), denemenin başka bir yolu var mı?
Nikolaus Krismer

İlginç bir sorun .... bazı test verilerini paylaşmak istiyor musunuz?
dbaston

Eğer yardımcı olursa bazı verileri paylaşmaktan mutluluk duyarım. Burada yaptığım tüm şeyler açık kaynak kodlu, bu yüzden bu büyük bir sorun olmamalı. Dikkat edilmesi gereken ilk şey: Test için bir web uygulaması dbis-isochrone.uibk.ac.at:8080/testing adresinde bulunmaktadır . Üzerinde çalıştığım şeyler hakkında daha fazla bilgiyi dbis-isochrone.uibk.ac.at adresinde bulabilirsiniz . Web sitesinin "bağlantılar" bölümünde bazı referanslar vardır (bazı test verileri dahil)
Nikolaus Krismer

Yanıtlar:


5

GeoJSON serileştirmesini bir kenara bırakarak, dizüstü bilgisayarımda aşağıdakiler yaklaşık 6,3 saniye sürüyor:

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(geom, 20, 2)))).geom))
FROM bz_edges

OpenJUMP'daki verilere baktığımda, çıktıdaki istenen ayrıntı düzeyine göre sokak segmentlerinde biraz ayrıntı fark ettim. Bu çizgilerin anında basitleştirilmesi bile PostGIS'de büyük bir hızlanmaya neden olabilir:

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(ST_Simplify(geom, 10), 20, 2)))).geom))
FROM bz_edges

bu da 2,3 saniyeye düşüyor. Genelleştirilmiş geometriyi anında hesaplamak yerine ayrı bir sütunda saklayarak daha iyi yapabileceğimi düşündüm, ama aslında ek bir fayda sağladı.

Ne kadar kod yazmak istediğinize bağlı olarak, başka hiçbir şey yoksa Java'da neredeyse kesinlikle daha iyisini yapabilirsiniz, çünkü birden fazla çekirdekten yararlanabilirsiniz. (Değeri ne olursa olsun, JTS yukarıdaki işlemi 2.8 saniyede gerçekleştirir). Bir yaklaşım CascadedPolygonUnion, bazı sendika operasyonlarının paralel gerçekleşmesini sağlamaktır. (güncelleme - işte bir ParallelCascadedPolygonUnion )

Örnek verilerde, kenarların başlangıç ​​ve bitiş düğümlerine referanslarla saklandığını fark ettim, yani önceden oluşturulmuş bir grafiğiniz var. Genel geometri işlemlerini kullanmak yerine grafikten çalışırsanız bu çokgenleri çok daha hızlı oluşturabileceğinizden şüpheleniyorum . Örneğin, böyle bir şey yapabileceğinizi düşünüyorum:

  1. grafiğin bağlı bileşenlerini tanımlayabilir
  2. bağlı her bileşen için, minimum X koordinatına sahip düğümü bulun (bileşenin dışında olduğu garanti edilir)
  3. mümkün olduğunda daima sola (veya sağa) dönerek bileşenin kenarlarını yürüyün. Bu size her bir bileşenin dış halkasını verecektir.
  4. dış halkayı ve tamponu uygun şekilde çokgenleştirin.

Teşekkürler ... sadeleştirme büyük ve hatta "basit" bir gelişmedir. Dizüstü bilgisayarımda gereken süreyi 1,5 saniyeye düşürdü. Olmak istediğim yer değil, biraz daha iyi.
Nikolaus Krismer

Önerilen çözüm hakkında (1-4. Noktalar). Sesler de çok basit ve denemeye değer. Ben benzer bir şey düşündüm, ama ben point1 (çok çok erken :-)) sıkışmış. Bir bağlı bileşenleri nasıl tanımlayacaktı (aklıma gelen tek şey, çok yavaş olabilen özyinelemeli bir sorgudur).
Nikolaus Krismer

Ben ikisini de kullanmak @NikolausKrismer JGraphT ve tezgah böyle görevler için. Bunun yerine kendi grafik yöntemlerinizi yazarsanız (en iyi performans için kötü bir fikir değil), önce derinlemesine bir arama size bileşenleri bulur. (Onları ile yaklaşan PostGIS 2.2'de bulabilirsiniz, ST_ClusterIntersectingancak her türlü grafik işlemenin veritabanının dışında gerçekleşmesini istediğinizi düşünüyorum, bu muhtemelen yararlı değildir).
dbaston

bunlar bazı harika ipuçları. JGraphT'a baktım ve bu kesinlikle sorunumu çözmeye yardımcı olabilir. Ancak, Postgis 2.2 ve ST_ClusterIntersecting işlevine de baktım -> yukarıdaki durumda farklı kümeleri tanımlamak yaklaşık 200-250 msn sürer. Benim için sorun değil (JGraphT kesinlikle daha iyisini yapabilir). Şimdi (ST_MakePolygon benim olunan bağlantılar hiçbir kabuk diyor çünkü ST_ExteriorRing, başarısız) exteriorRing oluşturma ile uğraşmak zorunda
Nikolaus Krismer

İki komplikasyon görüyorum: (a) sadece dış halkaya değil, aynı zamanda bu halkanın dışına doğru uzanan segmentlere de ihtiyacınız var ve (b) çizgileriniz aslında bazı kavşaklarda kesişmiyor gibi görünüyor. Bir grafik yürüyüşünün sonuçlarından bir geometri oluşturmaya çalışacaksanız (b) 'yi düzeltmeniz gerekecektir.
dbaston
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.