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?

Taras
  • 32,823
  • 4
  • 66
  • 137
BERA
  • 72,339
  • 13
  • 72
  • 161
  • 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 Jun 23 '18 at 11:09

2 Answers2

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
Taras
  • 32,823
  • 4
  • 66
  • 137
Kadir Şahbaz
  • 76,800
  • 56
  • 247
  • 389
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'])

Taras
  • 32,823
  • 4
  • 66
  • 137
Ben
  • 727
  • 5
  • 19