Erste Schritte mit der Earth Engine

Dieser Leitfaden soll Ihnen den Einstieg in die Programmierung mit der Earth Engine JavaScript API erleichtern. Eine Einführung in JavaScript und ausführlichere Übungen mit der Earth Engine API finden Sie in den Tutorials. Informationen zum empfohlenen JavaScript-Programmierstil finden Sie im Google JavaScript Style Guide.

Mit Google Earth Engine können Nutzer Algorithmen auf georeferenzierten Bildern und Vektoren ausführen, die in der Google-Infrastruktur gespeichert sind. Die Google Earth Engine API bietet eine Bibliothek mit Funktionen, die auf Daten angewendet werden können, um sie darzustellen und zu analysieren. Der öffentliche Datenkatalog von Earth Engine enthält eine große Menge an öffentlich verfügbaren Bildern und Vektordatensätzen. Private Assets können auch in den persönlichen Ordnern der Nutzer erstellt werden.

Verwendung dieser Dokumente

Die Earth Engine-Dokumentation richtet sich an Nutzer, die mit der Analyse raumbezogener Daten vertraut sind. Die Dokumente sind hauptsächlich nach Datentyp strukturiert. Die linke Navigationsleiste enthält beispielsweise Links zu Abschnitten oder Seiten zu wichtigen Datentypen wie Image, ImageCollection, Feature, FeatureCollection, Geometry, Reducer, Chart, Join und Array. In diesem Leitfaden werden diese Typen nur kurz beschrieben, um Ihnen den Einstieg zu erleichtern. Es gibt auch Abschnitte zu maschinellem Lernen, speziellen oder sensorspezifischen Algorithmen (z.B. Landsat-Algorithmen), öffentlichen Apps, Daten-/Asset-Verwaltung und wichtigen Details zur internen Funktionsweise von Earth Engine. Bevor du loslegst, solltest du dir diese Informationen durchlesen.

Code-Editor

Der Code-Editor ist eine interaktive Umgebung zum Entwickeln von Earth Engine-Anwendungen (Abbildung 1). Im mittleren Bereich finden Sie einen JavaScript-Code-Editor. Über dem Editor befinden sich Schaltflächen, mit denen Sie das aktuelle Script speichern, ausführen und die Karte löschen können. Über die Schaltfläche Link abrufen wird in der Adressleiste eine eindeutige URL für das Script generiert. Die Karte im unteren Bereich enthält die vom Script hinzugefügten Ebenen. Oben befindet sich ein Suchfeld für Datensätze und Orte. Der linke Bereich enthält Codebeispiele, Ihre gespeicherten Scripts, eine suchbare API-Referenz und einen Asset-Manager für private Daten. Der rechte Bereich enthält einen Prüfer zum Abfragen der Karte, eine Ausgabekonsole und einen Manager für langlaufende Aufgaben. Die Schaltfläche „Hilfe“  oben rechts enthält Links zu diesem Leitfaden und anderen Hilferessourcen. Weitere Informationen finden Sie im Leitfaden zum Code-Editor und im Leitfaden zum Einholen von Hilfe.

Code-Editor
Abbildung 1. Der Earth Engine-Code-Editor unter code.earthengine.google.com

Code im Code-Editor öffnen und ausführen

In den folgenden Schritten wird gezeigt, wie Sie Earth Engine öffnen und ein benutzerdefiniertes Script ausführen, das ein Bild anzeigt. Die besten Ergebnisse erzielen Sie, wenn Sie die aktuelle Version von Chrome, dem Webbrowser von Google, installieren. Sie können sie hier herunterladen.

  1. Öffnen Sie den Earth Engine-Codeeditor unter code.earthengine.google.com.
  2. Klicken Sie ganz links im Code-Editor auf den Tab Scripts. Dort finden Sie eine Sammlung von Beispielscripts, mit denen auf Earth Engine-Daten zugegriffen, diese angezeigt und analysiert werden können.
  3. Wählen Sie unter „Bildersammlung“ das Beispiel „Gefiltertes Komposit“ aus. In der mittleren Konsole wird ein Script angezeigt. Drücken Sie die Schaltfläche Ausführen, um das Script auszuführen. Im Beispiel für ein gefiltertes Komposit werden Landsat 7-Bilder ausgewählt, die sich überschneiden oder innerhalb der Grenzen von Colorado und Utah liegen. Daraufhin wird eine Echtfarben-Kompositaufnahme der ausgewählten Bilder angezeigt. Die Beispiele stellen gängige Methoden wie filter(), clip() und Map.addLayer() vor.

Earth Engine-Datenstrukturen

Die beiden grundlegendsten geografischen Datenstrukturen in Earth Engine sind Image und Feature, die den Raster- und Vektordatentypen entsprechen. Bilder bestehen aus Bändern und einem Wörterbuch mit Eigenschaften. Funktionen bestehen aus einem Geometry und einem Wörterbuch mit Properties. Ein Stapel von Bildern (z.B. eine Bildzeitreihe) wird von einem ImageCollection verarbeitet. Eine Sammlung von Funktionen wird von einem FeatureCollection verwaltet. Weitere grundlegende Datenstrukturen in Earth Engine sind Dictionary, List, Array, Date, Number und String. Weitere Informationen zu den grundlegenden Datentypen finden Sie in diesem Tutorial. Wichtig: Dies sind alles serverseitige Objekte, die nicht auf die gleiche Weise wie clientseitige JavaScript-Objekte manipuliert werden (weitere Informationen).

Earth Engine-Algorithmen

Es gibt mehrere Möglichkeiten, Vorgänge in der API auszuführen:

  • Aufrufen von Methoden, die mit Objekten verknüpft sind.
  • Aufrufalgorithmen
  • Code-Editor-spezifische Funktionen aufrufen
  • Neue Funktionen definieren

Auf dem Tab Docs des Code-Editors sind die Methoden der einzelnen API-Klassen aufgeführt. Angenommen, die Klasse Image hat eine add()-Methode:

Code-Editor (JavaScript)

var image3 = image1.add(image2);

Bei dieser Methode werden die Bänder von image2 zu den Bändern von image1 hinzugefügt. Die Kategorie ee.Algorithms enthält eine Liste der derzeit unterstützten Algorithmen für die spezialisierte oder domänenspezifische Verarbeitung. So erstellen Sie beispielsweise topografische Ebenen aus einem digitalen Höhenmodell (Digital Elevation Model, DEM):

Code-Editor (JavaScript)

var terrainImage = ee.Algorithms.Terrain(dem);

Zu den Code-Editor-spezifischen Funktionen gehören die Methoden Map und Export, mit denen gesteuert wird, wie Ebenen dem Kartenbereich hinzugefügt oder in Google Drive exportiert werden. Funktionen können auch in JavaScript mit

Code-Editor (JavaScript)

var myFunction = function(args) {
  // do something
  return something;
};

Wie im Abschnitt zum Abgleich dargestellt, sind benutzerdefinierte Funktionen nützlich, um benutzerdefinierte Funktionen zu erstellen oder die Elemente einer Sammlung mithilfe der folgenden Funktionen zu ändern:

Code-Editor (JavaScript)

var collection2 = collection1.map(aFunction);

In den folgenden Abschnitten werden diese Konzepte anhand verschiedener einfacher Anwendungsfälle veranschaulicht.

„Hallo Welt!“ JavaScript

Das Drucken von Informationen in die Konsole ist eine grundlegende Aufgabe, um Informationen zu einem Objekt abzurufen, das numerische Ergebnis einer Berechnung anzuzeigen, Objektmetadaten anzuzeigen oder bei der Fehlerbehebung zu helfen. Das berühmte „Hello World!“-Beispiel im Code-Editor sieht so aus:

Code-Editor (JavaScript)

print('Hello world!');

Kopieren Sie diese Zeile in den Code-Editor und klicken Sie auf Ausführen. Die Ausgabe wird rechts neben dem Code-Editor auf dem Tab Console angezeigt. Hier ein Beispiel für die Remote-Szenenerfassung: Mit dem folgenden Befehl werden die Metadaten eines Landsat 8-Bildes ausgegeben:

Code-Editor (JavaScript)

print(ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'));

Sehen Sie sich die Ausgabe in der Konsole an, um die für Landsat-Bilder verfügbaren Metadaten zu sehen.

Daten zur Karte hinzufügen

Neben dem Ausdrucken von Informationen in der Konsole können Sie auch Daten zu Map hinzufügen, um geografische Daten zu visualisieren. Verwenden Sie dazu Map.addLayer(). Im folgenden Beispiel wird ein Image mit ee.Image() instanziiert (wie Sie diese Bilder finden, wird später erläutert). Es wird der Karte mit Map.addLayer() hinzugefügt und die Karte wird über dem Bild zentriert:

Code-Editor (JavaScript)

// Load an image.
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');

// Center the map on the image.
Map.centerObject(image, 9);

// Display the image.
Map.addLayer(image);

Der zweite Parameter von Map.centerObject() ist eine Zoomstufe. Je höher die Zahl, desto größer der Maßstab (näher herangezoomt). Die Parameter für die Map-Funktionen werden ausführlich in der API-Referenz beschrieben, die du auf dem Tab Docs aufrufen kannst. Wenn das Bild nicht zufriedenstellend dargestellt wird, konfigurieren Sie die Anzeigeparameter mit einem zusätzlichen Argument für Map.addLayer(). Beispiel:

Code-Editor (JavaScript)

// Load the image from the archive.
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');

// Define visualization parameters in an object literal.
var vizParams = {bands: ['B5', 'B4', 'B3'], min: 0.02, max: 0.4, gamma: 1.3};

// Center the map on the image and display.
Map.centerObject(image, 9);
Map.addLayer(image, vizParams, 'Landsat 8 false color');

Die Visualisierungsparameter werden durch ein Objektliteral definiert, das eine Liste der anzuzeigenden Bänder, einen Mindest- und Höchstreflexionswert sowie einen Gammawert enthält. Weitere Informationen zu Landsat-Bändern Weitere Informationen zur Bildvisualisierung

Verwenden Sie Map.addLayer(), um der Karte Elemente und Elementsammlungen hinzuzufügen. Beispiel:

Code-Editor (JavaScript)

var counties = ee.FeatureCollection('TIGER/2018/Counties');
Map.addLayer(counties, {}, 'counties');

Bilder, Bildsammlungen und Feature-Sammlungen finden

Bilder, Bildersammlungen und Elementsammlungen können im Earth Engine-Datenkatalog gefunden werden. Wenn Sie beispielsweise „Landsat 8“ in das Suchfeld eingeben, wird eine Liste mit Rasterdatensätzen angezeigt. Eine vollständige Liste der Earth Engine-Datasets finden Sie im Earth Engine-Datenkatalog. Klicken Sie auf den Namen des Datensatzes, um eine kurze Beschreibung, Informationen zur zeitlichen Verfügbarkeit, zum Datenanbieter und zur Sammlungs-ID aufzurufen. Klicken Sie auf die Schaltfläche Importieren, um oben im Script automatisch den Bereich Importe mit einer Variablen für diese Sammlung zu erstellen.

Alternativ können Sie die Sammlungs-ID kopieren und in Ihren Code einfügen. Wählen Sie beispielsweise das Tier-1-TOA-Ergebnis der Suche nach „Landsat 8“ aus und kopieren Sie die ID so:

Code-Editor (JavaScript)

var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');

Da es sich um eine Sammlung vieler Bilder handelt, die die Erdoberfläche abdecken, ist zum Finden eines einzelnen Bildes in der Sammlung ein Filter erforderlich, um die Suche einzugrenzen. Alternativ kann die Bildsammlung mithilfe von Komposition und Mosaiktechniken auf ein einzelnes Bild reduziert werden. Weitere Informationen zu Filtern und Compositing finden Sie in den nächsten Abschnitten unter Reduzieren.

Feature-Sammlungen sind auch über den Data Catalog verfügbar. Sie sind kleiner als Bildsammlungen, aber Sie finden dort unter anderem internationale Grenzen, Volkszählungsgrenzen, Einzugsgebiete und Grenzen von Schutzgebieten. Weitere Informationen zum Importieren eigener Vektordatensätze

Filtern und Sortieren

Oft ist es erforderlich, eine Sammlung nach Raum und/oder Zeit zu filtern, um die Anzahl der Ergebnisse einzugrenzen. Angenommen, Sie möchten die Landsat 8-Szenensammlung sortieren, um eine wolkenfreie Szene für San Francisco zu finden. Zuerst müssen Sie den gewünschten Bereich definieren. Dazu eignet sich oft ein Punkt. Aktivieren Sie den Tab Inspector (Inspekteur) auf der rechten Seite des Code-Editors und klicken Sie in der Nähe des Mittelpunkts des gewünschten Bereichs. Kopieren Sie die Koordinaten auf dem Tab Inspector und erstellen Sie dann eine Point mit folgendem Code:

Code-Editor (JavaScript)

var point = ee.Geometry.Point(-122.262, 37.8719);

Start- und Enddatum festlegen:

Code-Editor (JavaScript)

var start = ee.Date('2014-06-01');
var finish = ee.Date('2014-10-01');

Filtern Sie die Landsat 8-Sammlung anhand des Punkts und der Datumsangaben und sortieren Sie sie dann anhand einer Metadateneigenschaft, die bei der Prüfung der Landsat 8-Szenenmetadaten gefunden wurde:

Code-Editor (JavaScript)

var filteredCollection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
  .filterBounds(point)
  .filterDate(start, finish)
  .sort('CLOUD_COVER', true);

Diese Sammlung kann sicher gedruckt und geprüft werden. Wenn die Sammlung zu viele Bilder enthält, ist der Druck entweder sehr langsam, es tritt ein Zeitüberschreitungsfehler auf oder es wird ein Fehler zurückgegeben. Die Bilder in der Sammlung sind List, die im Attribut „features“ der ImageCollection gespeichert sind. Die ID eines beliebigen Bildes in der Sammlung kann wie oben in den Konstruktor von Image kopiert werden. Alternativ können Sie sich das erste Bild ansehen (geringste Wolkenbedeckung):

Code-Editor (JavaScript)

var first = filteredCollection.first();

Mit filter() und einem ee.Filter als Argument können Sie auf die gesamte Earth Engine-Filterfunktion zugreifen. Die oben verwendeten Methoden filterBounds() und filterDate() sind Verknüpfungen. Im folgenden Beispiel wird beispielsweise eine Filter erstellt, mit der eine FeatureCollection gefiltert und das Ergebnis angezeigt wird:

Code-Editor (JavaScript)

// Load a feature collection.
var featureCollection = ee.FeatureCollection('TIGER/2016/States');

// Filter the collection.
var filteredFC = featureCollection.filter(ee.Filter.eq('NAME', 'California'));

// Display the collection.
Map.setCenter(-119.604, 37.798, 6);
Map.addLayer(filteredFC, {}, 'California');

Bandmathematik

Mithilfe von Image-Methoden mathematische Vorgänge auf Bilder anwenden Dazu gehören Bandrekombinationen (Spektralindizes), Bilddifferenzen oder mathematische Vorgänge wie die Multiplikation mit einer Konstante. So berechnen Sie beispielsweise den Unterschied zwischen NDVI-Bildern (Normalized Difference Vegetation Index), die 20 Jahre auseinander liegen:

Code-Editor (JavaScript)

// This function gets NDVI from Landsat 5 imagery.
var getNDVI = function(image) {
  return image.normalizedDifference(['B4', 'B3']);
};

// Load two Landsat 5 images, 20 years apart.
var image1 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_19900604');
var image2 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_20100611');

// Compute NDVI from the scenes.
var ndvi1 = getNDVI(image1);
var ndvi2 = getNDVI(image2);

// Compute the difference in NDVI.
var ndviDifference = ndvi2.subtract(ndvi1);

Beachten Sie in diesem Beispiel die Verwendung eines benutzerdefinierten function. Weitere Informationen zu Funktionen finden Sie im nächsten Abschnitt.

Zuordnung (statt einer For-Schleife)

Mit map() können Sie über Elemente in einer Sammlung iterieren. For-Schleifen sind in der Earth Engine NICHT der richtige Ansatz und sollten vermieden werden. Die Funktion map() kann auf eine ImageCollection, eine FeatureCollection oder eine List angewendet werden und akzeptiert eine function als Argument. Das Argument der Funktion ist ein Element der Sammlung, über die sie zugeordnet wird. Das ist nützlich, wenn Sie jedes Element der Sammlung auf dieselbe Weise ändern möchten, z. B. hinzufügen. Im folgenden Code wird beispielsweise jedem Bild in einer ImageCollection ein NDVI-Band hinzugefügt:

Code-Editor (JavaScript)

// This function gets NDVI from Landsat 8 imagery.
var addNDVI = function(image) {
  return image.addBands(image.normalizedDifference(['B5', 'B4']));
};

// Load the Landsat 8 TOA data, filter by location and date.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
  .filterBounds(ee.Geometry.Point(-122.262, 37.8719))
  .filterDate('2014-06-01', '2014-10-01');

// Map the function over the collection.
var ndviCollection = collection.map(addNDVI);

Eine weitere häufige Aufgabe besteht darin, Features in einer FeatureCollection eine neue Property (oder ein neues Attribut oder Feld) hinzuzufügen. Im folgenden Beispiel ist die neue Property eine Berechnung, die zwei vorhandene Attribute umfasst:

Code-Editor (JavaScript)

// This function creates a new property that is the sum of two existing properties.
var addField = function(feature) {
  var sum = ee.Number(feature.get('property1')).add(feature.get('property2'));
  return feature.set({'sum': sum});
};

// Create a FeatureCollection from a list of Features.
var features = ee.FeatureCollection([
  ee.Feature(ee.Geometry.Point(-122.4536, 37.7403),
    {property1: 100, property2: 100}),
    ee.Feature(ee.Geometry.Point(-118.2294, 34.039),
    {property1: 200, property2: 300}),
]);

// Map the function over the collection.
var featureCollection = features.map(addField);

// Print a selected property of one Feature.
print(featureCollection.first().get('sum'));

// Print the entire FeatureCollection.
print(featureCollection);

Hinweis: Die Umwandlung in ee.Number ist erforderlich, damit der Property-Wert als Zahl erkannt und die add()-Methode verwendet werden kann. Der Typ der Sammlung kann durch map() geändert werden. Beispiel:

Code-Editor (JavaScript)

// This function returns the image centroid as a new Feature.
var getGeom = function(image) {
  return ee.Feature(image.geometry().centroid(), {foo: 1});
};

// Load a Landsat 8 TOA collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
  .filterBounds(ee.Geometry.Point(-122.262, 37.8719))
  .filterDate('2014-06-01', '2014-10-01');

// Map the function over the ImageCollection.
var featureCollection = ee.FeatureCollection(collection.map(getGeom));

// Print the collection.
print(featureCollection);

Beachten Sie die hinzugefügte Property (foo) für jede Funktion, die aus dem Bildmittelpunkt erstellt wurde. In der letzten Zeile wird die resultierende Sammlung durch die Umwandlung als FeatureCollection erkannt.

Kleiner

Durch das Reduzieren können Sie Daten in Earth Engine über Zeit, Raum, Bänder, Arrays und andere Datenstrukturen hinweg aggregieren. In der API gibt es verschiedene Methoden zu diesem Zweck. Wenn Sie beispielsweise ein ImageCollection-Composite erstellen möchten, können Sie mit reduce() die Bilder in der Sammlung auf ein Bild reduzieren. Ein einfaches Beispiel ist das Erstellen des Median-Composites der fünf am wenigsten bewölkten Szenen in der zuvor definierten Landsat 8-Sammlung:

Code-Editor (JavaScript)

// Load a Landsat 8 TOA collection.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
  // Filter by date and location.
  .filterBounds(ee.Geometry.Point(-122.262, 37.8719))
  .filterDate('2014-01-01', '2014-12-31')
  // Sort by increasing cloudiness.
  .sort('CLOUD_COVER');

// Compute the median of each pixel for each band of the 5 least cloudy scenes.
var median = collection.limit(5).reduce(ee.Reducer.median());

Durch die Reduzierung können Sie auch Statistiken zu einem Bild in den durch Feature oder FeatureCollection definierten Regionen abrufen. Angenommen, Sie möchten die Mittelpixelwerte in einem bestimmten Bereich berechnen. Verwenden Sie dazu reduceRegion(). Beispiel:

Code-Editor (JavaScript)

// Load and display a Landsat TOA image.
var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318');
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 0.3});

// Create an arbitrary rectangle as a region and display it.
var region = ee.Geometry.Rectangle(-122.2806, 37.1209, -122.0554, 37.2413);
Map.addLayer(region);

// Get a dictionary of means in the region.  Keys are bandnames.
var mean = image.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: region,
  scale: 30
});

Weitere Informationen zu Reduzierern finden Sie im Dokument zu Reduzierern.

Maskieren

Jedes Pixel in einem ee.Image hat sowohl einen Wert als auch eine Maske, die von 0 (keine Daten) bis 1 reicht. Maskierte Pixel (bei denen mask==0) werden als keine Daten behandelt. Pixel mit 0 < mask ≤ 1 haben einen Wert, der bei numerischen Berechnungen jedoch durch die Maske gewichtet wird.

Mithilfe von Masken können Sie Pixel transparent machen oder aus der Analyse ausschließen. Pixels werden maskiert, wenn der Maskenwert null ist. Im Beispiel zur Bilddifferenzierung können Sie mit einer Maske Bereiche mit erhöhtem und verringertem NDVI im Differenzintervall anzeigen:

// This function gets NDVI from Landsat 5 imagery.
var getNDVI = function(image) {
  return image.normalizedDifference(['B4', 'B3']);
};

// Load two Landsat 5 images, 20 years apart.
var image1 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_19900604');
var image2 = ee.Image('LANDSAT/LT05/C02/T1_TOA/LT05_044034_20100611');

// Compute NDVI from the scenes.
var ndvi1 = getNDVI(image1);
var ndvi2 = getNDVI(image2);

// Compute the difference in NDVI.
var ndviDifference = ndvi2.subtract(ndvi1);
// Load the land mask from the SRTM DEM.
var landMask = ee.Image('CGIAR/SRTM90_V4').mask();

// Update the NDVI difference mask with the land mask.
var maskedDifference = ndviDifference.updateMask(landMask);

// Display the masked result.
var vizParams = {min: -0.5, max: 0.5, palette: ['FF0000', 'FFFFFF', '0000FF']};
Map.setCenter(-122.2531, 37.6295, 9);
Map.addLayer(maskedDifference, vizParams, 'NDVI difference');

In diesem Beispiel wird die Maske der NDVI-Unterschiede durch die Landmaske mit updateMask() aktualisiert. Dadurch wird die Maske der NDVI-Unterschiedspixel auf die Landmaske gesetzt, sofern der Wert der NDVI-Unterschiedsmaske ungleich Null ist.

Das Maskieren ist auch nützlich, um Daten von der Analyse auszuschließen. Sehen wir uns das Beispiel reduceRegion() aus dem Abschnitt Reduzieren noch einmal an. Angenommen, Sie möchten einen saisonalen Mittelwert für den NDVI für Santa Clara County, Kalifornien, berechnen, wobei bewölkte Pixel ausgeschlossen werden sollen. Das folgende Beispiel veranschaulicht mehrere Konzepte: filtering, mapping, reducing und die Verwendung einer Wolkenmaske:

Code-Editor (JavaScript)

// This function gets NDVI from a Landsat 8 image.
var addNDVI = function(image) {
  return image.addBands(image.normalizedDifference(['B5', 'B4']));
};

// This function masks cloudy pixels.
var cloudMask = function(image) {
  var clouds = ee.Algorithms.Landsat.simpleCloudScore(image).select(['cloud']);
  return image.updateMask(clouds.lt(10));
};

// Load a Landsat collection, map the NDVI and cloud masking functions over it.
var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
  .filterBounds(ee.Geometry.Point([-122.262, 37.8719]))
  .filterDate('2014-03-01', '2014-05-31')
  .map(addNDVI)
  .map(cloudMask);

// Reduce the collection to the mean of each pixel and display.
var meanImage = collection.reduce(ee.Reducer.mean());
var vizParams = {bands: ['B5_mean', 'B4_mean', 'B3_mean'], min: 0.02, max: 0.4};
Map.addLayer(meanImage, vizParams, 'mean');

// Load a region in which to compute the mean and display it.
var counties = ee.FeatureCollection('TIGER/2018/Counties');
var santaClara = ee.Feature(counties.filter(ee.Filter.eq('NAME', 'Santa Clara')).first());
Map.addLayer(santaClara);

// Get the mean of NDVI in the region.
var mean = meanImage.select(['nd_mean']).reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: santaClara.geometry(),
  scale: 30
});

// Print mean NDVI for the region.
mean.get('nd_mean').evaluate(function(val){
  print('Santa Clara spring mean NDVI:', val);
});