简体   繁体   中英

Extract points/coordinates from a polygon in Shapely

How do you get/extract the points that define a shapely polygon? Thanks!

Example of a shapely polygon

from shapely.geometry import Polygon

# Create polygon from lists of points
x = [list of x vals]
y = [list of y vals]

polygon = Polygon(x,y)

So, I discovered the trick is to use a combination of the Polygon class methods to achieve this.

If you want geodesic coordinates, you then need to transform these back to WGS84 (via pyproj , matplotlib 's basemap , or something).

from shapely.geometry import Polygon

#Create polygon from lists of points
x = [list of x vals]
y = [list of y vals]

some_poly = Polygon(x,y)

# Extract the point values that define the perimeter of the polygon
x, y = some_poly.exterior.coords.xy

You can use the shapely mapping function:

>>> from shapely.geometry import Polygon, mapping
>>> sh_polygon = Polygon(((0,0), (1,1), (0,1)))
>>> mapping(sh_polygon)
{'type': 'Polygon', 'coordinates': (((0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (0.0, 0.0)),)}

It took me a while to learn that a Polygon has an exterior boundary and possibly several interior boundaries. I am posting here because some of the answers don't reflect that distinction, though to be fair the original post did not use as an example a polygon with interior boundaries.

The points forming the exterior boundary are arranged in a CoordinateSequence, which can be obtained as

polygon.exterior.coords

You can find the length of this object using len(polygon.exterior.coords) and can index the object like a list. To get the first vertex, for example, use polygon.exterior.coords[0] . Note that the first and last points are the same; if you want a list consisting of the vertices without that repeated point, use polygon.exterior.coords[:-1] .

You can convert the CoordinateSequence (including the repeated vertex) to a list of points thus:

list(polygon.exterior.coords)

Similarly, the CoordinateSequence consisting of the vertices forming the first interior boundary is obtained as polygon.interiors[0].coords , and the list of those vertices (without the repeated point) is obtained as polygon.interiors[0].coords[:-1] .

I used this:

list(zip(*p.exterior.coords.xy))

Polygon created with: p = Polygon([(0,0),(1,1),(1,0),(0,0)]) returns:

[(0.0, 0.0), (1.0, 1.0), (1.0, 0.0), (0.0, 0.0)]

如果你真的想要构成多边形的形状点对象 ,而不仅仅是坐标元组,你可以这样做:

points = MultiPoint(polygon.boundary.coords)

You can convert a shapely Polygon to a NumPy array using NumPy.array. I find using NumPy arrays more useful than the arrays returned by coords.xy, since the coordinates are paired, rather than in two one-dimensional arrays. Use whichever is more useful to your application.

import numpy as np
x = [1, 2, 3, 4]
y = [9, 8, 7, 6]
polygon = Polygon(x,y)
points = np.array(polygon)

# points is:
[[ 1 9]
 [ 2 8]
 [ 3 7]
 [ 4 6]]

Update (2017-06-09):

As the last answer seems not to work anymore with newest version of shapely, I propose this update.

shapely provides the Numpy array interface (as the doc says: http://toblerity.org/shapely/project.html )

So, let poly be a shapely polygon geometry:

In [2]: type(poly)
Out[2]: shapely.geometry.polygon.Polygon

This command will do the conversion to a numpy array:

In [3]: coordinates_array = np.asarray(poly.exterior.coords)

Hint:
One must need to give the exterior.coords for a polygon because giving the direct geometry seems not to work either:

In [4]: coordinates_array = np.asarray(poly)
Out[4]: array(<shapely.geometry.polygon.Polygon object at 0x7f627559c510>, dtype=object)    

You can use any of the two following methods.

1)

p = Polygon([(1,0),(1,1),(0,1),(0,0)])
for x,y in p.exterior.coords:
   print(x,y)

The above code prints the following. Note that (1,0) is printed twice, since exterior.coords returns an ordered sequence that completes the polygon.

1.0 0.0
1.0 1.0
0.0 1.0
0.0 0.0
1.0 0.0

2)

p.exterior.coords.xy

It outputs the following

(array('d', [1.0, 1.0, 0.0, 0.0, 1.0]), array('d', [0.0, 1.0, 1.0, 0.0, 0.0]))
d0=[]
for n in range(0,len(gdf1['geometry'])):
    try:
        k=(len(gdf1['geometry'][n].geoms))    
        ce+=1
    except:
        d0.append(n)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM