1

I have a GeoPandas dataframe which contains many rows and also a column named 'geometry' with the following input:

geometry        LINESTRING (445125.050522556 5536587.67127983, 445124.450035...

I want to get a new dataframe which splits the old one into equal 1 metre brackets.

Is that possible? There are some topics about these question but none of them worked well... How can I get it to work?

Here is my code:

from shapely.geometry import Point, LineString import
matplotlib.pyplot as plt import math

line_strings=[LineString([(10,20),(50,70)]),
              LineString([(11,22),(72,80)]),
              LineString([(32,11),(90,96)]),
              LineString([(32,34),(37,38)]),
              LineString([(50,60),(80,90)])]

split_len = 1 
coor_list = []
for i in range(len(line_strings)):
    Y1 = line_strings[i].coords.xy[0][0]
    X1 = line_strings[i].coords.xy[1][0]
    Y2 = line_strings[i].coords.xy[0][1]
    X2 = line_strings[i].coords.xy[1][1]

    lenght = ((X1 - X2) ** 2 + (Y1 - Y2) ** 2) ** (1 / 2)
    list_name = 'line_parts_coor' + str(i)
    list_name = []

    if lenght <= split_len:
        line = LineString([(Y1, X1), (Y2, X2)])
        list_name.append(line)
    else:
        AB = math.atan((Y2 - Y1) / (X2 - X1))

        YT = Y1 + split_len * math.sin(AB)
        XT = X1 + split_len * math.cos(AB)

        for j in range(int(lenght / split_len) + 1):
            YT = Y1 + split_len * j * math.sin(AB)
            XT = X1 + split_len * j * math.cos(AB)
            last_lenght = ((XT - X2) ** 2 + (YT - Y2) ** 2) ** (1 / 2)

            if last_lenght <= split_len:
                line = LineString([(YT, XT), (Y2, X2)])
                list_name.append(line)
            else:
                YT2 = Y1 + split_len * (j + 1) * math.sin(AB)
                XT2 = X1 + split_len * (j + 1) * math.cos(AB)
                line = LineString([(YT, XT), (YT2, XT2)])
                list_name.append(line)

    for k in range(len(list_name)):
        YL1 = list_name[k].coords.xy[0][0]
        XL1 = list_name[k].coords.xy[1][0]
        YL2 = list_name[k].coords.xy[0][1]
        XL2 = list_name[k].coords.xy[1][1]
        plt.plot([YL1, YL2], [XL1, XL2], label='line ' + str(i) + '-' + str(k), marker='o')
        coor_list.append('line ' + str(i) + '-' + str(k)+ ' ['
                         + str(YL1) + ','
                         + str(XL1) + ','
                         + str(YL2) + ','
                         + str(XL2)+']')

    plt.legend()
    plt.show()

print(coor_list)
1
  • 1
    What do you mean by "splits the old one into equal 1 metre brackets."? Edit your question to include some images of what you are trying to attempt.
    – Hornbydd
    Commented Aug 3, 2022 at 10:56

1 Answer 1

3

You can use this script:

Steps:

  1. Make an empty list
  2. Iterate over rows
  3. Split the line
  4. Add the split part to the list
  5. Make a GeoDataFrame from the list.
from shapely.geometry import  LineString
import geopandas as gpd
import math

line_strings=[LineString([(10,20),(50,70)]),
              LineString([(11,22),(72,80)]),
              LineString([(32,11),(90,96)]),
              LineString([(32,34),(37,38)]),
              LineString([(50,60),(80,90)])]

source_gdf = gpd.GeoDataFrame(line_strings, columns=["geometry"])

split_len = 1
data = []
for i, line in source_gdf.iterrows():
    geom = line["geometry"]
    Y1 = geom.coords.xy[0][0]
    X1 = geom.coords.xy[1][0]
    Y2 = geom.coords.xy[0][1]
    X2 = geom.coords.xy[1][1]

    length = ((X1 - X2) ** 2 + (Y1 - Y2) ** 2) ** (1 / 2)

    if length <= split_len:
        new_line = LineString([(Y1, X1), (Y2, X2)])
        data.append([f"line {i} - 0", new_line])
    else:
        AB = math.atan((Y2 - Y1) / (X2 - X1))

        YT = Y1 + split_len * math.sin(AB)
        XT = X1 + split_len * math.cos(AB)

        for j in range(int(length / split_len) + 1):
            YT = Y1 + split_len * j * math.sin(AB)
            XT = X1 + split_len * j * math.cos(AB)
            last_length = ((XT - X2) ** 2 + (YT - Y2) ** 2) ** (1 / 2)

            if last_length <= split_len:
                new_line = LineString([(YT, XT), (Y2, X2)])
                data.append([f"line {i} - {j}", new_line])
            else:
                YT2 = Y1 + split_len * (j + 1) * math.sin(AB)
                XT2 = X1 + split_len * (j + 1) * math.cos(AB)
                new_line = LineString([(YT, XT), (YT2, XT2)])
                data.append([f"line {i} - {j}", new_line])

gdf = gpd.GeoDataFrame(data, columns=["line_part", "geometry"]) 
gdf.plot(cmap = "prism", figsize=(8, 8))

Result for split_len = 10:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.