Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans ce guide de démarrage rapide, vous créez une application web qui affiche des images satellites et des données géospatiales à partir de votre GeoCatalog sur une carte interactive. Vous authentifiez les utilisateurs avec l’ID Microsoft Entra, interrogez les collections STAC et affichez des vignettes de carte, toutes à partir du navigateur JavaScript.
Ce que vous apprenez :
- Authentifier les utilisateurs et acquérir des jetons d’accès à l’aide de MSAL.js
- Interroger l’API STAC pour découvrir des collections et des éléments
- Afficher des vignettes raster sur une carte MapLibre GL avec des en-têtes d’autorisation
- Créer des couches de mosaïque transparentes dans l’ensemble des collections
- Télécharger des ressources brutes à l’aide de jetons SAP
Les modèles de code fonctionnent avec n’importe quelle infrastructure JavaScript moderne (React, Vue, Angular) ou JavaScript vanille. Les API GeoCatalog disposent d’une prise en charge CORS complète. Vous pouvez donc les appeler directement depuis localhost pendant le développement, sans proxy requis.
Vous pouvez télécharger et tester ce code à partir du dépôt GitHub public Microsoft Planetary Computer Pro.
Prerequisites
- Un compte Azure avec un abonnement actif. Créez un compte gratuitement.
- Ressource GeoCatalog déployée avec au moins une collection contenant des éléments.
- Votre identité d’utilisateur doit disposer d’un accès GeoCatalog Reader (ou supérieur) à la ressource GeoCatalog. Consultez Gérer l’accès à une ressource GeoCatalog.
- Node.js version 18 ou ultérieure.
Vue d’ensemble de l’architecture
Une application web GeoCatalog classique suit cette architecture :
Inscrire votre application dans l’ID Microsoft Entra
Avant que votre application web puisse authentifier les utilisateurs, inscrivez-la dans Microsoft Entra ID. Ce guide de démarrage rapide utilise un enregistrement d'application à page unique (SPA), ce qui est idéal pour les applications JavaScript côté client et le développement local. Les modèles d’intégration d’API présentés dans les étapes ultérieures fonctionnent avec n’importe quel type d’application.
Note
Pour les applications de production avec un serveur principal, envisagez de choisir un autre type d’inscription (Web, Natif, etc.). Consultez Configurer l’authentification d’application pour obtenir des conseils sur le choix de l’approche appropriée pour votre scénario.
S’inscrire en tant qu’application à page unique
- Accédez à Microsoft Entra ID dans le portail Azure.
- Sélectionnez Inscriptions d’applications dans le volet latéral.
- Sélectionnez Nouvelle inscription.
- Entrez un nom pour votre application (par exemple, « GeoCatalog Web App »).
- Sous Types de comptes pris en charge, sélectionnez Comptes dans cet annuaire organisationnel uniquement.
- Sous URI de redirection, sélectionnez Application monopage (SPA) et entrez votre URL de développement (par exemple).
http://localhost:5173 - Sélectionnez Inscrire.
Après l’inscription, notez les valeurs suivantes dans la page Vue d’ensemble :
- ID d’application (client)
- ID de l’annuaire (locataire)
Pour plus d’informations, consultez l'enregistrement de l'application Quickstart.
Accorder des autorisations d’API
Votre application doit être autorisée à appeler l’API GeoCatalog pour le compte des utilisateurs connectés :
- Dans l’inscription de votre application, sélectionnez Autorisations d’API>Ajouter une autorisation.
- Sélectionnez les API que mon organisation utilise et recherchez Azure Orbital Spatio.
- Sélectionnez Autorisations déléguées et vérifiez user_impersonation.
- Sélectionnez Ajouter des autorisations.
- Si vous êtes administrateur, sélectionnez Accorder le consentement de l’administrateur pour le compte de tous les utilisateurs de votre locataire.
Configuration de votre application
Votre application a besoin des valeurs de configuration suivantes. La façon dont vous fournissez ces valeurs dépend de vos outils de génération (variables d’environnement, fichiers de configuration, et ainsi de suite) :
| Paramétrage | Valeur | Descriptif |
|---|---|---|
| URL du catalogue | https://{name}.{region}.geocatalog.spatio.azure.com |
Votre point de terminaison GeoCatalog |
| ID du locataire | Depuis l'inscription de l'application | Votre locataire Microsoft Entra |
| ID de client | Depuis l'inscription de l'application | ID client de votre application |
| Étendue de l’API | https://geocatalog.spatio.azure.com/.default |
Utilisez toujours cette valeur exacte |
Installer des dépendances
Installez la bibliothèque d’authentification Microsoft (MSAL) pour les applications de navigateur et une bibliothèque de cartes :
npm install @azure/msal-browser maplibre-gl
- @azure/msal-browser - Gère l’authentification OAuth 2.0 avec l’ID Microsoft Entra
- maplibre-gl - Bibliothèque de cartes open source pour la visualisation des vignettes
Conseil / Astuce
Structure du projet : Les exemples de code de ce démarrage rapide sont des fonctions autonomes que vous pouvez organiser comme vous le souhaitez. Modèle courant :
-
auth.js: fonctions de configuration MSAL et de jeton -
api.js: API STAC, API Tiler et fonctions de jeton SAS -
map.js: Initialisation mapLibre et gestion des couches de mosaïques -
App.jsoumain.js: Connectez tout avec votre interface utilisateur
Chaque fonction reçoit ses dépendances (jetons d’accès, URL) en tant que paramètres, ce qui facilite leur intégration dans n’importe quelle structure de framework ou de projet.
Implémenter l’authentification MSAL
Configurez MSAL pour l’authentification du navigateur. L’exemple suivant montre la configuration clé et le modèle d’acquisition de jeton :
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();
}
API STAC : Interroger des collections et des éléments
L’API STAC GeoCatalog fournit des points de terminaison pour découvrir et interroger des données géospatiales. Toutes les requêtes nécessitent un en-tête Authorization avec un jeton Bearer obtenu à partir de l'implémentation de l'authentification MSAL.
Lister les collections
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
}
Répertorier les éléments d’une collection
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
}
Rechercher dans plusieurs collections
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 de tuiles : Générer des URL pour la visualisation de cartes
L’API GeoCatalog Tiler sert les données raster comme vignettes cartographiques. Construire des URL de tuiles avec le modèle suivant :
Vignettes d’élément unique
{catalogUrl}/data/mosaic/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
?api-version=2026-04-15
&tileMatrixSetId=WebMercatorQuad
&assets=visual
Fonction Générateur d’URL de vignette
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' }
);
Paramètres de vignette clé
| Paramètre | Obligatoire | Descriptif |
|---|---|---|
api-version |
Oui | Version de l’API (2026-04-15) |
tileMatrixSetId |
Oui | Utiliser WebMercatorQuad pour les cartes web |
assets |
Oui | Noms des ressources à afficher (exemple : visual, image) |
colormap_name |
Non | Palette de couleurs nommée (Exemple : viridis, terrain) |
rescale |
Non | Plage de valeurs pour la mise à l’échelle (exemple : 0,255) |
asset_bidx |
Non | Index de bande (exemple : image\|1,2,3 pour RVB) |
Note
Pour les collections avec des images à quatre bandes (comme NAIP avec RVB + NIR), utilisez asset_bidx=image|1,2,3 pour sélectionner uniquement les bandes RVB. Le tiler ne peut pas encoder quatre bandes en tant que PNG.
Intégration de la carte : afficher des vignettes avec MapLibre GL
Les bibliothèques cartographiques telles que MapLibre GL, Leaflet et OpenLayers peuvent afficher des vignettes raster. Le défi clé consiste à ajouter des en-têtes d’autorisation aux demandes de vignettes, car ces bibliothèques extraient directement des vignettes.
Exemple d'utilisation de MapLibre GL
MapLibre GL offre une option transformRequest permettant d’injecter des en-têtes :
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 });
}
}
Important
La transformRequest fonction est appelée pour chaque demande de vignette. Stockez le jeton d’accès dans une variable qui transformRequest peut y accéder et mettez-le à jour lors de l’actualisation du jeton.
Mosaïques : Affichage d’images à l’échelle de la collection
Pour afficher tous les éléments d’une collection en tant que couche transparente, inscrivez une recherche en mosaïque et utilisez l’ID de recherche retourné :
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()}`;
}
Jetons SAP : télécharger des ressources brutes
L’API SAS fournit des jetons à durée limitée pour télécharger des fichiers d'actifs bruts (GeoTIFFs, COGs et autres fichiers) directement à partir du Stockage Blob Azure. Utilisez cette option lorsque vous avez besoin des fichiers sources d’origine plutôt que des vignettes rendues.
Important
Les jetons SAP activent uniquement les téléchargements dans les applications de navigateur. En raison des stratégies CORS de l'Stockage Blob Azure, les navigateurs ne peuvent pas lire les données des objets blob via JavaScript fetch(). Consultez la section Limitations du navigateur .
Obtenir un jeton SAP
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
}
Générer une URL de téléchargement signée
/**
* 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);
Déclencher un téléchargement de fichier
/**
* 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');
Limitations du navigateur
Les jetons SAP fonctionnent différemment dans les navigateurs et dans le code côté serveur :
| Cas d’usage | Browser | Server-side |
|---|---|---|
| Télécharger des fichiers (l’utilisateur sélectionne le lien) | ✅ Fonctionne | ✅ Fonctionne |
Lire les données de blob via fetch() |
❌ CORS bloqué | ✅ Fonctionne |
| Traiter les pixels bruts en JavaScript | ❌ Impossible | ✅ Fonctionne |
Les téléchargements du navigateur fonctionnent, car la navigation (en cliquant sur des liens) contourne CORS. Toutefois, les fetch() demandes adressées au stockage Blob Azure sont bloquées, car le compte de stockage n’inclut pas l’origine de votre application dans sa stratégie CORS.
Si votre application doit lire et traiter des données de ressources brutes dans le navigateur, implémentez un proxy côté serveur :
Note
Le code suivant est un exemple simplifié pour illustrer le modèle proxy. Pour les applications de production, votre point de terminaison proxy doit authentifier les demandes (par exemple, en transférant le jeton du porteur de l’utilisateur ou à l’aide de l’authentification de session) et vérifier que l’utilisateur est autorisé à accéder aux ressources demandées.
// ❌ 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!
Votre back-end peut récupérer l’objet blob à l’aide du jeton SAP et retourner les résultats traités.
Considérations relatives au développement
Prise en charge de CORS
Les API GeoCatalog incluent la prise en charge complète de CORS avec Access-Control-Allow-Origin: *. Les applications basées sur un navigateur peuvent effectuer des requêtes directes vers GeoCatalog à partir de n’importe quelle origine, y compris http://localhost pendant le développement. Aucun proxy ou solution de contournement n’est nécessaire.
L’API autorise l’en-tête Authorization dans les requêtes CORS. Les appels authentifiés fetch() fonctionnent donc directement à partir du javaScript du navigateur.
Choix de la méthode d’accès aux données appropriée
| Méthode | Navigateur fetch() |
Téléchargements du navigateur | Server-side | Idéal pour |
|---|---|---|---|---|
| Tiler API | ✅ Entièrement pris en charge | ✅ Oui | ✅ Oui | Visualisation de carte |
| Jetons SAP | ❌ CORS bloqué | ✅ Oui | ✅ Oui | Téléchargements de fichiers bruts |
API Tiler : permet d’afficher des images sur des cartes. Retourne des vignettes PNG ou WebP rendues avec prise en charge complète de CORS. Consultez URL de vignette et Intégration de la carte.
Jetons SAS : permet de télécharger des fichiers sources d’origine (GeoTIFFs, COGs). Les téléchargements du navigateur fonctionnent, mais
fetch()est bloqué par les stratégies CORS d'Stockage Blob Azure. Pour plus d’informations et de solutions de contournement, consultez les jetons SAP .
Actualisation des jetons
Les jetons d’accès expirent généralement après une heure. Votre application doit :
- Gérez les erreurs 401 en acquérant un nouveau jeton.
- Utilisez l’acquisition de jetons silencieuse de MSAL, qui actualise automatiquement les jetons expirés.
- Mettez à jour la référence de jeton utilisée par la carte
transformRequest.
Gestion des erreurs
Gérez les scénarios d’erreur courants :
| État HTTP | La cause | Solution |
|---|---|---|
| 401 | Jeton expiré ou non valide | Actualiser le jeton d’accès |
| 404 | Élément ou collection introuvable | Vérifier que les ID existent |
| 424 | Tuile en dehors de l'étendue des données | Attendu - traiter avec élégance |
Résolution des problèmes
| Erreur | La cause | Solution |
|---|---|---|
| « AADSTS50011 : Incompatibilité de l’URL de réponse » | L'URI de redirection dans le code ne correspond pas à l'enregistrement de Microsoft Entra ID | Ajoutez votre URL de développement (par exemple http://localhost:3000) en tant qu’URI de redirection SPA dans l’enregistrement de votre application |
| Erreur « Étendue non valide » | Utilisation de l’URL GeoCatalog au lieu de l’étendue de l’API | Utiliser https://geocatalog.spatio.azure.com/.default comme étendue |
| 401 Non autorisé sur les demandes de vignette | Bibliothèque de cartes sans en-têtes d'authentification | Utiliser transformRequest (MapLibre) pour ajouter le jeton du porteur ; vérifiez que le jeton est actif |
| Les vignettes ne s’alignent pas sur le mappage de base | Jeu de matrices de tuiles incorrect | Utiliser tileMatrixSetId=WebMercatorQuad pour la projection Web Mercator (EPSG :3857) |
| « Impossible de décoder l’image » | Nom de ressource incorrect, image multibande ou étendue de données externe | Recherchez des noms valides avec item_assets, utilisez asset_bidx=image\|1,2,3 pour le RVB, et attendez-vous à des erreurs 404/424 en dehors de la couverture. |