Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
V tomto rychlém startu vytvoříte webovou aplikaci, která zobrazí satelitní snímky a geoprostorová data z geoCatalogu na interaktivní mapě. Ověřujete uživatele pomocí Microsoft Entra ID, dotazujete kolekce STAC a vykreslujete mapové dlaždice - vše z JavaScriptu prohlížeče.
Co se naučíte:
- Ověřování uživatelů a získávání přístupových tokenů pomocí MSAL.js
- Dotazování rozhraní STAC API ke zjišťování kolekcí a položek
- Zobrazení rastrových dlaždic na mapě MapLibre GL s autorizačními hlavičkami
- Vytváření bezproblémových vrstev mozaiky napříč celými kolekcemi
- Stažení surových assetů pomocí tokenů SAS
Vzory kódu fungují s jakoukoli moderní architekturou JavaScriptu (React, Vue, Angular) nebo vanilla JavaScript. Rozhraní API GeoCatalog mají plnou podporu CORS, takže je můžete volat přímo z localhost během vývoje – není nutné používat žádný proxy server.
Tento kód si můžete stáhnout a otestovat z veřejného úložiště GitHubu Microsoft Planety Computer Pro.
Požadavky
- Účet Azure s aktivním předplatným. Vytvořte si bezplatný účet.
- Nasazený prostředek GeoCatalog s alespoň jednou kolekcí obsahující položky.
- Vaše uživatelské jméno musí mít přístup GeoCatalog Reader (nebo vyšší) k prostředku GeoCatalog. Viz Jak spravovat přístup k prostředku GeoCatalog.
- Node.js verze 18 nebo novější.
Přehled architektury
Typická webová aplikace GeoCatalog se řídí touto architekturou:
Registrace aplikace v Microsoft Entra ID
Než bude vaše webová aplikace moct ověřovat uživatele, zaregistrujte ji v Microsoft Entra ID. V tomto rychlém startu se používá registrace jednostránkové aplikace (SPA), která je ideální pro javascriptové aplikace na straně klienta a místní vývoj. Vzory integrace rozhraní API uvedené v pozdějších krocích fungují s libovolným typem aplikace.
Poznámka:
U produkčních aplikací s back-endovým serverem zvažte výběr jiného typu registrace (web, nativní atd.). Pokyny k výběru správného přístupu pro váš scénář najdete v tématu Konfigurace ověřování aplikací .
Registrace jako jednostráková aplikace
- Na webu Azure Portal přejděte na ID Microsoft Entra .
- Na bočním panelu vyberte registrace aplikací .
- Vyberte Nová registrace.
- Zadejte název aplikace (například "Webová aplikace GeoCatalog").
- V části Podporované typy účtů vyberte Pouze účty v tomto organizačním adresáři.
- V části Identifikátor URI přesměrování vyberte jednostránkovou aplikaci (SPA) a zadejte adresu URL pro vývoj (například
http://localhost:5173). - Vyberte Zaregistrovat.
Po registraci si na stránce Přehled poznamenejte následující hodnoty:
- ID aplikace (klienta)
- ID adresáře (tenanta)
Další informace naleznete v rychlém startu registrace aplikace.
Udělení oprávnění rozhraní API
Vaše aplikace potřebuje oprávnění k volání rozhraní GEOCatalog API jménem přihlášených uživatelů:
- V registraci aplikace vyberte oprávnění >Přidat oprávnění.
- Vyberte rozhraní API, která moje organizace používá , a vyhledejte Azure Orbital Spatio.
- Vyberte Delegovaná oprávnění a zkontrolujte user_impersonation.
- Vyberte Přidat oprávnění.
- Pokud jste správce, vyberte Udělit souhlas správce jménem všech uživatelů ve vašem tenantovi.
Konfigurace aplikace
Vaše aplikace potřebuje následující konfigurační hodnoty. Způsob zadání těchto hodnot závisí na nástrojích sestavení (proměnné prostředí, konfigurační soubory atd.):
| Konfigurace | Hodnota | Description |
|---|---|---|
| Adresa URL katalogu | https://{name}.{region}.geocatalog.spatio.azure.com |
Koncový bod GeoCatalogu |
| Identifikátor nájemce | Z registrace aplikace | Váš tenant Microsoft Entra |
| ID klienta | Z registrace aplikace | ID klienta vaší aplikace |
| Obor rozhraní API | https://geocatalog.spatio.azure.com/.default |
Vždy používejte tuto přesnou hodnotu. |
Nainstalujte závislosti
Nainstalujte knihovnu Microsoft Authentication Library (MSAL) pro aplikace prohlížeče a knihovnu map:
npm install @azure/msal-browser maplibre-gl
- @azure/msal-browser – zpracovává ověřování OAuth 2.0 s ID Microsoft Entra
- maplibre-gl – opensourcová knihovna map pro vizualizaci dlaždic
Návod
Struktura projektu: Ukázky kódu v tomto průvodci rychlým spuštěním jsou samostatné funkce, které si můžete uspořádat podle vlastních preferencí. Běžný vzor:
-
auth.js: Konfigurační a tokenové funkce MSAL -
api.js: StaC API, rozhraní Tiler API a funkce tokenu SAS -
map.js: Inicializace MapLibre a správa vrstev dlaždic -
App.jsnebomain.js: Vše propojte s uživatelským rozhraním.
Každá funkce přijímá závislosti (přístupové tokeny, adresy URL) jako parametry a usnadňuje jejich integraci do jakékoli architektury nebo struktury projektu.
Implementace ověřování MSAL
Nakonfigurujte MSAL pro ověřování v prohlížeči. Následující příklad ukazuje model konfigurace klíče a získání tokenu:
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: Dotazování kolekcí a položek
Rozhraní API STAC GeoCatalog poskytuje koncové body pro zjišťování a dotazování geoprostorových dat. Všechny požadavky vyžadují hlavičku Authorization s Bearer tokenem získaným z Implement MSAL authentication.
Seznam kolekcí
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
}
Výpis položek v kolekci
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
}
Hledání napříč kolekcemi
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,
});
Adresy URL dlaždic: Vytvářejte adresy URL pro vizualizaci mapy
Rozhraní API GeoCatalog Tiler obsluhuje rastrová data ve formě mapových dlaždic. Vytvořte adresy URL dlaždic s následujícím vzorem:
Dlaždice s jednou položkou
{catalogUrl}/data/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
?api-version=2025-04-30-preview
&tileMatrixSetId=WebMercatorQuad
&assets=visual
Funkce generátoru adres URL dlaždic
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' }
);
Parametry důležité dlaždice
| Parameter | Povinné | Description |
|---|---|---|
api-version |
Ano | Verze rozhraní API (2025-04-30-preview) |
tileMatrixSetId |
Ano | Použití WebMercatorQuad pro webové mapy |
assets |
Ano | Názvy assetů k vykreslení (například: visual, image) |
colormap_name |
Ne | Pojmenovaná mapa barev (příklad: viridis, terrain) |
rescale |
Ne | Rozsah hodnot pro škálování (příklad: 0,255) |
asset_bidx |
Ne | Pruhové indexy (například pro image\|1,2,3 RGB) |
Poznámka:
U kolekcí se čtyřmi pásmy (například NAIP s RGB + NIR) vyberte asset_bidx=image|1,2,3 pouze pásma RGB. Tiler nemůže zakódovat čtyři pásma jako PNG.
Integrace mapy: Zobrazení dlaždic pomocí MapLibre GL
Mapové knihovny, jako jsou MapLibre GL, Leaflet a OpenLayers, můžou zobrazovat rastrové dlaždice. Klíčovým problémem je přidání autorizačních hlaviček k požadavkům na dlaždice, protože tyto knihovny dlaždice načítají přímo.
Příklad MapLibre GL
MapLibre GL poskytuje transformRequest možnost vložení hlaviček:
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 });
}
}
Důležité
Funkce transformRequest se volá pro každý požadavek na dlaždici. Uložte přístupový token do proměnné, ke které má transformRequest přístup, a aktualizujte ho, když se token obnoví.
Mozaikové dlaždice: Zobrazení kolekčních obrázků
Pokud chcete zobrazit všechny položky v kolekci jako bezproblémovou vrstvu, zaregistrujte si hledání s mozaikou a použijte vrácené ID hledání:
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()}`;
}
Tokeny SAS: Stažení surových zdrojů
Rozhraní API SAS poskytuje časově omezené tokeny pro stahování surových datových souborů (GeoTIFF, COG a dalších souborů) přímo z úložiště Azure Blob Storage. Tuto možnost použijte, pokud potřebujete původní zdrojové soubory místo vykreslených dlaždic.
Důležité
Tokeny SAS umožňují stahování jenom v aplikacích prohlížeče. Vzhledem k zásadám CORS služby Azure Blob Storage nemůžou prohlížeče číst data objektů blob prostřednictvím JavaScriptu fetch(). Viz část Omezení prohlížeče .
Získání tokenu 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
}
Vytvořte podepsanou adresu URL pro stažení
/**
* 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);
Aktivace stahování souboru
/**
* 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');
Omezení prohlížeče
Tokeny SAS fungují v prohlížečích jinak než v kódu na straně serveru:
| Případ použití | Browser | Server-side |
|---|---|---|
| Stažení souborů (uživatel vybere odkaz) | ✅ Funguje | ✅ Funguje |
Čtení blobových dat přes fetch() |
❌ CORS bylo zablokováno | ✅ Funguje |
| Zpracování nezpracovaných pixelů v JavaScriptu | ❌ Není možné | ✅ Funguje |
Stažení prohlížeče funguje, protože navigace (kliknutí na odkazy) obchází CORS. Požadavky na službu Azure Blob Storage jsou však blokovány, protože účet úložiště nezahrnuje původ vaší aplikace v zásadách CORS.
Pokud vaše aplikace potřebuje číst a zpracovávat nezpracovaná data prostředků v prohlížeči, implementujte proxy server na straně serveru:
Poznámka:
Následující kód je zjednodušený příklad, který znázorňuje vzor proxy serveru. U produkčních aplikací by měl koncový bod proxy serveru ověřovat požadavky (například předáním nosného tokenu uživatele nebo pomocí ověřování relace) a ověřit, jestli má uživatel oprávnění pro přístup k požadovaným prostředkům.
// ❌ 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!
Váš back-end může načíst objekt blob pomocí tokenu SAS a vrátit zpracované výsledky.
Aspekty vývoje
Podpora CORS
Rozhraní API GeoCatalog zahrnují plnou podporu CORS s Access-Control-Allow-Origin: *. Aplikace založené na prohlížeči můžou provádět přímé požadavky na GeoCatalog z libovolného původu, včetně http://localhost během vývoje. Nevyžaduje se žádný proxy server ani alternativní řešení.
Rozhraní API umožňuje hlavičku Authorization v požadavcích CORS, takže ověřená fetch() volání fungují přímo z JavaScriptu prohlížeče.
Výběr správné metody přístupu k datům
| Metoda | Prohlížeče fetch() |
Soubory ke stažení v prohlížeči | Server-side | Nejlepší pro |
|---|---|---|---|---|
| Rozhraní API Tiler | ✅ Plně podporovaná | ✅ Ano | ✅ Ano | Vizualizace mapy |
| Tokeny SAS | ❌ CORS blokováno | ✅ Ano | ✅ Ano | Nezpracované soubory ke stažení |
Rozhraní API tiler: Slouží k zobrazení obrázků na mapách. Vrátí vykreslené díly PNG nebo WebP s plnou podporou CORS. Vizte dlaždicové adresy URL a integraci mapy.
Tokeny SAS: Slouží ke stahování původních zdrojových souborů (GeoTIFFs, COG). Stahování v prohlížeči funguje, ale
fetch()je blokováno zásadami CORS ve službě Azure Blob Storage. Podrobnosti a alternativní řešení najdete v tokenech SAS .
Aktualizace tokenu
Platnost přístupových tokenů vyprší obvykle po jedné hodině. Vaše aplikace by měla:
- Zpracování chyb 401 získáním nového tokenu
- Použijte bezobslužné získání tokenu MSAL, které automaticky aktualizuje tokeny s vypršenou platností.
- Aktualizujte odkaz na token používaný mapou
transformRequest.
Zpracování chyb
Zpracování běžných chybových scénářů:
| Stav HTTP | Příčina | Solution |
|---|---|---|
| 401 | Platnost tokenu vypršela nebo je neplatná | Aktualizace přístupového tokenu |
| 404 | Položka nebo kolekce nebyla nalezena. | Ověřte existenci ID |
| 424 | Dlaždice mimo rozsah dat | Očekáváno - zvládnout elegantně |
Řešení problémů
| Error | Příčina | Solution |
|---|---|---|
| "AADSTS50011: Neshoda adres URL odpovědi" | Identifikátor URI pro přesměrování v kódu neodpovídá registraci v Microsoft Entra ID. | Přidejte ve vaší registraci aplikace adresu URL pro vývoj (například http://localhost:3000) jako URI pro přesměrování SPA. |
| Chyba Neplatný obor | Použití adresy URL GeoCatalog místo rozsahu API | Použít https://geocatalog.spatio.azure.com/.default jako obor |
| 401 Neautorizováno u žádostí o dlaždici | Knihovna map nezahrnuje ověřovací hlavičky | Použijte transformRequest k přidání autentizačního tokenu; ujistěte se, že token je aktuální (MapLibre). |
| Dlaždice nejsou zarovnané se základní mapou | Nesprávná souprava matic dlaždic | Použijte tileMatrixSetId=WebMercatorQuad pro projekci Web Mercator (EPSG:3857) |
| Nepodařilo se dekódovat obrázek. | Nesprávný název prostředku, multiband image nebo rozsah externích dat | Platné názvy kontrolovat pomocí item_assets, použití asset_bidx=image\|1,2,3 pro RGB, očekává se 404/424 mimo pokrytí |