Repository: opendatacube/datacube-core

Issue:
Need the spatial coords to carry correct `spatial_ref` and `crs`
### Expected behaviour
The spatial coordinates `x` and `y` should have correct `spatial_ref` and `crs` after reproject

### Actual behaviour
Only the values are changed but with the old `spatial_ref` and no `crs`. Hence the `results.geobox` crs is wrong.
https://github.com/opendatacube/datacube-core/blob/6ee0462c5de320d820aa4fdd27a4807fe2ab76c2/datacube/virtual/impl.py#L909-L910

### Steps to reproduce the behaviour
N/A

### Environment information

* Which ``datacube --version`` are you using?
  Open Data Cube core, version 1.8.4.dev52+g07bc51a5
* What datacube deployment/enviornment are you running against?
  Sandbox



Discussion:

Resolving patch:
diff --git a/datacube/virtual/impl.py b/datacube/virtual/impl.py
--- a/datacube/virtual/impl.py
+++ b/datacube/virtual/impl.py
@@ -802,6 +802,9 @@ def group(self, datasets: VirtualDatasetBag, **group_settings: Dict[str, Any]) -
 
     def fetch(self, grouped: VirtualDatasetBox, **load_settings: Dict[str, Any]) -> xarray.Dataset:
         """ Convert grouped datasets to `xarray.Dataset`. """
+        from collections import OrderedDict
+        spatial_ref = 'spatial_ref'
+
         geobox = grouped.geobox
 
         measurements = self.output_measurements(grouped.product_definitions)
@@ -824,8 +827,8 @@ def fetch(self, grouped: VirtualDatasetBox, **load_settings: Dict[str, Any]) ->
         result = xarray.Dataset()
         result.coords['time'] = grouped.box.coords['time']
 
-        for name, coord in grouped.geobox.coordinates.items():
-            result.coords[name] = (name, coord.values, {'units': coord.units, 'resolution': coord.resolution})
+        coords = OrderedDict(**geobox.xr_coords(with_crs=spatial_ref))
+        result.coords.update(coords)
 
         for measurement in measurements:
             result[measurement] = xarray.concat([reproject_band(raster[measurement],


Test patch:
diff --git a/tests/api/test_virtual.py b/tests/api/test_virtual.py
--- a/tests/api/test_virtual.py
+++ b/tests/api/test_virtual.py
@@ -178,6 +178,18 @@ def catalog():
                                 measurements: [blue]
                               - product: ls8_nbar_albers
                                 measurements: [blue]
+
+            reproject_utm:
+                recipe:
+                    reproject:
+                        output_crs: EPSG:32755
+                        resolution: [30, -30]
+                    input:
+                        collate:
+                          - product: ls7_nbar_albers
+                            measurements: [blue]
+                          - product: ls8_nbar_albers
+                            measurements: [blue]
     """)
 
 
@@ -509,3 +521,17 @@ def measurements(self, input_measurements):
         data = bluegreen.load(dc, **query)
 
     assert 'bluegreen' in data
+
+
+def test_reproject(dc, query, catalog):
+    reproject_utm = catalog['reproject_utm']
+
+    with mock.patch('datacube.virtual.impl.Datacube') as mock_datacube:
+        mock_datacube.load_data = load_data
+        mock_datacube.group_datasets = group_datasets
+        data = reproject_utm.load(dc, **query)
+
+    assert data.crs == geometry.CRS('EPSG:32755')
+    assert data.geobox.crs == geometry.CRS('EPSG:32755')
+    assert data.coords['x'].attrs['resolution'] == -30
+    assert data.coords['y'].attrs['resolution'] == 30