5

I trying to save file from GeoDataFrame to shapefile or spatialite. But for some reason i got error:

Error

My GeoDataFrame appear correctly without any issuesi look's like there is something wrong with my gdf.to_file commend but i have no idea what. I also checked if i got most up to date lib.

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?

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

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 = 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")
  • 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 Apr 19 '17 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 Apr 19 '17 at 10:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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