2

I'm trying to connect a polygon drawing tool that I have code for to an app that allows the user to generate a download link for the raster layer displayed. The idea is that the user draws a polygon and any raster points that fall within their polygon are included in the downloaded image. Currently the download button (in second link) just downloads the entire viewport.

Here is the drawing tool code from the GEE website (I don't understand it fully tbh): https://code.earthengine.google.com/e0b5eff2f2b44349187d215d42ce7eff

Here is my current simple app:

var m = {};

m.col = ee.ImageCollection(
  'users/harleyzhang/CurrentSagebrushBmass')
  
m.imgInfo = {
  bands: {
    'Current Sagebrush Biomass': {
      bname: 'b1',
      //color: 'd4e7b0',
      vis: {
        min: 284.9775085449219,
        max: 998.4847412109375,
        palette: ['feedde', 'fdbe85', 'fd8d3c', 'e6550d', 'a63603']
      }
    }
  }
}

var c = {};

c.controlPanel = ui.Panel();
c.map = ui.Map();

c.info = {};
c.info.titleLabel = ui.Label('Current Sagebrush Biomass Test App');
c.info.aboutLabel = ui.Label('Test app for Stepwat2 interpolated data for current sagebrush biomass.');

c.info.panel = ui.Panel([
  c.info.titleLabel, c.info.aboutLabel
  ]);

c.selectLayer = {};
c.selectLayer.label = ui.Label('Select a layer to display');
c.selectLayer.selector = ui.Select(Object.keys(m.imgInfo.bands), null, 'Current Sagebrush Biomass'); // GET RASTERS
c.selectLayer.panel = ui.Panel([c.selectLayer.label, c.selectLayer.selector]);

c.dividers = {}
c.dividers.divider1 = ui.Panel()

ui.root.clear();
ui.root.add(c.controlPanel);
ui.root.add(c.map);

c.controlPanel.add(c.info.panel);
c.controlPanel.add(c.dividers.divider1)
c.controlPanel.add(c.selectLayer.panel);

var s = {};

c.controlPanel.style().set({
  width: '350px'
});

s.aboutText = {
  fontSize: '13px',
  color: '505050'
};
s.widgetTitle = {
  fontSize: '15px',
  fontWeight: 'bold',
  margin: '8px 8px 0px 8px',
  color: '383838'
};
s.stretchHorizontal = {
  stretch: 'horizontal'
};

s.divider = {
  backgroundColor: 'F0F0F0',
  height: '4px',
  margin: '20px 0px'
};

c.info.titleLabel.style().set({
  fontSize: '20px',
  fontWeight: 'bold'
});

c.info.aboutLabel.style().set(s.aboutText);

c.selectLayer.selector.style().set(s.stretchHorizontal);
c.selectLayer.label.style().set(s.widgetTitle);
c.dividers.divider1.style().set(s.divider);

var imgCol;
function updateMap() {
  var band = c.selectLayer.selector.getValue();
  
  imgCol = m.col.select(m.imgInfo.bands[band].bname);

  var layer = ui.Map.Layer({
    eeObject: imgCol,
    visParams: m.imgInfo.bands[band].vis, 
    name: band
  });
  c.map.layers().set(0, layer);
}

c.selectLayer.selector.onChange(updateMap)

updateMap()

// function to generate a download URL of the image for the viewport region. 
function downloadImg() {
  var viewBounds = ee.Geometry.Rectangle(Map.getBounds()); // entire viewport is selected
  var downloadArgs = {
    name: 'sample_image',
    crs: 'EPSG:4326',
    region: viewBounds.toGeoJSONString()
 };
 var size = imgCol.size();
 var img = imgCol.first(); 

 var url =img.getDownloadURL(downloadArgs);
 urlLabel.setUrl(url);
 urlLabel.style().set({shown: true});
}

var downloadButton = ui.Button('Get download link', downloadImg);
var urlLabel = ui.Label('Download', {shown: false});
var buttons = ui.Panel([downloadButton, urlLabel]);
c.controlPanel.add(buttons);

My question is, how can I pass the geometry of a drawn polygon to first to the raster dataset (to select only the points inside their shape) and then pass the raster points to the getDownloadURL()?

1 Answer 1

1

In the most basic way, you want to initialize drawing tools for your map. Then you can access geometries drawn with those drawing tools using layers().

From there you can convert them to geometries and pass them to the region parameter.

// This sets the available draw modes. point and line would also be available
c.map.drawingTools().setDrawModes(["polygon", "rectangle"])
// This sets the shape selected by default
c.map.drawingTools().setShape("rectangle")


// function to generate a download URL of the image for the viewport region. 
function downloadImg() {
  var viewBounds = ee.Geometry.Rectangle(Map.getBounds()); // entire viewport is selected
  var downloadArgs = {
    name: 'sample_image',
    crs: 'EPSG:4326',
    // This gets the first layer of the drawn geometries and unions all of them into one
    region: c.map.drawingTools().layers().get(0).toGeometry()
 };
 var size = imgCol.size();
 var img = imgCol.first(); 

 var url =img.getDownloadURL(downloadArgs);
 urlLabel.setUrl(url);
 urlLabel.style().set({shown: true});
}
2
  • Thanks a lot. I finally got around to trying it out and it works. I did have to comment out the crs: 'EPSG:4326' because I guess my data was not in that format but everything else was perfect. Commented Dec 29, 2021 at 19:19
  • I actually noticed something while I was testing it out and noticed that when I download using the polygon drawingtool, it downloads a rectangle tif of the farthest point in each direction of the drawn polygon. Would it be possible for the tif to be rectangular but not download any raster points from outside of the polygon? Commented Jan 1, 2022 at 21:12

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.