Holen Sie sich einen Punkt auf einer Polylinie von den Endpunkten, die den Abstand entlang der Polylinie angegeben haben

10

Ich habe Startpunkt und Endpunkt einer Polylinie. Wie kann ich einen Punkt auf dieser Polylinie von Endpunkten erhalten, die durch den angegebenen Abstand angegeben sind?

Geben Sie hier die Bildbeschreibung ein

Wie kann ich dies mithilfe von arcpy erreichen, vorausgesetzt, dieses Skript sollte in ArcView funktionieren, ohne dass Module importiert werden ( wie diese Antwort ). Ich versuche, Werte nicht fest zu codieren.

Verwandte Frage:

Nutzer
quelle
Erhalten Sie mit object.interpolate (distance [, normalized = False]) keine Ergebnisse?
Vinayan
1
Wo hast du object.interpolate(distance[, normalized=False]). Ist es eine Methode von Arcpy? Wenn ja, können Sie bitte den Link posten. Ich habe es gegoogelt, aber nicht gefunden.
Benutzer
Es ist Shapelys Methode. toblerity.github.com/shapely/… Ich glaube, Sie haben es in der anderen Frage versucht . Ich bin mir nicht sicher, ob Sie Ergebnisse erzielt haben.
Vinayan
2
Eine weitere verwandte Frage ist gis.stackexchange.com/questions/6476/… , die die Umkehrung dieses Problems betrifft (ermitteln Sie die Entfernung anhand des Punkts). Die beiden Lösungen sind eng miteinander verbunden: Sobald die Polylinie messbar gemacht wurde, können alle Punkte entlang ihrer Polylinie in Bezug auf ihre Abstände adressiert werden (und beliebige Segmente entlang dieser Polylinie können durch Entfernungsbereiche adressiert werden).
whuber

Antworten:

7

Dies klingt ähnlich wie "Lineare Referenzierung" und dieses Toolset wäre in ArcView verfügbar. Darüber hinaus können Sie dieses Tool sehr einfach skripten.

Link zur ESRI-Hilfe für die lineare Referenzierung

Louis H.
quelle
1
+1 Dies ist der "richtige" Ansatz im Sinne der Verwendung einer ausgereiften Fähigkeit, die ausdrücklich für dieses Problem entwickelt wurde.
whuber
6

Basierend auf Ihren Anforderungen, wie @LouisH erwähnt, ist die Verwendung der linearen Referenzierung definitiv der richtige Weg. Ich habe einen Code zusammengeschustert, der Ihren Bedarf an nicht hartcodierten Elementen erfüllen sollte, sondern sie stattdessen als Parameter anfordert.

Zur Erläuterung verwendet das unten verwendete lineare Referenzierungswerkzeug "Routen", in Ihrem Fall die Linienmerkmale, und platziert "Ereignisse", in Ihrem Fall die Punkte, basierend auf einem Entfernungsfeld entlang dieser. Dies führt zu einem FeatureLayer, der im Speicher gespeichert ist. Dies ist der Grund für die letzte Funktion, die die Features in eine Ausgabe-Feature-Class kopiert.

import arcpy
import os
from arcpy import env

#Working directory
wkspace        = arcpy.GetParameterAsText(0)
#Line feature class
rtecls         = arcpy.GetParameterAsText(1)
#Line Unique ID
rtecls_ID      = arcpy.GetParameterAsText(2)
#Table of points to be located
pnttbl         = arcpy.GetParameterAsText(3)
#Field in point table that references line point will be located along
pttbl_rteid    = arcpy.GetParameterAsText(4)
#Distance field in point table
pttbl_dst      = arcpy.GetParameterAsText(5)
#Output Layer, layer is stored in memory.  Features still need to be copied to feature class saved to disk
outlayer       = arcpy.GetParameterAsText(6)
#Output Feature Class - If shapefile, make sure to include ".shp" at the end.
outclass       = arcpy.GetParameterAsText(7)

#Type of feature being located
fttype = "POINT"

#Set Workspace
env.workspace = wkspace

#Build String for input parameters in Linear Referencing tool
pt_props = pttbl_rteid + " " + fttype + " " + pttbl_dst

#Output featureclass path
outfclass = wkspace + os.sep + outclass

# Execute MakeRouteEventLayer
arcpy.MakeRouteEventLayer_lr (rtecls, rtecls_ID, pnttbl, pt_props, outlayer)

#Save feature layer to feature class on disk
arcpy.CopyFeatures_management(outlayer, outfclass)

Bearbeiten - Eine Sache, über die Sie mit diesem Werkzeug nachdenken sollten, und wahrscheinlich jede Operation zum Lokalisieren von Punkten basierend auf dem Abstand vom Ende einer Linie, ist das Ende der Linie, von dem aus Sie beginnen. Das lineare Referenzierungswerkzeug arbeitet beispielsweise basierend auf der digitalisierten Richtung einer Linie. Es ist wichtig sicherzustellen, dass Sie auf irgendeine Weise feststellen können, auf welchem ​​Endpunkt Ihre Messungen basieren.

Holen Sie sich räumlich
quelle
5

Das Lösen eines solchen linearen Referenzproblems without importing any modulesliegt außerhalb meines Bereichs.

Ich habe verwendet Shapely(Python-Paket für die Manipulation und Analyse von 2D-Geodatengeometrien. Und es ist BSD-lizenziert :-))

Laden Sie es hier herunter . Die Version 2.6 ist die einzige, die arcgis 10 arcpy unterstützt. Es handelt sich um eine einfache Installation (Größe 1,5 MB).

und jetzt ist hier das arcpy-Skript, um den Zweck zu erreichen. Verzeih meine Python. Nur heute habe ich etwas über die Schleifen, Tupel usw. gelernt :)

import arcpy
import math
from arcpy import env

env.workspace = r"C:\testshape"

desc = arcpy.Describe("Rivers.shp")
shapefieldname = desc.ShapeFieldName

rows = arcpy.SearchCursor("Rivers.shp")

temptup = ()

# get ESRI geometries out of their cage..
for row in rows:

    feat = row.getValue(shapefieldname)
    partnum = 0
    for part in feat:
        for pnt in feat.getPart(partnum):
            if pnt:
                temptup += ((pnt.X, pnt.Y),)
            else:
                print "Interior Ring:"
        partnum += 1    

# and now the shapely magic :)

import shapely
from shapely.geometry import LineString
lnstr = LineString(temptup)
rsltPoint = lnstr.interpolate(0.5)
print(rsltPoint.x,rsltPoint.y)

Hinweis : Dies funktioniert nicht, wenn das Feature Kurvensegmente enthält

Vinayan
quelle
2

Ich fand diese Frage beim Versuch, das zu tun, was ich für dasselbe halte. Ich wollte, dass alles über arcpy erledigt wird. Die Verwendung der linearen Referenzierung war für mich nicht sinnvoll, da ich die Punktereignisse noch nicht habe (und nicht herausfinden konnte, wie ich sie mit LR abrufen kann). Der Kern dessen, was ich letztendlich benutzte, war

    line = arcpy.Polyline(arrayPts)
    pt = line.positionAlongLine (0.99, 'True')

Dies erfordert Arc 10.1 oder höher. Ich konnte nicht herausfinden, ob dies unter der von mir angegebenen ArcInfo-Lizenzstufe (OP-spezifiziertes ArcView) verfügbar war.

In meinem obigen Beispiel wollte ich einen Punkt nicht in einem festen Abstand, sondern um einen Prozentsatz der gesamten Linienlänge. Dazu habe ich das zweite optionale Argument an geliefert positionAlongLine. Sie überspringen das zweite Argument, wenn Sie nur einen absoluten Abstand angeben möchten. Hier ist das Dokument .

Das ausführlichere Codebeispiel ist

import numpy
ptsList = list()
id = 0

with arcpy.da.SearchCursor('flFL', ["SHAPE@"]) as cursor:
    for row in cursor: 
        arrayPts = row[0].getPart()
        line = arcpy.Polyline(arrayPts)
        pt = line.positionAlongLine (0.99, 'True')
        ptsList.append((id, (pt.getPart().X, pt.getPart().Y)))
        id += 1

array = numpy.array([ptsList], \
numpy.dtype([('idfield',numpy.int32),('XY', '<f8', 2)]))

SR = arcpy.Describe("flFL").spatialReference
arcpy.da.NumPyArrayToFeatureClass(array, 'nsegSamplePts', ['XY'], SR)

'flFL'ist meine FeatureLayer-Linie, auf der ich die Punkte lokalisieren möchte. Läuft ziemlich schnell. NumPyArrayToFeatureClasswar eine sehr schöne Möglichkeit, alle meine Punkte wieder in eine Feature-Klasse zu stecken (danke an meinen Kollegen Curtis für diesen Teil!). Hatte mit experimentiert, Append_managementaber das war ein bisschen langsamer.

Roland
quelle
+1 Danke, dass du das geteilt hast. Es sieht nach einer guten einmaligen Lösung aus, wenn Sie nicht den Aufwand für die Einrichtung einer gemessenen Polylinie investieren möchten. Beachten Sie, dass diese Lösung die implizite Ausrichtung der Polylinie verwendet, die durch die Reihenfolge bestimmt wird, in der ihre Koordinaten gespeichert werden. Wenn Sie nicht darauf achten, erhalten Sie möglicherweise Punkte, die am falschen Ende berechnet werden. Daher wäre es schön, diese Lösung zu verbessern, damit der Benutzer (irgendwie) festlegen kann - möglicherweise durch Eingabe eines Punktes in der Nähe eines Endes -, der der Anfang der Polylinie ist.
whuber
1
Das stimmt definitiv. Ich verwende Leitungen aus einem Entwässerungsnetz, die alle (angeblich) stromabwärts ausgerichtet sind, also musste ich mich nicht darum kümmern. Wenn die Linienausrichtung nicht absichtlich ist, kann sie als Vorprozess zu dem angeordnet werden, was ich oben vorgeschlagen habe. Wenn die Orientierung absichtlich ist, kann man eine Kopie erstellen, neu orientieren und mein Rezept verwenden. Die Punkte werden weiterhin korrekt auf der ursprünglichen Linien-Feature-Class ausgerichtet, auch wenn ihre Ausrichtung der aktuellen Analyse nicht förderlich ist.
Roland
1

Könnte ein Overkill sein, aber wenn Sie Zugriff auf die Netzwerkanalyse-Erweiterung haben, können Sie ein Netzwerk aus Ihren Polylinien erstellen und dann Servicebereiche um Ihre Eingabepunkte erstellen , wobei Sie die SA-Größe als interessierende Entfernung angeben. Hier ist ein flüchtiges Beispiel mit 111 Metern SA vom Punkt:

Geben Sie hier die Bildbeschreibung ein

Dann müssten Sie Punkte finden, an denen SA die Linie kreuzt.

Radek
quelle
-1

Ich denke, Sie können es mit Feature Vertices To Points (Datenverwaltung) Methode erhalten. Weitere Informationen erhalten Sie hier .

oder Sie können aus Split Linie bei Point (Data Management) überprüfen hier .

Sie sind nicht genug, aber Sie können Ihren eigenen Code schreiben ...

ich hoffe es hilft dir ...

Aragon
quelle
2
Es scheint, dass das Problem bei diesen Optionen darin besteht, dass sie Vorkenntnisse über die Punktposition erfordern, um die Linie zu teilen, oder um vor dem Teilen einen Scheitelpunkt an der Linie hinzuzufügen. Dieser Punkt ist in der obigen Frage nicht bekannt, daher ist es schwierig, eine dieser Lösungen anzuwenden.
Holen Sie sich Spatial