Obter um ponto em uma polilinha a partir dos pontos finais, dada a distância ao longo da polilinha

10

Eu tenho ponto inicial e final de uma polilinha. Como posso obter um ponto nessa polilinha a partir dos pontos finais especificados pela distância especificada.

insira a descrição da imagem aqui

Como conseguir isso usando o arcpy, desde que esse script funcione no ArcView sem importar nenhum módulo ( como esta resposta ). Estou tentando não codificar valores.

Pergunta relacionada:

do utilizador
fonte
você não está obtendo nenhum resultado usando object.interpolate (distance [, normalized = False])?
Vinayan # 31/12
1
Onde você conseguiu object.interpolate(distance[, normalized=False]). É um método de arcpy? Se for esse o caso, você pode postar o link. Eu pesquisei no Google, mas não o encontrei.
usuário
É o método de bem torneadas .. toblerity.github.com/shapely/... acho que você tentou fazê-lo em outro question..not certeza se você tem resultados ..
Vinayan
2
Outra questão relacionada é gis.stackexchange.com/questions/6476/… , que diz respeito ao inverso desse problema (encontre a distância conforme o ponto). As duas soluções estão intimamente relacionadas: uma vez que a polilinha é mensurável, todos os pontos ao longo dela podem ser abordados em termos de distâncias (e segmentos arbitrários podem ser abordados por faixas de distância).
whuber

Respostas:

7

Isso soa semelhante a "Referência linear" e esse conjunto de ferramentas estaria disponível no ArcView. Além disso, você pode criar um script dessa ferramenta com muita facilidade.

Link para a Ajuda da ESRI para referência linear

Louis H
fonte
1
+1 Essa é a abordagem "correta" no sentido de usar um recurso maduro criado expressamente para esse problema.
whuber
6

Com base em suas necessidades, como @LouisH referido, o uso da referência linear é definitivamente o caminho a percorrer. Criei um código que deveria atender à sua necessidade de não codificar elementos, mas solicitá-los como parâmetros.

Como explicação, a ferramenta de referência linear usada abaixo pega "Rotas", no seu caso, a linha apresenta e coloca "Eventos", no seu caso, os pontos ao longo deles com base em um campo de distância. Isso resulta em um FeatureLayer, armazenado na memória, razão pela qual a última função que copia os recursos para uma classe de recurso de saída.

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 - Uma coisa em que pensar com esta ferramenta e, provavelmente, qualquer operação para localizar pontos com base na distância do final de uma linha, é de qual final da linha você começará. A ferramenta de referência linear, por exemplo, funciona com base na direção digitalizada de uma linha. Será importante garantir que você tenha alguma maneira de identificar em qual ponto de extremidade suas medidas são baseadas.

Get Spatial
fonte
5

Resolver um problema de referência linear como esse without importing any modulesestá além do meu alcance.

Eu usei Shapely(pacote python para manipulação e análise de geometrias geoespaciais 2D. E é licenciado em BSD :-))

faça o download aqui . A versão 2.6, que é a única que suporta o arcgis 10 arcpy. É uma instalação simples (tamanho de 1,5 MB)

e agora aqui está o script arcpy para atingir o objetivo .. perdoe meu python .. só hoje eu aprendi sobre os loops, 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 : isso não funcionará se o recurso tiver segmentos de curva

vinayan
fonte
2

Eu encontrei essa pergunta tentando fazer o que acho que é a mesma coisa. Eu queria que tudo fosse feito via arcpy. Usar a referência linear não fazia sentido para mim, porque ainda não tenho os eventos pontuais (e não consegui descobrir como usar o LR para obtê-los). O ponto crucial do que acabei usando foi

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

Isso requer Arc 10.1 ou superior; Não consegui descobrir se isso estava disponível abaixo do nível de licenciamento do ArcInfo que eu tenho (o ArcView especificado pelo OP).

No meu exemplo acima, eu queria um ponto não a uma distância fixa, mas por uma porcentagem do comprimento total da linha. Para fazer isso, forneci o segundo argumento opcional para positionAlongLine. Você pula o segundo argumento se quiser especificar uma distância absoluta. Aqui está o documento .

O exemplo de código mais 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'é o meu featureLayer de linhas nas quais desejo localizar os pontos. Corre muito rápido. NumPyArrayToFeatureClassfoi uma maneira muito legal de despejar todos os meus pontos de volta em um featureClass (obrigado ao meu colega Curtis por essa parte!). Tinha experimentado w / Append_managementmas isso era um pouco mais lento.

Roland
fonte
+1 Obrigado por compartilhar isso. Parece uma boa solução pontual quando você não deseja investir o esforço de configurar uma polilinha medida. Observe que esta solução usa a orientação implícita da polilinha determinada pela ordem em que suas coordenadas são armazenadas. Se não for tomado cuidado com isso, você pode acabar com pontos calculados a partir do lado errado. Assim, seria bom aprimorar essa solução para permitir que o usuário (de alguma forma) estipule - talvez por meio da inserção de um ponto próximo a uma extremidade - que é o início da polilinha.
whuber
1
Definitivamente isso é verdade. Estou usando linhas de uma rede de drenagem que são todas (supostamente) orientadas a jusante, então não tive que lidar com isso. Se a orientação da linha não for deliberada, ela poderá ser organizada como um pré-processo para o que sugeri acima. Se a orientação for deliberada, é possível fazer uma cópia, reorientar e usar minha receita. Os pontos ainda serão alinhados corretamente na classe original, mesmo que sua orientação não seja favorável à análise atual.
Roland
1

Pode ser um exagero, mas se você tiver acesso à extensão Network Analysis, poderá criar rede a partir de suas polilinhas e, em seguida, criar áreas de serviço em torno de seus pontos de entrada, especificando o tamanho da SA como a distância de interesse. Aqui está um exemplo superficial com 111 metros SA do ponto:

insira a descrição da imagem aqui

Então você teria que encontrar pontos onde o SA cruza a linha.

radek
fonte
-1

Eu acho que você pode obtê-lo com o recurso Feature Vertices To Points (Data Management). Você pode obter mais informações aqui .

ou você pode conferir a linha dividida no ponto (gerenciamento de dados) aqui .

eles não são suficientes, mas você pode escrever seu próprio código ...

espero que ajude você ...

Aragão
fonte
2
Parece que o problema com essas opções é que elas exigem conhecimento prévio da localização do ponto para dividir a linha ou adicionar um vértice na linha antes de dividi-la. Esse local do ponto é o que não é conhecido na pergunta acima, portanto, é difícil aplicar qualquer uma dessas soluções.
Get Spatial