Holen Sie sich alle Linien, die einen Punkt einschließen

12

Ich benutze QGIS und ich habe einen Punkt und das Straßennetz. Ich muss die Straßennamen, die den bestimmten Punkt einschließen, automatisch extrahieren. Bildbeschreibung hier eingeben Analyse- und Pufferzonen für die nächsten Nachbarn können diese Aufgabe nicht ausführen, da der Punkt in vielen Fällen in Abhängigkeit von der gemessenen Entfernung näher an den Nachbarstraßen liegt und nicht an den angrenzenden Straßen. Gibt es irgendwelche Ideen, wie nur die umliegenden Straßen extrahiert werden könnten?

ML
quelle
6
Vielleicht konvertieren Sie den umschließenden Bereich (bestehend aus einer Reihe von Linien) in ein Polygon mit Attributen, aus welchen Straßen die Polygonwände bestehen - dann können Sie eine einfache Auswahl treffen, indem Sie die Position überlappen. In diesem Beispiel fällt der Punkt "145699" in das Polygon "roada_roadb_roadc_roadd".
Map Man

Antworten:

3

Über meine Testdaten:

  1. Wie bei OSM Road Data endet jede einzelne Straßengeometrie an einer Kreuzung.
  2. Jede Straße hat eine eindeutige ID.

LÖSUNG I

Wenn es die zwei Annahmen gibt:

  1. Straßen bauen Viertel.

  2. Sie arbeiten in einem metrischen System.

Die Idee ist, die X- und Y-Koordinaten des Punktes zu erhöhen / zu verringern. Wenn Sie in einem metrischen System arbeiten, können Sie 1 m östlich von Ihrem Punkt einen neuen Punkt erstellen und eine Linie mit dem ursprünglichen Punkt erstellen. Sie fahren weiter nach Osten, bis die Linie eine Straße kreuzt. Um nach einer Kreuzung im Westen zu suchen, müssen Sie 1 m von der ursprünglichen X-Koordinate subtrahieren. Gleiches gilt für die Y-Koordinate. Wenn es im Norden / Osten / Süden / Westen keine Straße gibt, hält der Zähler bei 1000 (m). Wenn Sie wissen, dass sich eine Straße in einer Entfernung von mehr als 1000 m befindet, müssen Sie diesen Wert ändern.

Sie können die Aufgabe mit folgendem Code lösen:

Bearbeitet

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

startpoint_iter = startpoint.getFeatures()
for feature in startpoint_iter:
    geom = feature.geometry()
    if geom.type() == QGis.Point:
        xy = geom.asPoint()
        x,y = xy[0], xy[1]

line_start = QgsPoint(x,y)      

def reached(direction, count_m):
    road_reached = None
    road = None
    count=1
    while road_reached < 1 and count <=count_m:
        count += 1
        if direction == 'N':
            line_end = QgsPoint(x, y+count)
        if direction == 'E':
            line_end = QgsPoint(x+count,y)
        if direction == 'S':
            line_end = QgsPoint(x,y-count)
        if direction == 'W':
            line_end = QgsPoint(x-count,y)
        line = QgsGeometry.fromPolyline([line_start,line_end])
        for f in roads.getFeatures():
            if line.intersects(f.geometry()):
                road_reached = 1
                road = f['name']
                print road

reached('N', 1000)
reached('E', 1000)
reached('S', 1000)
reached('W', 1000)

Ein weiteres Beispiel dafür, dass die Straße e im Osten nicht als nahe gelegene Straße des Punkts erkannt wird.

Bildbeschreibung hier eingeben

So rufen Sie die Funktion und den Ausgang auf:

>>>>reached('N', 1000)
road a
>>>>reached('E', 1000)
road b
>>>>reached('S', 1000)
road c
>>>>reached('W', 1000)
road d

Wenn der Punkt von mehr als 4 Straßen umschlossen ist, müssen Sie in mehrere Richtungen schauen (ändern Sie sowohl X als auch Y). Oder Sie können den Azimut Ihrer Linie ändern, dh Sie können sie um einen Grad im Bereich von 0 bis 360 ° drehen.

LÖSUNG II

Inspiriert von dem Kommentar kannst du auch zuerst Polygonizedeine Straßen. Dafür können Sie ein Werkzeug aus QGIS benutzen Processing > Toolbox > QGIS geoalgorithms > Vector geometry tools > Polygonize. Benennen Sie die temporäre Ebene in um polygon. Angenommen, Sie möchten nur die Straßennamen für den Punkt haben, der vollständig von Straßen umschlossen ist. Andernfalls müssen Sie LÖSUNG I verwenden . Dies funktioniert nur, wenn alle Straßen verbunden (eingerastet) sind!

Bildbeschreibung hier eingeben

Zuerst muss sich der Punkt mit dem Polygon schneiden. Die Idee ist nun, dass sich beide Start- und ANDEndpunkte einer umschließenden Linie mit dem Polygon schneiden müssen.

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "point":
        startpoint = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "polygon":
        poly = lyr

for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "roads":
        roads = lyr

for h in startpoint.getFeatures():
    for g in poly.getFeatures():
        if h.geometry().intersects(g.geometry()):
            poly_geom = g.geometry()
            for f in roads.getFeatures():
                geom = f.geometry().asPolyline()
                start_point = QgsGeometry.fromPoint(QgsPoint(geom[0]))
                end_point = QgsGeometry.fromPoint(QgsPoint(geom[-1]))
                if poly_geom.intersects(start_point) and poly_geom.intersects(end_point):
                    print f['name']

Die Ausgabe:

road c
road b
road e
road f
Stefan
quelle