Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In dieser Schnellstartanleitung erstellen Sie eine Webanwendung, die Satellitenbilder und Geospatialdaten aus Ihrem GeoCatalog auf einer interaktiven Karte anzeigt. Sie authentifizieren Benutzer mit Microsoft Entra ID, fragen STAC-Sammlungen ab und rendern Kartenkacheln – alles von Browser-JavaScript aus.
Was Sie lernen:
- Authentifizieren von Benutzern und Erwerben von Zugriffstoken mithilfe von MSAL.js
- Abfragen der STAC-API zum Ermitteln von Sammlungen und Elementen
- Anzeigen von Rasterkacheln auf einer MapLibre GL-Karte mit Autorisierungsheadern
- Erstellen nahtloser Mosaikschichten über ganze Sammlungen hinweg
- Herunterladen von Rohressourcen mithilfe von SAS-Token
Die Codemuster funktionieren mit jedem modernen JavaScript-Framework (React, Vue, Angular) oder Vanille-JavaScript. GeoCatalog-APIs verfügen über vollständige CORS-Unterstützung, sodass Sie sie während der localhost Entwicklung direkt aufrufen können – kein Proxy erforderlich.
Sie können diesen Code aus dem öffentlichen GitHub-Repository von Microsoft Planetary Computer Pro herunterladen und testen.
Voraussetzungen
- Ein Azure-Konto mit einem aktiven Abonnement. Kostenlos ein Konto erstellen.
- Eine bereitgestellte GeoCatalog-Ressource mit mindestens einer Sammlung, die Elemente enthält.
- Ihre Benutzeridentität muss über den GeoCatalog Reader (oder höher) Zugriff auf die GeoCatalog-Ressource verfügen. Siehe Verwalten des Zugriffs auf eine GeoCatalog-Ressource.
- Node.js Version 18 oder höher.
Architekturübersicht
Eine typische GeoCatalog-Webanwendung folgt dieser Architektur:
Registrieren Ihrer Anwendung in der Microsoft Entra-ID
Bevor Ihre Webanwendung Benutzer authentifizieren kann, registrieren Sie sie in der Microsoft Entra-ID. Diese Schnellstartanleitung verwendet eine Single Page Application (SPA) -Registrierung, die ideal für clientseitige JavaScript-Anwendungen und lokale Entwicklung ist. Die in späteren Schritten gezeigten API-Integrationsmuster funktionieren mit jedem beliebigen Anwendungstyp.
Hinweis
Für Produktionsanwendungen mit einem Back-End-Server sollten Sie einen anderen Registrierungstyp (Web, Native usw.) auswählen. Informationen zum Auswählen des richtigen Ansatzes für Ihr Szenario finden Sie unter Konfigurieren der Anwendungsauthentifizierung .
Registrieren als Einzelseitenanwendung
- Wechseln Sie im Azure-Portal zur Microsoft Entra-ID .
- Wählen Sie im seitlichen Bereich App-Registrierungen aus.
- Wählen Sie Neue Registrierung aus.
- Geben Sie einen Namen für Ihre Anwendung ein (z. B. "GeoCatalog Web App").
- Wählen Sie unter Unterstützte Kontotypen die Option Nur Konten in diesem Organisationsverzeichnis aus.
- Wählen Sie unter Umleitungs-URIdie Einzelseitenanwendung (Single Page Application, SPA) aus, und geben Sie Ihre Entwicklungs-URL ein (z. B
http://localhost:5173. ). - Wählen Sie Registrieren aus.
Notieren Sie sich nach der Registrierung die folgenden Werte auf der Seite "Übersicht ":
- Anwendungs-ID (Client)
- Verzeichnis-ID (Mandant)
Weitere Informationen finden Sie unter Schnellstart-App-Registrierung überprüfen.
Erteilen von API-Berechtigungen
Ihre Anwendung benötigt die Berechtigung, die GeoCatalog-API im Namen der angemeldeten Benutzer aufzurufen:
- Wählen Sie in Ihrer App-Registrierung API-Berechtigungen>"Berechtigung hinzufügen" aus.
- Wählen Sie APIs aus, die meine Organisation verwendet und nach Azure Orbital Spatio sucht.
- Wählen Sie delegierte Berechtigungen aus, und überprüfen Sie user_impersonation.
- Wählen Sie "Berechtigungen hinzufügen" aus.
- Wenn Sie ein Administrator sind, wählen Sie "Administratorzustimmung erteilen " aus, um im Namen aller Benutzer in Ihrem Mandanten zuzustimmen.
Konfigurieren der Anwendung
Ihre Anwendung benötigt die folgenden Konfigurationswerte. Wie Sie diese Werte bereitstellen, hängt von der Erstellungstools (Umgebungsvariablen, Konfigurationsdateien usw.) ab:
| Konfiguration | Wert | Description |
|---|---|---|
| Katalog-URL | https://{name}.{region}.geocatalog.spatio.azure.com |
Ihr GeoCatalog-Endpunkt |
| Mieter-ID | Aus der App-Registrierung | Ihr Microsoft Entra-Mandant |
| Kunden-ID | Von App-Registrierung | Client-ID Ihrer Anwendung |
| API-Bereich | https://geocatalog.spatio.azure.com/.default |
Verwenden Sie immer diesen genauen Wert. |
Installieren von Abhängigkeiten
Installieren Sie die Microsoft Authentication Library (MSAL) für Browseranwendungen und eine Kartenbibliothek:
npm install @azure/msal-browser maplibre-gl
- @azure/msal-browser – Behandelt die OAuth 2.0-Authentifizierung mit Microsoft Entra ID
- maplibre-gl – Open-Source-Kartenbibliothek für die Kachelvisualisierung
Tipp
Projektstruktur: Die Codebeispiele in dieser Schnellstartanleitung sind eigenständige Funktionen, die Sie nach Belieben organisieren können. Ein gängiges Muster:
-
auth.js: MSAL-Konfigurations- und Tokenfunktionen -
api.js: STAC-API, Tiler-API und SAS-Tokenfunktionen -
map.js: MapLibre-Initialisierung und Kachelebenenverwaltung -
App.jsodermain.js: Integrieren Sie alles in Ihre Benutzeroberfläche.
Jede Funktion empfängt ihre Abhängigkeiten (Zugriffstoken, URLs) als Parameter, wodurch sie leicht in eine beliebige Framework- oder Projektstruktur integriert werden können.
Implementieren der MSAL-Authentifizierung
Konfigurieren Sie MSAL für die Browserauthentifizierung. Das folgende Beispiel zeigt das Schlüsselkonfigurations- und Tokenakquisitionsmuster:
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: Abfragen von Sammlungen und Elementen
Die GEOCatalog STAC-API stellt Endpunkte zum Ermitteln und Abfragen von Geospatialdaten bereit. Für alle Anforderungen ist ein Authorization Header mit einem Bearer-Token erforderlich, das aus der Implementierung der MSAL-Authentifizierung abgerufen wurde.
Sammlungen auflisten
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
}
Auflistung von Elementen in einer Sammlung
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
}
Sammlungen durchsuchen
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,
});
Kachel-URLs: Erstellen von URLs für die Kartenvisualisierung
Die GeoCatalog Tiler-API dient Rasterdaten als Kartenkacheln. Erstellen Sie Kachel-URLs mit dem folgenden Muster:
Kacheln für einzelne Elemente
{catalogUrl}/data/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
?api-version=2025-04-30-preview
&tileMatrixSetId=WebMercatorQuad
&assets=visual
URL-Generator für Kacheln
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' }
);
Wichtige Kachelparameter
| Parameter | Erforderlich | Description |
|---|---|---|
api-version |
Yes | API-Version (2025-04-30-preview) |
tileMatrixSetId |
Yes | Verwenden Sie WebMercatorQuad für Webkarten |
assets |
Yes | Zu rendernde Objektnamen (Beispiel: visual, image) |
colormap_name |
Nein | Benannte Colormap (Beispiel: viridis, terrain) |
rescale |
Nein | Wertbereich für skalierung (Beispiel: 0,255) |
asset_bidx |
Nein | Bandindizes (Beispiel: image\|1,2,3 für RGB) |
Hinweis
Verwenden Sie asset_bidx=image|1,2,3, um nur die RGB-Bänder für Sammlungen mit vier Bandbildern (z. B. NAIP mit RGB + NIR) auszuwählen. Der Tiler kann vier Bänder nicht als PNG codieren.
Kartenintegration: Anzeigen von Kacheln mit MapLibre GL
Kartenbibliotheken wie MapLibre GL, Leaflet und OpenLayers können Rasterkacheln anzeigen. Die wichtigste Herausforderung besteht darin, Autorisierungsheader zu Kachelanforderungen hinzuzufügen, da diese Bibliotheken Kacheln direkt abrufen.
MapLibre GL-Beispiel
MapLibre GL bietet eine transformRequest Option zum Einfügen von Headern:
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 });
}
}
Von Bedeutung
Die transformRequest Funktion wird für jede Kachelanforderung aufgerufen. Speichern Sie das Zugriffstoken in einer Variablen, auf die transformRequest zugegriffen werden kann, und aktualisieren Sie es, wenn das Token aktualisiert wird.
Mosaikkacheln: Sammlungsweite Bilder anzeigen
Um alle Elemente in einer Sammlung als nahtlose Ebene anzuzeigen, registrieren Sie eine Mosaiksuche, und verwenden Sie die zurückgegebene Such-ID:
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()}`;
}
SAS-Token: Rohressourcen herunterladen
Die SAS-API stellt zeitlich begrenzte Token zum Herunterladen von Rohobjektdateien (GeoTIFFs, COGs und anderen Dateien) direkt aus Azure Blob Storage bereit. Verwenden Sie diese Option, wenn Sie die ursprünglichen Quelldateien anstelle gerenderter Kacheln benötigen.
Von Bedeutung
SAS-Token aktivieren Downloads nur in Browseranwendungen. Aufgrund von Azure Blob Storage CORS-Richtlinien können Browser BLOB-Daten nicht über JavaScript fetch()lesen. Weitere Informationen finden Sie im Abschnitt " Browserbeschränkungen ".
Abrufen eines SAS-Tokens
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
}
Erstellen einer signierten Download-URL
/**
* 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);
Auslösen eines Dateidownloads
/**
* 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');
Browserbeschränkungen
SAS-Token funktionieren in Browsern anders als serverseitiger Code:
| Anwendungsfall | Browser | Serverseitig |
|---|---|---|
| Dateien herunterladen (Benutzer wählt den Link aus) | ✅ Funktioniert | ✅ Funktioniert |
Lesen von BLOB-Daten über fetch() |
❌ CORS blockiert | ✅ Funktioniert |
| Verarbeiten von Rohpixeln in JavaScript | ❌ Nicht möglich | ✅ Funktioniert |
Browserdownloads funktionieren, da die Navigation (Klicken auf Links) CORS umgeht. Anforderungen an Azure Blob Storage werden jedoch blockiert, fetch() da das Speicherkonto den Ursprung Ihrer Anwendung nicht in die CORS-Richtlinie einschließt.
Wenn Ihre Anwendung rohe Ressourcendaten im Browser lesen und verarbeiten muss, implementieren Sie einen serverseitigen Proxy:
Hinweis
Der folgende Code ist ein vereinfachtes Beispiel zur Veranschaulichung des Proxymusters. Bei Produktionsanwendungen sollte Ihr Proxyendpunkt Anforderungen authentifizieren (z. B. durch Weiterleiten des Bearertokens des Benutzers oder mithilfe der Sitzungsauthentifizierung) und überprüfen, ob der Benutzer berechtigt ist, auf die angeforderten Ressourcen zuzugreifen.
// ❌ 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!
Ihr Back-End kann das Blob mithilfe des SAS-Tokens abrufen und verarbeitete Ergebnisse zurückgeben.
Überlegungen zur Entwicklung
CORS-Support
GeoCatalog-APIs enthalten vollständige CORS-Unterstützung mit Access-Control-Allow-Origin: *. Browserbasierte Anwendungen können direkt Anfragen an GeoCatalog von jedem Ursprung aus senden, einschließlich http://localhost während der Entwicklung. Es ist kein Proxy oder keine Problemumgehung erforderlich.
Die API ermöglicht den Authorization Header in CORS-Anforderungen, sodass authentifizierte Aufrufe fetch() direkt über Browser-JavaScript funktionieren.
Auswählen der richtigen Datenzugriffsmethode
| Methode | Browser fetch() |
Browser-Downloads | Serverseitig | Am besten geeignet für |
|---|---|---|---|---|
| Tiler-API | ✅ Vollständig unterstützt | ✅ Ja | ✅ Ja | Kartenvisualisierung |
| SAS-Token | ❌ CORS blockiert | ✅ Ja | ✅ Ja | Downloads von Rohdateien |
Tiler-API: Wird zum Anzeigen von Bildern auf Karten verwendet. Gibt gerenderte PNG- oder WebP-Kacheln mit vollständiger CORS-Unterstützung zurück. Siehe Kachel-URLs und Kartenintegration.
SAS-Token: Wird zum Herunterladen ursprünglicher Quelldateien (GeoTIFFs, COGs) verwendet. Browser-Downloads funktionieren, werden jedoch
fetch()durch Azure Blob Storage CORS-Richtlinien blockiert. Details und Problemumgehungen finden Sie unter SAS-Token .
Tokenaktualisierung
Zugriffstoken laufen in der Regel nach einer Stunde ab. Ihre Anwendung sollte:
- Beheben Sie 401-Fehler, indem Sie ein neues Token abrufen.
- Verwenden Sie den stillen Tokenerwerb von MSAL, der abgelaufene Token automatisch aktualisiert.
- Aktualisieren Sie den Tokenverweis
transformRequest, der von Ihrer Karte verwendet wird.
Fehlerbehandlung
Behandeln allgemeiner Fehlerszenarien:
| HTTP-Status | Ursache | Lösung |
|---|---|---|
| 401 | Token abgelaufen oder ungültig | Aktualisieren des Zugriffstokens |
| 404 | Element oder Sammlung nicht gefunden | Überprüfen, ob IDs vorhanden sind |
| 424 | Kachel außerhalb des Datenbereichs | Erwartet – vorsichtiger Umgang |
Problembehandlung
| Fehler | Ursache | Lösung |
|---|---|---|
| AADSTS50011: Reply-URL-Nichtübereinstimmung | Die Umleitungs-URI im Code stimmt nicht mit der Registrierung bei Microsoft Entra ID überein. | Fügen Sie Ihre Entwicklungs-URL (z. B http://localhost:3000. ) als SPA-Umleitungs-URI in Ihrer App-Registrierung hinzu. |
| Fehler "Ungültiger Gültigkeitsbereich" | Verwenden der GeoCatalog-URL anstelle des API-Geltungsbereichs | Verwenden Sie https://geocatalog.spatio.azure.com/.default als Bereich |
| 401 Nicht autorisiert für Kachel-Anfragen | Kartenbibliothek ohne Authentifizierungsheader | Verwenden Sie transformRequest (MapLibre), um das Bearertoken hinzuzufügen. Stellen Sie sicher, dass das Token aktuell ist. |
| Die Kacheln sind nicht mit dem Basiskartenlayout ausgerichtet. | Falscher Kachelmatrixsatz | Verwenden Sie tileMatrixSetId=WebMercatorQuad für die Web Mercator-Projektion (EPSG:3857) |
| "Bild konnte nicht decodiert werden" | Falscher Objektname, Multibandabbildung oder außerhalb des Datenbereichs | Überprüfen Sie item_assets auf gültige Namen; verwenden Sie asset_bidx=image\|1,2,3 für RGB; 404/424 außerhalb der Abdeckung wird erwartet |