1

Let the following file be the result of a GeoDataFrame dump to a CSV file: gdf.to_csv('/path/to/gdf.csv')

$ cat '/path/to/gdf.csv'

myid,geometry
332,"MULTIPOLYGON Z (((0 0 0, 0 0 1, 0 1 1, 0 0 0)))"
220,"MULTIPOLYGON Z (((1 1 1, 1 1 2, 1 2 2, 1 1 1)))"

When I try to load it back, things surprisingly go wrong:

import geopandas as gpd

gdf = gpd.read_file('/path/to/gdf.csv')

Traceback (most recent call last):

  File "/tmp/ipykernel_369762/4150368047.py", line 1, in <cell line: 1>
    gpd.read_file('/path/to/gdf.csv')

  File "/usr/local/lib/python3.10/dist-packages/geopandas/io/file.py", line 259, in _read_file
    return _read_file_fiona(

  File "/usr/local/lib/python3.10/dist-packages/geopandas/io/file.py", line 360, in _read_file_fiona
    df = GeoDataFrame.from_features(

  File "/usr/local/lib/python3.10/dist-packages/geopandas/geodataframe.py", line 643, in from_features
    return cls(rows, columns=columns, crs=crs)

  File "/usr/local/lib/python3.10/dist-packages/geopandas/geodataframe.py", line 159, in __init__
    raise ValueError(

ValueError: GeoDataFrame does not support multiple columns using the geometry column name 'geometry'.

while if I sed -i 's/geometry/geometry2/g' /path/to/gdf.csv and then open the same file again:

gpd.read_file('/path/to/gdf.csv')

>: 
  myid                                geometry2 geometry
0  332  MULTIPOLYGON Z (((0 0 0, 0 0 1, 0 1 ...     None
1  220  MULTIPOLYGON Z (((1 1 1, 1 1 2, 1 2 ...     None

So, for the moment, I have to load it this way:

import pandas as pd
import geopandas as gpd

gpd.GeoDataFrame(pd.read_csv('/path/to/gdf.csv'))

>: myid                                geometry2
0   332  MULTIPOLYGON Z (((0 0 0, 0 0 1, 0 1 ...
1   220  MULTIPOLYGON Z (((1 1 1, 1 1 2, 1 2 ...

Also, by carefully reading the doc of the read_file() method, one can notice the ignore_geometry option (which is a little counter intuitive imho):

gdf = gpd.read_file('/path/to/gdf.csv', ignore_geometry=True)

type(gdf)
>: pandas.core.frame.DataFrame

This forces me to do kind of a casting-back-to-GeoDataFrame operation:

gdf = gpd.GeoDataFrame(gpd.read_file('/path/to/gdf.csv', ignore_geometry=True))

type(gdf)
>: geopandas.geodataframe.GeoDataFrame

which sounds to be a bit of an "overstatement" to me, because I must tell it first to ignore the geometry, and then set it back as a geometry the step after...

I'm therefore wondering if there is a more natural/intuitive way of loading a CSV file dumped from a GeoDataFrame back into a GeoDataFrame?

My GeoPandas' version is '0.12.2'.

0

1 Answer 1

0

From @gene's answer to a similar question:

When you open a csv file, with GeoPandas it automatically adds a geometry field

As you already have a field called "geometry", GeoPandas raises an exception. GeoPandas doesn't read the WKT strings in the "geometry" field as geometry.

However, if you look at the GDAL/OGR CSV driver documentation, if a field is named "WKT" it will be read as geometry:

When reading a field named “WKT” is assumed to contain WKT geometry, but also is treated as a regular field.

Approaches:

  1. One option is to write out the CSV using "WKT" as the geometry column name and then it can be read straight back in:

    gdf = gdf.rename_geometry('WKT')
    gdf.to_csv('/path/to/gdf.csv', index=False)
    
    gdf = gpd.read_file('/path/to/gdf.csv')
    
  2. Alternatively, the CSV driver also supports the open option GEOM_POSSIBLE_NAMES which lets you specify a different field name to look for geometry in.

    gdf = gpd.read_file('/path/to/gdf.csv', GEOM_POSSIBLE_NAMES="geometry", KEEP_GEOM_COLUMNS="NO") 
    

    The KEEP_GEOM_COLUMNS option is also required otherwise GDAL/OGR will return a "geometry" column as well as the geometry and you still get the original ValueError: GeoDataFrame does not support multiple columns using the geometry column name 'geometry'.

  3. A final option is to read the CSV in as a Pandas DataFrame then manually create the geometry from the WKT and convert to a GeoDataFrame:

    import geopandas as gpd
    
    df = gpd.read_file('/path/to/gdf.csv', ignore_geometry=True)
    
    # Create geometry objects from WKT strings
    df['geometry'] = gpd.GeoSeries.from_wkt(df['geometry'])
    
    # Convert to GDF
    gdf = gpd.GeoDataFrame(df)
    

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.