Mais

Crie linhas que se cruzam e remova dangles

Crie linhas que se cruzam e remova dangles


Tenho 3 casos mostrados na imagem.

Em todos eles, eu quero cruzar as linhas e remover dangles usando python no console Qgis python para depois eu poder fazer um plugin para este trabalho no qgis. No caso 1, eu quero estender a linha vertical para a linha horizontal. No caso dois Eu quero estender ambas as linhas para que se cruzem. No caso três, eu quero remover a parte extra (remover os dangles).

Consigo obter as coordenadas da variável.

Alguém pode me dizer como fazer isso usando o código python?


Você precisa pensar em termos de geometria analítica ou geometria vetorial:

Ilustro a abordagem com o primeiro exemplo (o mesmo com os outros) com PyQGIS aqui, mas você também pode usar Shapely.

Você precisa criar um segmento na direção da linha1 e calcular o ponto de interseção com a linha2.

1) Encontre o azimute da linha 1 (Como faço para encontrar o rumo da linha do vetor em QGIS ou GRASS?) E projete um ponto nesta direção usando cossenos de direção (Como criar pontos em uma distância especificada ao longo da linha em QGIS?)

importar matemática def azimute (ponto1, ponto2): retornar ponto1.azimute (ponto2) #em graus def cosdir_azim (azim): azim = math.radians (azim) cosa = math.sin (azim) cosb = math.cos (azim) return cosa, cosb seg_start, seg_end = line1.asPolyline () cosa, cosb = cosdir_azim (azimuth (seg_start, seg_end)) comprimento = a_distance resultado = QgsPoint (seg_end.x () + (a_distance * cosa), seg_end.y () + (a_distancer * cosb))

segment = QgsGeometry.fromPolyline ([seg_end, resultado])

2) encontre a interseção e calcule a linha resultante

inter = segment.intersection (line2) # um ponto, em verde

result = QgsGeometry.fromPolyline ([seg_start, inter])


Não posso fornecer o código python (não o uso há algum tempo), mas espero poder ajudá-lo com uma lógica.

Para esclarecer: "Linha" se estende em ambas as direções infinitamente. Se tiver extremidades, é denominado "segmento de linha".

Você precisará escrever 2 funções simples (posso postar o código-fonte em Java se você precisar):

  1. intersectionOfTwoLines (line1StartPoint, line1EndPoint, line2StartPoint, line2EndPoint)
  2. isPointOnTheLineSegment (segmentStartPoint, segmentEndPoint, point)

Etapa 1 - encontre o ponto de interseção de 2 linhas. Vamos chamar esse ponto P e chamar nossos segmentos de linha S1 e S2.

Etapa 2 - verifique se P está em S1.

Etapa 3 - verifique se P está em S2.

Etapa 4 - P está em S1, mas não em S2 (seu caso 1). Encontre o nó mais próximo do S2 ao P e substitua esse nó pelo P.

Etapa 5 - P está em S2, mas não em S1 (seu caso 1). Encontre o nó mais próximo do S1 ao P e substitua esse nó pelo P.

Etapa 6 - P não está em S1 e não em S2 (seu caso 2). Encontre o nó mais próximo do S1 ao P e substitua esse nó pelo P. Faça o mesmo para o S2.

Etapa 7 - P está em S1 e em S2 (seu caso 3). Isso é um pouco complicado. Presumo que você sempre considerará dangle o segmento mais curto da interseção. Se for esse o caso, você precisará calcular as distâncias de P a cada nó de S1 e S2. A distância mais curta dirá qual ponto substituir por P. Por exemplo, se a distância mais curta for de P ao nó final S2, então você só precisa substituir o nó final de S2 por P.

Desculpe pelo meu péssimo inglês.

EDITAR Não sou um desenvolvedor de Python, mas isso deve funcionar:

Código Python 3

import math def intersection_of_two_lines (l1_pt1, l1_pt2, l2_pt1, l2_pt2): "" "Retorna o ponto de intersecção de duas linhas. Argumentos de palavra-chave: l1_pt1 - Linha 1 - Ponto 1. l1_pt2 - Linha 1 - Ponto 2. l2_pt1 - Linha 2 - Ponto 1. l2_pt2 - Linha 2 - Ponto 2. "" "dx1 = l1_pt1 [" x "] - l1_pt2 [" x "] dx2 = l2_pt1 [" x "] - l2_pt2 [" x "] dy1 = l1_pt1 ["y"] - l1_pt2 ["y"] dy2 = l2_pt1 ["y"] - l2_pt2 ["y"] # Determinante. d = dx1 * dy2 - dy1 * dx2 if (d == 0): aumentar Exception ('As linhas são paralelas.') a = l1_pt1 ["x"] * l1_pt2 ["y"] - l1_pt1 ["y"] * l1_pt2 ["x"] b = l2_pt1 ["x"] * l2_pt2 ["y"] - l2_pt1 ["y"] * l2_pt2 ["x"] p = {} p ["x"] = (a * dx2 - dx1 * b) / dp ["y"] = (a * dy2 - dy1 * b) / d return p def distance (p1, p2): "" "Retorna a distância entre dois pontos. Argumentos de palavra-chave: p1 - Ponto 1. p2 - Ponto 2. "" "dx = p1 [" x "] - p2 [" x "] dy = p1 [" y "] - p2 [" y "] return math.sqrt (dx * dx + dy * dy) def is_point_on_line_segment (p, seg_pt1, seg_pt2): "" "Retorna verdadeiro se o ponto estiver no segmento de linha. Argumentos de palavra-chave: p - Ponto a verificar. seg_pt1 - Primeiro ponto do segmento de linha. seg_pt2 - Segundo ponto do segmento de linha. "" "D = distância (seg_pt1, seg_pt2) d1 = distância (p, seg_pt1) d2 = distância (p, seg_pt2) if (d == d1 + d2): retornar True return False # How para usar: # Segmento 1 l1_pt1 = {} l1_pt1 ["x"] = -10 l1_pt1 ["y"] = -5 l1_pt2 = {} l1_pt2 ["x"] = 10 l1_pt2 ["y"] = 25 # Segmento 2 l2_pt1 = {} l2_pt1 ["x"] = 20 l2_p t1 ["y"] = -10 l2_pt2 = {} l2_pt2 ["x"] = -20 l2_pt2 ["y"] = 30 impressão (intersection_of_two_lines (l1_pt1, l1_pt2, l2_pt1, l2_pt2)) # Ponto no segmento 1 pt1 = {} pt1 ["x"] = 0 pt1 ["y"] = 10 impressão (is_point_on_line_segment (pt1, l1_pt1, l1_pt2)) # O ponto não está no segmento 1 pt2 = {} pt2 ["x"] = 50 pt2 [" y "] = 10 imprimir (is_point_on_line_segment (pt2, l1_pt1, l1_pt2))

Assista o vídeo: As linhas para crianças - Geometria para crianças