0

I am using the code below to run random forest classification, clip and mask the layer, and then export the map to Google Drive. I expected the export process to be slow. Nevertheless, why are the maps I am viewing (Map.addLayer) on GEE load very slowly although they are single band masks. I also commented the confusion matrix part because I thought it's heavy but still, the map viewing is really slow even though all calculations are complete.

P.S. roi is a simple polygon over my area of interest.
P.S. The original code is from here (https://developers.google.com/earth-engine/classification) but using MODIS for training instead of NLCD.

// Define a region of interest as a point.  Change the coordinates  
// to get a classification of any place where there is imagery.  
//var roi = ee.Geometry.Point(-122.3942, 37.7295);  

// Load Landsat 5 input imagery.  
var landsat = ee.Image(ee.ImageCollection('LANDSAT/LT05/C01/T1_TOA')  
  // Filter to get only one year of images.  
  .filterDate('2004-01-01', '2004-12-31')  
  // Filter to get only images under the region of interest.  
  .filterBounds(roi)  
  // Sort by scene cloudiness, ascending.  
  .sort('CLOUD_COVER')  
  // Get the first (least cloudy) scene.  
  .first());  

// Compute cloud score.  
var cloudScore =  
 ee.Algorithms.Landsat.simpleCloudScore(landsat).select('cloud');  

// Mask the input for clouds.  Compute the min of the input mask to mask  
// pixels where any band is masked.  Combine that with the cloud mask.  
var input =   
 landsat.updateMask(landsat.mask().reduce('min').and(cloudScore.lte(50)));  

// Use MODIS land cover, IGBP classification, for training.  
var modis = ee.Image('USGS/NLCD/NLCD2001')  
    .select('landcover');  

// Sample the input imagery to get a FeatureCollection of training data.  
var training = input.addBands(modis).sample({  
  numPixels: 10000,  
  seed: 0  
});  

// Make a Random Forest classifier and train it.  
var classifier = ee.Classifier.randomForest(20)  
    .train(training, 'landcover');  

// Classify the input imagery.  
var classified = input.classify(classifier);  

// Get a confusion matrix representing resubstitution accuracy.  
//var trainAccuracy = classifier.confusionMatrix();  
//print('Resubstitution error matrix: ', trainAccuracy);  
//print('Training overall accuracy: ', trainAccuracy.accuracy());  

// Sample the input with a different random seed to get validation data.  
//var validation = input.addBands(modis).sample({  
//  numPixels: 10000,  
//  seed: 1  
  // Filter the result to get rid of any null pixels.  
//}).filter(ee.Filter.neq('B1', null));  

// Classify the validation data.  
//var validated = validation.classify(classifier);  

// Get a confusion matrix representing expected accuracy.  
//var testAccuracy = validated.errorMatrix('landcover', 'classification');  
//print('Validation error matrix: ', testAccuracy);  
//print('Validation overall accuracy: ', testAccuracy.accuracy());  

//// Define a palette for the IGBP classification.  
var landcoverVis = {  
  min: 0.0,  
  max: 95.0,  
  palette: [  
    '466b9f', 'd1def8', 'dec5c5', 'd99282', 'eb0000', 'ab0000', 'b3ac9f',
    '68ab5f', '1c5f2c', 'b5c58f', 'af963c', 'ccb879', 'dfdfc2', 'd1d182',
    'a3cc51', '82ba9e', 'dcd939', 'ab6c28', 'b8d9eb', '6c9fb8'
  ],  
};  

// Display the input and the classification.  
Map.centerObject(roi, 10);  
//Map.addLayer(input, {bands: ['B3', 'B2', 'B1'], max: 0.4}, 'landsat');  
var clippedland = classified.clip(roi);  
//Map.addLayer(clippedland,landcoverVis, 'classification');  
 var dataset = ee.Image('USGS/NLCD/NLCD2011');  
 var landcover = dataset.select('landcover');  
 var landcoverVis = {  
   min: 0.0,  
   max: 95.0,  
   palette: [  
     '466b9f', 'd1def8', 'dec5c5', 'd99282', 'eb0000', 'ab0000', 'b3ac9f',
     '68ab5f', '1c5f2c', 'b5c58f', 'af963c', 'ccb879', 'dfdfc2', 'd1d182',
     'a3cc51', '82ba9e', 'dcd939', 'ab6c28', 'b8d9eb', '6c9fb8'  
   ],  
 };
// clip and mask urban area (category 22, 23, 24 from NLCD)  
var clippednlcd = landcover.clip(roi);  
 var urbn = clippedland.eq(23).add(clippedland.eq(22)).add(clippedland.eq(24));  
 var urbn = urbn.neq(0);  
 var urbn = urbn.updateMask(urbn).neq(0);  
 var palette2 = ['0000FF'];  
 Map.addLayer(urbn,{palette: palette2},  
             'urban area');  

// Export to Google Drive  
Export.image.toDrive({  
  image: urbn,  
  description: 'urbn',  
  scale: 30,  
  region: roi,  
  fileFormat: 'GeoTIFF',  
  formatOptions: {  
    cloudOptimized: true  
  }  
});    
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  • The variable urbn6 is used but not defined in your script. – Tyler Erickson Aug 23 '19 at 12:19
  • Fixed, thanks for pointing that out. – Mohamed Aug 23 '19 at 16:17
0

Your script is training a 20-tree random forest classification model based on 10,000 sample points, which can be slow to complete. This model needs to be trained before either the map is displayed or the image is exported.

If you want responsive viewing of the model results (or any other expensive computation), you can export the classified image to a new asset (using Export.image.toAsset()) and then display your new asset on the map.

  • Thanks Tyler. This makes a lot of sense, I kind of tried to do so by exporting the image and then doing the analysis elsewhere. I guess what I want to understand now is, is there some sort of memory assigned to the user that if exceeded will slow things down as if you are running things on your own PC? Is it possible to clear the variables and the model after it's done to help free this "memory"? – Mohamed Aug 23 '19 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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