14

I am trying to save a GeoDataFrame as a shapefile or spatialite, but for some reason, I get this error:

File "fiona\ogrext.pyx", line 951, in fiona.ogrext.WritingSession.start (fiona/ogrext.c:16479) AttributeError: 'int' object has no attribute 'encode'

My GeoDataFrame appears correctly without any issues, look's like there is something wrong with my gdf.to_file command, but I have no idea what.

I checked if I have the most up-to-date libraries.

This is the code I use:

def writeIntoDatabase(input_path, numpy_point_array, 30):
    
    print ('Reading data into shp')
    df = pd.DataFrame(numpy_point_array)
    dfthresh = df.loc[df[3] < 30]
    geometry = [Point(xyz) for xyz in zip(dfthresh[0], dfthresh[1], dfthresh[2])]
    #df = df.drop(['Lon', 'Lat', 'Alt'], axis=1)

    print(geometry)    

    crs = {'init': 'epsg:27700'}

    gdf = GeoDataFrame(dfthresh, crs=crs, geometry = geometry)
    print (gdf)

    gdf.to_file(driver = 'ESRI Shapefile', filename = input_path)

Can you help me?

2
  • Without knowing what are fd, pts and clearance_zone_max, we can do nothing
    – gene
    Commented Apr 18, 2017 at 15:03
  • Ok sorry, please see my edits :)
    – Losbaltica
    Commented Apr 18, 2017 at 15:06

1 Answer 1

20

As I don't know your data, I give you a solution with my data (with x,y, z and a colum to test < 30). If I use your solution

import geopandas as gpd
import numpy as np
import pandas as pd
numpy_point_array = np.array([[202104.271187,90516.656257,170.520004272, 45],[202139.659561,90516.656257,170.740005493, 15],[202175.047935,90516.656257,170.809997559, 12],[202210.436309,90516.656257,170.75, 10],[202245.824683,90516.656257,170.13999939, 31]])
df = pd.DataFrame(numpy_point_array)
dfthresh = df.loc[df[3] < 30]
from shapely.geometry import Point
geometry = [Point(xyz) for xyz in zip(dfthresh[0], dfthresh[1], dfthresh[2])]
import geopandas as gpd
crs = {'init': 'epsg:27700'}
gdf = gpd.GeoDataFrame(dfthresh, crs=crs, geometry = geometry)

The name of the columns are

list(gdf)
[0, 1, 2, 3, 'geometry'] 

And a shapefile does not accept integers as column names -> Fiona error AttributeError: 'int' object has no attribute 'encode'

The solution ?, give a name to the fields when you create a DataFrame

# creation of a DataFrame with string column names
df = pd.DataFrame(numpy_point_array, columns=['x','y','z','test'])
df.head()
         x             y           z        test
0  202104.271187  90516.656257  170.520004  45.0
1  202139.659561  90516.656257  170.740005  15.0
2  202175.047935  90516.656257  170.809998  12.0
3  202210.436309  90516.656257  170.750000  10.0
4  202245.824683  90516.656257  170.139999  31.0

And you can simplify your script

# selection
df =  df[df['test'] < 30]
df.head()
           x             y           z      test
1  202139.659561  90516.656257  170.740005  15.0
2  202175.047935  90516.656257  170.809998  12.0
3  202210.436309  90516.656257  170.750000  10.0
# convert to GeoDataFrame
# create a geometry column from the dataFrame x,y,z columns
df['geometry'] = df.apply(lambda row: Point(row.x,row.y,row.z),axis=1)
df = df.drop(['x', 'y', 'z'], axis=1)
# create the GeoDatFrame
gdf = gpd.GeoDatFrame(df, geometry = df.geometry)
# save the GeoDataFrame
gdf.to_file(driver = 'ESRI Shapefile', filename= "result.shp")
# or directly
gdf.to_file("result2.shp")
2
  • Thank you it works amazing :) The only problem is with process speed. To save 540k points it taking me about 30 minutes. The you know how to speed up this process?
    – Losbaltica
    Commented Apr 19, 2017 at 8:11
  • Also i found out that my output shapefile is still 2D but when i change driver for eg. to GeoJSON it saves as 3D
    – Losbaltica
    Commented Apr 19, 2017 at 10:17

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.