Eşleşen segmentler için algoritmalar


23

Segmentleri eşleştirmek için en iyi algoritmalar hangileridir?

İki harita kaynağından karşılık gelen segmentleri eşleştirmeye çalışıyorum, biri daha az doğru fakat segment isimleriyle, diğeri de isimler olmadan isabetli. Segment adlarını yarı otomatik olarak daha doğru haritaya uygulamak istiyorum.

İstenen algoritmanın oldukça belirsiz bir açıklaması vardır, çünkü "eşleşme" iyi tanımlanmamıştır ve birçok faktörün (oryantasyon, bağıl uzunluk, mesafe) farklı senaryolarda farklı ağırlıkları olabilir; Ancak, bu problemi ele almak için genel yaklaşımlar hakkında temel bilgileri arıyorum.

Açık kaynaklı ortam için çalışma uygulamaları (PostGIS, düzgün, ...) sıcak bir şekilde kabul edilir.

Örnek parçalar : Resimlerin altındaki açıklamaya bakınız.


Segment yoğunluğuna ve bunların ne kadar farklı olduğuna dair bir genel bakış sağlamak için verilerinizin bir görüntüsünü gönderebilir misiniz?
julien

1
Flickr'da bazı resimler yayınladım, bağlantıya bakınız.
Adam Matan

1
"Konfederasyon" için arama yapmayı deneyebilirsiniz.
Kirk Kuykendall

Yanıtlar:



10

Neyin "en iyisi" olacağını bilmiyorum, çünkü bu, segmentlerinizin özelliklerine bağlı olacaktır.

Genel olarak iyi bir yaklaşım, segmentleri çok önemli geometrik bilgilere ayırmaktır . Bu, en azından merkezin konumunu (x, y), yönelimi (0 ila 180 derece) ve uzunluğu içerir. Uygun ağırlıklar uygulanmış ve oryantasyondaki bazı ustalıklar (180 "0'a dönüyor" olduğundan, hemen hemen tüm istatistiksel kümeleme algoritmasını tüm segmentlerin koleksiyonuna uygulayabilirsiniz . ( K-araçları iyi bir seçenektir, ancak çoğu hiyerarşik yöntem iyi çalışması gerekir. kolay.

Oryantasyon sorunuyla ilgilenmenin bir yolu etiketli bölümlerin bir kopyasını çıkarmaktır. 90’dan küçükse, ilk kopyanın oryantasyonuna 180 derece ekleyin ve aksi takdirde oryantasyondan 180 derece çıkarın. Bu, veri kümenizi büyütür (tabii ki), ancak aksi halde algoritmayı hiçbir şekilde değiştirmez.

Ağırlıklara ihtiyaç vardır, çünkü koordinatların, uzunlukların ve yönlerin farklılıkları, karşılık gelen bölümlerinin benzerlikleri ile ilgili oldukça farklı şeyler anlamına gelebilir. Birçok uygulamada segmentler arasındaki farklılıklar, bitiş noktalarındaki yerlerdeki farklılıklardan kaynaklanmaktadır. Kaba bir yaklaşım olarak, segment uzunluklarındaki tipik değişikliklerin, bitiş noktaları arasındaki tipik değişikliklerle yaklaşık olarak aynı olmasını bekleyebiliriz. Bu nedenle, x, y ve uzunlukla ilişkili ağırlıklar yaklaşık olarak aynı olmalıdır. En zor kısım oryantasyonu arttırmaktır, çünkü oryantasyon mesafe ile eşitlenemez ve daha da kötüsü kısa parçaların uzun parçalara göre yanlış yönlendirilmiş olma ihtimalleri daha yüksektir. Birkaç derece yanlış yönlendirmeyi, segmentler arasındaki tipik bir boşluğun boyutuna eşitleyen ve ardından prosedürün iyi işlediği anlaşılana kadar ayarlayan bir deneme yanılma yöntemi düşünün. Rehberlik içinL , tipik bir segment uzunluğu olabilir. Ufacık açı ile oryantasyon değişikliği t derece, yaklaşık bir mesafe üzerinden süpürecek L / 2 * t / 60, (60, bir radyan olarak derece sayısını yaklaşacağı şekilde) L / 120 kez t . Bu, x, y ve uzunluk için birim ağırlıklarla başlamak ve oryantasyon için L / 120 ağırlık anlamına gelir .

Özet olarak , bu öneri:

  1. Etiketli bölümlerin kopyalarını alın (oryantasyona ilişkin paragrafta açıklandığı gibi).

  2. Her bir parçayı dörtlü (x, y, uzunluk, L / 120 * yönlendirme) içine dönüştürün, burada L tipik bir segment uzunluğudur.

  3. Dörtlülerin küme analizi yapın. İyi bir istatistiksel paket kullanın ( R ücretsizdir).

  4. Etiketli bölümleri yakındaki etiketlenmemiş bölümlerle ilişkilendirmek için küme analizi çıktısını arama tablosu olarak kullanın.


4

Yaklaşık 5 yıl önce benzer bir projede çalıştım. Sokak merkez hatlarından ( nispeten yüksek koordinat hassasiyetine sahip) koordinatları Otoyol Performans İzleme Sistemi (HPMS) trafik ağı bağlantıları ile birleştirmeyi içeriyordu.

O zaman FHWA bu tür şeyleri yapmak için hiçbir araç sağlamadı. Değişmiş olabilir, kontrol etmek isteyebilirsiniz. Otoyol verileriyle çalışmıyor olsanız bile, araçlar yine de alakalı olabilir.

ArcGIS ile yazdım, ancak ISegmentGraph'a benzer izleme yetenekleri sağladığı sürece algoritma açık kaynakta çalışmalıdır :

// features is a collection of features with higher geometry
// Links are a collection features with attributes but low res geometry
For each Link in lowResFeatureclass
    point startPoint = SnapToClosestPoint(Link.StartPoint, hiResfeatures);
    if(startPoint == null)
       continue;
    point endPoint = SnapToClosest(Link.EndPoint, hiResfeatures);
    if(endPoint == null)
       continue;
    polyline trace = Trace(hiResfeatures,startPoint,endPoint);
    if(polyline != null)
    {
        // write out a link with high precision polyline
        Write(Link,polyline);
    }
Next Link

4

İşte bir fikir geliyor

Karşılaştırma yapmak ve bağlantı noktalarının karşılaştırma yapmak için diğer bağlantı noktalarından belirli bir mesafede olup olmadığını test etmek için bağlantı noktalarından birini ayırırsanız testi birçok şekilde kontrol edebilirsiniz.

Bu örnekler PostGIS’de (kim tahmin edebilir :-))

Birincisi, eğer tablo_1'deki bir çizgideki tüm köşe noktalarının 0,5 metre (harita birimleri) veya tablo_2'deki bir çizgiye yakın olması durumunda bir eşleşme olduğunu söylersek:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points,
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(*)=num_of_points;

Öyleyse, tablo_1'deki bir çizgideki vertex_points öğelerinin% 60'ından fazlası, tablo_2'deki bir çizginin mesafesi dahilindeyse bir eşleşme olduğunu söyleyebiliriz.

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)/num_of_points::float > 0.6

Veya bir noktanın menzilde olmadığını kabul edebiliriz:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)-num_of_points <= 1;

Ayrıca sorguyu tablo_1 ve tablo_2 ile ters çevrilmiş rollerde çalıştırmanız gerekir.

Ne kadar hızlı olacağını bilmiyorum. ST_Dumppoints şu anda PostGIS'te bir sql işlevidir ve olması gerekenden daha yavaş olmasını sağlayan bir C işlevi değildir. Ama yine de oldukça hızlı olacağını düşünüyorum.

Mekansal dizinler ST_Dwithin'ın etkili olması için çok yardımcı olacaktır.

HTH Nicklas


1
+1 Bu, en sonunda kullandığım yaklaşıma çok benziyor (yakında bir cevap gönderecek).
Adam Matan

4

Sınır Oluşturucu'da özensiz çizgi kesimi eşleştirmesini (ve üst üste bindirmeyi) ele almak için kod yazdım. (Oldukça basit) matematiğini burada yazdım: http://blog.shoutis.org/2008/10/inside-boundary-generator-computational.html . Kod açık kaynak kodlu ve o blog postasına bağlı.

Kod gerçekten basit bir yaklaşım izler:

  • İki çizgi parçasının verilen açı ve mesafe toleransları ve örtüşme miktarı dahilinde çakışıp çakışmadığını size söyleyen bir segment segmenti testi.
  • Veri kümesindeki her satır parçasını, veri kümesindeki tüm diğer satır parçalarına karşı sınama gereksinimini ortadan kaldıran hızlı ve uzamsal bir dizin.

Bu yaklaşımın temel avantajı, geçerli açı, mesafeler ve örtüşme uzunluğu için hassas topuzlar elde etmektir; Dezavantajı ise, genellikle iki çizgi parçasının benzerliğini ölçmenin bir yolu değildir, bu nedenle olası eşleşmeleri belirlemek için örneğin istatistiksel kümelemeyi yapmak çok zordur - hassas düğmelerle sıkışıp kalıyorsunuz.

Not: Yeterli SQL kesimi ile segment segmenti testini bir WHERE deyimine tıkayabileceğinizi tahmin ediyorum ... :)

Şerefe!


+1 Bu güzel bir yaklaşım; dörtlü bina hesaplamada üstündür. Ama bakım ayrıntılarda gereklidir: bulunan segment menşeli: segment yakınlık veya benzerlik (yerine kavşak) belirlemede, veri yapısı bir segmentin benzersiz temsilini sağlamaz gerçeği hesaba ihtiyaç x yönde, v uzunluğun t de kademeli bir kaynak eşit derecede iyi bir x + t v yönde -v uzunluğu t .
whuber

1

Harita eşleme için burada kullanımı kolay olan kaba bir prototip uyguladım . Açık kaynak kodlu yönlendirme motoruna dayanır ve Java ile yazılmıştır. Kullanılan algoritma burada açıklanmaktadır .

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.