Overlapping polygons with hexagons

577 Views Asked by At

I have been struggling with polygons in python 3 for a long time. There is a geojson with a list of polygons and multipolygons. It is necessary to cover these polygons with hexes of a CERTAIN level. At the moment, hexagons are level 5, but there may be others. If I now cross polygons with level 5 hexes, then some polygons do not find hexagon at all. When I began to debug the output, I concluded that a hex is issued only if the polygon area covers 50% of the hex area. And how to do the same, only to set the degree of overlap yourself? I want to be able to get all the hexes where at least 1 pixel is occupied by a polygon. Ideally, you want to manually set the overlap area.

Now I get hexagons by polygons with this function:

def hex_id(df_polygon, resolution):
global h3_id_df
global msc

list_set_h3_id = []
list_h3_id = []
gdf = geopandas.GeoDataFrame(df_polygon, geometry = 'geometry')
exploded = gdf.explode()
polygons_list = exploded['geometry'].astype('str').tolist()

for i in polygons_list:
    msc = geojson.Feature(geometry = shapely.wkt.loads(i), properties={})
    list_set_h3_id.append(h3.polyfill_geojson(msc.geometry, resolution))
    
df_polygon['geo_id'] = list_set_h3_id

for i in list_set_h3_id:
    for i in (list(i)):
        list_h3_id.append(i)
        
h3_id_df = pd.DataFrame({'geo_id':list_h3_id})

return h3_id_df

Function input and output

1

There are 1 best solutions below

0
On

Per the polyfill docs:

Containment is determined by the cells' centroids.

So at times you may have polygons that do not get any cells, because no cells have a center point falling inside the polygon. It's on the H3 roadmap to add other containment modes, but at the moment this is all that's available in the library.

At the moment, if you want other containment modes, you will need to implement them yourself. There are various approaches you can take here, depending on how important edge cases are. One basic approach:

  • Use polyfill to get cells with contained centers
  • Buffer the output cells by one:
for idx in indexes:
 for neighbor in h3.k_ring(idx, 1):
   if not neighbor in indexes:
     buffer.append(neighbor)
  • Test each cell in the buffer for polygon intersection (likely using h3_to_geo_boundary and a geometry lib like shapely), and add those that pass to the list.