Skip to content

Commit

Permalink
Issue #114/#211/#197 from_geodataframe: add dummy cube when no proper…
Browse files Browse the repository at this point in the history
…ties are specified
  • Loading branch information
soxofaan committed Aug 4, 2023
1 parent 69cf166 commit 1dd06e3
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
17 changes: 13 additions & 4 deletions openeo_driver/datacube.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ class DriverVectorCube:
COLUMN_SELECTION_ALL = "all"
COLUMN_SELECTION_NUMERICAL = "numerical"

# Xarray cube attribute to indicate that it is a dummy cube
CUBE_ATTR_VECTOR_CUBE_DUMMY = "vector_cube_dummy"

def __init__(
self,
geometries: gpd.GeoDataFrame,
Expand Down Expand Up @@ -319,8 +322,14 @@ def from_geodataframe(
return cls(geometries=geometries_df, cube=cube)

else:
# TODO: add a dummy 1D no-data cube?
return cls(geometries=data)
# Use 1D dummy cube of NaN values
cube: xarray.DataArray = xarray.DataArray(
data=numpy.full(shape=[data.shape[0]], fill_value=numpy.nan),
dims=[cls.DIM_GEOMETRIES],
coords={cls.DIM_GEOMETRIES: data.geometry.index.to_list()},
attrs={cls.CUBE_ATTR_VECTOR_CUBE_DUMMY: True},
)
return cls(geometries=data, cube=cube)

@classmethod
def from_fiona(
Expand Down Expand Up @@ -412,7 +421,7 @@ def _as_geopandas_df(
"""Join geometries and cube as a geopandas dataframe"""
# TODO: avoid copy?
df = self._geometries.copy(deep=True)
if self._cube is not None:
if self._cube is not None and not self._cube.attrs.get(self.CUBE_ATTR_VECTOR_CUBE_DUMMY):
assert self._cube.dims[0] == self.DIM_GEOMETRIES
# TODO: better way to combine cube with geometries
# Flatten multiple (non-geometry) dimensions from cube to new properties in geopandas dataframe
Expand Down Expand Up @@ -507,7 +516,7 @@ def to_legacy_save_result(self) -> Union["AggregatePolygonResult", "JSONResult"]
# TODO: eliminate these legacy, non-standard formats?
from openeo_driver.save_result import AggregatePolygonResult, JSONResult

if self._cube is None:
if self._cube is None or self._cube.attrs.get(self.CUBE_ATTR_VECTOR_CUBE_DUMMY):
# No cube: no real data to return (in legacy style), so let's just return a `null` per geometry.
return JSONResult(data=[None] * self.geometry_count())

Expand Down
26 changes: 24 additions & 2 deletions tests/test_vectorcube.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,18 @@ def test_to_internal_json_defaults(self, gdf):
"attrs": {},
},
),
([], None),
(
[],
{
"name": None,
"dims": ("geometries",),
"coords": {
"geometries": {"attrs": {}, "data": [0, 1], "dims": ("geometries",)},
},
"data": [IsNan(), IsNan()],
"attrs": {"vector_cube_dummy": True},
},
),
(
["pop", "id"],
{
Expand Down Expand Up @@ -359,7 +370,18 @@ def test_from_geodataframe_default(self, gdf):
"attrs": {},
},
),
([], None),
(
[],
{
"name": None,
"dims": ("geometries",),
"coords": {
"geometries": {"attrs": {}, "data": [0, 1], "dims": ("geometries",)},
},
"data": [IsNan(), IsNan()],
"attrs": {"vector_cube_dummy": True},
},
),
(
["id"],
{
Expand Down

0 comments on commit 1dd06e3

Please sign in to comment.