Como dividir a linha em um número específico de peças?

11

Eu já vi muitas perguntas envolvendo dividir uma linha com a ajuda de uma camada de pontos.

Eu quero dividir uma linha em frações do seu comprimento.

Por exemplo, tenho uma linha de 400metros, quero dividi-la em quatro linhas de 100 metros cada.

Existe o módulo grass v.split, mas recebo uma mensagem de erro quando inicio na caixa de ferramentas qgis:

*"TypeError: object of type 'NoneType' has no len()"*

Portanto, não tenho certeza se vou fazê-lo funcionar, se isso seria uma solução.

Gilles
fonte
Por favor, esclareça: Deseja dividir por comprimento, ou seja, 100 metros ou em um número específico de peças?
Underdark
Em um número específico de partes. Joseph, abaixo, deu uma boa solução alternativa.
Gilles

Respostas:

10

A função v.split.length do GRASS deve fazer exatamente o que você deseja dividindo a linha em segmentos iguais definidos pelo usuário sem a necessidade de uma camada de pontos. Aqui está um exemplo simples de uma linha reta (também funciona em linhas não retas e múltiplas):

Linha simples

Eu adicionei uma coluna para calcular seu comprimento usando $lengthna expressão:

Atributo de linha

Usando a função v.split.length do GRASS por meio da Processing Toolbox , escolhi dividir a linha em segmentos de 25m, o que deve totalizar 4 partes:

Função v.split.length

Atualizei a coluna Comprimento da camada de saída e usei o mesmo comando acima para recalcular o comprimento:

Resultado do atributo

Não sabe ao certo por que está recebendo o erro, você pode compartilhar sua camada de linha para que as pessoas testem?

Joseph
fonte
Olá, obrigado pela sua resposta. Está funcionando. Porém, não está dividindo a linha em frações de comprimento, pois ainda tenho que calcular o número de segmentos a partir do comprimento medido, mas é uma boa solução alternativa. Obrigado.
Gilles
2
Se o "Comprimento máximo do segmento" estiver definido como 25, por que você obteve 4 segmentos com mais de 25 (25.465) e não 5 segmentos (4 de 25 e um de 1,86 ou 5 de 20.372 se a ferramenta produz igual comprimento)?
JR
1
@JR - Essa é uma boa pergunta a ser feita há 5 anos :). Eu não tenho uma resposta para isso, talvez tenha sido um bug na ferramenta, considerando que seria uma versão antiga do QGIS. Além disso, como era nos meus primeiros dias de aprendizado de SIG, eu deveria ter usado outro CRS ao medir distâncias precisas em metros!
Joseph
1
@ Joseph, acho que você escolheria o PyQGIS hoje, não é? =)
Taras
1
@Taras - Eu estaria mais inclinado, sim :)
Joseph
2

Testado no QGIS 2.18 e QGIS 3.4

Vamos supor que haja uma camada de polilinha chamada "lines".

entrada

Eu posso sugerir o uso de uma "Camada Virtual" através Layer > Add Layer > Add/Edit Virtual Layer...


Existem vários casos possíveis:


Caso 1. Dividindo a linha em segmentos iguais, basicamente o mesmo comprimento, definido pelo usuário.

Com a seguinte consulta, é possível alcançar o resultado. Para aumentar / diminuir o comprimento do segmento, ajuste o 1000 AS step_lengthpol -- configurations.

-- generate series
WITH RECURSIVE generate_sections(id, sec) AS (
SELECT conf.start + 1, conf.start
FROM conf
UNION ALL
SELECT id + conf.step, sec + conf.step_length/conf.length_line
FROM generate_sections, conf
WHERE sec + conf.step_length/conf.length_line <= 1
),

-- configurations
conf AS (
SELECT
0.0 AS start,
1.0 AS step,
1000 AS step_length,
ST_Length(l.geometry) AS length_line
FROM lines AS l
)

-- query
SELECT gs.id AS id,
        ROUND(ST_Length(ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line)),0) AS seg_length,
        ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line) AS geom
FROM generate_sections AS gs, lines AS l, conf
GROUP BY gs.id

A camada virtual de saída terá a seguinte aparência

output_1

Nota: Se 'delta' (por exemplo, o último segmento mais curto) não devem ser incluídos, em seguida, inserirWHERE sec_length >= step_lengthem-- query, veja abaixo

-- query
SELECT gs.id AS id,
        ROUND(ST_Length(ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line)),0) AS seg_length,
        ST_Line_Substring(l.geometry, start + sec, sec + conf.step_length/conf.length_line) AS geom
FROM generate_sections AS gs, lines AS l, conf
WHERE seg_length >= step_length
GROUP BY gs.id

Caso 2. Dividindo a linha em um certo número de segmentos

Com a seguinte consulta, é possível alcançar o resultado. Para aumentar / diminuir o número de segmentos, ajuste o 8 AS sectionspol -- configurations.

-- generate series
WITH RECURSIVE generate_sections(id, sec) AS (
SELECT conf.start + 1, conf.start
FROM conf
UNION ALL
SELECT id + conf.step, sec + conf.step
FROM generate_sections, conf
WHERE sec + conf.step < conf.sections
),

-- configurations
conf AS (
SELECT
8 AS sections,
0.0 AS start,
1.0 AS step
)

-- query
SELECT gs.id AS id,
    ST_Line_Substring(l.geometry, conf.start + sec/conf.sections, sec/conf.sections + step/conf.sections) AS geom,
    ROUND(ST_Length(ST_Line_Substring(l.geometry, conf.start + sec/conf.sections, sec/conf.sections + step/conf.sections)),2) AS seg_length
FROM generate_sections AS gs, lines AS l, conf
WHERE start + step < sections
GROUP BY gs.id

A camada virtual de saída terá a seguinte aparência

output_2

Taras
fonte