Search code examples
pythongeopandaspython-xarray

How to store GeoDataFrame to NetCDF file


I want to save GeoDataFrame as a NetCDF file. Then, I can combine it with another NetCDF file later.

However, there's an error for saving the Dataset converted from GeoDataFrame. Here's a simple code and error info:

import geopandas

world = geopandas.read_file(geopandas.datasets.get_path('naturalearth_lowres'))
ds = world.to_xarray()
ds.to_netcdf('test.nc')

Error:

    ds.to_netcdf('test.nc')
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/core/dataset.py", line 1902, in to_netcdf
    return to_netcdf(
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/api.py", line 1072, in to_netcdf
    dump_to_store(
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/api.py", line 1119, in dump_to_store
    store.store(variables, attrs, check_encoding, writer, unlimited_dims=unlimited_dims)
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/common.py", line 261, in store
    variables, attributes = self.encode(variables, attributes)
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/backends/common.py", line 350, in encode
    variables, attributes = cf_encoder(variables, attributes)
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 855, in cf_encoder
    new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 855, in <dictcomp>
    new_vars = {k: encode_cf_variable(v, name=k) for k, v in variables.items()}
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 275, in encode_cf_variable
    var = ensure_dtype_not_object(var, name=name)
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 233, in ensure_dtype_not_object
    data = _copy_with_dtype(data, dtype=_infer_dtype(data, name))
  File "/public/home/zhangxin/new/miniconda3/envs/knmi_arctic_new/lib/python3.8/site-packages/xarray/conventions.py", line 167, in _infer_dtype
    raise ValueError(
ValueError: unable to infer dtype on variable 'geometry'; xarray cannot serialize arbitrary Python objects

Is it impossible to save MULTIPOLYGON or POLYGON in NC file? If you have any advice, I would appreciate a lot.


Solution

  • You can expand out the geometry to sequences of lat / lon.

    import geopandas
    import shapely.geometry
    
    world = geopandas.read_file(geopandas.datasets.get_path("naturalearth_lowres"))
    
    ds = world.drop(columns="geometry").join(
        world["geometry"]
        .apply(lambda g: [g] if isinstance(g, shapely.geometry.Polygon) else g.geoms)
        .explode()
        .apply(lambda p: p.exterior.coords)
        .explode()
        .apply(pd.Series)
        .rename(columns={0: "lat", 1: "lon"})
    ).to_xarray()
    
    ds.to_netcdf('test.nc')