QGIS ile Python kullanarak geçiş yapmak için kesişen çizgiler mi var?


11

Otobüs hatlarını temsil eden bir dizi hattım var. Bazı çizgiler üst üste biniyor ve aynı yolları kullanıyor.

resim açıklamasını buraya girin

Düğümleri çıkarabiliyorum. resim açıklamasını buraya girin

Ancak ben sadece böyle geçişleri ayıklamak ilgileniyorum: resim açıklamasını buraya girin

Bunu nasıl yapabilirim? QGIS veya Python ile yollar arıyorum.

GDAL Python'dan kesişim yöntemini denedim ama bu temelde bana sadece köşeleri döndürüyor.

Çizgi Intersections yöntemi iki satır çapraz eğer QGIS dan bana geçişleri döndürür. Ancak iki otobüs hattının aynı yol üzerindeki güzergahlarının bir kısmına gitmesi durumunda, bana birleştikleri yere işaret etmiyorlar.


QGIS'te çizgi kavşak aracını denediniz mi: Vektör Analiz Aracı> Çizgi Kavşakları ... Size bir çizginin bitiş ve başlangıç ​​düğümlerini değil, tüm kavşakları verir.
Jakob

Evet, bu soru hakkında yazdım.
ustroetz

Sorduğunuz şeyden emin değilim, kısmen tüm çizgiler görüntülerinizde aynı şekilde sembolize edildi - Hangi düğümlere baktığınızı veya neden bu kadar çok düğüm bulunduğunu anlamak için farklı yollar söyleyemiyorum. ikinci görüntü. Rotalar yollarda çakışıyor mu? Hepsi iki noktalı çizgi parçaları mı yoksa sürekli çoklu çizgiler mi? Açıkladığınız davranışın ArcGIS 'Kesişim aracı ile aynı olduğunu unutmayın - satır çıktısı olan çizgiler / çizgiler size çakışma veriyor, ancak nokta çıktısı olan çizgiler / çizgiler sadece geçişler veriyor.
Chris W

Buna dayanarak, istediğinizi elde etmek için her iki yöntemi de kullanmak zorunda kalabilirsiniz. Geçişleri alın (çizgi / çizgi = nokta) ve ardından çakışmaları (çizgi / çizgi = çizgi) alın ve bu çakışan çizgiler için başlangıç ​​/ bitiş düğümlerini çıkarın. Bunlar aradığınız tüm noktalar / düğümler olmalıdır.
Chris W

Yanıtlar:


22

Düğümler:

İki şey istiyorsunuz, çoklu çizgilerin bitiş noktaları (ara düğümler olmadan) ve kesişim noktaları. Ek bir sorun var, bazı çoklu hatların uç noktaları da kesişim noktalarıdır:

resim açıklamasını buraya girin

Çözüm Python ve Shapely ve Fiona modüllerini kullanmaktır

1) şekil dosyasını okuyun:

from shapely.geometry import Point, shape
import fiona
lines = [shape(line['geometry']) for line in fiona.open("your_shapefile.shp")]

2) Çizgilerin uç noktalarını bulun (bir çoklu çizginin uç noktalarını nasıl elde edersiniz? ):

endpts = [(Point(list(line.coords)[0]), Point(list(line.coords)[-1])) for line  in lines]
# flatten the resulting list to a simple list of points
endpts= [pt for sublist in endpts  for pt in sublist] 

resim açıklamasını buraya girin

3) Kavşakları hesaplayın ( itertools modülü ile katmandaki geometri çiftleri üzerinden yineleme ). Bazı kavşakların sonucu MultiPoints'tir ve bir nokta listesi istiyoruz:

import itertools
inters = []
for line1,line2 in  itertools.combinations(lines, 2):
  if  line1.intersects(line2):
    inter = line1.intersection(line2)
    if "Point" == inter.type:
        inters.append(inter)
    elif "MultiPoint" == inter.type:
        inters.extend([pt for pt in inter])
    elif "MultiLineString" == inter.type:
        multiLine = [line for line in inter]
        first_coords = multiLine[0].coords[0]
        last_coords = multiLine[len(multiLine)-1].coords[1]
        inters.append(Point(first_coords[0], first_coords[1]))
        inters.append(Point(last_coords[0], last_coords[1]))
    elif "GeometryCollection" == inter.type:
        for geom in inter:
            if "Point" == geom.type:
                inters.append(geom)
            elif "MultiPoint" == geom.type:
                inters.extend([pt for pt in geom])
            elif "MultiLineString" == geom.type:
                multiLine = [line for line in geom]
                first_coords = multiLine[0].coords[0]
                last_coords = multiLine[len(multiLine)-1].coords[1]
                inters.append(Point(first_coords[0], first_coords[1]))
                inters.append(Point(last_coords[0], last_coords[1]))

resim açıklamasını buraya girin

4) Bitiş noktaları ile kesişme noktaları arasındaki kopyaları ortadan kaldırın (şekillerde gördüğünüz gibi)

result = endpts.extend([pt for pt in inters  if pt not in endpts])

5) Ortaya çıkan şekil dosyasını kaydedin

from shapely.geometry import mapping
# schema of the shapefile
schema = {'geometry': 'Point','properties': {'test': 'int'}}
# creation of the shapefile
with fiona.open('result.shp','w','ESRI Shapefile', schema) as output:
    for i, pt in enumerate(result):
        output.write({'geometry':mapping(pt), 'properties':{'test':i}})

Son sonuç:

resim açıklamasını buraya girin

Çizgi parçaları

Düğümler arasındaki segmentleri de istiyorsanız, şekil dosyanızı "planarize" ( Düzlemsel Grafik , hiçbir kenar birbirini geçmez ). Bu Shapely'nin unary_union işlevi tarafından yapılabilir

from shapely.ops import unary_union
graph = unary_union(lines)

resim açıklamasını buraya girin


Ayrıntılı cevap için @ gene teşekkürler. Farklı geometri türlerinin üzerinden geçtiği kısmı düzenledim. Benim durumumda kesişme çizgileri, geometri toplamaları vb. De döndürür. Ancak bu girdi verilerine bağlıdır. Sorumda yeterince açık değildim.
ustroetz

Mükemmel cevap. Aşağıdakileri yapmanın gerekli olmadığını ekleyebilirim: result = endpts.extend([pt for pt in inters if pt not in endpts])çünkü .extendyöntemin değiştiği anlaşılıyor endpt. Bu result = Noneoperasyondan sonra benim durumumda . Öyle endptssonuç taşları içeren biter hangi
user32882
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.