Uzyskaj punkt na polilinii z punktów końcowych podanych w odległości wzdłuż linii wieloliniowej


10

Mam punkt początkowy i końcowy polilinii. Jak mogę uzyskać punkt na tej polilinii z punktów końcowych określonych przez podaną odległość.

wprowadź opis zdjęcia tutaj

Jak mogę to uzyskać za pomocą arcpy, pod warunkiem, że ten skrypt powinien działać w ArcView bez importowania żadnych modułów ( taka odpowiedź ). Staram się nie wprowadzać twardych wartości kodu.

Powiązane pytanie:


nie otrzymujesz żadnych wyników za pomocą object.interpolate (odległość [, znormalizowany = Fałsz])?
vinayan

1
Skąd wziąłeś object.interpolate(distance[, normalized=False]). Czy to metoda arkady? Jeśli tak, czy możesz wysłać link. Przejrzałem go, ale go nie znalazłem.
użytkownik

jest to metoda foremna .. toblerity.github.com/shapely/ ... myślę, że wypróbowałeś to w innym pytaniu .. nie jestem pewien, czy uzyskałeś wyniki ..
vinayan

2
Kolejnym powiązanym pytaniem jest gis.stackexchange.com/questions/6476/... , który dotyczy odwrotności tego problemu (znajdź odległość podaną w punkcie). Oba rozwiązania są ze sobą ściśle powiązane: gdy polilinia jest mierzalna, wszystkie punkty wzdłuż niej można rozwiązać pod względem ich odległości (a dowolne segmenty wzdłuż niej można rozwiązać za pomocą zakresów odległości).
whuber

Odpowiedzi:



6

Bazując na twoich potrzebach, jak to określił @LouisH, korzystanie z Linear Referencing jest zdecydowanie najlepszym rozwiązaniem. Zebraliśmy trochę kodu, który powinien zaspokoić twoją potrzebę nie kodowania na sztywno elementów, ale zamiast tego żądanie ich jako parametrów.

Jako wyjaśnienie, zastosowane poniżej narzędzie odniesienia liniowego przyjmuje „Trasy”, w twoim przypadku cechy linii, i umieszcza „Zdarzenia”, w twoim przypadku punkty, wzdłuż nich na podstawie pola odległości. W rezultacie funkcja FeatureLayer jest przechowywana w pamięci, co jest przyczyną ostatniej funkcji, która kopiuje funkcje do wyjściowej klasy cech.

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)

Edycja - jedną rzeczą do przemyślenia przy pomocy tego narzędzia i prawdopodobnie każdą operacją lokalizowania punktów na podstawie odległości od końca linii jest to, od którego końca linii zaczniesz. Na przykład narzędzie odniesienia liniowego działa w oparciu o cyfrowy kierunek linii. Ważne będzie, aby upewnić się, że masz jakiś sposób na określenie, na którym punkcie końcowym są oparte twoje pomiary.


5

Rozwiązanie takiego liniowego problemu odniesienia without importing any modulesjest poza moim zasięgiem.

Użyłem Shapely(pakiet Pythona do manipulacji i analizy geometrii geoprzestrzennych 2D. I jest na licencji BSD :-))

pobierz go stąd . Wersja 2.6, która jako jedyna obsługuje archpy arcgis 10 .. Jest to prosta instalacja (rozmiar 1,5 MB)

a teraz tutaj jest skrypt do osiągania celu .. wybacz mojemu pytonowi… tylko dzisiaj dowiedziałem się o pętlach, krotkach itp. :)

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)

Uwaga : nie zadziała, jeśli operacja ma segmenty krzywej


2

Znalazłem to pytanie, próbując zrobić to, co uważam za to samo. Chciałem, żeby to wszystko było zrobione za pomocą arcpy. Korzystanie z referencji liniowych nie miało dla mnie sensu, ponieważ nie mam już zdarzeń punktowych (i nie mogłem wymyślić, jak użyć LR, aby je uzyskać). Sedno tego, co ostatecznie wykorzystałem, było

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

Wymaga to Arc 10.1 lub nowszego; Nie byłem w stanie dowiedzieć się, czy był on dostępny poniżej poziomu licencjonowania ArcInfo, jaki posiadam (ArcView określony przez OP).

W powyższym przykładzie chciałem punktu nie w stałej odległości, ale o procent całkowitej długości linii. Aby to zrobić, podałem drugi opcjonalny argument positionAlongLine. Pomiń drugi argument, jeśli chcesz tylko określić odległość bezwzględną. Oto dokument .

Pełniejszy przykładowy kod to

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'to moja cecha Warstwa linii, na której chcę zlokalizować punkty. Działa dość szybko. NumPyArrayToFeatureClassbył bardzo fajnym sposobem na zrzucenie wszystkich moich punktów z powrotem do FeatureClass (podziękowania dla mojego kolegi Curtisa za tę część!). Eksperymentowałem z, Append_managementale to było trochę wolniejsze.


+1 Dzięki za udostępnienie. Wygląda to na dobre, jednorazowe rozwiązanie, gdy nie chcesz inwestować wysiłku w tworzenie zmierzonej polilinii. Zauważ, że to rozwiązanie wykorzystuje niejawną orientację polilinii określoną przez kolejność, w której są przechowywane jej współrzędne. Jeśli nie będziesz się tym przejmować, możesz skończyć z punktami obliczonymi, zaczynając od złego końca. Dlatego fajnie byłoby ulepszyć to rozwiązanie, aby umożliwić użytkownikowi (w jakiś sposób) ustalenie - być może poprzez wprowadzenie punktu w pobliżu jednego końca - który jest początkiem polilinii.
whuber

1
To zdecydowanie prawda. Używam linii z sieci drenażowej, które są (rzekomo) zorientowane w dół rzeki, więc nie musiałem sobie z tym poradzić. Jeśli orientacja linii nie jest zamierzona, można ją ustawić jako wstępny proces do tego, co zasugerowałem powyżej. Jeśli orientacja jest celowa, można zrobić kopię, zmienić orientację i użyć mojego przepisu. Punkty nadal będą prawidłowo układać się na oryginalnej linii cech, nawet jeśli ich orientacja nie sprzyja bieżącej analizie.
Roland

1

Może to być przesada, ale jeśli masz dostęp do rozszerzenia analizy sieci, możesz utworzyć sieć z polilinii, a następnie utworzyć obszary usług wokół punktów wejściowych, określając rozmiar SA jako odległość zainteresowania. Oto pobieżny przykład z 111 metrów SA od punktu:

wprowadź opis zdjęcia tutaj

Następnie musisz znaleźć punkty, w których SA przecina linię.


-1

Myślę, że można to uzyskać za pomocą metody Feature Vertices To Points (Data Management). możesz uzyskać więcej informacji tutaj .

lub możesz sprawdzić linię podziału linii w punkcie (zarządzanie danymi) tutaj .

nie są całkowicie wystarczające, ale możesz napisać własny kod ...

Mam nadzieję, że Ci to pomoże...


2
Wygląda na to, że problem z tymi opcjami polega na tym, że wymagają one wcześniejszej znajomości położenia punktu w celu podzielenia linii lub dodania wierzchołka na linii przed jej podzieleniem. Ta lokalizacja punktu jest nieznana w powyższym pytaniu, więc trudno jest zastosować jedno z tych rozwiązań.
Uzyskaj Spatial
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.