Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här snabbstarten skapar du ett webbprogram som visar satellitbilder och geospatiala data från din GeoCatalog på en interaktiv karta. Du autentiserar användare med Microsoft Entra-ID, förfrågar STAC-samlingar och renderar kartplattor – allt från webbläsaren JavaScript.
Det här lär du dig:
- Autentisera användare och hämta åtkomsttoken med hjälp av MSAL.js
- Anropa STAC-API för att upptäcka samlingar och föremål
- Visa rasterpaneler på en MapLibre GL-karta med auktoriseringshuvuden
- Skapa sömlösa mosaikskikt i hela samlingar
- Ladda ned råtillgångar med hjälp av SAS-token
Kodmönstren fungerar med alla moderna JavaScript-ramverk (React, Vue, Angular) eller vanilj-JavaScript. GeoCatalog-API:er har fullständigt CORS-stöd, så du kan anropa dem direkt från localhost under utvecklingen – ingen proxy krävs.
Du kan ladda ned och testa den här koden från den offentliga GitHub-lagringsplatsen Microsoft Planetary Computer Pro.
Förutsättningar
- Ett Azure-konto med en aktiv prenumeration. Skapa ett konto kostnadsfritt.
- En distribuerad GeoCatalog-resurs med minst en samling som innehåller objekt.
- Din användaridentitet måste ha GeoCatalog Reader (eller högre) åtkomst till GeoCatalog-resursen. Se Hantera åtkomst till en GeoCatalog-resurs.
- Node.js version 18 eller senare.
Översikt över arkitektur
Ett typiskt GeoCatalog-webbprogram följer den här arkitekturen:
Registrera ditt program i Microsoft Entra-ID
Innan webbprogrammet kan autentisera användare registrerar du det i Microsoft Entra-ID. Den här snabbstarten använder en SPA-registrering (Single Page Application), som är perfekt för JavaScript-program på klientsidan och lokal utveckling. API-integreringsmönstren som visas i senare steg fungerar med alla programtyper.
Anmärkning
För produktionsapplikationer med en backend-server bör du överväga att välja en annan registreringstyp (Web, Native osv.). Se Konfigurera programautentisering för vägledning om hur du väljer rätt metod för ditt scenario.
Registrera som en enkeltsidesapplikation
- Gå till Microsoft Entra-ID i Azure-portalen.
- Välj Appregistreringar på sidopanelen.
- Välj Ny registrering.
- Ange ett namn för ditt program (till exempel "GeoCatalog Web App").
- Under Kontotyper som stöds, välj Endast konton i den här organisationskatalogen.
- Under Omdirigerings-URI väljer du Enkelsidigt program (SPA) och anger din utvecklings-URL (till exempel
http://localhost:5173). - Välj Registrera.
Observera följande värden på sidan Översikt efter registreringen:
- Applikations-ID (klient)
- Katalog-ID (hyresgäst)
Mer information finns i snabbstartsguide för appregistrering.
Bevilja API-behörigheter
Ditt program behöver behörighet att anropa GeoCatalog-API:et för inloggade användare:
- I appregistreringen väljer du API-behörigheter>Lägg till en behörighet.
- Välj API:er som min organisation använder och sök efter Azure Orbital Spatio.
- Välj Delegerade behörigheter och kontrollera user_impersonation.
- Välj Lägg till behörigheter.
- Om du är administratör väljer du Bevilja administratörsmedgivande för att godkänna för alla användare i din klientorganisation.
Konfigurera ditt program
Programmet behöver följande konfigurationsvärden. Hur du anger dessa värden beror på dina byggverktyg (miljövariabler, konfigurationsfiler och så vidare):
| Konfiguration | Värde | Description |
|---|---|---|
| Katalog-URL | https://{name}.{region}.geocatalog.spatio.azure.com |
Din GeoCatalog-endpunkt |
| Hyresgäst-ID | Från appregistrering | Din Microsoft Entra-klientorganisation |
| Klient-ID | Från appregistrering | Programmets klient-ID |
| API-omfång | https://geocatalog.spatio.azure.com/.default |
Använd alltid det här exakta värdet |
Installera beroenden
Installera Microsofts autentiseringsbibliotek (MSAL) för webbläsarprogram och ett kartbibliotek:
npm install @azure/msal-browser maplibre-gl
- @azure/msal-browser – Hanterar OAuth 2.0-autentisering med Microsoft Entra-ID
- maplibre-gl – Kartbibliotek med öppen källkod för panelvisualisering
Tips/Råd
Projektstruktur: Kodexemplen i den här snabbstarten är fristående funktioner som du kan ordna hur du vill. Ett vanligt mönster:
-
auth.js: MSAL-konfigurations- och tokenfunktioner -
api.js: FUNKTIONER för STAC API, Tiler API och SAS-token -
map.js: MapLibre-initiering och hantering av panelskikt -
App.jsellermain.js: Koppla ihop allt med ditt användargränssnitt
Varje funktion får sina beroenden (åtkomsttoken, URL:er) som parametrar, vilket gör dem enkla att integrera i alla ramverk eller projektstrukturer.
Implementera MSAL-autentisering
Konfigurera MSAL för webbläsarautentisering. I följande exempel visas mönstret för nyckelkonfiguration och tokenförvärv:
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: Frågesamlingar och objekt
GeoCatalog STAC-API:et tillhandahåller slutpunkter för identifiering och frågekörning av geospatiala data. Alla begäranden kräver ett Authorization huvud med en ägartoken som hämtats från Implementera MSAL-autentisering.
Lista samlingar
const API_VERSION = '2026-04-15';
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
}
Visa en lista över objekt i en samling
const API_VERSION = '2026-04-15';
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
}
Sök mellan samlingar
const API_VERSION = '2026-04-15';
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:er för paneler: Skapa URL:er för kartvisualisering
Api:et GeoCatalog Tiler hanterar rasterdata som kartpaneler. Skapa panel-URL:er med följande mönster:
Enstaka objektplattor
{catalogUrl}/data/mosaic/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
?api-version=2026-04-15
&tileMatrixSetId=WebMercatorQuad
&assets=visual
Url-builder-funktion för panel
const API_VERSION = '2026-04-15';
/**
* 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/mosaic/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' }
);
Nyckelplattparametrar
| Parameter | Krävs | Description |
|---|---|---|
api-version |
Yes | API-version (2026-04-15) |
tileMatrixSetId |
Yes | Använd WebMercatorQuad för webbkartor |
assets |
Yes | Tillgångsnamn som ska återges (exempel: visual, image) |
colormap_name |
Nej | Namngiven färgkarta (exempel: viridis, terrain) |
rescale |
Nej | Värdeintervall för skalning (exempel: 0,255) |
asset_bidx |
Nej | Bandindex (exempel: image\|1,2,3 för RGB) |
Anmärkning
För samlingar med fyrbandsbilder (t.ex. NAIP med RGB + NIR) använder du asset_bidx=image|1,2,3 för att endast välja RGB-banden. Tile-servern kan inte koda fyra band som PNG.
Kartintegrering: Visa paneler med MapLibre GL
Kartbibliotek som MapLibre GL, Leaflet och OpenLayers kan visa rasterpaneler. Den viktigaste utmaningen är att lägga till auktoriseringshuvuden i panelbegäranden, eftersom dessa bibliotek hämtar paneler direkt.
MapLibre GL-exempel
MapLibre GL ger ett transformRequest alternativ för att mata in rubriker:
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 });
}
}
Viktigt!
Funktionen transformRequest anropas för varje panelbegäran. Lagra åtkomsttoken i en variabel som transformRequest kan komma åt och uppdatera den när token uppdateras.
Mosaikpaneler: Visa samlingsomfattande bilder
Om du vill visa alla objekt i en samling som ett sömlöst lager registrerar du en mosaiksökning och använder det returnerade sök-ID:t:
const API_VERSION = '2026-04-15';
/**
* 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/searches/${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: Ladda ned råtillgångar
SAS-API:et tillhandahåller tidsbegränsade token för nedladdning av råa tillgångsfiler (GeoTIFF:er, KSG:er och andra filer) direkt från Azure Blob Storage. Använd det här alternativet när du behöver de ursprungliga källfilerna i stället för renderade paneler.
Viktigt!
SAS-token aktiverar endast nedladdningar i webbläsarprogram. På grund av CORS-principer för Azure Blob Storage kan webbläsare inte läsa blobdata via JavaScript fetch(). Se avsnittet Webbläsarbegränsningar .
Hämta en SAS-token
const API_VERSION = '2026-04-15';
/**
* 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
}
Skapa en signerad nedladdnings-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);
Utlösa en filnedladdning
/**
* 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');
Webbläsarbegränsningar
SAS-token fungerar annorlunda i webbläsare jämfört med kod på serversidan:
| Användningsfall | Browser | På serversidan |
|---|---|---|
| Ladda ned filer (användaren väljer länk) | ✅ Fungerar | ✅ Fungerar |
Läsa blobdata via fetch() |
❌ CORS blockerad | ✅ Fungerar |
| Bearbeta råa pixlar i JavaScript | ❌ Inte möjligt | ✅ Fungerar |
Webbläsarnedladdningar fungerar eftersom navigeringen (klicka på länkar) kringgår CORS. Begäranden till Azure Blob Storage blockeras dock fetch() eftersom lagringskontot inte inkluderar applikationens ursprung i sin CORS-princip.
Om programmet behöver läsa och bearbeta rådata i webbläsaren implementerar du en proxy på serversidan:
Anmärkning
Följande kod är ett förenklat exempel för att illustrera proxymönstret. För produktionsprogram bör proxyslutpunkten autentisera begäranden (till exempel genom att vidarebefordra användarens ägartoken eller använda sessionsautentisering) och verifiera att användaren har behörighet att komma åt de begärda resurserna.
// ❌ 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!
Serverdelen kan hämta bloben med hjälp av SAS-token och returnera bearbetade resultat.
Utvecklingsöverväganden
CORS-support
GeoCatalog-API:er innehåller fullständigt CORS-stöd med Access-Control-Allow-Origin: *. Webbläsarbaserade program kan göra direkta begäranden till GeoCatalog från alla ursprung, inklusive http://localhost under utvecklingen. Ingen proxy eller lösning krävs.
API:t tillåter Authorization-headern i CORS-begäranden, så autentiserade fetch()-anrop fungerar direkt i webbläsarens JavaScript.
Välja rätt dataåtkomstmetod
| Metod | Webbläsare fetch() |
Nedladdningar av webbläsare | På serversidan | Bäst för |
|---|---|---|---|---|
| Tiler-API | ✅ Stöds fullt ut | ✅ Ja | ✅ Ja | Kartvisualisering |
| SAS-token | ❌ CORS blockerad | ✅ Ja | ✅ Ja | Raw-filnedladdningar |
Tiler-API: Används för att visa bilder på kartor. Returnerar renderade PNG- eller WebP-paneler med fullständigt CORS-stöd. Se Panel-URL:er och Kartintegrering.
SAS-token: Används för att ladda ned ursprungliga källfiler (GeoTIFF:er, KSG:er). Webbläsarnedladdningar fungerar, men
fetch()blockeras av CORS-principer för Azure Blob Storage. Mer information och lösningar finns i SAS-token .
Tokenförnyelse
Åtkomsttoken upphör att gälla, vanligtvis efter en timme. Ditt program bör:
- Hantera 401-fel genom att hämta en ny token.
- Använd MSAL:s tysta token-anskaffning, som automatiskt förnyar förfallna token.
- Uppdatera tokenreferensen som används av kartans
transformRequest.
Felhantering
Hantera vanliga felscenarier:
| HTTP-status | Orsak | Lösning |
|---|---|---|
| 401 | Token har upphört att gälla eller är ogiltig | Uppdatera åtkomsttoken |
| 404 | Objektet eller samlingen hittades inte | Kontrollera att ID:t finns |
| 424 | Panel utanför datautbredning | Förväntat resultat – hantera situationen smidigt |
Felsökning
| Error | Orsak | Lösning |
|---|---|---|
| "AADSTS50011: Matchningsfel för svars-URL" | Omdirigerings-URI i kod matchar inte Microsoft Entra ID-registrering | Lägg till din utvecklings-URL (till exempel http://localhost:3000) som en SPA-omdirigerings-URI i din appregistrering |
| Felet "Ogiltig räckvidd" | Använda GeoCatalog-URL i stället för API-omfång | Använd https://geocatalog.spatio.azure.com/.default som omfång |
| 401 Obehörig på panelbegäranden | Mappningsbibliotek som inte innehåller autentiseringshuvuden | Använd transformRequest (MapLibre) för att lägga till ägartoken. Se till att token är aktuell |
| Paneler överensstämmer inte med baskartan | Fel kakelmatrissättning | Använda tileMatrixSetId=WebMercatorQuad för Web Mercator-projektion (EPSG:3857) |
| "Det gick inte att avkoda bilden" | Fel tillgångsnamn, flerbandsbilder eller extern datautbredning | Kontrollera item_assets för giltiga namn; använd asset_bidx=image\|1,2,3 för RGB; 404/424 utanför täckning kan förekomma |