Search code examples
pythongeospatialgeopandasgdalfiona

Dissolving polygons in python results in some polygons missing


I have a large code that is essentially vectorizing a tiff layer into polygon shapefile. the last step of the code is dissolving the polygons based on their value (ranging 1-5). I tried using 'Geopandas's 'dissolve', 'Shapely' and 'Fiona's 'unary_union' function, I tried 'GDAl's ogr2ogr function and in all of them I get the same issue. Some of the lower level polygons are being 'Swallowed' by the higher levels. for some reason, in some areas the polygons change their borders and go over the lower levels. this means that in the final output I'm missing some of the poylgons. The same effect happens when I use the dissolve tool in ArcMap, BUT the same tool in Qgis works perfectly and does not cause this issues.

in the attached image you can see to the right how the shapefile should look, and in the left, the output after the dissolve process. you can see one of the green polygons is missing.]

Any ideas how to overcome this issue?

the current code i have that causes the issue:

    def dissolve_shapefiles(self, algo_class):
       """Dissolves merged shapefiles by SM_LV column."""
       try:
           dissolved = self.final_gdf.dissolve(by='SM_LV', as_index=False)
           algo_class.dissolved_output_path = os.path.abspath(os.path.join(self.output_directory, "..",
                                                                           self.project_name + '_Vectorized_Dissolved.shp'))
           dissolved.to_file(algo_class.dissolved_output_path)
           full_path = os.path.abspath(algo_class.dissolved_output_path)
           print(f"Dissolved shapefile saved as {algo_class.dissolved_output_path}")
           print(f"Full path: {full_path}")
           self.split_merged_shapefile(algo_class.dissolved_output_path)
       except Exception as e:
           print(f"Error dissolving shapefile: {e}") 

Solution

  • As Sam advised in the comments, the problem was with the geometries. I used Shapley's 'make_valid' to fix the geometries before dissolving them.

    def dissolve_shapefiles(self, algo_class):
        """Dissolves merged shapefiles by SM_LV column."""
        try:
    
            self.final_gdf['geometry'] = self.final_gdf['geometry'].apply(make_valid)
    
            dissolved = self.final_gdf.dissolve(by='SM_LV', as_index=False)
            algo_class.dissolved_output_path = os.path.abspath(os.path.join(self.output_directory, "..",
                                                                            self.project_name + '_Vectorized_Dissolved.shp'))
            dissolved.to_file(algo_class.dissolved_output_path)
            full_path = os.path.abspath(algo_class.dissolved_output_path)
            print(f"Dissolved shapefile saved as {algo_class.dissolved_output_path}")
            print(f"Full path: {full_path}")
            self.split_merged_shapefile(algo_class.dissolved_output_path)
        except Exception as e:
            print(f"Error dissolving shapefile: {e}")