Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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
- Sebuah akun Azure dengan langganan aktif. Buat akun secara gratis.
- Sebuah GeoCatalog resource yang diimplementasikan dengan setidaknya satu koleksi yang berisi item-item.
- Identitas pengguna Anda harus memiliki akses GeoCatalog Reader (atau lebih tinggi) ke sumber daya GeoCatalog. Lihat Mengelola akses ke sumber daya GeoCatalog.
- Node.js versi 18 atau yang lebih baru.
Gambaran umum arsitektur
Aplikasi web GeoCatalog yang khas mengikuti arsitektur ini:
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
- Buka ID Microsoft Entra di portal Microsoft Azure.
- Pilih Pendaftaran aplikasi dari panel samping.
- Pilih Pendaftaran baru.
- Masukkan nama untuk aplikasi Anda (misalnya, "GeoCatalog Web App").
- Di bawah Jenis akun yang didukung, pilih Akun di direktori organisasi ini saja.
- Di bawah URI Pengalihan, pilih Aplikasi halaman tunggal (SPA) dan masukkan URL pengembangan Anda (misalnya,
http://localhost:5173). - 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:
- Di pendaftaran aplikasi Anda, pilih Izin> APITambahkan izin.
- Pilih API yang digunakan organisasi saya dan cari Azure Orbital Spatio.
- Pilih Izin yang didelegasikan dan periksa user_impersonation.
- Pilih Tambahkan izin.
- 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.jsataumain.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
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
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
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
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
{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
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 .
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:
- Tangani kesalahan 401 dengan memperoleh token baru.
- Gunakan akuisisi token senyap MSAL, yang secara otomatis menyegarkan token yang kedaluwarsa.
- 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. |