Exporting requires all bands to be of the same type, if you use the function bandTypes()
, you will notice indeed differences:
- B2: signed int16
- B3: signed int16
- ...
- NDVI: float ∈ [-1, 1]
So to have all bands in the same type, you would usally cast the image into the least restrictive type, which is in this case float (indeed, casting integer to float does not loose data, while float to integer would). use the function toFloat()
in this case.
Reproducible example
Your code was unfortunately not reproducible, see here a simple and dummy code, showing the issue with Landsat data:
var geometry = /* color: #0b4a8b */ee.Geometry.Polygon(
[[[-104.1558837890625, 42.950391774502876],
[-104.13665771484375, 42.83569550641452],
[-103.831787109375, 42.85784648372956],
[-103.84002685546875, 42.95441233121331]]]);
var imageCollection = ee.ImageCollection("LANDSAT/LE07/C01/T2_SR");
var image_one = ee.Image(imageCollection.first())
//Calculating VIs
var ndvi = image_one.normalizedDifference(['B3', 'B4']).rename('NDVI');
var image_one_withNDVI = image_one.addBands(ndvi)
print(image_one_withNDVI, "image_one_withNDVI")
First try: export without toFloat()
:
Export.image.toDrive({
image: image_one_withNDVI,
description: "test_task",
fileNamePrefix: "test",
region: geometry,
scale:30
})
This will return: Error: Exported bands must have compatible data types; found inconsistent types: Int16 and Byte.
Second try, use: ge_one_withNDVI.toFloat()
Export.image.toDrive({
image: image_one_withNDVI.toFloat(),
description: "test_task_OK",
fileNamePrefix: "test_OK",
region: geometry,
scale:30
})
The short answer is "it's the 100 sorts". You can work around it by doing a reduceColumns instead of a sort, with a max()
reducer using the numInputs
option to bring along the image ID that goes with the maximum random number. (Yes, it's a little screwy, but sorting ends up needing the whole collection in memory at once and reduceColumns does not.)
// For each point, get a random image
var getBandData = function(feat){
var point = ee.Geometry(feat.geometry())
// Get a random image for this point
var result = s2sr
.filterBounds(point)
.randomColumn('random', 123)
.reduceColumns(ee.Reducer.max(2), ['random', 'system:index'])
return s2sr.filter(ee.Filter.eq('system:index', result.get('max1')))
}
https://code.earthengine.google.com/bdd36facac25401263fc9812596bf473
Best Answer
This is not a pyramiding problem. Pyramiding only applies to stored images — taking a high-resolution base image and making lower-resolution images out of it. Here, the image is being generated from scratch at the resolution you're viewing it at. You need to approach this as asking the image operations to do what you want.
You can change your second
.paint()
to have a line-width, like this:This way, even if the feature area is less than 1 pixel, it will still try to draw a 1-pixel-wide line around the perimeter, which will result in there being at least one pixel with value 1 no matter how small it shrinks.
Another possibility would be to paint the point and the buffered point. Painting a point geometry always fills in exactly one pixel, so if you paint both, you're guaranteed there will be at least one pixel. This won't affect the exact boundary whereas the line-width option may (by 1 pixel).