Skip to content

Interpolation of Z values in GEOSInterpolate and GEOSInterpolateNormalized #1348

@theroggy

Description

@theroggy

For both GEOSInterpolate and GEOSInterpolateNormalized, it seems that the interpolation distance along the line is treated as a 2D distance rather than a 3D distance.

Possibly this is by design, but in that case it might be useful to document it. However, especially for a perfectly vertical line this gives some odd results...

In addition, GEOSInterpolateNormalized on a vertical line always seems to return the starting point, even if the relative interpolation distance is 1, which doesn't seem logical even if the distance is treated as 2D.

edit: I added the "length" as calculated by GEOS for each line in the output as well... and it seems that the Z dimension is being ignored in the length calculation.

Test script:

from shapely import LineString

for line in [
    LineString([(0, 0, 0), (0, 0, 1), (0, 0, 2)]),
    LineString([(0, 0, 0), (0, 1, 1), (0, 2, 2)]),
]:
    for normalized in [True, False]:
        for dist in [0.5, 1]:
            result = line.interpolate(dist, normalized=normalized)
            print(f"interpolate {line=} ({line.length=}), {dist=}, {normalized=}: {result}")

Results:

interpolate line=<LINESTRING Z (0 0 0, 0 0 1, 0 0 2)> (line.length=0.0), dist=0.5, normalized=True: POINT Z (0 0 0)
interpolate line=<LINESTRING Z (0 0 0, 0 0 1, 0 0 2)> (line.length=0.0), dist=1, normalized=True: POINT Z (0 0 0)
interpolate line=<LINESTRING Z (0 0 0, 0 0 1, 0 0 2)> (line.length=0.0), dist=0.5, normalized=False: POINT Z (0 0 2)
interpolate line=<LINESTRING Z (0 0 0, 0 0 1, 0 0 2)> (line.length=0.0), dist=1, normalized=False: POINT Z (0 0 2)
interpolate line=<LINESTRING Z (0 0 0, 0 1 1, 0 2 2)> (line.length=2.0), dist=0.5, normalized=True: POINT Z (0 1 1)
interpolate line=<LINESTRING Z (0 0 0, 0 1 1, 0 2 2)> (line.length=2.0), dist=1, normalized=True: POINT Z (0 2 2)
interpolate line=<LINESTRING Z (0 0 0, 0 1 1, 0 2 2)> (line.length=2.0), dist=0.5, normalized=False: POINT Z (0 0.5 0.5)
interpolate line=<LINESTRING Z (0 0 0, 0 1 1, 0 2 2)> (line.length=2.0), dist=1, normalized=False: POINT Z (0 1 1)

Originally reported here: shapely/shapely#1195

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