0

How would I access each x, y coordinate within a GeoDataFrame.geometry.interior?

With:

for ids, row in gdf.iterrows():
    for interior in row.geometry.interiors:
        for oring in list(interior.coords):
            print(oring)
            break

you would get something like:

(281755.0807502931, 6242820.412169201)
(281849.4055729074, 6242837.953621909)
...
(282022.0423603806, 6242795.454011634)
(282182.65706839535, 6242633.633094577)

This is a LINEARRING. I want to perform some function with each coordinate but don't know how to access it. If I now go:

for ids, row in rd_diff.iterrows():
    for interiors in row.geometry.interiors:
        for oring in list(interiors.coords):
            for x, y in oring:
                print(x, y)
                break

I get:


TypeError: cannot unpack non-iterable float object

How can I access each coordinate within a LINEARRING?

arkriger
  • 327
  • 2
  • 10

1 Answers1

2
exterior = [(2, 8), (7, 8), (7, 3), (2, 3), (2, 8)]
interior = [(4, 7), (4, 5), (6, 5), (6, 7), (4, 7)]
poly = Polygon(exterior, holes=[interior])
# numbers of holes
len(poly.interiors)
1
# therefore
print(list(poly.interiors[0].coords))
[(4.0, 7.0), (4.0, 5.0), (6.0, 5.0), (6.0, 7.0), (4.0, 7.0)]
#
print(poly.interiors[0].coords[:])
[(4.0, 7.0), (4.0, 5.0), (6.0, 5.0), (6.0, 7.0), (4.0, 7.0)]

And

for coord in poly.interiors[0].coords[:]:
     print(coord)
(4.0, 7.0)
(4.0, 5.0)
(6.0, 5.0)
(6.0, 7.0)
(4.0, 7.0)
# or
# first coordinate
poly.interiors[0].coords[:][0]
(4.0, 7.0)
# second coordinate
poly.interiors[0].coords[:][1]
(4.0, 5.0)
....

type(poly.interiors[0]) <class 'shapely.geometry.polygon.LinearRing'>

New

There is a problem with your solution: oring is a simple 1D list therefore you can iterate iterate over a list by one value

for i in (1,2):
    print(i,)
1,2

But not by more:

  for x,y in (1,2):
       print(x,y)
  TypeError: 'int' object is not iterable

The solution is (destructuring the list as variables)

  x,y = (1,2) # len = 2

Therefore, with geometry.interior as a list of Polygons

exterior = [(2, 8), (7, 8), (7, 3), (2, 3), (2, 8)]
interior = [(4, 7), (4, 5), (6, 5), (6, 7), (4, 7)]
interior2 = [(3, 5), (3, 4), (4, 4), (4, 5), (3, 5)]
poly = Polygon(exterior, holes=[interior,interior2])

To extract individual x,y

 # first coordinate of the first interior polygon
 x,y = poly.interiors[0].coords[:][0]
 print(x,y)
 x: 4.0 y: 7.0
 # third coordinate of the second interior polygon
 x,y = poly.interiors[1].coords[:][2]
 print("x:",x,"y:",y)
 x: 4.0 y: 4.0

all coordinates

for i, interior in enumerate(poly.interiors): print("interior: ",i) for oring in list(interior.coords): x,y = oring # oring is a list of floats print("oring:",oring,"x:",x,"y: ",y) interior: 0 oring:(4.0, 7.0) x: 4.0 y: 7.0 oring:(4.0, 5.0) x: 4.0 y: 5.0 oring:(6.0, 5.0) x: 6.0 y: 5.0 oring:(6.0, 7.0) x: 6.0 y: 7.0 oring:(4.0, 7.0) x: 4.0 y: 7.0 interior: 1 oring:(3.0, 5.0) x: 3.0 y: 5.0 oring:(3.0, 4.0) x: 3.0 y: 4.0 oring:(4.0, 4.0) x: 4.0 y: 4.0 oring: 4.0, 5.0) x: 4.0 y: 5.0 oring:(3.0, 5.0) x: 3.0 y: 5.0

To extract lists of x and y

for i, interior in enumerate(poly.interiors):
    ppx, ppy = zip(*interior.coords)
    print("interior:",i,"ppx:",ppx,"ppy:",ppy)

interior: 0 ppx: (4.0, 4.0, 6.0, 6.0, 4.0) ppy: (7.0, 5.0, 5.0, 7.0, 7.0) interior: 1 ppx: (3.0, 3.0, 4.0, 4.0, 3.0) ppy: (5.0, 4.0, 4.0, 5.0, 5.0)

gene
  • 54,868
  • 3
  • 110
  • 187
  • after for coord in interior[0].coords[:]: print(coord) -> TypeError: 'LinearRing' object is not subscriptable – arkriger Apr 18 '22 at 09:02
  • Then try with for coord in list(poly.interior.coords): because coordinates slicing has been introduced in the version 1.2.14. – gene Apr 18 '22 at 09:15
  • TypeError: cannot unpack non-iterable float object – arkriger Apr 18 '22 at 13:58
  • What is your shapely version ? – gene Apr 18 '22 at 15:23
  • you are being very patient with me. thank you. shapely=1.8.0 It might be the geometry.interior is Multipart ---does this mean: more than one interior polygon? If so iteration is not supported. How does one extract a (x, y) pair then? – arkriger Apr 18 '22 at 19:46
  • Look at New in my answer – gene Apr 19 '22 at 10:05
  • You have been extremely helpful. I'm not able to extract each coordinate pair ---one after the other. If I go: for co in zip(ppx, ppy): print(co) after ppx, ppy = zip(*interior.coords) I get the first pair in BOTH interiors. I want to iterate each interior and then each coordinate pair in that interior. And then the next interior; and so forth. I must be missing something obvious because I am unable too. – arkriger Jun 08 '22 at 13:05
  • I am going to accept your answer. ---I got the full solution from here – arkriger Jun 09 '22 at 13:15