Estou lutando com esse problema. Eu tenho uma polilinha composta de vários segmentos. Cada segmento é composto de pontos, cada ponto identificado no espaço 3D por coordenadas e elevação. Juntos, se plotados, os segmentos formam uma linha mais ou menos contínua (pode haver quebras entre os segmentos), mas os segmentos em si não são consecutivos, nem os pontos de todos os segmentos seguem a mesma direção de deslocamento.
A questão é: como posso criar, usando Python, de preferência, uma única linha desses segmentos não consecutivos para que eu possa medir a distância entre os pontos e o comprimento total da linha.
Eu nem sei qual dos segmentos é o primeiro ou o último da linha, mas de alguma forma eu tenho que colocá-los na sequência correta e garantir que todos apontem na mesma direção para que eu possa medi-los.
Obrigado por qualquer ajuda. Ficarei feliz em fornecer informações, dados, etc. adicionais. Sublinho que não estou pedindo o código python real (não que eu o recusasse ...), apenas a estratégia. Prumo
8
Respostas:
Os segmentos podem ser usados para formar um gráfico abstrato G no qual eles desempenham o papel de nós . Considere um nó que é o segmento (arco) do ponto P ao ponto Q, PQ. Seja R o ponto final mais próximo entre todos os outros pontos finais do segmento para P e S seja o outro ponto final do segmento de R. G então contém uma aresta do nó PQ ao nó RS e iremos rotular essa aresta com os pontos P e R.
Se queremos ter sucesso, G é um gráfico linear ou um único ciclo. Você pode detectar qual é qual armazenando os graus dos nós ao criar as arestas. (O grau de um nó conta as arestas que emanam desse nó.) Todos os nós, exceto possivelmente dois, devem ter o grau 2. Os outros dois devem ter o grau 2 (para um ciclo) ou o grau 1: isso os marca como as extremidades da polilinha. No primeiro caso, escolha qualquer nó para começar a construir a polilinha; no segundo caso, escolha uma das de grau 1. Qualquer outra combinação de graus é um erro.
A polilinha é inicializada no nó inicial (um arco). Observe uma das arestas e o incidente nesse nó: o outro nó informa qual arco deve ser processado a seguir e o rótulo indica quais vértices desses arcos devem ser unidos. (Junte-se aos vértices com um novo segmento de linha, se eles não têm coordenadas idênticas.) Atualize a crescente polilinha desta forma e, ao mesmo tempo, borda remove e do gráfico G . Continue até que ocorra um erro (e relate que as bordas não formam uma polilinha conectada sem ramificação) ou que todas as bordas são removidas. Se nenhum erro for gerado, imprima a polilinha que você criou.
Exemplo
Na figura, os arcos são AB, CD, EF e FG. Os nós do gráfico são, portanto, {AB, CD, EF, FG}. As bordas são AB - CD (rotulado com B e C), CD-EF (rotulado com E e F) e EF - FG (rotulado com F e F). Os graus de AB e FG são 1, enquanto os graus de CD e EF são 2. Aqui está um esquema do gráfico abstrato e seus rótulos de aresta:
Vamos começar arbitrariamente com FG, um dos nós de grau um. Por ter o grau 1, há uma aresta EF-FG conectada a ele, rotulada com F. Inicialize a polilinha com arco G -> F. Como o rótulo designa um ponto de extremidade comum de GF e EF, não precisamos fazer uma nova conexão. Remova a aresta EF - FG do gráfico e estenda a polilinha com EF através de G -> F -> E.
Essa remoção de aresta reduz o grau de EF de 2 para 1, deixando-o com uma única aresta para formar um CD marcado com E e D. Isso permite que você estenda a polilinha de E para D (com um novo segmento de linha) e depois arco CD: G -> F -> E -> D -> C. Da mesma maneira, após remover a borda ED - CD, você estenderá a polilinha ainda mais para sua forma final G -> F -> E -> D -> C -> B -> A. Você para porque todas as arestas foram removidas do gráfico: isso indica que o procedimento foi bem-sucedido.
fonte
Seguindo a resposta do whuber, se você estiver procurando fazer isso no Python, consulte a biblioteca NetworkX que possui todo tipo de funcionalidade relacionada a gráficos, nós e arestas. Eu acho que são as funções da Traversal que implementam o que o whuber está descrevendo. Também inclui funcionalidade básica de desenho.
Depois de receber os pedidos de sua linha, você poderá facilmente construir geometrias no Shapely para fazer mais análises do tipo GIS ou exibir no MatPlotLib, exportar para GeoJSON etc.
fonte
Eu calcularia a distância entre cada segmento inicial e final e depois juntaria os com a menor distância entre eles?
fonte
Você tem muitos segmentos, nenhuma ordem ou orientação específica. Você não sabe quais realmente tocam ou se sobrepõem e quais são apenas próximas.
Para cada segmento, apenas o ponto inicial e o ponto final são importantes. O objetivo é fazer uma grande polilinha, a orientação dessa polilinha não é importante, eu acho.
Nesse caso, eu faria algum tipo de conjunto / matriz de segmentos, começando com o primeiro, que é inteiramente aleatório.
No pseudocódigo, faça algo como
Algo parecido? Esse é um nível muito alto. Você precisará lidar com casos de fronteira. Suponho que você conheça ou possa ter a maior distância / distância possível, porque será necessário excluir de alguma forma os pontos encontrados: se o ponto mais próximo possível estiver na outra extremidade da polilinha, isso não é uma opção :) A maneira mais fácil de lidar com isso é definir uma distância de intervalo máxima. Isso também limitará o número de pontos que você terá que procurar para cada segmento.
[EDIT: detalhe o
find_segment_closes_to
]Para deixar absolutamente claro como eu encontraria o segmento de fechamentos, escreverei primeiro uma abordagem muito grosseira:
Essa é uma abordagem muito grosseira, que irá percorrer todos os segmentos e verificar cada ponto final mais próximo.
Idealmente, você teria alguma estrutura de dados na qual poderia solicitar todos os pontos de partida e pontos finais que estão dentro do alcance e encontrar apenas o ponto mais próximo entre eles.
Isso ajuda? Espero que você comece.
fonte