Bagikan melalui


Mulai cepat: Membangun aplikasi web dengan Microsoft Planetary Computer Pro

Dalam mulai cepat ini, Anda membangun aplikasi web yang menampilkan citra satelit dan data geospasial dari GeoCatalog Anda pada peta interaktif. Anda mengautentikasi pengguna dengan ID Microsoft Entra, mengkueri koleksi STAC, dan merender petak peta—semuanya dari browser JavaScript.

Apa yang Anda pelajari:

  • Mengautentikasi pengguna dan memperoleh token akses menggunakan MSAL.js
  • Mengkueri API STAC untuk menemukan koleksi dan item
  • Menampilkan petak raster pada peta MapLibre GL dengan header otorisasi
  • Membuat lapisan mosaik yang mulus di seluruh koleksi
  • Mengunduh aset mentah menggunakan token SAS

Pola kode bekerja dengan kerangka kerja JavaScript modern (React, Vue, Angular) atau vanilla JavaScript. API GeoCatalog memiliki dukungan CORS penuh, sehingga Anda dapat memanggilnya langsung dari localhost selama pengembangan—tidak ada proksi yang diperlukan.

Anda dapat mengunduh dan menguji kode ini dari repositori GitHub publik Microsoft Planetary Computer Pro.

Prasyarat

Gambaran umum arsitektur

Aplikasi web GeoCatalog yang khas mengikuti arsitektur ini:

Diagram memperlihatkan arsitektur aplikasi web GeoCatalog dengan klien browser yang terhubung ke ID Microsoft Entra untuk autentikasi dan ke API GeoCatalog untuk akses data.

Mendaftarkan aplikasi Anda di ID Microsoft Entra

Sebelum aplikasi web Anda dapat mengautentikasi pengguna, daftarkan di ID Microsoft Entra. Panduan kilat ini menggunakan pendaftaran Aplikasi Halaman Tunggal (SPA), yang ideal untuk aplikasi JavaScript sisi klien dan pengembangan lokal. Pola integrasi API yang ditampilkan dalam langkah-langkah selanjutnya berfungsi dengan jenis aplikasi apa pun.

Nota

Untuk aplikasi produksi dengan server backend, pertimbangkan untuk memilih jenis pendaftaran yang berbeda (Web, Asli, dll.). Lihat Mengonfigurasi autentikasi aplikasi untuk panduan tentang memilih pendekatan yang tepat untuk skenario Anda.

Daftarkan sebagai aplikasi halaman tunggal

  1. Buka ID Microsoft Entra di portal Microsoft Azure.
  2. Pilih Pendaftaran aplikasi dari panel samping.
  3. Pilih Pendaftaran baru.
  4. Masukkan nama untuk aplikasi Anda (misalnya, "GeoCatalog Web App").
  5. Di bawah Jenis akun yang didukung, pilih Akun di direktori organisasi ini saja.
  6. Di bawah URI Pengalihan, pilih Aplikasi halaman tunggal (SPA) dan masukkan URL pengembangan Anda (misalnya, http://localhost:5173).
  7. Pilih Daftarkan.

Setelah pendaftaran, perhatikan nilai berikut dari halaman Gambaran Umum :

  • ID Aplikasi (klien)
  • ID direktori (penyewa)

Untuk informasi selengkapnya, tinjau panduan cepat registrasi aplikasi.

Memberikan izin API

Aplikasi Anda memerlukan izin untuk memanggil API GeoCatalog atas nama pengguna yang masuk:

  1. Di pendaftaran aplikasi Anda, pilih Izin> APITambahkan izin.
  2. Pilih API yang digunakan organisasi saya dan cari Azure Orbital Spatio.
  3. Pilih Izin yang didelegasikan dan periksa user_impersonation.
  4. Pilih Tambahkan izin.
  5. Jika Anda adalah admin, pilih Berikan persetujuan admin untuk menyetujui atas nama semua pengguna di penyewa Anda.

Mengonfigurasi aplikasi Anda

Aplikasi Anda memerlukan nilai konfigurasi berikut. Cara Anda memberikan nilai-nilai ini tergantung pada alat build Anda (variabel lingkungan, file konfigurasi, dan sebagainya):

Konfigurasi Nilai Description
URL Katalog https://{name}.{region}.geocatalog.spatio.azure.com Titik akhir GeoCatalog Anda
ID Penyewa Dari pendaftaran aplikasi Akun Penyewa Microsoft Entra Anda
ID Pelanggan Dari pendaftaran aplikasi ID klien aplikasi Anda
Cakupan API https://geocatalog.spatio.azure.com/.default Selalu gunakan nilai yang tepat ini

Pasang dependensi

Instal Microsoft Authentication Library (MSAL) untuk aplikasi browser dan pustaka peta:

npm install @azure/msal-browser maplibre-gl
  • @azure/msal-browser - Menangani autentikasi OAuth 2.0 dengan ID Microsoft Entra
  • maplibre-gl - Pustaka peta sumber terbuka untuk visualisasi petak peta

Tip

Struktur proyek: Contoh kode dalam panduan memulai cepat ini adalah fungsi mandiri yang dapat Anda atur sesuai keinginan Anda. Pola umum:

  • auth.js: Konfigurasi MSAL dan fungsi token
  • api.js: Fungsi TOken STAC API, Tiler API, dan SAS
  • map.js: Inisialisasi MapLibre dan manajemen lapisan petak peta
  • App.js atau main.js: Hubungkan semuanya dengan UI Anda

Setiap fungsi menerima dependensinya (token akses, URL) sebagai parameter, membuatnya mudah diintegrasikan ke dalam kerangka kerja atau struktur proyek apa pun.

Menerapkan autentikasi MSAL

Cuplikan layar memperlihatkan alur autentikasi dalam aplikasi web sampel.

Konfigurasikan MSAL untuk autentikasi browser. Contoh berikut menunjukkan konfigurasi utama dan pola akuisisi token:

import { PublicClientApplication, InteractionRequiredAuthError } from '@azure/msal-browser';

// Configuration - replace with your values or load from environment/config
const msalConfig = {
  auth: {
    clientId: 'YOUR_CLIENT_ID',
    authority: 'https://login.microsoftonline.com/YOUR_TENANT_ID',
    redirectUri: window.location.origin,
  },
  cache: {
    cacheLocation: 'sessionStorage',
    storeAuthStateInCookie: false,
  },
};

// Create MSAL instance
const msalInstance = new PublicClientApplication(msalConfig);

// GeoCatalog API scope - always use this exact value
const scopes = ['https://geocatalog.spatio.azure.com/.default'];

/**
 * Acquire an access token for GeoCatalog API calls.
 * Tries silent acquisition first, falls back to popup if needed.
 */
async function getAccessToken() {
  const account = msalInstance.getActiveAccount() || msalInstance.getAllAccounts()[0];
  
  if (!account) {
    throw new Error('No authenticated account. Call login() first.');
  }

  try {
    // Try silent token acquisition (uses cached token)
    const result = await msalInstance.acquireTokenSilent({ account, scopes });
    return result.accessToken;
  } catch (error) {
    // If silent fails (token expired), fall back to popup
    if (error instanceof InteractionRequiredAuthError) {
      const result = await msalInstance.acquireTokenPopup({ scopes });
      return result.accessToken;
    }
    throw error;
  }
}

/**
 * Sign in the user via popup.
 */
async function login() {
  const result = await msalInstance.loginPopup({ scopes });
  msalInstance.setActiveAccount(result.account);
  return result.account;
}

/**
 * Sign out the user.
 */
function logout() {
  msalInstance.logoutPopup();
}

STAC API: Meminta koleksi dan item

API STAC GeoCatalog menyediakan titik akhir untuk menemukan dan mengkueri data geospasial. Semua permintaan memerlukan Authorization header dengan Bearer token yang diperoleh dari Mengimplementasikan autentikasi MSAL.

Daftar Koleksi

Cuplikan layar memperlihatkan daftar koleksi STAC dalam aplikasi web sampel.

const API_VERSION = '2025-04-30-preview';

async function listCollections(accessToken, catalogUrl) {
  const url = `${catalogUrl}/stac/collections?api-version=${API_VERSION}`;
  
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
    },
  });
  
  if (!response.ok) {
    throw new Error(`Failed to list collections: ${response.statusText}`);
  }
  
  const data = await response.json();
  return data.collections; // Array of STAC Collection objects
}

Mencantumkan item dalam koleksi

Cuplikan layar memperlihatkan daftar item STAC dalam aplikasi web sampel.

const API_VERSION = '2025-04-30-preview';

async function listItems(accessToken, catalogUrl, collectionId, limit = 10) {
  const url = `${catalogUrl}/stac/collections/${collectionId}/items?limit=${limit}&api-version=${API_VERSION}`;
  
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
    },
  });
  
  if (!response.ok) {
    throw new Error(`Failed to list items: ${response.statusText}`);
  }
  
  const data = await response.json();
  return data.features; // Array of STAC Item objects
}

Mencari di seluruh koleksi

Cuplikan layar memperlihatkan cara menggunakan pencarian STAC untuk mengembalikan item yang menarik.

const API_VERSION = '2025-04-30-preview';

async function searchItems(accessToken, catalogUrl, searchParams) {
  const url = `${catalogUrl}/stac/search?api-version=${API_VERSION}`;
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(searchParams),
  });
  
  if (!response.ok) {
    throw new Error(`Search failed: ${response.statusText}`);
  }
  
  return await response.json();
}

// Example usage:
const results = await searchItems(token, catalogUrl, {
  collections: ['my-collection'],
  bbox: [-122.5, 37.5, -122.0, 38.0],  // [west, south, east, north]
  datetime: '2024-01-01/2024-12-31',
  limit: 20,
});

URL Tile: Membangun URL untuk visualisasi peta

API GeoCatalog Tiler melayani data raster sebagai petak peta. Buat URL tile dengan pola berikut:

Petak peta item tunggal

Cuplikan layar memperlihatkan cara menampilkan petak peta untuk satu item.

{catalogUrl}/data/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
  ?api-version=2025-04-30-preview
  &tileMatrixSetId=WebMercatorQuad
  &assets=visual

Fungsi pembuat URL tile

const API_VERSION = '2025-04-30-preview';

/**
 * Build a tile URL template for a STAC item.
 * Returns a URL with {z}/{x}/{y} placeholders for use with map libraries.
 */
function buildTileUrl(catalogUrl, collectionId, itemId, options = {}) {
  const { assets = 'visual', colormap, rescale } = options;
  
  const base = `${catalogUrl}/data/collections/${collectionId}/items/${itemId}/tiles/{z}/{x}/{y}@1x.png`;
  
  const params = new URLSearchParams();
  params.set('api-version', API_VERSION);
  params.set('tileMatrixSetId', 'WebMercatorQuad');
  params.set('assets', assets);
  
  if (colormap) params.set('colormap_name', colormap);
  if (rescale) params.set('rescale', rescale);
  
  return `${base}?${params.toString()}`;
}

// Example usage:
const tileUrl = buildTileUrl(
  'https://mygeocatalog.northcentralus.geocatalog.spatio.azure.com',
  'aerial-imagery',
  'image-001',
  { assets: 'visual' }
);

Parameter utama ubin

Pengaturan Diperlukan Description
api-version Yes Versi API (2025-04-30-preview)
tileMatrixSetId Yes Gunakan WebMercatorQuad untuk peta web
assets Yes Nama aset yang akan dirender (misalnya: visual, image)
colormap_name Tidak. Peta warna bernama (contoh: viridis, terrain)
rescale Tidak. Rentang nilai untuk penskalaan (contoh: 0,255)
asset_bidx Tidak. Indeks pita (misalnya: image\|1,2,3 untuk RGB)

Nota

Untuk koleksi dengan citra empat pita (seperti NAIP dengan RGB + NIR), gunakan asset_bidx=image|1,2,3 untuk memilih hanya pita RGB. Pengode tidak dapat mengenkode empat pita sebagai PNG.


Integrasi peta: Menampilkan petak peta dengan MapLibre GL

Pustaka peta seperti MapLibre GL, Leaflet, dan OpenLayers dapat menampilkan petak peta raster. Tantangan utamanya adalah menambahkan header otorisasi ke permintaan petak peta, karena pustaka ini mengambil petak peta secara langsung.

Contoh MapLibre GL

MapLibre GL menyediakan transformRequest opsi untuk menyuntikkan header:

import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

// Store the current access token
let currentAccessToken = null;

function initializeMap(containerId, accessToken) {
  currentAccessToken = accessToken;
  
  const map = new maplibregl.Map({
    container: containerId,
    style: {
      version: 8,
      sources: {
        osm: {
          type: 'raster',
          tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
          tileSize: 256,
          attribution: '© OpenStreetMap contributors',
        },
      },
      layers: [{ id: 'osm', type: 'raster', source: 'osm' }],
    },
    center: [0, 0],
    zoom: 2,
    // Add authorization header to tile requests
    transformRequest: (url, resourceType) => {
      // Only add auth for GeoCatalog tile requests
      if (url.includes('geocatalog.spatio.azure.com') && currentAccessToken) {
        return {
          url,
          headers: { 'Authorization': `Bearer ${currentAccessToken}` },
        };
      }
      return { url };
    },
  });
  
  return map;
}

function addTileLayer(map, tileUrl, bounds) {
  // Remove existing layer and source if present
  if (map.getLayer('data-layer')) {
    map.removeLayer('data-layer');
  }
  if (map.getSource('data-tiles')) {
    map.removeSource('data-tiles');
  }
  
  // Add tile source
  map.addSource('data-tiles', {
    type: 'raster',
    tiles: [tileUrl],
    tileSize: 256,
    minzoom: 10,  // Many aerial collections require zoom 10+
    maxzoom: 18,
  });
  
  // Add tile layer
  map.addLayer({
    id: 'data-layer',
    type: 'raster',
    source: 'data-tiles',
  });
  
  // Zoom to bounds [west, south, east, north]
  if (bounds) {
    map.fitBounds([[bounds[0], bounds[1]], [bounds[2], bounds[3]]], { padding: 50 });
  }
}

Penting

Fungsi transformRequest ini dipanggil untuk setiap permintaan petak peta. Simpan token akses dalam variabel yang transformRequest dapat mengakses, dan memperbaruinya saat token di-refresh.


Ubin mosaik: Menampilkan citra dari seluruh koleksi

Cuplikan layar yang menunjukkan cara menampilkan petak mosaik dari koleksi.

Untuk melihat semua item dalam koleksi sebagai lapisan yang mulus, daftarkan pencarian mosaik dan gunakan ID pencarian yang dikembalikan:

const API_VERSION = '2025-04-30-preview';

/**
 * Register a mosaic search for a collection.
 * Returns a search ID that can be used to fetch mosaic tiles.
 */
async function registerMosaic(catalogUrl, collectionId, accessToken) {
  const url = `${catalogUrl}/data/mosaic/register?api-version=${API_VERSION}`;
  
  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      collections: [collectionId],
    }),
  });
  
  if (!response.ok) {
    throw new Error(`Failed to register mosaic: ${response.statusText}`);
  }
  
  const data = await response.json();
  // Note: API returns 'searchid' (lowercase), not 'searchId'
  return data.searchid;
}

/**
 * Build a mosaic tile URL template.
 */
function buildMosaicTileUrl(catalogUrl, searchId, collectionId, options = {}) {
  const { assets = 'visual' } = options;
  
  const base = `${catalogUrl}/data/mosaic/${searchId}/tiles/{z}/{x}/{y}@1x.png`;
  
  const params = new URLSearchParams();
  params.set('api-version', API_VERSION);
  params.set('tileMatrixSetId', 'WebMercatorQuad');
  params.set('collection', collectionId);
  params.set('assets', assets);
  
  return `${base}?${params.toString()}`;
}

Token SAS: Mengunduh aset mentah

SAS API menyediakan token terbatas waktu untuk mengunduh file aset mentah (GeoTIFF, COG, dan file lainnya) langsung dari Azure Blob Storage. Gunakan opsi ini saat Anda memerlukan file sumber asli daripada petak peta yang dirender.

Penting

Token SAS memungkinkan pengunduhan hanya di aplikasi browser. Karena kebijakan CORS Azure Blob Storage, browser tidak dapat membaca data blob melalui JavaScript fetch(). Lihat bagian Batasan browser .

Cuplikan layar memperlihatkan cara mengunduh aset menggunakan token SAS.

Mendapatkan token SAS

const API_VERSION = '2025-04-30-preview';

/**
 * Get a SAS token for accessing assets in a collection.
 * Returns a token string that can be appended to asset URLs.
 */
async function getCollectionSasToken(accessToken, catalogUrl, collectionId) {
  const url = `${catalogUrl}/sas/token/${collectionId}?api-version=${API_VERSION}`;
  
  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${accessToken}`,
    },
  });
  
  if (!response.ok) {
    throw new Error(`Failed to get SAS token: ${response.statusText}`);
  }
  
  const data = await response.json();
  return data.token; // SAS token string
}

Membangun URL unduhan yang ditandatangani

/**
 * Build a signed URL for downloading an asset.
 * Appends the SAS token to the asset's href.
 */
function buildSignedAssetUrl(assetHref, sasToken) {
  const separator = assetHref.includes('?') ? '&' : '?';
  return `${assetHref}${separator}${sasToken}`;
}

// Example usage:
const sasToken = await getCollectionSasToken(accessToken, catalogUrl, 'my-collection');
const assetHref = item.assets['visual'].href;
const signedUrl = buildSignedAssetUrl(assetHref, sasToken);

Memicu unduhan file

/**
 * Trigger a browser download for an asset file.
 * Works by creating a temporary anchor element.
 */
function downloadAsset(signedUrl, filename) {
  const link = document.createElement('a');
  link.href = signedUrl;
  link.download = filename || 'download';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

// Example: Download an asset
downloadAsset(signedUrl, 'aerial-image.tif');

Batasan browser

Token SAS bekerja secara berbeda di browser versus kode sisi server:

Kasus Penggunaan Browser Server-side
Unduh file (pengguna memilih tautan) ✅ Bekerja ✅ Bekerja
Membaca data blob dengan fetch() ❌ CORS diblokir ✅ Bekerja
Memproses piksel mentah di JavaScript ❌ Tidak dimungkinkan ✅ Bekerja

Unduhan browser berfungsi karena navigasi (mengklik tautan) melewati CORS. Namun, fetch() permintaan ke Azure Blob Storage diblokir karena akun penyimpanan tidak menyertakan asal aplikasi Anda dalam kebijakan CORS-nya.

Jika aplikasi Anda perlu membaca dan memproses data aset mentah di browser, terapkan proksi sisi server:

Nota

Kode berikut adalah contoh yang disederhanakan untuk mengilustrasikan pola proksi. Untuk aplikasi produksi, titik akhir proksi Anda harus mengautentikasi permintaan (misalnya, dengan meneruskan token Pembawa pengguna atau menggunakan autentikasi sesi) dan memvalidasi bahwa pengguna berwenang untuk mengakses sumber daya yang diminta.

// ❌ Browser: This fails due to CORS
const response = await fetch(signedUrl);
const data = await response.arrayBuffer(); // Error!

// ✅ Browser: Call your backend instead
const response = await fetch('/api/proxy-asset', {
  method: 'POST',
  body: JSON.stringify({ collectionId, itemId, assetName })
});
const data = await response.json(); // Works!

Backend Anda dapat mengambil blob menggunakan token SAS dan mengembalikan hasil yang diproses.


Pertimbangan pengembangan

Dukungan CORS

API GeoCatalog mencakup dukungan CORS penuh dengan Access-Control-Allow-Origin: *. Aplikasi berbasis browser dapat membuat permintaan langsung ke GeoCatalog dari asal apa pun, termasuk http://localhost selama pengembangan. Tidak diperlukan proksi atau solusi.

API mengizinkan penggunaan Authorization header dalam permintaan CORS, sehingga panggilan fetch() yang terautentikasi dapat berfungsi langsung dari JavaScript di browser.

Memilih metode akses data yang tepat

Metode Browser fetch() Unduhan Browser Server-side Terbaik untuk
Tiler API ✅ Didukung sepenuhnya ✅ Ya ✅ Ya Visualisasi peta
Token SAS ❌ CORS diblokir ✅ Ya ✅ Ya Unduhan file mentah
  • TILER API: Gunakan untuk menampilkan citra di peta. Mengembalikan petak peta PNG atau WebP yang dirender dengan dukungan CORS penuh. Lihat URL Tile dan integrasi peta.

  • Token SAS: Gunakan untuk mengunduh file sumber asli (GeoTIFF, COG). Unduhan browser berfungsi, tetapi fetch() diblokir oleh kebijakan AZURE Blob Storage CORS. Lihat token SAS untuk detail dan solusinya.

Refresh token

Token akses kedaluwarsa, biasanya setelah satu jam. Aplikasi Anda harus:

  1. Tangani kesalahan 401 dengan memperoleh token baru.
  2. Gunakan akuisisi token senyap MSAL, yang secara otomatis menyegarkan token yang kedaluwarsa.
  3. Perbarui referensi token yang digunakan oleh transformRequest.

Penanganan kesalahan

Menangani skenario kesalahan umum:

HTTP Status Penyebab Solusi
401 Token kedaluwarsa atau tidak valid Memperbarui token akses
404 Item atau koleksi tidak ditemukan Pastikan ID sudah ada
424 Petak di luar batas data Diharapkan - menangani dengan lancar

Troubleshooting

Kesalahan Penyebab Solusi
"AADSTS50011: Ketidakcocokan URL Balasan" URI pengalihan dalam kode tidak cocok dengan pendaftaran ID Microsoft Entra Menambahkan URL pengembangan Anda (misalnya, http://localhost:3000) sebagai URI pengalihan SPA di pendaftaran aplikasi Anda
Kesalahan "Cakupan tidak valid" Menggunakan URL GeoCatalog alih-alih cakupan API Gunakan https://geocatalog.spatio.azure.com/.default sebagai cakupan
401 Tidak Diizinkan pada permintaan tile Pustaka peta tidak menyertakan header autentikasi Gunakan transformRequest (MapLibre) untuk menambahkan token Pembawa; pastikan token terkini
Petak peta tidak sejajar dengan peta dasar Matriks petak yang salah Gunakan tileMatrixSetId=WebMercatorQuad untuk proyeksi Web Mercator (EPSG:3857)
"Tidak dapat mendekode gambar" Nama aset, citra multiband, atau tingkat data luar yang salah Periksa item_assets untuk nama yang sah; gunakan asset_bidx=image\|1,2,3 untuk RGB; diharapkan 404/424 muncul di luar cakupan.

Langkah selanjutnya