本指南說明如何建構網頁,顯示 Earth Engine 即時運算的結果,並以互動式地圖呈現。適用對象為具備 HTML、CSS 和 JavaScript 初級或中級知識的使用者。
以下是您將在本指南中建立的互動式地圖示範。畫面顯示 Earth Engine 計算出的大峽谷地形坡度,並以不同深淺的灰色表示。您可以平移及縮放地圖,計算並顯示其他區域的結果。請注意,您必須登入才能使用試用版。
建立單頁應用程式 (SPA) 時,通常會使用這裡所述的方法。在 SPA 中,整個應用程式都可在網頁瀏覽器中使用,無須從伺服器重新載入網頁。因此,這類應用程式不需要開發及代管自訂伺服器端元件。
由於應用程式的程式碼會在使用者網頁瀏覽器中執行 (也稱為用戶端執行),開發人員不應直接在應用程式中嵌入服務帳戶私密金鑰等機密憑證。應用程式使用者必須使用已註冊 Earth Engine 存取權的帳戶進行驗證。
這份指南說明如何:
- 顯示按鈕,讓使用者透過 Earth Engine 帳戶登入。
- 在 Earth Engine 中定義基本分析。
- 嵌入互動式地圖,使用 Maps JavaScript API 顯示結果。
必要條件
設定 Cloud 專案
- 開始之前,請按照「設定已啟用 Earth Engine 的 Cloud 專案」中的操作說明進行。請記下「設定 OAuth 2.0」一節中取得的用戶端 ID。由於您的應用程式會允許使用者登入自己的 Google 帳戶,因此您可以略過「建立及註冊服務帳戶」一節。
- 為專案啟用 Maps JavaScript API。
取得 Maps API 金鑰
請參閱 Maps JavaScript API 說明文件中的「取得 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 和地圖
定義使用者登入後要執行的函式。使用者通過驗證後,才能初始化及叫用 Earth Engine API。我們很快就會發布更多相關消息。
這個範例會初始化 Earth Engine 和 Maps API,建立可依需求計算地形坡度的圖塊來源,並將圖塊來源新增至地圖,做為 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); }
定義登入按鈕點擊事件的處理常式
接著,新增函式,在點選登入按鈕時顯示登入彈出式視窗。如果成功,系統會呼叫 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); }
這個回呼會透過 onclick 屬性與上述 HTML 中的按鈕建立關聯。請注意,在本範例中,登入按鈕會在網頁載入時隱藏。在下一節中,我們會先檢查使用者是否已登入,再顯示按鈕。
定義主要進入點
現在要定義網頁載入時首先執行的頂層程式碼。這會使用 Earth Engine 的內建驗證輔助函式 ee.data.authenticateViaPopup(),檢查使用者是否已登入。如果使用者已登入,函式會要求適當的權限,並在成功時呼叫 setUp() 來初始化 Earth Engine 和 Maps API。
如果使用者未登入,系統會顯示登入按鈕。使用者可以點選按鈕觸發 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 替換為在必要條件中取得的 Maps API 金鑰和 OAuth 用戶端 ID (您可以點選下方程式碼中的這些預留位置,系統就會自動插入)。此外,請將 'my-project' 替換為您的 Google Cloud 雲端專案 ID。
<!-- 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>