Earth Engine API w aplikacjach internetowych po stronie klienta

Z tego przewodnika dowiesz się, jak utworzyć stronę internetową z interaktywną mapą, która będzie wyświetlać wyniki obliczone na bieżąco w Earth Engine. Jest on przeznaczony dla osób, które mają podstawową lub średnio zaawansowaną wiedzę na temat HTML, CSS i JavaScript.

Poniżej znajdziesz wersję demonstracyjną interaktywnej mapy, którą utworzysz w tym przewodniku. Pokazuje ona nachylenie terenu Wielkiego Kanionu obliczone w Earth Engine, przedstawione za pomocą różnych odcieni szarości. Możesz przesuwać i powiększać mapę, aby obliczać i wyświetlać wyniki dla dodatkowych obszarów. Pamiętaj, że musisz zalogować się w wersji demonstracyjnej.

Opisane tutaj podejście jest zwykle stosowane podczas tworzenia aplikacji jednostronicowych (SPA). W przypadku aplikacji jednostronicowej cała aplikacja jest dostępna w przeglądarce internetowej bez ponownego wczytywania strony z serwera. Dlatego te aplikacje nie wymagają tworzenia ani hostowania niestandardowego komponentu po stronie serwera.

Ponieważ kod aplikacji będzie uruchamiany w przeglądarce internetowej użytkownika (czyli po stronie klienta), deweloperzy nie powinni osadzać w aplikacji poufnych danych logowania, takich jak klucze prywatne konta usługi. Zamiast tego użytkownicy aplikacji muszą uwierzytelnić się za pomocą własnych kont zarejestrowanych w Earth Engine.

Z tego przewodnika dowiesz się, jak:

  1. wyświetlić przycisk umożliwiający użytkownikom logowanie się za pomocą konta Earth Engine;
  2. zdefiniować podstawową analizę w Earth Engine;
  3. osadzić interaktywną mapę, aby wyświetlać wyniki za pomocą interfejsu Maps JavaScript API.

Wymagania wstępne

Konfigurowanie projektu Cloud

  1. Zanim zaczniesz, wykonaj instrukcje opisane w artykule Konfigurowanie projektu Cloud z włączoną usługą Earth Engine. Zanotuj identyfikator klienta uzyskany w sekcji „Konfigurowanie OAuth 2.0”. Ponieważ Twoja aplikacja będzie umożliwiać użytkownikom logowanie się za pomocą własnego konta Google, możesz pominąć sekcję „Tworzenie i rejestrowanie konta usługi”.
  2. Włącz w projekcie interfejs Maps JavaScript API.

Uzyskiwanie klucza interfejsu API Map Google

Aby dowiedzieć się, jak uzyskać klucz interfejsu API, który umożliwi Ci korzystanie z interfejsu Maps JavaScript API w aplikacji internetowej, przeczytaj artykuł Uzyskiwanie klucza interfejsu API w dokumentacji interfejsu Maps JavaScript API.

Zdecydowanie zalecamy też wykonanie instrukcji podanych w sekcji Ograniczanie klucza interfejsu API , aby mieć pewność, że za pomocą Twojego klucza interfejsu API będą wysyłane tylko autoryzowane żądania.

Tworzenie aplikacji

Krok 1. Tworzenie strony HTML

Na początek zdefiniuj podstawową stronę internetową HTML w ten sposób:

<!DOCTYPE html>
<html>
  <head>
    <style>
      /* Set the size of the div element that contains the map. */
      #map-container {
        height: 400px;
        width: 100%;
        background-color: #eee;
      }
    </style>
  </head>
  <body>
    <!-- The "Sign in with Google" button, initially hidden. -->
    <input
      id="g-sign-in"
      type="image"
      src="https://developers.google.com/identity/images/btn_google_signin_light_normal_web.png"
      onclick="onSignInButtonClick()"
      alt="Sign in with Google"
      hidden
    />

    <!-- Element where map will be added. -->
    <div id="map-container"></div>
    <script>
      // JavaScript code goes here.
    </script>
  </body>
</html>

Ten podstawowy HTML wykonuje kilka czynności:

  • Używa stylów CSS do określenia rozmiaru i koloru tła mapy wyświetlanej podczas inicjowania.
  • Definiuje przycisk „Zaloguj się przez Google”, który po kliknięciu wywołuje funkcję onSignInButtonClick(). Ta funkcja zostanie zdefiniowana w JavaScript w następnych sekcjach.
  • Definiuje pusty element, który będzie zawierać mapę po jej zainicjowaniu.
  • Dodaje pusty <script> blok, który będzie zawierać kod JavaScript zdefiniowany poniżej.

Krok 2. Definiowanie zachowań w JavaScript

W kolejnych krokach kod JavaScript można umieścić bezpośrednio w tagu <script>.

Definiowanie wywołania zwrotnego do konfigurowania interfejsów API i mapy

Zdefiniuj funkcję, która będzie wykonywać działania po zalogowaniu się użytkownika. Interfejs Earth Engine API można zainicjować i wywołać dopiero po uwierzytelnieniu użytkownika. Więcej informacji na ten temat znajdziesz w dalszej części tego przewodnika.

Ten przykład inicjuje interfejsy Earth Engine i Maps API, tworzy źródło kafelków, które na żądanie oblicza nachylenie terenu, i dodaje to źródło kafelków do mapy jako nakładkę wyświetlaną przez interfejs Maps JavaScript API:

// Initializes Maps JavaScript API and Earth Engine API, instructing the map
// to pull tiles from Earth Engine and to overlay them on the map.
function setUpMap() {
  // Hide the sign-in button.
  document.getElementById("g-sign-in").setAttribute("hidden", "true");

  // Initialize the Earth Engine API. Must be called once before using the API.
  ee.initialize(null, null, null, null, null, 'my-project');

  // Get a reference to the placeholder DOM element to contain the map.
  const mapContainerEl = document.getElementById("map-container");

  // Create an interactive map inside the placeholder DOM element.
  const embeddedMap = new google.maps.Map(mapContainerEl, {
    // Pan and zoom initial map viewport to Grand Canyon.
    center: {lng: -112.8598, lat: 36.2841},
    zoom: 9,
  });

  // Obtain reference to digital elevation model and apply algorithm to
  // calculate slope.
  const srtm = ee.Image("CGIAR/SRTM90_V4");
  const slope = ee.Terrain.slope(srtm);

  // Create a new tile source to fetch visible tiles on demand and display them
  // on the map.
  const mapId = slope.getMap({min: 0, max: 60});
  const tileSource = new ee.layers.EarthEngineTileSource(mapId);
  const overlay = new ee.layers.ImageOverlay(tileSource);
  embeddedMap.overlayMapTypes.push(overlay);
}

Definiowanie modułu obsługi kliknięć przycisku logowania

Następnie dodaj funkcję, która będzie wyświetlać wyskakujące okienko logowania po kliknięciu przycisku logowania. Jeśli operacja się powiedzie, zostanie wywołana metoda setUp().

// Handles clicks on the sign-in button.
function onSignInButtonClick() {
  // Display popup allowing the user to sign in with their Google account and to
  // grant appropriate permissions to the app.
  ee.data.authenticateViaPopup(setUpMap);
}

To wywołanie zwrotne jest powiązane z przyciskiem w powyższym kodzie HTML za pomocą atrybutu onclick. Pamiętaj, że w tym przykładzie przycisk logowania jest początkowo ukryty po wczytaniu strony. W następnej sekcji sprawdzimy, czy użytkownik jest zalogowany, zanim wyświetlimy przycisk.

Definiowanie głównego punktu wejścia

Teraz zdefiniuj kod najwyższego poziomu, który będzie wykonywany jako pierwszy po wczytaniu strony. Używa on wbudowanej funkcji pomocniczej uwierzytelniania Earth Engine ee.data.authenticateViaPopup() aby sprawdzić, czy użytkownik jest już zalogowany. Jeśli użytkownik jest zalogowany, funkcja prosi o odpowiednie uprawnienia i w razie powodzenia wywołuje metodę setUp() w celu zainicjowania interfejsów Earth Engine i Maps API.

Jeśli użytkownik nie jest zalogowany, wyświetlany jest przycisk logowania. Użytkownik może wtedy kliknąć przycisk, aby wywołać funkcję onSignInButtonClick(), która z kolei wyświetla wyskakujące okienko i wywołuje metodę setUp().

// If the user is signed in, display a popup requesting permissions needed to
// run the app, otherwise show the sign-in button.
ee.data.authenticateViaOauth(
  // The OAuth Client ID defined above.
  CLIENT_ID,
  // Callback invoked immediately when user is already signed in.
  setUpMap,
  // Show authentication errors in a popup.
  alert,
  // Request permission to only read and compute Earth Engine data on behalf of
  // user.
  /* extraScopes = */ ['https://www.googleapis.com/auth/earthengine.readonly'],
  // Show sign-in button if reusing existing credentials fails.
  () => document.getElementById("g-sign-in").removeAttribute("hidden"),
  // Don't require ability to write and access Cloud Platform on behalf of the
  // user.
  /* opt_suppressDefaultScopes = */ true
);

Wypróbuj

Poniżej znajdziesz pełne rozwiązanie opisane w tym przewodniku. W prawym górnym rogu przykładowego kodu znajdują się 3 przyciski. Kliknij przycisk po lewej stronie, aby otworzyć przykład w JSFiddle.

Zastąp YOUR_API_KEY i YOUR_CLIENT_ID kluczem interfejsu API Map Google i identyfikatorem klienta OAuth uzyskanym w sekcji Wymagania wstępne (możesz kliknąć te symbole zastępcze w kodzie poniżej, aby zostały automatycznie wstawione). Zastąp też 'my-project' identyfikatorem projektu Google Cloud.

<!-- Load Maps JavaScript API. For production apps, append you own ?key=YOUR_API_KEY. -->

<script src="https://maps.googleapis.com/maps/api/js?key="></script>
<script src="https://ajax.googleapis.com/ajax/libs/earthengine/0.1.365/earthengine-api.min.js"></script>
<!-- The "Sign in with Google" button, initially hidden. -->
<input
  id="g-sign-in"
  type="image"
  src="https://developers.google.com/identity/images/btn_google_signin_light_normal_web.png"
  onclick="onSignInButtonClick()"
  alt="Sign in with Google"
  hidden
/>

<!-- Element where map will be added. -->
<div id="map-container"></div>
/* Set the size of the div element that contains the map. */
  #map-container {
    height: 400px;
    width: 100%;
    background-color: #eee;
  }
// The OAuth Client ID from the Google Developers Console.
// REMINDER: Be sure to add a valid ID here!
const CLIENT_ID = "";

// Initializes Maps JavaScript API and Earth Engine API, instructing the map
// to pull tiles from Earth Engine and to overlay them on the map.
function setUpMap() {
  // Hide the sign-in button.
  document.getElementById("g-sign-in").setAttribute("hidden", "true");

  // Initialize the Earth Engine API. Must be called once before using the API.
  ee.initialize(null, null, null, null, null, 'my-project');

  // Get a reference to the placeholder DOM element to contain the map.
  const mapContainerEl = document.getElementById("map-container");

  // Create an interactive map inside the placeholder DOM element.
  const embeddedMap = new google.maps.Map(mapContainerEl, {
    // Pan and zoom initial map viewport to Grand Canyon.
    center: {lng: -112.8598, lat: 36.2841},
    zoom: 9,
  });

  // Obtain reference to digital elevation model and apply algorithm to
  // calculate slope.
  const srtm = ee.Image("CGIAR/SRTM90_V4");
  const slope = ee.Terrain.slope(srtm);

  // Create a new tile source to fetch visible tiles on demand and display them
  // on the map.
  const mapId = slope.getMap({min: 0, max: 60});
  const tileSource = new ee.layers.EarthEngineTileSource(mapId);
  const overlay = new ee.layers.ImageOverlay(tileSource);
  embeddedMap.overlayMapTypes.push(overlay);
}

// Handles clicks on the sign-in button.
function onSignInButtonClick() {
  // Display popup allowing the user to sign in with their Google account and to
  // grant appropriate permissions to the app.
  ee.data.authenticateViaPopup(setUpMap);
}

// If the user is signed in, display a popup requesting permissions needed to
// run the app, otherwise show the sign-in button.
ee.data.authenticateViaOauth(
  // The OAuth Client ID defined above.
  CLIENT_ID,
  // Callback invoked immediately when user is already signed in.
  setUpMap,
  // Show authentication errors in a popup.
  alert,
  // Request permission to only read and compute Earth Engine data on behalf of
  // user.
  /* extraScopes = */ ['https://www.googleapis.com/auth/earthengine.readonly'],
  // Show sign-in button if reusing existing credentials fails.
  () => document.getElementById("g-sign-in").removeAttribute("hidden"),
  // Don't require ability to write and access Cloud Platform on behalf of the
  // user.
  /* opt_suppressDefaultScopes = */ true
);
<!DOCTYPE html>
<html>
  <head>
    <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/earthengine/0.1.365/earthengine-api.min.js"></script>
    <style>
      /* Set the size of the div element that contains the map. */
      #map-container {
        height: 400px;
        width: 100%;
        background-color: #eee;
      }
    </style>
  </head>
  <body>
    <!-- The "Sign in with Google" button, initially hidden. -->
    <input
      id="g-sign-in"
      type="image"
      src="https://developers.google.com/identity/images/btn_google_signin_light_normal_web.png"
      onclick="onSignInButtonClick()"
      alt="Sign in with Google"
      hidden
    />

    <!-- Element where map will be added. -->
    <div id="map-container"></div>
    <script>
      // The OAuth Client ID from the Google Developers Console.
      const CLIENT_ID = "YOUR_CLIENT_ID";
      
      // Initializes Maps JavaScript API and Earth Engine API, instructing the map
      // to pull tiles from Earth Engine and to overlay them on the map.
      function setUpMap() {
        // Hide the sign-in button.
        document.getElementById("g-sign-in").setAttribute("hidden", "true");
      
        // Initialize the Earth Engine API. Must be called once before using the API.
        ee.initialize(null, null, null, null, null, 'my-project');
      
        // Get a reference to the placeholder DOM element to contain the map.
        const mapContainerEl = document.getElementById("map-container");
      
        // Create an interactive map inside the placeholder DOM element.
        const embeddedMap = new google.maps.Map(mapContainerEl, {
          // Pan and zoom initial map viewport to Grand Canyon.
          center: {lng: -112.8598, lat: 36.2841},
          zoom: 9,
        });
      
        // Obtain reference to digital elevation model and apply algorithm to
        // calculate slope.
        const srtm = ee.Image("CGIAR/SRTM90_V4");
        const slope = ee.Terrain.slope(srtm);
      
        // Create a new tile source to fetch visible tiles on demand and display them
        // on the map.
        const mapId = slope.getMap({min: 0, max: 60});
        const tileSource = new ee.layers.EarthEngineTileSource(mapId);
        const overlay = new ee.layers.ImageOverlay(tileSource);
        embeddedMap.overlayMapTypes.push(overlay);
      }
      
      // Handles clicks on the sign-in button.
      function onSignInButtonClick() {
        // Display popup allowing the user to sign in with their Google account and to
        // grant appropriate permissions to the app.
        ee.data.authenticateViaPopup(setUpMap);
      }
      
      // If the user is signed in, display a popup requesting permissions needed to
      // run the app, otherwise show the sign-in button.
      ee.data.authenticateViaOauth(
        // The OAuth Client ID defined above.
        CLIENT_ID,
        // Callback invoked immediately when user is already signed in.
        setUpMap,
        // Show authentication errors in a popup.
        alert,
        // Request permission to only read and compute Earth Engine data on behalf of
        // user.
        /* extraScopes = */ ['https://www.googleapis.com/auth/earthengine.readonly'],
        // Show sign-in button if reusing existing credentials fails.
        () => document.getElementById("g-sign-in").removeAttribute("hidden"),
        // Don't require ability to write and access Cloud Platform on behalf of the
        // user.
        /* opt_suppressDefaultScopes = */ true
      );
    </script>
  </body>
</html>