Ottieni un punto su una polilinea dai punti finali alla distanza lungo la polilinea


10

Ho punto iniziale e finale di una polilinea. Come posso ottenere un punto su quella polilinea dai punti finali specificati dalla distanza data.

inserisci qui la descrizione dell'immagine

Come posso ottenere questo usando arcpy a condizione che questo script funzioni su ArcView senza importare alcun modulo ( come questa risposta ). Sto cercando di non codificare i valori.

Domanda correlata:


non stai ottenendo risultati usando object.interpolate (distance [, normalized = False])?
Vinayan,

1
Dove hai preso object.interpolate(distance[, normalized=False]). È un metodo di arcpia? In tal caso, puoi pubblicare il link. L'ho cercato su Google, ma non l'ho trovato.
utente

è un metodo ben fatto .. toblerity.github.com/shapely/… pensa di averlo provato nell'altra domanda ... non sono sicuro di aver ottenuto risultati ..
vinayan,

2
Un'altra domanda correlata è gis.stackexchange.com/questions/6476/… , che riguarda l'inverso di questo problema (trova la distanza data il punto). Le due soluzioni sono strettamente correlate: una volta che la polilinea è misurabile, tutti i punti lungo di essa possono essere indirizzati in termini di distanze (e segmenti arbitrari lungo di essa possono essere indirizzati da intervalli di distanza).
whuber

Risposte:


7

Sembra simile a "Riferimenti lineari" e quel set di strumenti sarebbe disponibile in ArcView. Inoltre, puoi scrivere questo strumento molto facilmente.

Link alla Guida ESRI per riferimenti lineari


1
+1 Questo è l'approccio "giusto", nel senso di usare una capacità matura creata espressamente per questo problema.
whuber

6

In base alle tue esigenze, come indicato da @LouisH, l'utilizzo del riferimento lineare è sicuramente la strada da percorrere. Ho messo insieme un po 'di codice che dovrebbe soddisfare la tua necessità di non inserire elementi hard-coding, ma di richiederli come parametri.

Come spiegazione, lo strumento di riferimento lineare utilizzato di seguito utilizza "Percorsi", nel tuo caso le caratteristiche della linea e posiziona "Eventi", nel tuo caso i punti, lungo di essi in base a un campo di distanza. Ciò si traduce in un FeatureLayer, che è archiviato in memoria, che è il motivo dell'ultima funzione che copia le funzionalità in una featureclass di output.

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)

Modifica - Una cosa a cui pensare con questo strumento, e probabilmente qualsiasi operazione per localizzare i punti in base alla distanza dalla fine di una linea, è da quale fine della linea inizierai. Lo strumento di riferimento lineare, ad esempio, funziona in base alla direzione digitalizzata di una linea. Sarà importante assicurarsi di disporre di un modo per identificare su quale endpoint si basano le misurazioni.


5

Risolvere un problema di riferimento lineare come questo without importing any modulesva oltre la mia portata.

Ho usato Shapely(pacchetto python per manipolazione e analisi di geometrie geospaziali 2D. Ed è con licenza BSD :-))

scaricalo da qui . La versione 2.6 che è l'unica che supporta arcgis 10 arcpy..È un'installazione semplice (dimensione 1,5 MB)

e ora ecco la sceneggiatura arcpy per raggiungere lo scopo .. perdona il mio pitone..solo oggi ho imparato a conoscere loop, tuple ecc :)

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)

nota : questo non funzionerà se la funzione ha segmenti di curva


2

Ho trovato questa domanda cercando di fare ciò che penso sia la stessa cosa. Volevo che tutto fosse fatto tramite arcpy. L'uso del riferimento lineare non aveva senso per me perché non avevo già gli eventi punto (e non riuscivo a capire come usare LR per ottenerli). Il punto cruciale di quello che ho finito per usare era

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

Ciò richiede Arc 10.1 o successivo; Non sono riuscito a capire se questo era disponibile al di sotto del livello di licenza ArcInfo che ho (OP specificato ArcView).

Nel mio esempio sopra, volevo un punto non a una distanza fissa, ma di una percentuale della lunghezza complessiva della linea. Per fare questo, ho fornito il secondo argomento facoltativo a positionAlongLine. Si salta il secondo argomento se si desidera solo specificare una distanza assoluta. Ecco il documento .

L'esempio di codice più completo è

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'è la mia caratteristica Strato di linee su cui voglio individuare i punti. Funziona abbastanza velocemente. NumPyArrayToFeatureClassè stato un modo molto carino per riportare tutti i miei punti in una featureClass (grazie al mio collega Curtis per quella parte!). Avevo sperimentato w / Append_managementma era un po 'più lento.


+1 Grazie per averlo condiviso. Sembra una buona soluzione una tantum quando non vuoi investire lo sforzo di creare una polilinea misurata. Si noti che questa soluzione utilizza l'orientamento implicito della polilinea determinata dall'ordine in cui sono memorizzate le sue coordinate. Se non ci si preoccupasse, si potrebbe finire con i punti calcolati a partire dalla fine sbagliata. Quindi sarebbe bello migliorare questa soluzione per consentire all'utente (in qualche modo) di stabilire - forse inserendo un punto vicino a un'estremità - che è l'inizio della polilinea.
whuber

1
Questo è assolutamente vero. Sto usando linee da una rete di drenaggio che sono tutte (presumibilmente) orientate a valle, quindi non ho dovuto occuparmene. Se l'orientamento della linea non è intenzionale, potrebbe essere organizzato come un pre-processo rispetto a quello che ho suggerito sopra. Se l'orientamento è intenzionale, allora si potrebbe fare una copia, riorientare e usare la mia ricetta. I punti verranno comunque allineati correttamente sulla linea di featureclass originale, anche se il suo orientamento non è favorevole all'analisi corrente.
Roland,

1

Potrebbe essere un problema, ma se si ha accesso all'estensione Network Analysis è possibile creare una rete dalle polilinee e quindi creare aree di servizio attorno ai punti di input, specificando la dimensione SA come distanza di interesse. Ecco un esempio superficiale con 111 metri SA dal punto:

inserisci qui la descrizione dell'immagine

Quindi dovresti trovare i punti in cui SA attraversa la linea.


-1

penso che puoi ottenerlo con il metodo Feature Vertices To Points (Gestione dei dati). puoi ottenere maggiori informazioni qui .

oppure puoi consultare Split Line At Point (Gestione dati) qui .

non sono del tutto sufficienti ma puoi scrivere il tuo codice ...

spero che ti aiuti ...


2
Sembra che il problema con queste opzioni sia che richiedono una conoscenza preliminare della posizione del punto per dividere la linea o per aggiungere un vertice alla linea prima di dividerla. Quella posizione del punto è ciò che non è noto nella domanda sopra, quindi è difficile applicare una di queste soluzioni.
Ottieni Spatial
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.