I have a geopandas dataframe that looks likes this:
level_0 id \
0 0 028f342a-b26f-4e36-b5d1-25d3428cac2f
1 1 028f342a-b26f-4e36-b5d1-25d3428cac2f
2 2 028f342a-b26f-4e36-b5d1-25d3428cac2f
3 3 028f342a-b26f-4e36-b5d1-25d3428cac2f
4 4 028f342a-b26f-4e36-b5d1-25d3428cac2f
... ... ...
2959 2959 fef00a1e-a823-47fc-b6e4-4e5885cc587b
2960 2960 fef00a1e-a823-47fc-b6e4-4e5885cc587b
2961 2961 fef00a1e-a823-47fc-b6e4-4e5885cc587b
2962 2962 fef00a1e-a823-47fc-b6e4-4e5885cc587b
2963 2963 fef00a1e-a823-47fc-b6e4-4e5885cc587b
edges.id \
0 28cd1b27-dda1-4ba8-a79c-042e8af6a1d3
1 28cd1b27-dda1-4ba8-a79c-042e8af6a1d3
2 28cd1b27-dda1-4ba8-a79c-042e8af6a1d3
3 28cd1b27-dda1-4ba8-a79c-042e8af6a1d3
4 2cb0816e-de32-47ef-9695-eeb1f15e5771
... ...
2959 e0f9373d-0943-4eda-9ab2-0390eb0035a3
2960 e3eba3f8-0a1a-45a0-b3b1-cd9edcf50128
2961 e3eba3f8-0a1a-45a0-b3b1-cd9edcf50128
2962 e3eba3f8-0a1a-45a0-b3b1-cd9edcf50128
2963 e3eba3f8-0a1a-45a0-b3b1-cd9edcf50128
geometry_obstacle index x_polygon \
0 LINESTRING (32.46686 3.50903, 33.78148 3.50903... 106 32.47
1 LINESTRING (32.46686 3.50903, 33.78148 3.50903... 106 33.78
2 LINESTRING (32.46686 3.50903, 33.78148 3.50903... 106 33.78
3 LINESTRING (32.46686 3.50903, 33.78148 3.50903... 106 32.47
4 LINESTRING (32.46686 3.50903, 33.78148 3.50903... 106 32.47
... ... ... ...
2959 LINESTRING (4.77078 36.10261, 8.12194 36.10261... 48 4.77
2960 LINESTRING (4.77078 36.10261, 8.12194 36.10261... 48 4.77
2961 LINESTRING (4.77078 36.10261, 8.12194 36.10261... 48 8.12
2962 LINESTRING (4.77078 36.10261, 8.12194 36.10261... 48 8.12
2963 LINESTRING (4.77078 36.10261, 8.12194 36.10261... 48 4.77
y_polygon geometry
0 3.51 POINT (32.46686 3.50903)
1 3.51 POINT (33.78148 3.50903)
2 6.16 POINT (33.78148 6.16054)
3 6.16 POINT (32.46686 6.16054)
4 3.51 POINT (32.46686 3.50903)
... ... ...
2959 37.10 POINT (4.77078 37.10083)
2960 36.10 POINT (4.77078 36.10261)
2961 36.10 POINT (8.12194 36.10261)
2962 37.10 POINT (8.12194 37.10083)
2963 37.10 POINT (4.77078 37.10083)
[2964 rows x 8 columns]
It contains two geometries, one being a linestring (they are all closed polygons, all of them rectangles), the other being points (the edges of the polygons). What I am trying to do is the split the linestrings at the points, thus splitting the polygons/lenstrings into segments (ie the sides of the polygons).
I tried to do the following thing:
from shapely.ops import split
df = df.assign(New = lambda x: sp(x['geometry_obstacle'],x['geometry']))
but I get the following error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-30-77a268925585> in <module>
2 for lev in lev:
3 df = geostore_obstacles_geometry_new[geostore_obstacles_geometry_new['level_0']==lev]
----> 4 df = df.assign(New = lambda x: sp(x['geometry_obstacle'],x['geometry']))
5 New.append(df)
~\Anaconda3\envs\conda-qgis\lib\site-packages\pandas\core\frame.py in assign(self, **kwargs)
3828
3829 for k, v in kwargs.items():
-> 3830 data[k] = com.apply_if_callable(v, data)
3831 return data
3832
~\Anaconda3\envs\conda-qgis\lib\site-packages\pandas\core\common.py in apply_if_callable(maybe_callable, obj, **kwargs)
327 """
328 if callable(maybe_callable):
--> 329 return maybe_callable(obj, **kwargs)
330
331 return maybe_callable
<ipython-input-30-77a268925585> in <lambda>(x)
2 for lev in lev:
3 df = geostore_obstacles_geometry_new[geostore_obstacles_geometry_new['level_0']==lev]
----> 4 df = df.assign(New = lambda x: sp(x['geometry_obstacle'],x['geometry']))
5 New.append(df)
~\Anaconda3\envs\conda-qgis\lib\site-packages\shapely\ops.py in split(geom, splitter)
468 """
469
--> 470 if geom.type in ('MultiLineString', 'MultiPolygon'):
471 return GeometryCollection([i for part in geom.geoms for i in SplitOp.split(part, splitter).geoms])
472
~\Anaconda3\envs\conda-qgis\lib\site-packages\pandas\core\generic.py in __nonzero__(self)
1440 @final
1441 def __nonzero__(self):
-> 1442 raise ValueError(
1443 f"The truth value of a {type(self).__name__} is ambiguous. "
1444 "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
I suspect (I might very well be wrong) that split
tries all combinations.Therefore, I tried to apply split
line by line:
lev = list(geostore_obstacles_geometry_new.level_0)
New = []
for lev in lev:
df = geostore_obstacles_geometry_new[geostore_obstacles_geometry_new['level_0']==lev]
df = df.assign(New = lambda x: sp(x['geometry_obstacle'],x['geometry']))
New.append(df)
but I still get the same error.
How can I solve this? Any other approach is ok.
Since you seem to have duplicated line geometries with individual point geometries, I would start with a non-vectorized solution.
Everytime you call df.assign
you're (attempting) to define the entire column all at once (ie, as many times as your loop would be called if it didn't raise an error).
So in this case, I would use df.apply
along axis = 1. I'll also wrap split
into a function that accepts individual rows of dataframe so that we don't need nested lambda functions
from shapely.ops import split
def get_side_of_rect(row, linecol="geometry_obstacle", pointcol="geometry"):
return split(row[linecol], row[pointcol])
gdf = (
gdf.assign(sides=lambda df: df.apply(get_side_of_rect, axis=1))
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.