3

I imported a shapefile in the form of a pandas.DataFrame and ran operations on it. But I can't convert the DataFrame to a GeoDataFrame. I tried with gpd.GeoDataFrame, and with wkt.loads. I think it's because of the format of my geometry: they're Polygon Z:

0 POLYGON Z((653467.7 6840811 81.5 ...))

Here is my code when I try to create a geometry column before the conversion to GeoDataFrame

bat['BAT_COORD']=bat['BAT_COORD'].apply(wkt.loads)

and the error :

Traceback (most recent call last):
 File "cleanshp.py", line 34, in <module>
 bat['BAT_COORD']=bat['BAT_COORD'].apply(wkt.loads)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/pandas/core/series.py", line 4200, in apply
 mapped = lib.map_infer(values, f, convert=convert_dtype)
 File "pandas/_libs/lib.pyx", line 2388, in pandas._libs.lib.map_infer
 File "/home/windmyroof/.local/lib/python3.7/site-packages/shapely/wkt.py", line 10, in loads
 return geos.WKTReader(geos.lgeos).read(data)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/shapely/geos.py", line 279, in read
 raise TypeError("Only str is accepted.")
TypeError: Only str is accepted.

The code with the shapefile import as a geodataframe (seems good), and an attempt of export shapefile (that fails) :

import geopandas as gpd
import pandas as pd
from shapely.ops import unary_union
from shapely.geometry import Point, Polygon
from shapely import wkt
def import_shapefile(path):
 # import shapefile using geopandas
 sjer_plot_locations = gpd.read_file(path)
 # create right dataset for geometry reconstruction
 columns = ['BAT_ID', 'BAT_COORD', 'BAT_HAUTEUR', 'Z_SOL']
 bat = gpd.GeoDataFrame(index=range(len(sjer_plot_locations.geometry[:])), columns=columns)
 for i in range(len(sjer_plot_locations.geometry[:])):
 bat.at[i, 'BAT_ID'] = sjer_plot_locations.ID[i]
 bat.at[i, 'BAT_HAUTEUR'] = sjer_plot_locations.HAUTEUR[i]
 bat.at[i, 'Z_SOL'] = sjer_plot_locations.Z_MIN_SOL[i]
 bat.at[i, 'BAT_COORD'] = sjer_plot_locations.geometry[i]
 return bat, sjer_plot_locations
bat, sjer = import_shapefile('/home/windmyroof/salome_shp/bats.shp')
n_bats = [i for i in range(len(bat.index))]
# cleaning geometry
# u = unary_union([bat.at[i, 'BAT_COORD'] for i in range(len(bat.index)) if i in n_bats])
# u = u.simplify(0.5)
bat.to_file('/home/windmyroof/salome_shp/bats_cleaned.shp')

And the error :

Traceback (most recent call last):
 File "cleanshp.py", line 33, in <module>
 bat.to_file('/home/windmyroof/salome_shp/bats_cleaned.shp')
 File "/home/windmyroof/.local/lib/python3.7/site-packages/geopandas/geodataframe.py", line 746, in to_file
 _to_file(self, filename, driver, schema, index, **kwargs)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/geopandas/io/file.py", line 239, in _to_file
 schema = infer_schema(df)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/geopandas/io/file.py", line 299, in infer_schema
 geom_types = _geometry_types(df)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/geopandas/io/file.py", line 316, in _geometry_types
 geom_types_2D = df[~df.geometry.has_z].geometry.geom_type.unique()
 File "/home/windmyroof/.local/lib/python3.7/site-packages/pandas/core/generic.py", line 5130, in __getattr__
 return object.__getattribute__(self, name)
 File "/home/windmyroof/.local/lib/python3.7/site-packages/geopandas/geodataframe.py", line 173, in _get_geometry
 " column '%s'.)" % self._geometry_column_name
AttributeError: No geometry data set yet (expected in column 'geometry'.)

I fixed the problem using the comments. It was necessary to rename the column "BAT_COORD" to 'geometry'. Indeed importing directly in gdp and not pd works very well.

Taras
35.8k5 gold badges77 silver badges151 bronze badges
asked Aug 3, 2020 at 13:36
5
  • 3
    Why arent you reading the shape into a geodataframe? gpd.read_file("path/to/shapefile.shp"). Might be easier than pandas -> geopandas Commented Aug 3, 2020 at 13:38
  • 2
    thanks for your answer, I tried and it works, but I always have the problem : I want to export the shapefile on which I made operation to a new shapefile. I want to use the gpd.to_file function for that. This function requires the argument "geometry" which I can't extract. Commented Aug 3, 2020 at 13:52
  • It seems from the output string that the geometry is already a Shapely geometry object. As the error message says, loads expects a string object. I think you just setting the geometry column should be enough to create a GeoDataFrame, you don't need to convert something. Can you add the code how you tried to create the GeoDataFrame? Commented Aug 4, 2020 at 2:26
  • Yes I edited my question in which i added the code Commented Aug 4, 2020 at 14:48
  • Please cut and paste your answer from the area reserved for questions into the area reserved for answers. It is fine and encouraged to self-answer. Commented Aug 9, 2020 at 10:34

1 Answer 1

0

Import directly to geopandas is definitely the right move. The only step you are missing is setting which column contains the geometry! Try add this line before writing to file:

bat.set_geometry('BAT_COORD', inplace=True)
answered Aug 19, 2020 at 14:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.