'I want to split a line with a specific value in QGIS. Can I also split the value accordingly to the length splitted?

I have some multiline strings that cross through multiple polygons. When I split the line I would like QGIS to also split the value assigned to the line accordingly. E.g. if a line of 100 meters has a value 20 when split into segments of 50/30/20 I want the value to also split to 10/6/4 in the corresponding segments. Is that possible or I am shooting for the stars?



Solution 1:[1]

  • you have tagged geopandas so giving a solution in geopandas
  • start by creating a GeoDataFrame of polygons and line strings that intersect in different ways
  • now it's a case of iterating over line strings
    1. for each line find polygons that it intersects https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoSeries.intersection.html
    2. where intersection is a line or multi-line work out contribution by comparing lengths of lines
  • have visualised to demonstrate
import geopandas as gpd
import shapely

world = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres"))

# some polygons
poly = world.loc[world["iso_a3"].isin(["UKR", "POL", "HUN"])].drop(columns=["pop_est","gdp_md_est"]).copy()

# some linestrings
line = gpd.GeoDataFrame(
    data={"val": [100, 200]},
    geometry=[
        shapely.geometry.LineString([poly.total_bounds[0:2], poly.total_bounds[2:4]]),
        shapely.geometry.LineString([poly.total_bounds[0:2]+.5, poly.total_bounds[2:4], poly.total_bounds[[0,3]]-1]),

    ],
    crs=poly.crs,
)

# initialise contibution from line,  zero
poly = poly.assign(**{f"val{l}":0 for l in range(len(line))})
# iterate over the lines
for n, (i, r) in enumerate(line.iterrows()):
    # iterate over intersections between line and polygons
    for ii, ls in poly.intersection(r["geometry"]).iteritems():
        if ls.is_empty or isinstance(ls,shapely.geometry.Point):
            continue
        geom = [ls] if isinstance(ls, shapely.geometry.LineString) else ls.geoms
        # work out contribution of each intersection segment
        for ls in geom:
            poly.loc[ii, f"val{n}"] +=  (ls.length / r["geometry"].length) * r["val"]


# visualise ...            
m = poly.explore(height=300, width=500)
line.explore(m=m)

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Rob Raymond