The Oracle
The Oracle

Reputation: 488

How to convert convex hull vertices into a geopandas polygon

Iam using DBSCAN to cluster coordinates together and then using convexhull to draw 'polygons' around each cluster. I then want to construct geopandas polygons out of my convex hull shapes to be used for spatial joining.

import pandas as pd, numpy as np, matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from scipy.spatial import ConvexHull



Lat=[10,10,20,23,27,28,29,34,11,34,66,22]
Lon=[39,40,23,21,11,29,66,33,55,22,11,55]

D=list(zip(Lat, Lon))
df = pd.DataFrame(D,columns=['LAT','LON'])

X=np.array(df[['LAT', 'LON']])


kms_per_radian = 6371.0088
epsilon = 1500 / kms_per_radian
db = DBSCAN(eps=epsilon, min_samples=3) 


model=db.fit(np.radians(X))
cluster_labels = db.labels_




num_clusters = len(set(cluster_labels))



cluster_labels = cluster_labels.astype(float)
cluster_labels[cluster_labels == -1] = np.nan



labels = pd.DataFrame(db.labels_,columns=['CLUSTER_LABEL'])

dfnew=pd.concat([df,labels],axis=1,sort=False)





z=[] #HULL simplices coordinates will be appended here

for i in range (0,num_clusters-1):
    dfq=dfnew[dfnew['CLUSTER_LABEL']==i]
    Y = np.array(dfq[['LAT', 'LON']])
    hull = ConvexHull(Y)
    plt.plot(Y[:, 1],Y[:, 0],  'o')
    z.append(Y[hull.vertices,:].tolist())
    for simplex in hull.simplices:
        ploted=plt.plot( Y[simplex, 1], Y[simplex, 0],'k-',c='m')


plt.show()

print(z)

the vertices appended in list[z] represent coordinates of the convex hull however they are not constructed in sequence and closed loop object hence constructing polygon using polygon = Polygon(poin1,point2,point3) will not produce a polygon object. is there a way to construct geopandas polygon object using convex hull vertices in order to use for spatial joining. THanks for your advise.

Upvotes: 2

Views: 2255

Answers (1)

martinfleis
martinfleis

Reputation: 7804

Instead of generating polygon directly, I would make a MultiPoint out of your coordinates and then generate convex hull around that MultiPoint. That should result in the same geometry, but in properly ordered manner.

Having z as list of lists as you do:

from shapely.geometry import MultiPoint

chulls = []
for hull in z:
    chulls.append(MultiPoint(hull).convex_hull)

chulls
[<shapely.geometry.polygon.Polygon at 0x117d50dc0>,
 <shapely.geometry.polygon.Polygon at 0x11869aa30>]

Upvotes: 3

Related Questions