1

Not the best example, but say I have an image of Sea Surface Temperature and a point like so:

 // Load an image of sea surface temperature (SST).
var sst = ee.Image('NOAA/AVHRR_Pathfinder_V52_L3/20120802025048')
  .select('sea_surface_temperature')
  .rename('sst')
  .divide(100);

var geometry = ee.Geometry.Point([-81.2338, 42.4274])

Assuming variable "geometry" to be the center point, I would like to get the pixel coordinates 1 pixel west, northwest, north, northeast, etc. From there, I would try to get the pixel values, but I think I can figure out the rest. Essentially, I am trying to create a 3 pixel by 3 pixel window of sorts using a single center point as the input to construct said window.

2 Answers 2

2

This code, adapted from Extracting coordinates of pixels inside polygon in Google Earth Engine as single feature, might be what you are looking for.

//get projection and scale
var proj = sst.projection();
var scale = proj.nominalScale()

// get coordinates image
var latlon = ee.Image.pixelLonLat().reproject(proj);

//Create a geometry object at the true center of the pixel
var coords = latlon.select(['longitude', 'latitude'])
                 .reduceRegion({
  reducer: ee.Reducer.toList(),
  geometry: geometry,
  scale: 30
});
var lat = ee.List(coords.get('latitude'));
var lon = ee.List(coords.get('longitude'));
var point_list = lon.zip(lat);
var center = ee.Geometry.MultiPoint(point_list);

// Create your window by buffering by the scale
var mywindow = center.buffer(scale);

Repeat the above process but using the window geometry this time

var coords = latlon.select(['longitude', 'latitude'])
                 .reduceRegion({
  reducer: ee.Reducer.toList(),
  geometry: mywindow,
  scale: 30
});
var lat = ee.List(coords.get('latitude'));
var lon = ee.List(coords.get('longitude'));
var point_list = lon.zip(lat);
var centerpoints = ee.Geometry.MultiPoint(point_list);

Now extract values from the original raster?

var values = sst.reduceRegion({
reducer: ee.Reducer.toList(),
geometry: centerpoints,
scale: 30
});

I am not sure why the scale needs to be specified at 30, but it seems to work.

7
  • Thanks so much! Do you know what the ee.Reducer.toList() is doing in the reduceRegion()? I don't understand what it does in this case given there are no inputs that go into ee.Reducer.toList(). Commented Oct 7, 2019 at 18:48
  • It's creating a reducer object to be passed to the .ReduceRegion() method ... basically telling it HOW to do the reduction.
    – Nick
    Commented Oct 7, 2019 at 18:52
  • see developers.google.com/earth-engine/reducers_intro
    – Nick
    Commented Oct 7, 2019 at 19:01
  • So essentially, ee.Reducer.toList() is simply aggregating all the data without doing any sort of arithmetic computations? I just tried out the code in Earth Engine and this is very close to what I need. Rather than creating a buffer, my windows needs to be more of a square. From the center pixel that "var coords" computes, I need to figure out how to get the pixel coordinates from one pixel above that center pixel, one pixel northwest, one pixel west etc. until I get a 3 pixel by 3 pixel window. Thanks again for the input. Definitely helpful. Commented Oct 7, 2019 at 19:23
  • Oh wait a sec. So "var coords" computes the center of the pixel, but I need the entire pixel. I'm guessing this would be a polygon with 4 vertices. I can probably still use the center geometry object that "coords"creates to figure out how to create a polygon representing the entire pixel somehow. Is buffering by the scale creating the full pixel? The buffer would be double the area of a regular pixel, wouldn't it? And the buffer creates a circular polygon, which wouldn't match the shape of a square. Sorry for all the comments. I am thinking aloud at the same time I am writing stuff. Commented Oct 7, 2019 at 19:32
0

EDIT: in JS you can make a buffer around the point, and build a rectangle polygon based on buffer:

var point = ee.Geometry.Point(-122.082, 37.42);

Apply the buffer method to the Point object.

var pointBuffer = point.buffer({'distance': 100});// unit is meters

make a polygon based on bounds:

var polygonBounds = pointBuffer.bounds();//this gives you the polygon you needed

If you code in python, a manual way is to:

Cut an aoi around each lat/long point. Change 0.0001 to size that works for your AOI(consider the pixel size of the image.):

size = 0.0001 // this is equivalent of almost 10 m, ending in AOI of 30 m.

making 4 corner points of AOI:

cords = [[long-1.5*size, lat+size], [long-1.5*size, lat-size], 
      [long+1.5*size, lat-size], [long+1.5*size, lat+size]]

making AOI:

aoi = ee.Geometry.Polygon(cords, None, False) #order is longitude then latitude.

get the image collection and export it by geemap:

images = ee.ImageCollection("COPERNICUS/S2_SR") \
.filterBounds(aoi) \
.filterDate('2021-11-05', '2021-11-10') \
.filter('CLOUDY_PIXEL_PERCENTAGE < 25')

geemap.ee_export_image_collection(images, scale=10, 
                                out_dir= '/content', region=aoi, file_per_band=True)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.