0

I am reading multiple shapefiles (around 14) using the function below:

def import_shapes_list(path_to_data:str,shapes_folder:str,crs:str) ->gpd.GeoDataFrame:
    """
    """
    files = glob.iglob(path_to_data+shapes_folder+'*.shp')    
   
    gdfs = [gpd.read_file(file).to_crs(crs) for file in files]
    
    for gdf in gdfs:        
        gdf.columns = map(str.lower, gdf.columns)
    geomap = gpd.GeoDataFrame( pd.concat( gdfs, ignore_index=True) )   
    
    return geomap 

 geomap = import_shapes_list(path_to_data=xxx,shapes_folder=xxx,crs='EPSG:4326')

The error A LinearRing must have at least 3 coordinate tuples tells me that a polygon must have at least three points.

I tried to fix this by introducing try and except

try:
    # xxx
except ValueError:
    # xxx

As follows:

try:    
   gdfs = [gpd.read_file(file).to_crs(crs) for file in files]

except:
     print(e)
return gdfs

but I am still getting the same error. I also have no idea where that polygon with error is as I have 14 shapefiles.

Any idea on how to tackle this?

3
  • 3
    Technically, a linear ring must have four coordinates, with the first being the same as the last. If your data isn't valid polygon rings, you ought to have difficulty writing them to a polygon shapefile. Without more details on what is in these invalid geometries, it's difficult to help here.
    – Vince
    Dec 27, 2022 at 16:59
  • Thank you for your response. I need to look at each shape file and see where the problem is. Concatenating has never been an issue in the past, until i started adding new shape files from our supplier
    – bravopapa
    Dec 27, 2022 at 17:09
  • 1
    Smallest linear ring is a triangle with three distinct corners. In many geometry encodings (WKT etc.) the start point of the ring must indeed be repeated for closing the ring.
    – user30184
    Dec 27, 2022 at 19:01

1 Answer 1

1

This approach worked for me:

#Check Geometry
def isvalid(geom)-> int:
    try:
        shape(geom)
        return 1
    except:
        return 0
    
def read_gdf(file:str)->gpd.GeoDataFrame:
    #Read data
    collection = list(fiona.open(file,'r'))
    df1 = pd.DataFrame(collection)

    
    df1['isvalid'] = df1['geometry'].apply(lambda x: isvalid(x))
    df1 = df1[df1['isvalid'] == 1]
    collection = json.loads(df1.to_json(orient='records'))

    #Convert to geodataframe
    return gpd.GeoDataFrame.from_features(collection)

def import_shapes_list(path_to_data:str,shapes_folder:str,crs:str) ->gpd.GeoDataFrame:
    """
    """
    files = glob.iglob(pathxxxxx+'*.shp')
    
    gdfs = []
    for file in files:
        print(file)
        #gdf = gpd.read_file(file).to_crs(crs)
        gdf = read_gdf(file)
        gdf.columns = map(str.lower, gdf.columns)
        gdfs.append(gdf)
        
   
    geomap = gpd.GeoDataFrame( pd.concat( gdfs, ignore_index=True) )   
    
    return geomap 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.