Skip to content

Transition to new split_line implementation #497

@ghendrickx

Description

@ghendrickx

Within the repository, there were multiple functions that split a line (shapely.LineString) by a point (shapely.Point). In #494, a robust line-splitting function has been implemented (64f02db-846ef2d), replacing other/older implementations. The new function gets in robustness by not relying on the shapely.ops.split-function for splitting the line by a point, which is known not to work robustly using this built-in split-function.

Due to the modifications - and aligning the various line-splitting function - the signature slightly changes and the intended output will change as well:

  1. Signature change from def split_line(line: shapely.LineString, point: shapely.Point, tolerance: float = 0.1) (or similar) to def split_line(line: shapely.LineString, point: shapely.Point, *, tolerance: float = 0.1) (excluding transitional arguments).
  2. Output change from shapely.MultiLineString | shapely.LineString to tuple[shapely.LineString, ...].

The code-changes in #494 already include a transition strategy by a temporary signature (and typing.overload-functions):

@typing.overload
def split_line(
    line: LineString, point: Point, *deprecated: typing.Any, tolerance: float = 0.1, as_multilinestring: None
) -> MultiLineString | LineString: ...


# TODO: Next transition step: Default `as_multilinestring=None` with `=True`-behaviour and a UserWarning


@typing.overload
def split_line(
    line: LineString,
    point: Point,
    *deprecated: typing.Any,
    tolerance: float = 0.1,
    as_multilinestring: typing.Literal[True] = True,
) -> MultiLineString | LineString: ...


@typing.overload
def split_line(
    line: LineString,
    point: Point,
    *deprecated: typing.Any,
    tolerance: float = 0.1,
    as_multilinestring: typing.Literal[False],
) -> tuple[LineString, ...]: ...


def split_line(
    line: LineString,
    point: Point,
    *deprecated: typing.Any,
    tolerance: float = 0.1,
    as_multilinestring: bool | None = True,
) -> MultiLineString | LineString | tuple[LineString, ...]:
    ...

The *deprecated-argument catches positional use of the tolerance-argument, which will become keyword-only:

    if deprecated:
        warnings.warn(
            "Passing 'tolerance' positionally is deprecated. Use keyword argument 'tolerance='.",
            FutureWarning,
            stacklevel=2,
        )
        tolerance = deprecated[0]

The as_multilinestring-argument defaults to the old behaviour of returning shapely.MultiLineString-objects (or shapely.LineString-objects). Currently, it defaults to True. The next transition step would have it change to None by default; next, defaulting to False; and eventually will be removed and the function will always return the intended, more robust output: tuple[shapely.LineString, ...]:

    if as_multilinestring is None:
        warnings.warn(
            "Calling 'split_line' without specifying 'as_multilinestring' is deprecated. "
            "In a future version, this will return 'tuple[LineString, ...]'. "
            "Set 'as_multilinestring' explicitly (and set to False for future-proofing the code).",
            UserWarning,
            stacklevel=2,
        )
    elif as_multilinestring:
        warnings.warn(
            "The 'split_line'-function will return tuple with LineString-objects in the future. "
            "Change to the future behaviour by setting 'as_multilinestring=False'.",
            FutureWarning,
            stacklevel=2,
        )

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions