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?

7
  • You have already accessed each coordinate. Each line in the output is a coordinate. Apr 17, 2022 at 22:23
  • Sorry; I was not clear. I want to perform some-function with each (x, y) . I can access the entire LINEARRING. How do I now extract each coordinate pair ---as a seperate entity--- from a LINEARRING?
    – arkriger
    Apr 18, 2022 at 5:57
  • The result is a simple Python list of coordinates
    – gene
    Apr 18, 2022 at 6:33
  • @gene; If it were a list would for u in i: print(u) break ---following for i in interior.coords: not produce one (x, y) pair? The print statement is the entire LINEARRING. How do I extract each coordinte pair from a LINEARRING?
    – arkriger
    Apr 18, 2022 at 7:19
  • Look the answer below
    – gene
    Apr 18, 2022 at 8:51

1 Answer 1

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)
8
  • after for coord in interior[0].coords[:]: print(coord) -> TypeError: 'LinearRing' object is not subscriptable
    – arkriger
    Apr 18, 2022 at 9: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, 2022 at 9:15
  • TypeError: cannot unpack non-iterable float object
    – arkriger
    Apr 18, 2022 at 13:58
  • What is your shapely version ?
    – gene
    Apr 18, 2022 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, 2022 at 19:46

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.