'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
- for each line find polygons that it intersects https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoSeries.intersection.html
- 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)
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 |

