3

Given the following example:

def merge_with_largest(input_gdf,poly):
    
    # select the polygons bordering polygon
    close_by_gdf = input_gdf[input_gdf.geometry.intersects(poly)]
    # selects the index of the row with the largest area
    selected_index = close_by_gdf['area'].argmax()
    # now we merge the geometry of the selected index with the polygon geometry
    selected_geom = input_gdf.loc[selected_index]['geometry']
    # setting the 
    input_gdf.loc[selected_index,['geometry']] = gpd.GeoSeries((selected_geom,poly)).unary_union

What I want to do here is to merge the geometry of poly with the largest of the polygons that do intersect it with. I want to do this by using .unary_union between the two selected polygons and then update the geometry of the selected polygon with what .unary_union returns. The problem though is that sometimes .unary_union returns a mulitpolygon and then the .loc method throws an error because it's an iterable.

ValueError: Must have equal len keys and value when setting with an iterable

Is there a way to overwrite this and set the multipolygon as the the geometry for the selected column?

0

2 Answers 2

0

I found a workaround to my problem credit here goes to github https://github.com/geopandas/geopandas/issues/992

the solution in a nutshell:

geom = df.loc[1, 'geometry']
df.loc[[0], 'geometry'] = geopandas.GeoSeries([geom])

if geom is a multipolygon we cast it into a GeoSeries and then set the series as the new geometry

3
  • 1
    This didn't work for me, for what it's worth. The result of this was an empty geometry. Commented Aug 25, 2021 at 0:06
  • 1
    I looked back at some of the solutions in the geopandas issue linked above and appending .values on the end of your solution works: df.loc[[0], 'geometry'] = geopandas.GeoSeries([geom]).values Commented Aug 25, 2021 at 0:26
  • df.loc[[0], 'geometry'] = [input_gdf.loc[selected_index, 'geometry']] should work
    – mmann1123
    Commented Dec 8, 2021 at 14:30
0

I'm proposing another solution that solved a similar problem for me.

In my case, I had some Features in a GeoDataFrame with shared attributes and adjacent geometries, which could be consolidated as one Feature with a union.

The general solution is to create a temporary GeoDataFrame and using the GeoDataFrame.update() method. Important to note that the temporary GeoDataFrame needs to have a matching properties so it can be joined to update the original Feature.

Code:

original_gdf = gpd.read_file('geojson_filepath.geojson')

shared_id_attribute = 'unique_to_two_features'

idx_1, idx_2 = original_gdf.loc[original_gdf['aoid_id'].str.contains(shared_id_attribute), :].index
    
geom_1 = original_gdf.loc[idx_1, 'geometry']
geom_2 = original_gdf.loc[idx_2, 'geometry']
    
union_geom = geom_1.union(geom_2)
    
temp_df = gpd.GeoDataFrame({'aoi_id': aoi_id,
                            'geometry': [union]}, # need to wrap a list here
                           geometry='geometry', 
                           crs=original_gdf.crs)

# set an index to the unique identifier you want to join on
# otherwise `GeoDataFrame.update()` will update rows with matching index and column values. 
temp_df.index = temp_df['aoi_id']
    
# update geom 1 with union of both
original_gdf.update(temp_df)

assert original_gdf.loc[idx_1, 'geometry'] != None

original_gdf.drop(labels=idx_2, axis=0, inplace=True)

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.