I defined a polygon
var polygon = ee.Geometry.Polygon([114, 0.37, 114, 2.04, 112, 2.04, 112, 0.37]);
and a dataset that needs to be processed for the above polygon
var dataset = ee.ImageCollection('NASA/NEX-GDDP');
for a selected date
var startDate = ee.Date('1980-01-01');
var endDate = ee.Date('1980-01-02');
The dataset has 3 bands pr
, tasmax
and tasmin
and I am selecting the one that I need to process
var dataset = ee.ImageCollection('NASA/NEX-GDDP')
.filter(ee.Filter.date(startDate,endDate))
.filter(ee.Filter.bounds(polygon))
.select('tasmax');
Map.addLayer(dataset)
I want to export the data for all the grids falling under the polygon along with their respective lat long. Since there are 21 features (GCMs) for a single day, I am expecting the final data to have number rows equal to number of grids in polygon X 21 features (GCMs)
var dailyImg = dataset.toBands();
Export.table.toDrive({
collection: dailyImg,
description: 'hist_tx',
fileFormat: 'CSV',
});
When I try to do this, I get an error
Error: Invalid argument: 'collection' must be a FeatureCollection.
How can I solve this? In addition, even after restricting my spatial area to the polygon, the map still displays the data for the entire globe? Why is this happening?
Error: Invalid argument: 'collection' must be a FeatureCollection.
Export.table
is for exporting tables, also known as FeatureCollection
s. You have an image, not a table.
The most efficient way to get the data out of Earth Engine is to use Export.image
instead, then convert the downloaded GeoTIFF to suit your R program. However, since this dataset is very small, downloading it as a CSV will work fine, and the tool for that is ee.Image.sample
which converts a region of an Image
to a FeatureCollection
.
var collection = dailyImg.sample({
region: polygon,
geometries: true, // This specifies that you want the lat-long, rather
// than image samples without any position information.
});
If you export this, you will get the position in a single column in GeoJSON format. That's probably not what you want, so we can convert it to columns:
var collection_with_latlon = collection.map(function (feature) {
var coordinates = feature.geometry().transform('epsg:4326').coordinates();
return feature.set('lon', coordinates.get(0), 'lat', coordinates.get(1));
});
Here's everything put together as a working example:
var polygon = ee.Geometry.Polygon([114, 0.37, 114, 2.04, 112, 2.04, 112, 0.37]);
var startDate = ee.Date('1980-01-01');
var endDate = ee.Date('1980-01-02');
var dataset = ee.ImageCollection('NASA/NEX-GDDP')
.filter(ee.Filter.date(startDate,endDate))
.filter(ee.Filter.bounds(polygon))
.select('tasmax');
Map.addLayer(polygon);
var dailyImg = dataset.toBands();
var collection = dailyImg.sample({
region: polygon,
geometries: true, // This specifies that you want the lat-long.
});
// Break point coordinates up into properties (table columns) explicitly.
var collection_with_latlon = collection.map(function (feature) {
var coordinates = feature.geometry().transform('epsg:4326').coordinates();
return feature.set('lon', coordinates.get(0), 'lat', coordinates.get(1));
});
print(collection_with_latlon);
Export.table.toDrive({
collection: collection_with_latlon,
description: 'hist_tx',
fileFormat: 'CSV',
});
In addition, even after restricting my spatial area to the polygon, the map still displays the data for the entire globe? Why is this happening?
Filtering a collection to geometry only omits images that do not intersect the geometry. In this case, the images cover the entire globe, so no images are filtered out. In order to clip the images to the collection you would have to specify that, e.g.:
var dailyImg = dataset.toBands().clip(polygon);
However, this is not necessary if you are using .sample()
, because that operation has its own region parameter and will not use any pixels outside the polygon.