Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bounds filter fix #127

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 42 additions & 32 deletions xee/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,16 +186,19 @@ def __init__(
self.geometry = geometry
self.primary_dim_name = primary_dim_name or 'time'
self.primary_dim_property = primary_dim_property or 'system:time_start'


# If crs_arg is None, we try to get it from projection but if
# projection is None, we use a default value ('EPSG:4326').
# This logic is implemented in self.get_info().
self.crs_arg = crs
proj = self.get_info.get('projection', {})
self.crs_arg = self.get_info['crs_arg']
self.crs = CRS(self.crs_arg)

self.n_images = self.get_info['size']
self._props = self.get_info['props']
# Metadata should apply to all imgs.
self._img_info: types.ImageInfo = self.get_info['first']

proj = self.get_info.get('projection', {})

self.crs_arg = crs or proj.get('crs', proj.get('wkt', 'EPSG:4326'))
self.crs = CRS(self.crs_arg)
# Gets the unit i.e. meter, degree etc.
self.scale_units = self.crs.axis_info[0].unit_name
# Get the dimensions name based on the CRS (scale units).
Expand Down Expand Up @@ -224,22 +227,24 @@ def __init__(
# used for all internal `computePixels()` calls.
try:
if isinstance(geometry, ee.Geometry):
x_min_0, y_min_0, x_max_0, y_max_0 = _ee_bounds_to_bounds(
x_min, y_min, x_max, y_max = _ee_bounds_to_bounds(
self.get_info['bounds']
)
else:
# TODO: Maybe converting the area of use to the desired
# crs and them getting the bounds is a better approach.
x_min_0, y_min_0, x_max_0, y_max_0 = self.crs.area_of_use.bounds
x_min, y_min = self.transform(x_min_0, y_min_0)
x_max, y_max = self.transform(x_max_0, y_max_0)
self.bounds = x_min, y_min, x_max, y_max
except AttributeError:
# `area_of_use` is probable `None`. Parse the geometry from the first
# image instead (calculated in self.get_info())
x_min_0, y_min_0, x_max_0, y_max_0 = _ee_bounds_to_bounds(
x_min, y_min, x_max, y_max = _ee_bounds_to_bounds(
self.get_info['bounds']
)

x_min, y_min = self.transform(x_min_0, y_min_0)
x_max, y_max = self.transform(x_max_0, y_max_0)
)
self.bounds = x_min, y_min, x_max, y_max

max_dtype = self._max_itemsize()

# TODO(b/291851322): Consider support for laziness when chunks=None.
Expand All @@ -260,19 +265,27 @@ def __init__(
def get_info(self) -> Dict[str, Any]:
"""Make all getInfo() calls to EE at once."""

rpcs = [
('size', self.image_collection.size()),
('props', self.image_collection.toDictionary()),
('first', self.image_collection.first()),
]
rpcs = {
'size': self.image_collection.size(),
'props': self.image_collection.toDictionary(),
'first': self.image_collection.first(),
}

if isinstance(self.projection, ee.Projection):
rpcs.append(('projection', self.projection))
rpcs['projection'] = self.projection

if self.crs_arg is not None:
rpcs['crs_arg'] = self.crs_arg
elif 'projection' in rpcs.keys():
rpcs['crs_arg'] = rpcs['projection'].crs()
else:
rpcs['crs_arg'] = 'EPSG:4326'

if isinstance(self.geometry, ee.Geometry):
rpcs.append(('bounds', self.geometry.bounds()))
# TODO: Is 1 good enough for the max error?
rpcs['bounds'] = self.geometry.bounds(1, rpcs['crs_arg'])
else:
rpcs.append(('bounds', self.image_collection.first().geometry().bounds()))
rpcs['bounds'] = self.image_collection.first().geometry().bounds(1, rpcs['crs_arg'])

# TODO(#29, #30): This RPC call takes the longest time to compute. This
# requires a full scan of the images in the collection, which happens on the
Expand All @@ -285,18 +298,15 @@ def get_info(self) -> Dict[str, Any]:
# client-side. Ideally, this would live behind a xarray-backend-specific
# feature flag, since it's not guaranteed that data is this consistent.
columns = ['system:id', self.primary_dim_property]
rpcs.append((
'properties',
(
self.image_collection.reduceColumns(
ee.Reducer.toList().repeat(len(columns)), columns
).get('list')
),
))

info = ee.List([rpc for _, rpc in rpcs]).getInfo()
rpcs['properties'] = (
self.image_collection.reduceColumns(
ee.Reducer.toList().repeat(len(columns)), columns
).get('list')
)

return dict(zip((name for name, _ in rpcs), info))
info = ee.List([rpc for _, rpc in rpcs.items()]).getInfo()

return dict(zip((name for name, _ in rpcs.items()), info))

@property
def image_collection_properties(self) -> Tuple[List[str], List[str]]:
Expand Down