xarray-contrib / xvec

Vector data cubes for Xarray
https://xvec.readthedocs.io
MIT License
101 stars 9 forks source link

xvec.geom_coords and geom_coords_indexed don't work for DataArray #21

Closed martinfleis closed 1 year ago

martinfleis commented 1 year ago

In case of non-empty DataArray, xvec.geom_coords and geom_coords_indexed don't work. We test only for a DataArray and Dataset without the actual values (only coords are set).

import geopandas
import pandas
import xarray
import numpy
import xvec
import shapely

nc = geopandas.read_file("https://github.com/r-spatial/sf/raw/main/inst/gpkg/nc.gpkg")

origin = destination = nc.geometry.array
mode = ["car", "bike", "foot"]
day = pandas.date_range("2015-01-01", periods=100)
hours = range(24)
data = numpy.random.randint(1, 100, size=(3, 100, 24, 100, 100))
arr = xarray.DataArray(data, coords=(mode, day, hours, origin, destination), dims=["mode", "day", "time", "origin", "destination"])
arr = arr.xvec.set_geom_indexes(["origin", "destination"], crs=nc.crs)
arr.xvec.geom_coords
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[52], line 1
----> 1 arr.xvec.geom_coords

File ~/Git/xvec/xvec/accessor.py:144, in XvecAccessor.geom_coords(self)
    100 @property
    101 def geom_coords(self) -> Mapping[Hashable, xr.DataArray]:
    102     """Returns a dictionary of xarray.DataArray objects corresponding to
    103     coordinate variables composed of :class:`shapely.Geometry` objects.
    104 
   (...)
    142     is_geom_variable
    143     """
--> 144     return self._obj[self._geom_coords_all].coords

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/dataarray.py:819, in DataArray.__getitem__(self, key)
    816     return self._getitem_coord(key)
    817 else:
    818     # xarray-style array indexing
--> 819     return self.isel(indexers=self._item_key_to_dict(key))

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/dataarray.py:1390, in DataArray.isel(self, indexers, drop, missing_dims, **indexers_kwargs)
   1387 indexers = either_dict_or_kwargs(indexers, indexers_kwargs, "isel")
   1389 if any(is_fancy_indexer(idx) for idx in indexers.values()):
-> 1390     ds = self._to_temp_dataset()._isel_fancy(
   1391         indexers, drop=drop, missing_dims=missing_dims
   1392     )
   1393     return self._from_temp_dataset(ds)
   1395 # Much faster algorithm for when all indexers are ints, slices, one-dimensional
   1396 # lists, or zero or one-dimensional np.ndarray's

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/dataset.py:2465, in Dataset._isel_fancy(self, indexers, drop, missing_dims)
   2462 valid_indexers = dict(self._validate_indexers(indexers, missing_dims))
   2464 variables: dict[Hashable, Variable] = {}
-> 2465 indexes, index_variables = isel_indexes(self.xindexes, valid_indexers)
   2467 for name, var in self.variables.items():
   2468     if name in index_variables:

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/indexes.py:1460, in isel_indexes(indexes, indexers)
   1456 def isel_indexes(
   1457     indexes: Indexes[Index],
   1458     indexers: Mapping[Any, Any],
   1459 ) -> tuple[dict[Hashable, Index], dict[Hashable, Variable]]:
-> 1460     return _apply_indexes(indexes, indexers, "isel")

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/indexes.py:1444, in _apply_indexes(indexes, args, func)
   1442 index_args = {k: v for k, v in args.items() if k in index_dims}
   1443 if index_args:
-> 1444     new_index = getattr(index, func)(index_args)
   1445     if new_index is not None:
   1446         new_indexes.update({k: new_index for k in index_vars})

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/xarray/core/indexes.py:427, in PandasIndex.isel(self, indexers)
    423 if not isinstance(indxr, slice) and is_scalar(indxr):
    424     # scalar indexer: drop index
    425     return None
--> 427 return self._replace(self.index[indxr])

File ~/mambaforge/envs/xvec_dev/lib/python3.10/site-packages/pandas/core/indexes/base.py:5382, in Index.__getitem__(self, key)
   5379     else:
   5380         key = np.asarray(key, dtype=bool)
-> 5382 result = getitem(key)
   5383 # Because we ruled out integer above, we always get an arraylike here
   5384 if result.ndim > 1:

IndexError: arrays used as indices must be of integer (or boolean) type