Rövid útmutató: Webalkalmazás létrehozása a Microsoft Planetary Computer Pro használatával

Ebben a rövid útmutatóban egy webalkalmazást hoz létre, amely interaktív térképen jeleníti meg a GeoCatalog műholdképeit és térinformatikai adatait. A felhasználók hitelesítése a Microsoft Entra ID használatával, a STAC-gyűjtemények lekérdezése és a térképscsempék renderelése mind a böngésző JavaScript-jéből történik.

Mit tanul meg:

  • A felhasználók hitelesítése és a hozzáférési jogkivonatok beszerzése az MSAL.js használatával.
  • A STAC API lekérdezése gyűjtemények és elemek felderítéséhez
  • Rasztercsempék megjelenítése a MapLibre GL-térképen engedélyezési fejlécekkel
  • Zökkenőmentes mozaikrétegek létrehozása a teljes gyűjteményben
  • Nyers állományok letöltése SAS tokenekkel

A kódminták bármilyen modern JavaScript-keretrendszerrel (React, Vue, Angular) vagy vanília JavaScripttel működnek. A GeoCatalog API-k teljes körű CORS-támogatással rendelkeznek, így közvetlenül localhost a fejlesztés során hívhatja meg őket – nincs szükség proxyra.

Ezt a kódot a Microsoft Planetary Computer Pro nyilvános GitHub-adattárból töltheti le és tesztelheti.

Előfeltételek

Az architektúra áttekintése

Egy tipikus GeoCatalog-webalkalmazás ezt az architektúrát követi:

Egy GeoCatalog-webalkalmazás architektúráját bemutató ábra, amelyen egy böngészőügyfél csatlakozik a Microsoft Entra-azonosítóhoz hitelesítés céljából, valamint geocatalog API-khoz adathozzáférés céljából.

Alkalmazás regisztrálása a Microsoft Entra-azonosítóban

Mielőtt a webalkalmazás hitelesítené a felhasználókat, regisztrálja azt a Microsoft Entra-azonosítóban. Ez a rövid útmutató egyetlenoldalas alkalmazásregisztrációt (SPA) használ, amely ideális az ügyféloldali JavaScript-alkalmazásokhoz és a helyi fejlesztéshez. A későbbi lépésekben látható API-integrációs minták bármilyen alkalmazástípussal működnek.

Megjegyzés:

Háttérkiszolgálóval rendelkező éles alkalmazások esetén érdemes lehet másik regisztrációs típust választani (web, natív stb.). Az alkalmazáshitelesítés konfigurálása című témakör útmutatást nyújt a forgatókönyv megfelelő megközelítésének kiválasztásához.

Regisztrálás egyoldalas alkalmazásként

  1. Nyissa meg a Microsoft Entra-azonosítót az Azure Portalon.
  2. Válassza ki az alkalmazásregisztrációkat az oldalpanelen.
  3. Válassza Új regisztráció.
  4. Adja meg az alkalmazás nevét (például "GeoCatalog Web App").
  5. A támogatott fióktípusokalatt válassza a csak a jelen szervezeti könyvtárban található fiókokat.
  6. Az Átirányítási URI területen válassza az Egyoldalas alkalmazás (SPA) lehetőséget, és adja meg a fejlesztési URL-címet (például http://localhost:5173).
  7. Válassza a Regisztrálás lehetőséget.

A regisztráció után jegyezze fel a következő értékeket az Áttekintés lapon:

  • Alkalmazás (ügyfél) azonosítója
  • Címtár (bérlő) azonosítója

További információkért tekintse át a gyorsindítási alkalmazás-regisztrációt.

API-engedélyek megadása

Az alkalmazásnak engedéllyel kell meghívnia a GeoCatalog API-t a bejelentkezett felhasználók nevében:

  1. Az alkalmazásregisztrációban válassza az API-engedélyek>Hozzáadása engedélyt.
  2. Válassza ki a szervezet által használt API-kat , és keressen rá az Azure Orbital Spatio-ra.
  3. Válassza a Delegált engedélyek lehetőséget, és ellenőrizze a user_impersonation.
  4. Válassza a(z) Engedélyek hozzáadásalehetőséget.
  5. Ha Ön rendszergazda, válassza a rendszergazdai hozzájárulás megadását a bérlő összes felhasználója nevében.

Az alkalmazás konfigurálása

Az alkalmazásnak a következő konfigurációs értékekre van szüksége. Az értékek megadása a buildelési eszköztől (környezeti változók, konfigurációs fájlok stb.) függ:

Konfiguráció Érték Description
Katalógus URL https://{name}.{region}.geocatalog.spatio.azure.com A GeoCatalog-végpont
Bérlő azonosító Alkalmazásregisztrációból A Microsoft Entra-bérlője
Ügyfélazonosító Alkalmazásregisztrációból Az alkalmazás ügyfélazonosítója
API-hatókör https://geocatalog.spatio.azure.com/.default Mindig használja ezt a pontos értéket

Függőségek telepítése

Telepítse a Microsoft Authentication Library-t (MSAL) böngészőalkalmazásokhoz, és egy térképkönyvtárat:

npm install @azure/msal-browser maplibre-gl
  • @azure/msal-browser – OAuth 2.0-hitelesítés kezelése Microsoft Entra-azonosítóval
  • maplibre-gl – Nyílt forráskódú térképtár csempék vizualizációjához

Jótanács

Projektstruktúra: A rövid útmutatóban szereplő kódminták különálló függvények, amelyeket tetszés szerint rendszerezhet. Gyakori minta:

  • auth.js: MSAL-konfiguráció és tokenfüggvények
  • api.js: STAC API, Tiler API és SAS tokenfüggvények
  • map.js: MapLibre inicializálás és csemperéteg-kezelés
  • App.js vagy main.js: Mindent összeköthet a felhasználói felülettel

Minden függvény megkapja a függőségeit (hozzáférési jogkivonatok, URL-címek) paraméterekként, így könnyen integrálható bármely keretrendszerbe vagy projektstruktúrába.

MSAL-hitelesítés implementálása

Képernyőkép egy minta webalkalmazás hitelesítési folyamatáról.

Az MSAL konfigurálása böngészőhitelesítéshez. Az alábbi példa a kulcskonfigurációt és a jogkivonat-beszerzési mintát mutatja be:

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: Lekérdezésgyűjtemények és -elemek

A GeoCatalog STAC API végpontokat biztosít a térinformatikai adatok felderítéséhez és lekérdezéséhez. Minden kéréshez szükséges egy Authorization fejléc, amely tartalmaz egy bearer tokent, amit az MSAL-hitelesítés implementálásával szereztek be.

Listagyűjtemények

Képernyőkép a minta webalkalmazás STAC-gyűjteményeinek listájáról.

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
}

Gyűjtemény elemeinek listázása

Képernyőkép a minta webalkalmazás STAC-elemeinek listájáról.

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
}

Keresés gyűjtemények között

Képernyőkép arról, hogyan használható a STAC-keresés a fontos elemek visszaadására.

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

Csempe URL-címei: URL-címek létrehozása térképvizualizációhoz

A GeoCatalog Tiler API térképcsempékként raszteradatokat szolgál ki. Csempe URL-címeinek létrehozása a következő mintával:

Egyelemes csempék

Képernyőkép egy elem csempéinek megjelenítéséről.

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

Csempe URL-készítő függvény

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

Kulcscsempe-paraméterek

Paraméter Kötelező Description
api-version Igen API-verzió (2026-04-15)
tileMatrixSetId Igen Webtérképek használata WebMercatorQuad
assets Igen Megjelenítendő eszköznevek (például: visual, image)
colormap_name Nem Elnevezett színtérkép (például: viridis, terrain)
rescale Nem Skálázási értéktartomány (példa: 0,255)
asset_bidx Nem Sávindexek (például image\|1,2,3 RGB esetén)

Megjegyzés:

Négysávos képekkel (például NAIP RGB+ NIR) rendelkező gyűjtemények esetén csak az RGB-sávok kiválasztására használható asset_bidx=image|1,2,3 . A csempekezelő nem tud négy sávot PNG-ként kódolni.


Térképintegráció: Csempék megjelenítése a MapLibre GL-vel

Az olyan térképtárak, mint a MapLibre GL, a Szórólap és az OpenLayers, rasztercsempéket jeleníthetnek meg. A fő kihívás az engedélyezési fejlécek hozzáadása a csempekérelmekhez, mivel ezek a kódtárak közvetlenül lekérik a csempéket.

MapLibre GL példa

A MapLibre GL lehetőséget nyújt transformRequest a fejlécek injektálására:

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

Fontos

transformRequest függvényt minden csempekéréshez meghívnak. Tárolja a hozzáférési jogkivonatot egy elérhető változóban transformRequest , és frissítse azt a jogkivonat frissítésekor.


Mozaikcsempék: Gyűjteményszintű képek megjelenítése

Képernyőkép a gyűjtemény mozaikcsempeinek megjelenítéséről.

Ha egy gyűjtemény összes elemét zökkenőmentes rétegként szeretné megtekinteni, regisztráljon egy mozaikkeresést, és használja a visszaadott keresési azonosító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-jogkivonatok: Nyers adatok letöltése

Az SAS API időkorlátos jogkivonatokat biztosít a nyers objektumfájlok (GeoTIFF-ek, COG-k és egyéb fájlok) közvetlenül az Azure Blob Storage-ból való letöltéséhez. Ezt a lehetőséget akkor használja, ha a renderelt csempék helyett az eredeti forrásfájlokra van szüksége.

Fontos

Az SAS-jogkivonatok csak böngészőalkalmazásokban engedélyezik a letöltéseket . Az Azure Blob Storage CORS-szabályzatai miatt a böngészők nem tudják olvasni a blobadatokat JavaScript használatával fetch(). Lásd a Böngésző korlátai című szakaszt .

Képernyőkép az objektumok SAS-jogkivonattal való letöltéséről.

SAS-jogkivonat lekérése

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
}

Aláírt letöltési URL-cím létrehozása

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

Fájlletöltés aktiválása

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

Böngészőkorlátozások

Az SAS-jogkivonatok eltérően működnek a böngészőkben a kiszolgálóoldali kóddal szemben:

Használati eset Browser Server-side
Fájlok letöltése (a felhasználó kiválasztja a hivatkozást) ✅ Működik ✅ Működik
Blobadatok olvasása fetch() ❌ CORS blokkolva ✅ Működik
Nyers képpontok feldolgozása JavaScriptben ❌ Nem lehetséges ✅ Működik

A böngésző letöltése azért működik, mert a navigáció (a hivatkozásokra kattintva) áthalad a CORS-n. Az Azure Blob Storage-ba irányuló kérések azonban le vannak tiltva, fetch() mert a tárfiók nem tartalmazza az alkalmazás forrását a CORS-szabályzatában.

Ha az alkalmazásnak nyers eszközadatokat kell olvasnia és feldolgoznia a böngészőben, implementáljon egy kiszolgálóoldali proxyt:

Megjegyzés:

Az alábbi kód egy egyszerűsített példa a proxyminta szemléltetésére. Éles alkalmazások esetén a proxyvégpontnak hitelesítenie kell a kéréseket (például a felhasználó tulajdonosi jogkivonatának továbbításával vagy munkamenet-hitelesítéssel), és ellenőriznie kell, hogy a felhasználó jogosult-e a kért erőforrások elérésére.

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

A háttérrendszer lekérheti a blobot az SAS-jogkivonat használatával, és visszaadhatja a feldolgozott eredményeket.


Fejlesztési szempontok

CORS-támogatás

A GeoCatalog API-k teljes CORS-támogatást biztosítanak a Access-Control-Allow-Origin: *. A böngészőalapú alkalmazások bármilyen forrásból közvetlen kéréseket intézhetnek a GeoCataloghoz, beleértve a fejlesztés során is http://localhost . Nincs szükség proxyra vagy kerülő megoldásra.

Az API engedélyezi a fejlécet a Authorization CORS-kérelmekben, így a hitelesített fetch() hívások közvetlenül a böngészőBől, JavaScriptből működnek.

A megfelelő adatelérési módszer kiválasztása

Metódus Böngésző fetch() Böngészőletöltések Server-side Legjobb
Tiler API ✅ Teljes mértékben támogatott ✅ Igen ✅ Igen Térképvizualizáció
SAS-jogkivonatok ❌ CORS blokkolva ✅ Igen ✅ Igen Nyers fájlok letöltése
  • Tiler API: Képek térképeken való megjelenítésére használható. A renderelt PNG- vagy WebP-csempéket adja vissza teljes CORS-támogatással. Lásd Csempe URL-ek és Térképintegráció.

  • SAS-jogkivonatok: Eredeti forrásfájlok (GeoTIFF-ek, COG-k) letöltéséhez használható. A böngészőletöltések működnek, de fetch() az Azure Blob Storage CORS-szabályzatai blokkolják. Részletekért és kerülő megoldásokért nézze meg az SAS-tanúsítványokat.

Token frissítése

A hozzáférési jogkivonatok általában egy óra elteltével lejárnak. Az alkalmazásnak a következőnek kell lennie:

  1. Az 401-es hibákat új token beszerzésével kezelheti.
  2. Használja az MSAL csendes jogkivonat-beszerzését, amely automatikusan frissíti a lejárt jogkivonatokat.
  3. Frissítse a térképe által használt tokenhivatkozást transformRequest.

Hibakezelés

Gyakori hibaforgatókönyvek kezelése:

HTTP-állapot Oka Solution
401 A jogkivonat lejárt vagy érvénytelen A hozzáférési jogkivonat frissítése
404 Elem vagy gyűjtemény nem található Azonosítók meglétének ellenőrzése
424 Térképszelvény a külső adatterületen Várt – türelmesen kezelhető

Hibaelhárítás

Error Oka Solution
"AADSTS50011: Válasz URL-címének eltérése" A kódban lévő átirányítási URI nem egyezik a Microsoft Entra ID regisztrációval. Adja hozzá a fejlesztési URL-címet (például http://localhost:3000) spa átirányítási URI-ként az alkalmazásregisztrációban
"Érvénytelen hatókör" hiba GeoCatalog URL használata API-hatókör helyett Használja a https://geocatalog.spatio.azure.com/.default elemet hatókörként
401 Nem engedélyezett csempekérelmek esetén A térképtár nem tartalmazza a hitelesítési fejléceket A transformRequest (MapLibre) használatával adja hozzá a Hordozó tokent; győződjön meg arról, hogy a token aktuális.
A csempék nem igazodnak az alaptérképhez Helytelen csempemátrix-készlet Használja a tileMatrixSetId=WebMercatorQuad Web Mercator-vetítéshez (EPSG:3857)
"Nem sikerült dekódolni a képet" Helytelen eszköznév, többsávos rendszerkép vagy külső adatbőség Ellenőrizze a item_assets érvényes neveket; használja az asset_bidx=image\|1,2,3 RGB-t; 404/424 kívül eső lefedettség várható

Következő lépések