Fido
Fido

Reputation: 330

Shapely - get coordinates of crossings from complex linestring

I've created complex linestring as follows:

from shapely.geometry import LineString

complex_line = LineString([(-1, -1), (1, 1), (1, 0), (-1, 0)])

The line is valid but it is not simple. How can I get the crossing point (here [0,0])?

Upvotes: 1

Views: 1646

Answers (1)

Paul H
Paul H

Reputation: 68146

You want to split the line at some point after the self-intersection. Then you can do isect_pnt = first.intersection(second). The trick is finding that point after the self-intersection.

So I'm going to loop through "split fractions" from 0.1 to 0.9 and split the geometry at each fraction of the total length and see if shapely can find a valid intersection. If it can, we can break out of the loop and stop searching. For splits that are before the self-intersection, isect_pnt = first.intersects(second) will return False and we can can keep searching.

One nuance here is that I'm going to use the interpolate method to create the new geometries at a finer resolution

import numpy
from shapely.geometry import LineString, Point

complex_line = LineString([(-1, -1), (1, 1), (1, 0), (-1, 0)])

# initial, non-result
intersection = None

# fraction of total distance at which we'll split the line
for split in numpy.arange(0.1, 1, 0.1):

    full_len = complex_line.length
    split_len = full_len * split

    # endpoint = False to make sure we don't get a false-positive
    # at the split point
    first = LineString([
        complex_line.interpolate(d)
        for d in numpy.linspace(0, split_len, num=25, endpoint=False)
    ])

    second = LineString([
        complex_line.interpolate(d)
        for d in numpy.linspace(split_len, full_len, num=25)
    ])

    if first.intersects(second):
        intersection = first.intersection(second)
        break

print(intersection)

And on my machine, that outputs:

POINT (0 0)

This is not very well optimized. On large, complex geometries, I can imagine that this could require more resolved interpolations of each half of the line end up pretty slow .

Upvotes: 2

Related Questions