0

Lets say we have a polygon and need the vertices and edges.

import geopandas as gpd
from shapely.geometry import Polygon

lat_point_list = [50.854457, 52.518172, 50.072651, 48.853033, 50.854457]
lon_point_list = [4.377184, 13.407759, 14.435935, 2.349553, 4.377184]

polygon_geom = Polygon(zip(lon_point_list, lat_point_list))
polygon = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
coords_rounded = []
all_coords = []

for i, row in polygon.iterrows():
    ring = list(row.geometry.exterior.coords)
    ring.pop()
    if row.geometry.exterior.is_ccw == False:
        #-- to get proper orientation of the normals
        ring.reverse()
        
    for j, v in enumerate(ring[:-1]):
        rounded_x = round(float(ring[j][0]), 2)
        rounded_y = round(float(ring[j][1]), 2)
        rounded_z = 100
        coords_rounded.append((rounded_x, rounded_y, rounded_z))
        all_coords.append([rounded_x, rounded_y, rounded_z]) 

    #-- last-first edge
    rounded_x = round(float(ring[-1][0]), 2)
    rounded_y = round(float(ring[-1][1]), 2)
    rounded_z = 100
    coords_rounded.append((rounded_x, rounded_y, rounded_z))
    all_coords.append([rounded_x, rounded_y, rounded_z]) 

print(all_coords)

[[2.35, 48.85, 100], [14.44, 50.07, 100], [13.41, 52.52, 100], [4.38, 50.85, 100]]

Gives me the vertices in the format I need. A list with faces in the proper orientation where the order of the nodes define the normal vector pointing outward. I now need the indices of the coordinates in the form:

[[1351, 1358],
 [1358, 1360],
 [1360, 1359]...]

How do I extract the indices that define the edges of the polygon. A list-of-lists where where each element is the index of the to- and from-coordinate (of an edge) from the print(all_coords) list? I need a closed polygon please.

1
  • 1
    It's not 100% clear from your example where the numbers 1351, 1358... come from and why they do not simply increase with a +1 step. Dec 26, 2022 at 19:55

1 Answer 1

1

First of all, you can simplify your code because your first ring is:

[(4.377184, 50.854457),
 (13.407759, 52.518172),
 (14.435935, 50.072651),
 (2.349553, 48.853033),
 (4.377184, 50.854457)]

and you pop its last element:

ring.pop() # pops out: (4.377184, 50.854457)

so ring becomes:

[(4.377184, 50.854457),
 (13.407759, 52.518172),
 (14.435935, 50.072651),
 (2.349553, 48.853033)]

and then you loop over ring[:,-1] which is only [(4.377184, 50.854457), (13.407759, 52.518172), (14.435935, 50.072651)] so you are missing your last vertex (2.349553, 48.853033). That's why you must add it back at the end.

You can avoid that by simplifying your code:

import geopandas as gpd
from shapely.geometry import Polygon

lat_point_list = [50.854457, 52.518172, 50.072651, 48.853033, 50.854457]
lon_point_list = [4.377184, 13.407759, 14.435935, 2.349553, 4.377184]

polygon_geom = Polygon(zip(lon_point_list, lat_point_list))
polygon = gpd.GeoDataFrame(index=[0], crs='epsg:4326', geometry=[polygon_geom])
all_coords = []
edges = []

for i, row in polygon.iterrows():
    exterior = row.geometry.exterior
    ring = list(exterior.coords)
    ring.pop() # pop out duplicate vertice
    if exterior.is_ccw == False:
        #-- to get proper orientation of the normals
        ring.reverse()

    for j, v in enumerate(ring):
        edges.append([j,j+1])
        rounded_x = round(float(v[0]), 2)
        rounded_y = round(float(v[1]), 2)
        rounded_z = 100
        all_coords.append([rounded_x, rounded_y, rounded_z]) 
    
    edges.append([j+1,0])

print(all_coords)
print(edges)

which prints the same result:
[[2.35, 48.85, 100], [14.44, 50.07, 100], [13.41, 52.52, 100], [4.38, 50.85, 100]]

in addition with the indices of the vertices:
[[0, 1], [1, 2], [2, 3], [3, 4], [4, 0]]

But it's not 100% clear from your code why your indices do not simply increase with a +1 increment... A point in a ring should directly follow its previous neighbor.

1

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.