0

I would like to generate a chart time series of a region based on the user's drawing and the y-axis of a chart based on the user's selection. For example, when I clicked and drawed a polygon (step 1 on the image attached), then select the vege index such as EVI (step 2), then the app will generate an EVI chart and on the map, it only shows the drawing polygon with the boundary, not the filled one. If I change the vege index into NDVI, then the app will generate a NDVI chart. However, my script automatically drawed a chart after step 1 without using step 2 or when I changed the select from NDVI to EVI, the chart did not update. How to fix this? Below are my script

var drawingTools = Map.drawingTools();
drawingTools.setShown(false);
while (drawingTools.layers().length() > 0) {
  var layer = drawingTools.layers().get(0);
  drawingTools.layers().remove(layer);
}
var dummyGeometry =
    ui.Map.GeometryLayer({geometries: null, name: 'geometry', color: 'red'});

drawingTools.layers().add(dummyGeometry);

function clearMap() {
  var mapLayers = Map.layers();
  if (mapLayers.length() > 0) {
    mapLayers.reset();
  }
}   
function clearGeometry() {
  var layers = drawingTools.layers();
  layers.get(0).geometries().remove(layers.get(0).geometries().get(0));
}
function drawRectangle() {
  clearMap();
  clearGeometry();
  drawingTools.setShape('rectangle');
  drawingTools.draw();
}

var symbol = {
  rectangle: '⬛',
};
var controlPanel = ui.Panel({
  widgets: [
    ui.Label('1. Select a drawing mode.'),
    ui.Button({
      label: symbol.rectangle + ' Rectangle',
      onClick: drawRectangle,
      style: {stretch: 'horizontal'}
    }),
  ],
  style: {position: 'top-left'},
  layout: null,
});
Map.add(controlPanel); 
var chartPanel = ui.Panel({
  style:
      {height: '235px', width: '600px', position: 'bottom-right', shown: false}
});
Map.add(chartPanel);
var index_chose;
function chartNdviTimeSeries() {
  // Make the chart panel visible the first time a geometry is drawn.
  if (!chartPanel.style().get('shown')) {
    chartPanel.style().set('shown', true);
  }
  var aoi = drawingTools.layers().get(0).getEeObject();
  var aoiFc = ee.FeatureCollection(aoi);
  var empty = ee.Image().byte();
  var outline = empty.paint({
    featureCollection: aoiFc,
    color: 1,
    width: 3
  });
  
  Map.addLayer(outline, {palette: 'red'}, 'AOI');
  clearGeometry();

  // Set the drawing mode back to null; turns drawing off.
  drawingTools.setShape(null);
  
  // Chart NDVI time series for the selected area of interest.
  var chart = ui.Chart.image
                  .seriesByRegion({
                    imageCollection: ee.ImageCollection('MODIS/006/MOD13A2'),
                    regions: aoi,
                    reducer: ee.Reducer.mean(),
                    band:index_chose,
                    xProperty: 'system:time_start'
                  })
                  .setOptions({
                    titlePostion: 'none',
                    legend: {position: 'none'},
                    hAxis: {title: 'Date'},
                    vAxis: {title: select_index.getValue()},
                    series: {0: {color: '23cba7'}}
                  });

  // Replace the existing chart in the chart panel with the new chart.
  chartPanel.widgets().reset([chart]);
}

// Index set-up
var label_index= ui.Label('Select vege index');
var index=['NDVI','EVI'];
var select_index=ui.Select({
  items:index,
  onChange:function(){
    index_chose=select_index.getValue();
    return index_chose
  }
});

Map.add(ui.Panel([label_index,select_index],ui.Panel.Layout.flow('horizontal')));
drawingTools.onDraw(ui.util.debounce(chartNdviTimeSeries, 500));
drawingTools.onEdit(ui.util.debounce(chartNdviTimeSeries, 500));

The link for my code is https://code.earthengine.google.com/fcc81cfebae226157ba7dc4e67db4851

1 Answer 1

1

The main problem is clearGeometry(). So, an easy way is just deleted it. In that case each time that you run (change de vegetation index), you will create another AOI, if you want to keep it (because you will have the geometry drawn as area of analisis in the map), I would recommend just change this:

Map.addLayer(outline, {palette: 'red'}, 'AOI');

to this:

var area=ui.Map.Layer(outline, {palette: 'red'}, 'AOI').setShown(0)
Map.layers().set(0, area) 

In other hand, I also would recommend update the ee.Imagecolection and the band selection (because, currently you'r code show the same values for NDVI and EVI). So, this is the suggested function to chartNdviTimeSeries:

function chartNdviTimeSeries() {
  // Make the chart panel visible the first time a geometry is drawn.
  if (!chartPanel.style().get('shown')) {
    chartPanel.style().set('shown', true);
  }
  var aoi = drawingTools.layers().get(0).getEeObject();
  var aoiFc = ee.FeatureCollection(aoi);
  var empty = ee.Image().byte();
  var outline = empty.paint({
    featureCollection: aoiFc,
    color: 1,
    width: 3
  });
  
  
//Map.addLayer(outline, {palette: 'red'}, 'AOI').setShown(1);
var area=ui.Map.Layer(outline, {palette: 'red'}, 'AOI').setShown(1)
Map.layers().set(0, area)  


  // Set the drawing mode back to null; turns drawing off.
  drawingTools.setShape(null);

  
  // Chart NDVI time series for the selected area of interest.
  var chart = ui.Chart.image
                  .seriesByRegion({
                    imageCollection: ee.ImageCollection('MODIS/061/MOD13A2'),
                    regions: aoi,
                    reducer: ee.Reducer.mean(),
                    band:select_index.getValue(),
                    xProperty: 'system:time_start'
                  })
                  .setOptions({
                    titlePostion: 'none',
                    legend: {position: 'none'},
                    hAxis: {title: 'Date'},
                    vAxis: {title: select_index.getValue()},
                    series: {0: {color: '23cba7'}}
                  });

  // Replace the existing chart in the chart panel with the new chart.
  chartPanel.widgets().reset([chart]);

// move this lines of code here to skip the initial chart
drawingTools.onDraw(ui.util.debounce(chartNdviTimeSeries, 500));
drawingTools.onEdit(ui.util.debounce(chartNdviTimeSeries, 500));

//add this code to hide the geometry
dummyGeometry.setShown(false)
}

here the link

5
  • Thank you J. David Urquiza-Muñoz. However, I would like to show the AOI on the main map and not the geometry. How can I do this without using clearGeometry(). The reason why I would like to show on the map the AOI instead of the geometry as I only want to show the polygon with the boundary not the filled one.
    – user30985
    Commented Jan 10, 2023 at 1:59
  • See my updated answer, including all your firts questions and the updated link. Commented Jan 10, 2023 at 13:51
  • Thank you for your help J. David Urquiza-Muñoz. It works well. Could you please explain why you use Map.layers().set(0, area)? I searched on google to figure out what is the role of Map.layers().set() but I did not found it yet.
    – user30985
    Commented Jan 10, 2023 at 21:57
  • yeah, but will be better if you can do a new quetion related to this. Commented Jan 11, 2023 at 13:32
  • Thank you. I put a new question on this gis.stackexchange.com/questions/449385/…
    – user30985
    Commented Jan 11, 2023 at 21:52

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.