Share via


Quickstart: Een webtoepassing bouwen met Microsoft Planetary Computer Pro

In deze quickstart bouwt u een webtoepassing die satellietbeelden en georuimtelijke gegevens uit uw GeoCatalog op een interactieve kaart weergeeft. U verifieert gebruikers met Microsoft Entra ID, query's uitvoeren op STAC-verzamelingen en kaarttegels weergeven, allemaal vanuit javaScript in de browser.

Wat u leert:

  • Gebruikers verifiëren en toegangstokens verkrijgen met behulp van MSAL.js
  • Query's uitvoeren op de STAC-API om verzamelingen en items te detecteren
  • Rastertegels weergeven op een MapLibre GL-kaart met autorisatieheaders
  • Naadloze mozaïeklagen maken in hele verzamelingen
  • Onbewerkte assets downloaden met SAS-tokens

De codepatronen werken met elk modern JavaScript-framework (React, Vue, Angular) of vanille JavaScript. GeoCatalog-API's hebben volledige CORS-ondersteuning, zodat u ze rechtstreeks localhost tijdens de ontwikkeling kunt aanroepen. Er is geen proxy vereist.

U kunt deze code downloaden en testen vanuit de openbare GitHub-opslagplaats van Microsoft Planetary Computer Pro.

Vereiste voorwaarden

Overzicht van architectuur

Een typische GeoCatalog-webtoepassing volgt deze architectuur:

Diagram van de architectuur van een GeoCatalog-webtoepassing met een browserclient die verbinding maakt met Microsoft Entra-id voor verificatie en met GeoCatalog-API's voor gegevenstoegang.

Uw toepassing registreren in Microsoft Entra-id

Voordat uw webtoepassing gebruikers kan verifiëren, registreert u deze in Microsoft Entra-id. In deze quickstart wordt gebruikgemaakt van een spa-registratie (Single Page Application), wat ideaal is voor JavaScript-toepassingen aan de clientzijde en lokale ontwikkeling. De API-integratiepatronen die in latere stappen worden weergegeven, werken met elk toepassingstype.

Opmerking

Voor productietoepassingen met een back-endserver kunt u een ander registratietype kiezen (web, systeemeigen, enzovoort). Zie Toepassingsverificatie configureren voor hulp bij het kiezen van de juiste benadering voor uw scenario.

Registreren als een toepassing met één pagina

  1. Ga naar Microsoft Entra-id in Azure Portal.
  2. Selecteer App-registraties in het zijpaneel.
  3. Selecteer Nieuwe registratie.
  4. Voer een naam in voor uw toepassing (bijvoorbeeld 'GeoCatalog-web-app').
  5. Onder Ondersteunde accounttypen selecteert u Enkel accounts in deze organisatieadreslijst.
  6. Selecteer onder Omleidings-URIde optie Toepassing met één pagina (SPA) en voer uw ontwikkelings-URL in (bijvoorbeeld http://localhost:5173).
  7. Selecteer Registreren.

Noteer na de registratie de volgende waarden op de pagina Overzicht :

  • Applicatie (cliënt) ID
  • Directory (huurder) ID

Raadpleeg de quickstart-app-registratie voor meer informatie.

API-machtigingen verlenen

Uw toepassing heeft toestemming nodig om de GeoCatalog-API aan te roepen namens aangemelde gebruikers:

  1. Selecteer API-machtigingen>toevoegen in uw app-registratie.
  2. Selecteer API's die mijn organisatie gebruikt en zoek naar Azure Orbital Spatio.
  3. Selecteer Gedelegeerde machtigingen en controleer user_impersonation.
  4. Selecteer Machtigingen toevoegen.
  5. Als u een beheerder bent, selecteert u Beheerderstoestemming verlenen voor toestemming namens alle gebruikers in uw tenant.

Uw toepassing configureren

Uw toepassing heeft de volgende configuratiewaarden nodig. Hoe u deze waarden opgeeft, is afhankelijk van uw buildhulpprogramma's (omgevingsvariabelen, configuratiebestanden, enzovoort):

Configuratie Waarde Description
Catalogus-URL https://{name}.{region}.geocatalog.spatio.azure.com Uw GeoCatalog-eindpunt
Huurder-ID Vanuit de app-registratie Uw Microsoft Entra-tenant
Klant-ID Vanaf app-registratie De client-id van uw toepassing
API-bereik https://geocatalog.spatio.azure.com/.default Gebruik altijd deze exacte waarde

Afhankelijkheden installeren

Installeer de Microsoft Authentication Library (MSAL) voor browsertoepassingen en een kaartbibliotheek:

npm install @azure/msal-browser maplibre-gl
  • @azure/msal-browser - Verwerkt OAuth 2.0-verificatie met Microsoft Entra-id
  • maplibre-gl - Opensource-kaartbibliotheek voor tegelvisualisatie

Aanbeveling

Projectstructuur: De codevoorbeelden in deze quickstart zijn zelfstandige functies die u kunt ordenen zoals u dat wilt. Een veelvoorkomend patroon:

  • auth.js: MSAL-configuratie- en tokenfuncties
  • api.js: STAC API-, Tiler-API- en SAS-tokenfuncties
  • map.js: MapLibre initialisatie en tegellaagbeheer
  • App.js of main.js: Alles verbinden met uw gebruikersinterface

Elke functie ontvangt de afhankelijkheden (toegangstokens, URL's) als parameters, waardoor ze eenvoudig kunnen worden geïntegreerd in een framework of projectstructuur.

MSAL-verificatie implementeren

Schermopname van de verificatiestroom in een voorbeeldwebtoepassing.

MSAL configureren voor browserverificatie. In het volgende voorbeeld ziet u het sleutelconfiguratie- en tokenverwervingspatroon:

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: Verzamelingen en items opvragen

De GeoCatalog STAC-API biedt eindpunten voor het detecteren en opvragen van georuimtelijke gegevens. Alle aanvragen vereisen een Authorization header met een Bearer-token dat is verkregen via MSAL-verificatie implementeren.

Verzamelingen weergeven

Schermopname van de lijst met STAC-verzamelingen in een voorbeeldwebtoepassing.

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
}

Lijstitems in een verzameling

Schermopname van de lijst met STAC-items in een voorbeeldwebtoepassing.

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
}

Zoeken in verschillende verzamelingen

Schermopname die laat zien hoe u de STAC-zoekopdracht gebruikt om interessante items te retourneren.

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,
});

Tegel-URL's: URL's bouwen voor kaartvisualisatie

De GeoCatalog Tiler-API levert rastergegevens als kaarttegels. Tegel-URL's maken met het volgende patroon:

Tegels met één item

Schermopname van het weergeven van tegels voor één item.

{catalogUrl}/data/collections/{collectionId}/items/{itemId}/tiles/{z}/{x}/{y}@1x.png
  ?api-version=2025-04-30-preview
  &tileMatrixSetId=WebMercatorQuad
  &assets=visual

Tegel-URL-opbouwfunctie

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' }
);

Sleuteltegelparameters

Kenmerk Verplicht Description
api-version Yes API-versie (2025-04-30-preview)
tileMatrixSetId Yes Gebruiken WebMercatorQuad voor webkaarten
assets Yes Assetnamen die moeten worden weergegeven (voorbeeld: visual, image)
colormap_name Nee. Benoemde colormap (voorbeeld: viridis, terrain)
rescale Nee. Waardebereik voor schalen (bijvoorbeeld: 0,255)
asset_bidx Nee. Bandindexen (bijvoorbeeld: image\|1,2,3 voor RGB)

Opmerking

Voor verzamelingen met vier-bandafbeeldingen (zoals NAIP met RGB + NIR) kunt asset_bidx=image|1,2,3 u alleen de RGB-banden selecteren. Tiler kan vier banden niet coderen als PNG.


Kaartintegratie: Tegels weergeven met MapLibre GL

Kaartbibliotheken zoals MapLibre GL, Folder en OpenLayers kunnen rastertegels weergeven. De belangrijkste uitdaging is het toevoegen van autorisatieheaders aan tegelaanvragen, omdat deze bibliotheken tegels rechtstreeks ophalen.

Voorbeeld van MapLibre GL

MapLibre GL biedt een transformRequest optie voor het injecteren van headers:

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 });
  }
}

Belangrijk

De transformRequest functie wordt aangeroepen voor elke tegelaanvraag. Sla het toegangstoken op in een variabele die transformRequest kan benaderen, en werk de variabele bij wanneer het token wordt vernieuwd.


Mozaïektegels: Weergave van collectiebrede afbeeldingen

Schermopname van het weergeven van mozaïektegels voor een verzameling.

Als u alle items in een verzameling wilt weergeven als een naadloze laag, registreert u een mozaïekzoekopdracht en gebruikt u de geretourneerde zoek-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-tokens: originele assets downloaden

De SAS-API biedt tijdgebonden tokens voor het downloaden van onbewerkte assetbestanden (GeoTIFF's, COG's en andere bestanden) rechtstreeks vanuit Azure Blob Storage. Gebruik deze optie wanneer u de oorspronkelijke bronbestanden nodig hebt in plaats van weergegeven tegels.

Belangrijk

SAS-tokens schakelen in browsertoepassingen uitsluitend downloads in. Vanwege CORS-beleid voor Azure Blob Storage kunnen browsers geen blobgegevens lezen via JavaScript fetch(). Zie de sectie Browserbeperkingen .

Schermopname van het downloaden van assets met behulp van een SAS-token.

Een SAS-token ophalen

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
}

Een ondertekende download-URL bouwen

/**
 * 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);

Een bestand downloaden activeren

/**
 * 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');

Browserbeperkingen

SAS-tokens werken anders in browsers versus code aan de serverzijde:

Gebruikssituatie Browser Aan de serverzijde
Bestanden downloaden (gebruiker selecteert koppeling) ✅ Werkt ✅ Werkt
Blobgegevens lezen via fetch() ❌ CORS geblokkeerd ✅ Werkt
Onbewerkte pixels verwerken in JavaScript ❌ Niet mogelijk ✅ Werkt

Browserdownloads werken omdat navigeren (klikken op koppelingen) CORS omzeilt. fetch() Aanvragen voor Azure Blob Storage worden echter geblokkeerd omdat het opslagaccount de oorsprong van uw toepassing niet bevat in het CORS-beleid.

Als uw toepassing onbewerkte assetgegevens in de browser moet lezen en verwerken, implementeert u een proxy aan de serverzijde:

Opmerking

De volgende code is een vereenvoudigd voorbeeld om het proxypatroon te illustreren. Voor productietoepassingen moet uw proxy-eindpunt aanvragen verifiëren (bijvoorbeeld door het Bearer-token van de gebruiker door te sturen of sessieverificatie te gebruiken) en valideren dat de gebruiker gemachtigd is voor toegang tot de aangevraagde resources.

// ❌ 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!

Uw back-end kan de blob ophalen met behulp van het SAS-token en verwerkte resultaten retourneren.


Overwegingen voor ontwikkeling

CORS-ondersteuning

GeoCatalog-API's bevatten volledige CORS-ondersteuning met Access-Control-Allow-Origin: *. Browsertoepassingen kunnen rechtstreeks verzoeken indienen bij GeoCatalog vanuit elke herkomst, inclusief http://localhost tijdens de ontwikkeling. Er is geen proxy of tijdelijke oplossing vereist.

Met de API kan de Authorization header in CORS-aanvragen worden gebruikt. Geverifieerde fetch() aanroepen werken dus rechtstreeks vanuit javaScript in de browser.

De juiste methode voor gegevenstoegang kiezen

Methode Browser fetch() Browserdownloads Aan de serverzijde Geschikt voor
Tiler-API ✅ Volledig ondersteund ✅ Ja ✅ Ja Kaartvisualisatie
SAS-tokens ❌ CORS geblokkeerd ✅ Ja ✅ Ja Onbewerkt bestand wordt gedownload
  • Tiler-API: gebruiken voor het weergeven van afbeeldingen op kaarten. Retourneert weergegeven PNG- of WebP-tegels met volledige CORS-ondersteuning. Zie Tegel-URL's en Kaartintegratie.

  • SAS-tokens: gebruiken voor het downloaden van oorspronkelijke bronbestanden (GeoTIFF's, COG's). Browser downloadt werk, maar fetch() wordt geblokkeerd door CORS-beleid voor Azure Blob Storage. Zie SAS-tokens voor meer informatie en tijdelijke oplossingen.

Token vernieuwen

Toegangstokens verlopen doorgaans na één uur. Uw toepassing moet:

  1. 401-fouten verwerken door een nieuw token te verkrijgen.
  2. Gebruik de stille tokenverwerving van MSAL, waarmee verlopen tokens automatisch worden vernieuwd.
  3. Werk de tokenreferentie bij die wordt gebruikt door het transformRequest van je kaart.

Foutafhandeling

Veelvoorkomende foutscenario's verwerken:

HTTP-status Oorzaak Solution
401 Token is verlopen of ongeldig Het toegangstoken vernieuwen
404 Item of verzameling is niet gevonden Controleren of er id's bestaan
424 Tegel buiten gegevensbereik Verwacht - op een nette manier afhandelen

Probleemoplossingsproces

Fout Oorzaak Solution
"AADSTS50011: Antwoord-URL komt niet overeen" Omleidings-URI in code komt niet overeen met registratie van Microsoft Entra-id Voeg uw development-URL (bijvoorbeeld http://localhost:3000) toe als een SPA-omleidings-URI in uw app-registratie.
Fout 'Ongeldig bereik' GeoCatalog-URL gebruiken in plaats van API-bereik Gebruik https://geocatalog.spatio.azure.com/.default als bereik
401 Niet geautoriseerd voor tegelaanvragen Kaartbibliotheek bevat geen authenticatie-headers Gebruik transformRequest (MapLibre) om het Bearer-token toe te voegen; zorg ervoor dat het token actueel is
Tegels zijn niet uitgelijnd met de basiskaart. Verkeerde tegelmatrixset Gebruiken tileMatrixSetId=WebMercatorQuad voor Web Mercator-projectie (EPSG:3857)
"Kan afbeelding niet decoderen" Verkeerde assetnaam, multibandafbeeldingen of externe gegevensruimte Controleer item_assets op geldige namen; gebruik asset_bidx=image\|1,2,3 voor RGB; 404/424 buiten dekking wordt verwacht

Volgende stappen