-
Notifications
You must be signed in to change notification settings - Fork 29
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
transform dataset coordinates into specified crs #97
Changes from 3 commits
f1b63cf
d698f43
410104a
e260659
c6d574d
00ba444
b224db7
81766cf
24ff582
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -253,6 +253,10 @@ def __init__( | |
else: | ||
self.mask_value = mask_value | ||
|
||
self.coordinate_transformer = pyproj.Transformer.from_crs( | ||
'EPSG:4326', self.crs, always_xy=True | ||
) | ||
|
||
@functools.cached_property | ||
def get_info(self) -> Dict[str, Any]: | ||
"""Make all getInfo() calls to EE at once.""" | ||
|
@@ -555,11 +559,19 @@ def get_variables(self) -> utils.Frozen[str, xarray.Variable]: | |
lon_grid = self.project((0, 0, v0.shape[1], 1)) | ||
lat_grid = self.project((0, 0, 1, v0.shape[2])) | ||
lon = self.image_to_array( | ||
lnglat_img, grid=lon_grid, dtype=np.float32, bandIds=['longitude'] | ||
lnglat_img, | ||
grid=lon_grid, | ||
dtype=np.float32, | ||
bandIds=['longitude', 'latitude'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason you're including Same with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, If my understanding of Looking at this again, I think that using multidimensional coordinates may be a better solution because the difference between the two methods occurs because the x coordinates vary along the y axis and the y coordinates vary along the x axis... Open to input on that though. Here is a notebook that shows the difference There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I went back and looked at this again and I believe the way I'm doing it is correct. When I open a dataset -> grab the first image -> write to a geotiff using rioxarray -> upload back to earthengine -> compare against the original first image in the collection I get an exact match. See this notebook Additionally, extracting the top edge and left edge without grabbing both the longitude and latitude and transforming those together will fail if the region is not perfectly square because |
||
) | ||
lon = self.coordinate_transformer.transform(lon[0], lon[1])[0] | ||
lat = self.image_to_array( | ||
lnglat_img, grid=lat_grid, dtype=np.float32, bandIds=['latitude'] | ||
lnglat_img, | ||
grid=lat_grid, | ||
dtype=np.float32, | ||
bandIds=['longitude', 'latitude'], | ||
) | ||
lat = self.coordinate_transformer.transform(lat[0], lat[1])[1] | ||
width_coord = np.squeeze(lon) | ||
height_coord = np.squeeze(lat) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,10 @@ | |
import numpy as np | ||
import xarray as xr | ||
from xarray.core import indexing | ||
import os | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A couple import suggestions:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do for However, from the rioxarray docs:
so without that import,
I can add rioxarray as a test dependency along with rasterio though. |
||
import rioxarray | ||
import rasterio | ||
import tempfile | ||
import xee | ||
|
||
import ee | ||
|
@@ -397,6 +401,77 @@ def test_validate_band_attrs(self): | |
for _, value in variable.attrs.items(): | ||
self.assertIsInstance(value, valid_types) | ||
|
||
def test_write_projected_dataset_to_raster(self): | ||
# ensure that a projected dataset written to a raster intersects with the | ||
# point used to create the initial image collection | ||
with tempfile.TemporaryDirectory() as temp_dir: | ||
temp_file = os.path.join(temp_dir, 'test.tif') | ||
|
||
crs = 'epsg:32610' | ||
proj = ee.Projection(crs) | ||
point = ee.Geometry.Point([-122.44, 37.78]) | ||
geom = point.buffer(1024).bounds() | ||
|
||
col = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') | ||
col = col.filterBounds(point) | ||
col = col.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5)) | ||
col = col.limit(10) | ||
|
||
ds = xr.open_dataset( | ||
col, | ||
engine=xee.EarthEngineBackendEntrypoint, | ||
scale=10, | ||
crs=crs, | ||
geometry=geom, | ||
) | ||
|
||
ds = ds.isel(time=0).transpose('Y', 'X') | ||
ds.rio.set_spatial_dims(x_dim='X', y_dim='Y', inplace=True) | ||
ds.rio.write_crs(crs, inplace=True) | ||
ds.rio.reproject(crs, inplace=True) | ||
ds.rio.to_raster(temp_file) | ||
|
||
with rasterio.open(temp_file) as raster: | ||
# see https://gis.stackexchange.com/a/407755 for evenOdd explanation | ||
bbox = ee.Geometry.Rectangle(raster.bounds, proj=proj, evenOdd=False) | ||
intersects = bbox.intersects(point, 1, proj=proj) | ||
self.assertTrue(intersects.getInfo()) | ||
|
||
def test_write_dataset_to_raster(self): | ||
# ensure that a dataset written to a raster intersects with the point used | ||
# to create the initial image collection | ||
with tempfile.TemporaryDirectory() as temp_dir: | ||
temp_file = os.path.join(temp_dir, 'test.tif') | ||
|
||
crs = 'EPSG:4326' | ||
proj = ee.Projection(crs) | ||
point = ee.Geometry.Point([-122.44, 37.78]) | ||
geom = point.buffer(1024).bounds() | ||
|
||
col = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') | ||
col = col.filterBounds(point) | ||
col = col.filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5)) | ||
col = col.limit(10) | ||
|
||
ds = xr.open_dataset( | ||
col, | ||
engine=xee.EarthEngineBackendEntrypoint, | ||
scale=0.0025, | ||
geometry=geom, | ||
) | ||
|
||
ds = ds.isel(time=0).transpose('lat', 'lon') | ||
ds.rio.set_spatial_dims(x_dim='lon', y_dim='lat', inplace=True) | ||
ds.rio.write_crs(crs, inplace=True) | ||
ds.rio.reproject(crs, inplace=True) | ||
ds.rio.to_raster(temp_file) | ||
|
||
with rasterio.open(temp_file) as raster: | ||
# see https://gis.stackexchange.com/a/407755 for evenOdd explanation | ||
bbox = ee.Geometry.Rectangle(raster.bounds, proj=proj, evenOdd=False) | ||
intersects = bbox.intersects(point, 1, proj=proj) | ||
self.assertTrue(intersects.getInfo()) | ||
|
||
|
||
if __name__ == '__main__': | ||
absltest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @boothmanrylan we figured out that the issue is with
pixelLonLat()
actually as it gives the coordinates always into thedegree
so instead of that if you can use thislnglat_img = ee.Image.pixelCoordinates(ee.Projection(self.crs_arg))
then it gives the coordinates intogiven crs
format.Also change the bandIds from
longitude
tox
into at line 558.-> Same with
latitude
toy
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.