11

From the code available here: https://shapely.readthedocs.io/en/latest/reference/shapely.GeometryCollection.html:

from shapely import LineString, Point

p = Point(51, -1)
l = LineString([(52, -1), (49, 2)])
gc = GeometryCollection([p, l])

How can I access the individual elements of the GeometryCollection with shapely >= 2.0.0?

I've tried the most simplistic/pythonic way without any success:

list(gc)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'GeometryCollection' object is not iterable

So, if the object is not iterable, I guess it will be hard to extract every single feature out of the geometry collection for the moment.

And in a similar way, as suggested in this thread:

gc[0]

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'GeometryCollection' object is not subscriptable

The object is neither subscriptable.

3 Answers 3

10

Try this code instead:

from shapely.geometry import Point
from shapely.geometry import LineString
from shapely.geometry import GeometryCollection

p = Point(51, -1)
l = LineString([(52, -1), (49, 2)])
gc = GeometryCollection([p, l])

pnt = gc.geoms[0]  # return point
print(pnt.x)
6

.geoms was absolutely a proper decision based on the deprecation e.g. in version 1.8.1.

ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry.

ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the geoms property instead to get the number of parts of a multi-part geometry.

ShapelyDeprecationWarning: __getitem__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the geoms property to access the constituent parts of a multi-part geometry.

I just wanted to mention another possibility through the mapping() and shape() methods:

from shapely.geometry import mapping, shape, LineString, Point, GeometryCollection

p = Point(51, -1)
l = LineString([(52, -1), (49, 2)])
gc = GeometryCollection([p, l])

print(shape(mapping(gc)['geometries'][0]))
print(shape(mapping(gc)['geometries'][1]))

will result in:

POINT (51 -1)
LINESTRING (52 -1, 49 2)
5

I was told by one of the shapely's maintainer that now, one has to use the .geoms attribute to access individual geometries. E.g.:

list(gc.geoms)
>:
  [<POINT (51 -1)>, <LINESTRING (52 -1, 49 2)>]

So as Hornbydd said in his answer, accessing a single element is done with a subscript on .geoms, e.g.:

gc.geoms[0]
>:
  <POINT (51 -1)>

gc.geoms[1]
>:
  <LINESTRING (52 -1, 49 2)>

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.