Obtenga un punto en una polilínea a partir de los puntos finales a la distancia dada a lo largo de la polilínea

10

Tengo el punto de inicio y el punto final de una polilínea. ¿Cómo puedo obtener un punto en esa polilínea a partir de puntos finales especificados por la distancia dada?

ingrese la descripción de la imagen aquí

¿Cómo puedo obtener esto usando arcpy, siempre que este script funcione en ArcView sin importar ningún módulo ( como esta respuesta )? Estoy tratando de no codificar los valores.

Pregunta relacionada:

usuario
fuente
¿no está obteniendo ningún resultado usando object.interpolate (distance [, normalized = False])?
vinayan
1
¿De dónde sacó object.interpolate(distance[, normalized=False]). ¿Es un método de arcpy? Si es así, ¿puede publicar el enlace? Lo busqué en Google, pero no lo encontré.
usuario
se de bien formada método .. toblerity.github.com/shapely/... piensa que ha intentado en el otro question..not seguro si tienes resultados ..
Vinayan
2
Otra pregunta relacionada es gis.stackexchange.com/questions/6476/… , que se refiere a la inversa de este problema (encuentre la distancia dada el punto). Las dos soluciones están estrechamente relacionadas: una vez que la polilínea se puede medir, todos los puntos a lo largo de ella se pueden abordar en términos de sus distancias (y los segmentos arbitrarios a lo largo de ella se pueden abordar por rangos de distancia).
whuber

Respuestas:

7

Esto suena similar a "Referencia lineal" y ese conjunto de herramientas estaría disponible en ArcView. Además, puede escribir esta herramienta muy fácilmente.

Enlace a la Ayuda de ESRI para referencias lineales

Louis H
fuente
1
+1 Este es el enfoque "correcto" en el sentido de utilizar una capacidad madura creada expresamente para este problema.
whuber
6

En función de sus necesidades, como se mencionó en @LouisH, el uso de referencias lineales es definitivamente el camino a seguir. Elaboré un código que debería satisfacer su necesidad de elementos no codificados, sino que los solicité como parámetros.

Como explicación, la herramienta de referencia lineal utilizada a continuación toma "Rutas", en su caso las características de línea y coloca "Eventos", en su caso los puntos, a lo largo de ellos en función de un campo de distancia. Esto da como resultado un FeatureLayer, que se almacena en la memoria, que es la razón de la última función que copia las características en una clase de características de salida.

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)

Editar: una cosa para pensar con esta herramienta, y probablemente cualquier operación para localizar puntos en función de la distancia desde el final de una línea, es desde qué extremo de la línea comenzará. La herramienta de referencia lineal, por ejemplo, funciona en función de la dirección digitalizada de una línea. Será importante asegurarse de que tiene alguna forma de identificar en qué punto final se basan sus mediciones.

Consigue espacial
fuente
5

Resolver un problema de referencia lineal como este without importing any modulesestá más allá de mi rango.

He utilizado Shapely(paquete de Python para la manipulación y análisis de geometrías geoespaciales 2D. Y tiene licencia BSD :-))

descárgalo desde aquí . La versión 2.6, que es la única que admite arcgis 10 arcpy ... es una instalación simple (tamaño de 1,5 MB)

y ahora aquí está el script arcpy para lograr el propósito ... perdona mi pitón ... solo hoy aprendí sobre los bucles, tuplas, etc. :)

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 : esto no funcionará si la entidad tiene segmentos curvos

vinayan
fuente
2

Encontré esta pregunta tratando de hacer lo que creo que es lo mismo. Quería que todo se hiciera a través de arcpy. El uso de referencia lineal no tenía sentido para mí porque aún no tengo los eventos puntuales (y no pude descubrir cómo usar LR para obtenerlos). El quid de lo que terminé usando fue

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

Esto requiere Arc 10.1 o superior; No pude averiguar si esto estaba disponible por debajo del nivel de licencia de ArcInfo que tengo (OP especificó ArcView).

En mi ejemplo anterior, quería un punto no a una distancia fija, sino en un porcentaje de la longitud total de la línea. Para hacer esto, proporcioné el segundo argumento opcional para positionAlongLine. Omite el segundo argumento si solo desea especificar una distancia absoluta. Aquí está el documento .

El código de muestra más completo es

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'es mi característica Capa de líneas en la que quiero ubicar los puntos. Corre bastante rápido. NumPyArrayToFeatureClassfue una forma muy agradable de volcar todos mis puntos en una clase de función (¡gracias a mi colega Curtis por esa parte!). Había estado experimentando w / Append_managementpero eso fue un poco más lento.

Roland
fuente
+1 Gracias por compartir eso. Parece una buena solución única cuando no desea invertir el esfuerzo en configurar una polilínea medida. Tenga en cuenta que esta solución utiliza la orientación implícita de la polilínea determinada por el orden en que se almacenan sus coordenadas. Si no se tuvo cuidado con eso, podría terminar con puntos calculados comenzando desde el extremo equivocado. Por lo tanto, sería bueno mejorar esta solución para permitir que el usuario (de alguna manera) estipule, tal vez ingresando un punto cerca de un extremo, que es el comienzo de la polilínea.
whuber
1
Eso es definitivamente cierto. Estoy usando líneas de una red de drenaje que están todas (supuestamente) orientadas aguas abajo, por lo que no tuve que lidiar con esto. Si la orientación de la línea no es deliberada, podría organizarse como un proceso previo a lo que sugerí anteriormente. Si la orientación es deliberada, entonces se podría hacer una copia, reorientar y usar mi receta. Los puntos se alinearán correctamente en la clase de entidad de línea original, incluso si su orientación no es propicia para el análisis actual.
Roland
1

Puede ser una exageración, pero si tiene acceso a la extensión de Análisis de red, podría crear una red a partir de sus polilíneas y luego crear áreas de servicio alrededor de sus puntos de entrada, especificando el tamaño de SA como la distancia de interés. Aquí hay un ejemplo superficial con 111 metros de SA desde el punto:

ingrese la descripción de la imagen aquí

Entonces tendrías que encontrar puntos donde SA cruza la línea.

radek
fuente
-1

Creo que puede obtenerlo con el método de Vértices a puntos (gestión de datos). Puedes obtener más información aquí .

o puede consultar Split Line At Point (Gestión de datos) aquí .

no son suficientes por completo, pero puedes escribir tu propio código ...

Espero que te ayude...

Aragón
fuente
2
Parece que el problema con estas opciones es que requieren un conocimiento previo de la ubicación del punto para dividir la línea o agregar un vértice en la línea antes de dividirla. Esa ubicación de punto es lo que no se conoce en la pregunta anterior, por lo que es difícil aplicar cualquiera de estas soluciones.
Obtenga espacial