API Earth Engine в клиентских веб-приложениях

В этом руководстве показано, как создать веб-страницу с интерактивной картой, отображающей результаты, вычисляемые в режиме реального времени в Earth Engine. Оно подходит для пользователей с начальным или средним уровнем знаний HTML, CSS и JavaScript.

Ниже представлена ​​демонстрация интерактивной карты, которую вы создадите в этом руководстве. На ней показан уклон местности Большого каньона, рассчитанный в Earth Engine и представленный различными оттенками серого. Вы можете перемещать и масштабировать карту, чтобы рассчитать и отобразить результаты для дополнительных областей. Обратите внимание, что для доступа к демонстрационной версии необходимо войти в систему.

Описанный здесь подход обычно используется при создании одностраничных приложений (SPA) . В SPA всё приложение доступно для использования в веб-браузере без перезагрузки страницы с сервера. Таким образом, для таких приложений не требуется разработка и размещение пользовательского серверного компонента.

Поскольку код приложения будет выполняться в веб-браузере пользователя (также известном как выполнение на стороне клиента ), разработчикам не следует встраивать конфиденциальные учетные данные, такие как закрытые ключи учетных записей служб, непосредственно в приложение. Вместо этого пользователи приложения должны проходить аутентификацию, используя свои собственные учетные записи, зарегистрированные для доступа к Earth Engine.

В этом руководстве вы узнаете, как:

  1. Отобразить кнопку, позволяющую пользователям войти в систему, используя свою учетную запись Earth Engine.
  2. Проведите базовый анализ в Earth Engine.
  3. Встройте интерактивную карту для отображения результатов, используя JavaScript API для работы с картами.

Предварительные требования

Настройте свой облачный проект

  1. Прежде чем начать, следуйте инструкциям в разделе «Настройка облачного проекта с поддержкой Earth Engine ». Запишите идентификатор клиента, полученный в разделе «Настройка OAuth 2.0». Поскольку ваше приложение позволит пользователям входить в систему с помощью своих собственных учетных записей Google, вы можете пропустить раздел «Создание и регистрация сервисной учетной записи».
  2. Включите JavaScript API для работы с картами в вашем проекте.

Получите ключ API карт.

См. раздел «Получение ключа API» в документации по Maps JavaScript API, чтобы узнать, как получить ключ API, позволяющий использовать Maps JavaScript API в вашем веб-приложении.

Настоятельно рекомендуется также следовать инструкциям в разделе «Ограничение использования ключа API» , чтобы гарантировать, что с помощью вашего ключа API будут выполняться только авторизованные запросы.

Создайте своё приложение

Шаг 1. Создайте HTML-страницу.

Для начала определим базовую HTML-страницу следующим образом:

<!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>

Этот базовый HTML-код выполняет несколько функций:

  • Использует стили CSS для определения размера и цвета фона карты, отображаемой при инициализации.
  • Определяет кнопку «Войти через Google», которая при нажатии вызывает функцию onSignInButtonClick() . Эта функция будет определена на JavaScript в следующих разделах.
  • Определяет пустой элемент, который будет содержать карту после её инициализации.
  • Добавляет пустой блок <script> для размещения кода JavaScript, определенного ниже.

Шаг 2. Определение поведения в JavaScript.

В следующих шагах код JavaScript можно разместить непосредственно внутри тега <script> .

Определите функцию обратного вызова для настройки API и сопоставления.

Определите функцию, которая будет выполнять работу после авторизации пользователя. API Earth Engine может быть инициализирован и вызван только после аутентификации пользователя. Подробнее об этом позже.

В этом примере инициализируются API Earth Engine и Maps, создается источник тайлов, который вычисляет уклон местности по запросу, и добавляется этот источник тайлов на карту в качестве наложения, отображаемого с помощью JavaScript API Maps:

// 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);
}

Определите обработчик нажатий на кнопку входа в систему.

Далее добавьте функцию, которая будет отображать всплывающее окно входа в систему при нажатии кнопки входа. В случае успеха вызывается метод 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);
}

Этот коллбэк связан с кнопкой в ​​приведенном выше HTML-коде через ее атрибут onclick . Обратите внимание, что в этом примере кнопка входа изначально скрыта при загрузке страницы. В следующем разделе мы проверим, вошел ли пользователь в систему, прежде чем отображать кнопку.

Определить основную точку входа

Теперь определим основной код, который будет выполняться первым при загрузке страницы. Он использует встроенную в Earth Engine вспомогательную функцию аутентификации ee.data.authenticateViaPopup() для проверки того, авторизован ли пользователь. Если пользователь авторизован, функция запрашивает соответствующие разрешения и, в случае успеха, вызывает setUp() для инициализации API Earth Engine и Maps.

Если же пользователь не авторизован, отображается кнопка входа. Пользователь может нажать на эту кнопку, чтобы запустить onSignInButtonClick() , который, в свою очередь, отобразит всплывающее окно и вызовет метод 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
);

Попробуйте сами!

Ниже представлено полное решение, описанное в этом руководстве. В правом верхнем углу примера кода расположены три кнопки. Нажмите на самую левую кнопку, чтобы открыть пример в JSFiddle.

Замените YOUR_API_KEY и YOUR_CLIENT_ID на ключ API Maps и идентификатор клиента OAuth, полученные в разделе «Предварительные условия» (вы можете щелкнуть по этим заполнителям в приведенном ниже коде, чтобы они были автоматически вставлены). Также замените 'my-project' на идентификатор вашего проекта 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>