Split a LineString with a Point.
(line, splitter)
| 400 | |
| 401 | @staticmethod |
| 402 | def _split_line_with_point(line, splitter): |
| 403 | """Split a LineString with a Point.""" |
| 404 | if not isinstance(line, LineString): |
| 405 | raise GeometryTypeError("First argument must be a LineString") |
| 406 | if not isinstance(splitter, Point): |
| 407 | raise GeometryTypeError("Second argument must be a Point") |
| 408 | |
| 409 | # check if point is in the interior of the line |
| 410 | if not line.relate_pattern(splitter, "0********"): |
| 411 | # point not on line interior --> return collection with single identity line |
| 412 | # (REASONING: Returning a list with the input line reference and creating a |
| 413 | # GeometryCollection at the general split function prevents unnecessary |
| 414 | # copying of linestrings in multipoint splitting function) |
| 415 | return [line] |
| 416 | elif line.coords[0] == splitter.coords[0]: |
| 417 | # if line is a closed ring the previous test doesn't behave as desired |
| 418 | return [line] |
| 419 | |
| 420 | # point is on line, get the distance from the first point on line |
| 421 | distance_on_line = line.project(splitter) |
| 422 | coords = list(line.coords) |
| 423 | # split the line at the point and create two new lines |
| 424 | current_position = 0.0 |
| 425 | for i in range(len(coords) - 1): |
| 426 | point1 = coords[i] |
| 427 | point2 = coords[i + 1] |
| 428 | dx = point1[0] - point2[0] |
| 429 | dy = point1[1] - point2[1] |
| 430 | segment_length = (dx**2 + dy**2) ** 0.5 |
| 431 | current_position += segment_length |
| 432 | if distance_on_line == current_position: |
| 433 | # splitter is exactly on a vertex |
| 434 | return [LineString(coords[: i + 2]), LineString(coords[i + 1 :])] |
| 435 | elif distance_on_line < current_position: |
| 436 | # splitter is between two vertices |
| 437 | return [ |
| 438 | LineString(coords[: i + 1] + [splitter.coords[0]]), |
| 439 | LineString([splitter.coords[0]] + coords[i + 1 :]), |
| 440 | ] |
| 441 | return [line] |
| 442 | |
| 443 | @staticmethod |
| 444 | def _split_line_with_multipoint(line, splitter): |
no test coverage detected