2 votos

Dividir la línea en la intersección con otra línea utilizando Shapely

Estoy buscando una solución para dividir un LineString en la intersección con otro LineString . Mi primera solución es:

from shapely import wkt
from shapely.ops import split

first_line = wkt.loads('LINESTRING (28.112115297354478 57.00625960468798, 8.219782679723316 20.076477637253483)')
second_line = wkt.loads('LINESTRING (-36.57919844025919 19.94938832911169, 8.426621630216765 20.077064414418004, 29.684689833718174 0.223433149286052)')

real_intersection = second_line.intersection(first_line) # POINT (8.219782679723316 20.076477637253483)
split_second_line = split(second_line, real_intersection)

Basado en dividir() ' documentación espero ver al menos dos LINESTRING en GEOMETRYCOLLECTION . La salida: GEOMETRYCOLLECTION (LINESTRING (-36.57919844025919 19.94938832911169, 8.426621630216765 20.077064414418004, 29.684689833718174 0.223433149286052))

Aparentemente no hay intersección entre first_line y second_line así que construyo una extensión de first_line :

from math import atan2, cos, sin, degrees
from shapely.geometry import Point, LineString

first_line_coords = list(first_line.coords)
lon1 = first_line_coords[0][0]
lat1 = first_line_coords[0][1]
lon2 = first_line_coords[1][0]
lat2 = first_line_coords[1][1]

angle = atan2(cos(lat1)*sin(lat2)-sin(lat1) * cos(lat2)*cos(lon2-lon1), sin(lon2-lon1)*cos(lat2))
bearing = (degrees(angle) + 360) % 360

new_first_line_length = first_line.length + 10
end_point = Point(lon1 + new_first_line_length * math.cos(bearing), lon1 + new_first_line_length * math.sin(bearing))
start_point = Point(first_line_coords[0])
new_first_line = LineString([start_point, end_point])

new_real_intersection = second_line.intersection(new_first_line) # POINT (7.015156377654302 20.073060257673145)
new_split_second_line = split(second_line, new_real_intersection)

La salida es: GEOMETRYCOLLECTION (LINESTRING (-36.57919844025919 19.94938832911169, 8.426621630216765 20.077064414418004, 29.684689833718174 0.223433149286052))

De nuevo sólo tengo una LINESTRING . No entiendo dónde está mi error.

4voto

GreyCat Puntos 146

Utilice unión_unaria ( Gráfico plano )

La intersección es un punto y hay errores de precisión en coma flotante cuando se encuentra un punto en una línea ( Determinar si un punto Shapely está dentro de una LineString/MultiLineString )

real_intersection = second_line.intersection(first_line) # red point

enter image description here

# this point is on both lines
first_line.distance(real_intersection) < 1e-8 
True
second_line.distance(real_intersection) < 1e-8 
True
from shapely.ops import unary_union
uu = unary_union([first_line,second_line])
for line in uu:
   print(line)
LINESTRING (28.11211529735448 57.00625960468798, 8.219782679723316 20.07647763725348)
LINESTRING (-36.57919844025919 19.94938832911169, 8.219782679723316 20.07647763725348)
LINESTRING (8.219782679723316 20.07647763725348, 8.426621630216765 20.077064414418, 29.68468983371817 0.223433149286052)

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X