19

I'm trying to list all polygon vertices coordinates of a rectangle with four corners and a hole with four corners. I drew the vertices in this order:

enter image description here

import geopandas as gpd
#import matplotlib.pyplot as plt
import numpy as np

df = gpd.read_file('/home/bera/geodata/Rectangle_with_hole.shp')
g = [i for i in df.geometry]
x,y = g[0].exterior.coords.xy
coords = np.dstack((x,y)).tolist()

>>>coords
[[[536176.3224485546, 6724565.633642049],
  [538863.5583380334, 6724580.120088892],
  [539022.9092533124, 6722189.856359706],
  [536201.6737305308, 6722124.66734891],
  [536176.3224485546, 6724565.633642049]]]

Only five coordinate pairs are listed. How can I list all?

1
  • 3
    for the interior polygon, you need to use (interiors.coords). Regarding the order, normally geopandas use clockwise direction, that's why the order you got is (1,4,3,2,1)
    – Moh
    Commented Jun 23, 2018 at 11:09

2 Answers 2

32

Not sure if one line method exists, but the following ways could work. (Solutions are for the first feature's geometry, and they are just for Polygon, not for MultiPolygon)

Solution 1: boundary property of a polygon returns exterior and all interiors of the polygon.

import numpy as np
import geopandas as gpd

df = gpd.read_file('/home/bera/geodata/Rectangle_with_hole.shp')
g = [i for i in df.geometry]

all_coords = []
for b in g[0].boundary: # for first feature/row
    coords = np.dstack(b.coords.xy).tolist()
    all_coords.append(*coords)                 

all_coords

enter image description here

Result:

[[[0.0, 0.0],  #1  #exterior
  [0.0, 4.0],  #2
  [7.0, 4.0],  #3
  [7.0, 0.0],  #4
  [0.0, 0.0]], #1

 [[1.0, 1.0],  #5  #interior1
  [3.0, 1.0],  #6
  [3.0, 3.0],  #7
  [1.0, 3.0],  #8
  [1.0, 1.0]], #5 

 [[4.0, 3.0],  #9  #interior2
  [4.0, 1.0],  #10
  [6.0, 1.0],  #11
  [6.0, 3.0],  #12
  [4.0, 3.0]]] #9

Solution 2: polygon.interiors returns InteriorRingSequence object which consists of LinearRing objects.

import numpy as np
import geopandas as gpd

df = gpd.read_file('/home/bera/geodata/Rectangle_with_hole.shp')
g = [i for i in df.geometry]
x,y = g[0].exterior.coords.xy
all_coords = np.dstack((x,y)) ####

for interior in g[0].interiors: # for first feature/row
    x, y = interior.coords.xy
    coords = np.dstack((x,y))
    all_coords = np.append(all_coords, coords, axis=0)

all_coords  # or all_coords.tolist()

Result:

array([[[0., 0.],  #1  #exterior
        [0., 4.],  #2
        [7., 4.],  #3
        [7., 0.],  #4
        [0., 0.]], #1

       [[1., 1.],  #5  #interior1
        [3., 1.],  #6
        [3., 3.],  #7
        [1., 3.],  #8
        [1., 1.]], #5                     

       [[4., 3.],  #9  #interior2
        [4., 1.],  #10
        [6., 1.],  #11
        [6., 3.],  #12
        [4., 3.]]])#9

Solution 3: shapely.geometry.mapping function returns the GeoJSON-like mapping of a geometric object.

import geopandas as gpd
from shapely.geometry import mapping
    
df = gpd.read_file('/home/bera/geodata/Rectangle_with_hole.shp')

g = [i for i in df.geometry]
geojson_ob = mapping(g[0]) # for first feature/row
all_coords = geojson_ob["coordinates"]
all_coords

Result:

(((0.0, 0.0), (0.0, 4.0), (7.0, 4.0), (7.0, 0.0), (0.0, 0.0)), #exterior
 ((1.0, 1.0), (3.0, 1.0), (3.0, 3.0), (1.0, 3.0), (1.0, 1.0)), #interior1
 ((4.0, 3.0), (4.0, 1.0), (6.0, 1.0), (6.0, 3.0), (4.0, 3.0))) #interior2
0
11

One way might be to convert to JSON then read back to dictionary:

import json
import numpy as np
import geopandas as gpd

df = gpd.read_file('/home/bera/geodata/Rectangle_with_hole.shp')
g = json.loads(df.to_json())

coords = np.array(g['features'][0]['geometry']['coordinates'])
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.