Com base na resposta de @ kazuhito, montei uma expressão hacky na Calculadora de Campo QGIS, que deve fazer a mesma coisa em uma única etapa.
No entanto, posso imaginar que isso consome muitos recursos em conjuntos de dados maiores. Eu acho que o problema é mais adequado para uma implementação Python, que obviamente lida com referência e iteração muito melhor do que a Calculadora de Campo.
array_last(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1))
- array_first(array_sort(array_foreach(
generate_series(1,num_points($geometry)-1),
line_locate_point(aggregate('lines','collect',$geometry),
point_n($geometry,@element))),1))
Isso primeiro cria uma 'matriz' de números de nós usando generate_series()
, especificando o máximo como o número de nós em cada polígono - ou seja num_points($geometry)
, menos 1 para pular o primeiro / último nó repetido.
Você pode passar os valores dessa matriz por uma função para gerar outra matriz usando array_foreach()
. Aqui passamos o número do nó do polígono (representado como @element
) para point_n()
, que retorna a geometria real desse nó, e o alimentamos line_locate_point()
para determinar seu comprimento ao longo da linha especificada (consulte a Nota importante abaixo).
A matriz resultante é então classificada em ordem crescente usando o array_sort()
que permite obter as distâncias "mais à esquerda" e "mais à direita" ao longo da linha usando array_last()
e array_first()
. Subtraia os dois e o resultado é o "comprimento" do polígono ao longo da linha.
Veja abaixo um exemplo da expressão acima mostrada como um rótulo nos polígonos (mais as distâncias da linha "mais à esquerda" e "mais à direita" divididas em relação à expressão acima). Para comparação, incluí também vértices extraídos e valores relevantes de distância da linha. Vértices verdes são os vértices "mais à esquerda" e "mais à direita" ao longo da linha. Observe o polígono superior esquerdo em que o ponto verde está realmente mais ao longo da linha do que o ponto à direita abaixo dele, devido ao ângulo da linha ...
Nota importante :
A geometria da camada de linha é referenciada aqui usando aggregate()
. Você vai precisar para mudar o nome da camada ( 'lines'
) Se necessário, e se você tiver várias linhas, você deve adicionar um filtro para especificar qual linha você quer para o comparar com, por exemplo: aggregate('lines','collect',$geometry,"name"='TrainLine1')
. Para que isso funcione automaticamente na linha mais próxima, eu realmente recomendo SQL ou Python sobre o Field Calc.
Além disso, isso calcula o "comprimento" do polígono ao longo da linha, incluindo se a linha é dobrada pelo meu exemplo. Se você deseja a distância em linha reta ... talvez calcule o valor distance()
entre os nós relevantes?