Ottieni tutti i punti di una polilinea


11

Ho alcuni oggetti funzione polilinea in Python. Ora voglio ottenere tutti i punti di polilinee.

Ad esempio, se una polilinea ha il punto [0,0]finale del punto iniziale [5,5]. Risultato: [1,1];[2,2];[3,3];[4,4];[5,5].

Voglio trovare tutti i punti interi su quella linea inclusi i punti finali. Per la linea retta questo è molto semplice, ma se la polilinea ha tipi di geometria Curva di Beizer, Arco circolare, Arco ellittico, come posso farlo?

MODIFICARE:

Posso usare solo quegli strumenti disponibili in tutti i livelli di licenza di ArcGIS. Ad esempio, ArcGIS Basic.


2
In generale, spesso non si ottengono bei punti "interi". Funziona nel tuo esempio, ma non spesso nella vita reale. Di solito, ottieni solo posizioni per i vertici, quindi nel tuo caso otterrai [0,0] e [5,5]. I punti "intermedi" possono essere "ipotizzati". Non sei sicuro di come farlo in Python, ma diversi strumenti ti permetteranno di creare un file di punti di vertici da una linea.
— Darren Cope,

Risposte:


18

So che questo è vecchio ma stavo cercando lo stesso in quanto non ho ArcInfo per gli strumenti FeatureVerticesToPoints . Dopo aver usato la soluzione del cursore di ricerca sopra, sono andato avanti per semplificare il codice e ho scoperto che usando NumPy Arrays nel modulo di accesso ai dati è stato possibile creare uno script semplice e molto veloce. Sto usando questo come strumento di script.

Nota: la chiave è il explode_to_pointsparametro inarcpy.da.FeatureClassToNumPyArray

Ecco il link alla posizione del repository ArcGIS: dalla classe caratteristica ai punti

# Feature Class to Points
# 
# Paul Smith (2012) paul@neoncs.com.au

# Imports
import arcpy
import numpy

#Inputs from user parameters
InFc  = arcpy.GetParameterAsText(0) # input feature class
OutFc = arcpy.GetParameterAsText(1) # output feature class

# Spatial reference of input feature class
SR = arcpy.Describe(InFc).spatialReference

# Create NumPy array from input feature class
array = arcpy.da.FeatureClassToNumPyArray(InFc,["SHAPE@XY"], spatial_reference=SR, explode_to_points=True)

# Check array and Exit if no features found
if array.size == 0:
    arcpy.AddError(InFc + " has no features.")

# Create a new points feature class
else:
    arcpy.da.NumPyArrayToFeatureClass(array, OutFc, ['SHAPE@XY'], SR)

Benvenuto in GIS.se Paul :) +1 per un primo contributo ben arrotondato e migliore della media, con codice per l'avvio. Grazie! Alcuni suggerimenti per la modifica: selezionare il testo, in linea o un blocco, quindi ctrl-kapplicare la formattazione del codice (lo stesso per bvecchi e italic). Per convenzione tendiamo ad evitare frammenti come "ciao", "grazie", "evviva". Questi sono impliciti come sempre presenti e aiutano a rafforzare l'idea che questo posto sia diverso dai soliti forum ed e-mail. Benvenuto a bordo.
— Matt Wilkie,

Devi inserire un segnaposto per where_clause su questa riga del codice array = arcpy.da.FeatureClassToNumPyArray (InFc, ["SHAPE @ XY"], "", spatial_reference = SR, explode_to_points = True)
— Tristan Forward

4

Come ho capito, è necessario aumentare il numero di vertici per le funzioni della polilinea. E anche per trasformare tutti i segmenti "Curva di Beizer, Arco circolare, Arco ellittico" in diversi segmenti di linea.

Per questa attività in ArcGIS è possibile utilizzare lo strumento Densify (Modifica) in ArcToolbox.

Quindi è possibile convertire le polilinee i vertici per puntare caratteristiche come suggerito Darren Cope e artwork21.

Se si preferisce farlo in ArcMap, consultare Creazione di nuovi punti lungo un argomento della guida in linea .


3

Quanto segue dovrebbe funzionare su polilinee e poligoni:

import arcpy

infc = r"D:\Projects\GDBs\slowbutter.gdb\fc"

desc = arcpy.Describe(infc)
shapefieldname = desc.ShapeFieldName

rows = arcpy.SearchCursor(infc)
for row in rows:
    # Create the geometry object
    feat = row.getValue(shapefieldname)
    print "Feature %i: " % row.getValue(desc.OIDFieldName)
    partnum = 0
    # Step through each part of the feature
    for part in feat:
        print "Part %i: " % partnum
        part_list = []
        for pnt in feat.getPart(partnum):
            if pnt:
                # Add to list
                part_list.append([pnt.X, pnt.Y])
            else:
                # If pnt is None, this represents an interior ring
                print "Interior Ring:"
        partnum += 1  
        print part_list

Per alcuni dati stradali del Regno Unito, ottengo questo; un elenco nidificato di coppie X, Y per ciascun vertice che costituisce la polilinea:

Feature 7: 
Part 0: 
[[-0.48053999999996222, 51.482510000000048], [-0.48032999999992398, 
51.482609000000082], [-0.48026999999996178, 51.48273800000004], 
[-0.48043999999993048, 51.482891000000052], [-0.48065999999994347, 51.482948000000079],
[-0.48123999999995704, 51.483009000000038]]

L'ho visto sulla pagina ESRI. Ma se guardi attentamente nella loro descrizione questo codice restituisce solo i punti finali, non i punti tra loro
— utente

2
@crucifiedsoul - Sì, questa è una variazione di quel campione ESRI , ma fornisce la coppia X, Y di tutti i punti, non solo i punti finali. È quello che vuoi, giusto?
— Chad Cooper,

Non capisco L'unica cosa che sta cambiando si sta sostituendo print pnt.X, pnt.Ycon part_list.append([pnt.X, pnt.Y]). E lo stai stampando alla fine del ciclo. Come può il tuo codice ottenere tutti i punti di una linea ma il codice ESRI no?
— utente

Il metodo descritto non ha funzionato per me. Ho dovuto solo specificare il campo della mia forma - arcpy.da.SearchCursor (fc, ["SHAPE @"])
— jbalk,

1

Come ha suggerito Darren Cope, la conversione del livello in vertici punti può essere effettuata utilizzando lo strumento Feature Vertici in punti .

Ecco il codice python snippedt:

# import system modules 
import arcpy
from arcpy import env

# Set environment settings
env.workspace = "C:/data"

# Set local variables
inFeatures = "majorrds.shp"
outFeatureClass = "c:/output/output.gdb/majorrds_midpt"

# Execute FeatureVerticesToPoints
arcpy.FeatureVerticesToPoints_management(inFeatures, outFeatureClass, "MID")
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.