The best result I have had so far is this one:
list(gdf.select_dtypes('geometry'))[0]
And I think it's OK but if there was a more direct method I would be glad to hear about it.
In the case of a GeoDataFrame with multiple geometry columns, as there should normally be one active geometry column, one can get this particular one as follows (see at the bottom for the rare case of a GeoDataFrame with multiple active geometry columns):
import geopandas as gpd
from shapely.geometry import Point
d = {
'col1': ['name1', 'name2'],
'fancy': [Point(1, 2), Point(2, 1)],
'custom': [Point(3, 4), Point(5, 6)],
}
gdf = geopandas.GeoDataFrame(d)
gdf
>:
col1 fancy custom
0 name1 POINT (1 2) POINT (3 4)
1 name2 POINT (2 1) POINT (5 6)
Currently, none of the column is seen a a geometry column:
gdf.dtypes
>:
col1 object
fancy object
custom object
dtype: object
At this stage, if we use the method shown above to extract the geometry column name on the GeoDataFrame, it throws an error:
gdf.dtypes
>:
col1 object
fancy object
custom object
dtype: object
# running this naturally raises an error:
list(gdf.select_dtypes('geometry'))[0]
Traceback (most recent call last):
File "/tmp/ipykernel_369762/3000512511.py", line 1, in <cell line: 1>
list(gdf.select_dtypes('geometry'))[0]
IndexError: list index out of range
Because the list is actually empty:
gdf.select_dtypes('geometry')
>:
Empty GeoDataFrame
Columns: []
Index: [0, 1]
That's why we need to actually "set" the geometry column, i.e. we mark it as active:
gdf.set_geometry('fancy', inplace=True, crs=4326,)
gdf.dtypes
>:
col1 object
fancy geometry
custom object
dtype: object
So mow the previous code returns the active geometry column:
list(gdf.select_dtypes('geometry'))[0]
>: 'fancy'
But fortunately, you can set more than one active geometry column (although this is not the most common case):
gdf.set_geometry('custom', inplace=True, crs=4326,)
gdf.dtypes
>:
col1 object
fancy geometry
custom geometry
dtype: object
Then, because the list of geometry
columns has more than one element now, you will have to manually figure out which element you want:
list(gdf.select_dtypes('geometry'))
>: ['fancy', 'custom']