Udostępnij za pośrednictwem


Szybki start: tworzenie aplikacji internetowej za pomocą firmy Microsoft Planetary Computer Pro

W tym szybkim starcie utworzysz aplikację internetową, która wyświetla obrazy satelitarne i dane geoprzestrzenne z twojego GeoCatalogu na interaktywnej mapie. Uwierzytelniasz użytkowników za pomocą identyfikatora Entra firmy Microsoft, wykonujesz zapytania dotyczące kolekcji STAC i renderujesz kafelki mapy — wszystko z poziomu przeglądarki JavaScript.

Czego się nauczysz:

  • Uwierzytelnianie użytkowników i uzyskiwanie tokenów dostępu przy użyciu MSAL.js
  • Wykonywanie zapytań względem interfejsu API STAC w celu odnajdywania kolekcji i elementów
  • Wyświetlanie kafelków rastrowych na mapie MapLibre GL z użyciem nagłówków autoryzacji
  • Tworzenie bezproblemowych warstw mozaiki w całej kolekcji
  • Pobieranie nieprzetworzonych zasobów przy użyciu tokenów SAS

Wzorce kodu działają z dowolnym nowoczesnym frameworkiem JavaScript (React, Vue, Angular) lub w czystym JavaScripcie. Interfejsy API GeoCatalog mają pełną obsługę mechanizmu CORS, dzięki czemu można je wywoływać bezpośrednio z localhost podczas rozwoju — bez wymaganego serwera proxy.

Możesz pobrać i przetestować ten kod z publicznego repozytorium GitHub Microsoft Planetary Computer Pro.

Wymagania wstępne

Przegląd architektury

Typowa aplikacja internetowa GeoCatalog jest zgodna z tą architekturą:

Diagram przedstawiający architekturę aplikacji internetowej GeoCatalog z klientem przeglądarki łączącym się z identyfikatorem Entra firmy Microsoft na potrzeby uwierzytelniania oraz z interfejsami API geocatalog w celu uzyskania dostępu do danych.

Rejestrowanie aplikacji w identyfikatorze Entra firmy Microsoft

Zanim aplikacja internetowa będzie mogła uwierzytelnić użytkowników, zarejestruj ją w identyfikatorze Entra firmy Microsoft. W tym przewodniku Szybki start jest używana rejestracja aplikacji jednostronicowej (SPA), która jest idealna dla aplikacji JavaScript po stronie klienta i programowania lokalnego. Wzorce integracji interfejsu API pokazane w kolejnych krokach działają z dowolnym typem aplikacji.

Uwaga / Notatka

W przypadku aplikacji produkcyjnych z serwerem backend rozważ wybranie innego typu rejestracji (Web, Natywna, itp.). Zobacz Konfigurowanie uwierzytelniania aplikacji , aby uzyskać wskazówki dotyczące wybierania odpowiedniego podejścia dla danego scenariusza.

Rejestrowanie jako jednostronicowa aplikacja

  1. Przejdź do elementu Microsoft Entra ID w portalu Azure.
  2. Wybierz pozycję Rejestracje aplikacji w panelu bocznym.
  3. Wybierz opcję Nowa rejestracja.
  4. Wprowadź nazwę aplikacji (na przykład "GeoCatalog Web App").
  5. Pod Obsługiwane typy kont wybierz Konta tylko w tym katalogu organizacyjnym.
  6. W obszarze Identyfikator URI przekierowania wybierz pozycję Aplikacja jednostronicowa (SPA) i wprowadź adres URL deweloperski (na przykład http://localhost:5173).
  7. Wybierz pozycję Zarejestruj.

Po rejestracji zanotuj następujące wartości na stronie Przegląd :

  • Identyfikator aplikacji (klienta)
  • Identyfikator katalogu (klienta)

Aby uzyskać więcej informacji, zapoznaj się z artykułem Rejestracja aplikacji szybki start.

Przyznawanie uprawnień API

Aplikacja musi mieć uprawnienia do wywoływania interfejsu API GeoCatalog w imieniu zalogowanych użytkowników.

  1. W rejestracji aplikacji wybierz pozycję Uprawnienia interfejsu API>Dodaj uprawnienie.
  2. Wybierz Interfejsy API używane przez moją organizację i wyszukaj Azure Orbital Spatio.
  3. Wybierz Delegowane uprawnienia i zaznacz user_impersonation.
  4. Wybierz Dodaj uprawnienia.
  5. Jeśli jesteś administratorem, wybierz pozycję Udziel zgody administratora na wyrażenie zgody w imieniu wszystkich użytkowników w dzierżawie.

Konfigurowanie aplikacji

Aplikacja wymaga następujących wartości konfiguracji. Sposób podawania tych wartości zależy od narzędzi kompilacji (zmiennych środowiskowych, plików konfiguracji itd.):

Konfiguracja Wartość Description
Adres URL wykazu https://{name}.{region}.geocatalog.spatio.azure.com Punkt końcowy GeoKatalogu
Identyfikator dzierżawy Z rejestracji aplikacji Twoja dzierżawa Microsoft Entra
ID klienta Z rejestracji aplikacji Identyfikator klienta aplikacji
Zakres interfejsu API https://geocatalog.spatio.azure.com/.default Zawsze używaj tej dokładnej wartości

Instalowanie zależności

Zainstaluj bibliotekę Microsoft Authentication Library (MSAL) dla aplikacji przeglądarki i bibliotekę mapy:

npm install @azure/msal-browser maplibre-gl
  • @azure/msal-browser — obsługuje uwierzytelnianie OAuth 2.0 przy użyciu identyfikatora Entra firmy Microsoft
  • maplibre-gl — biblioteka map typu open source na potrzeby wizualizacji kafelków

Wskazówka

Struktura projektu: Przykłady kodu w tym przewodniku szybkiego startu to funkcje autonomiczne, które można organizować według własnych preferencji. Typowy wzorzec:

  • auth.js: Funkcje konfiguracji MSAL oraz tokenów
  • api.js: funkcje interfejsu API STAC, interfejsu API kafelkowania i tokenu SAS
  • map.js: Inicjowanie mapLibre i zarządzanie warstwami kafelków
  • App.js lub main.js: Połącz wszystko razem z interfejsem użytkownika

Każda funkcja odbiera zależności (tokeny dostępu, adresy URL) jako parametry, co ułatwia ich integrację z dowolną strukturą lub strukturą projektu.

Implementowanie uwierzytelniania MSAL

Zrzut ekranu przedstawiający przepływ uwierzytelniania w przykładowej aplikacji internetowej.

Skonfiguruj bibliotekę MSAL na potrzeby uwierzytelniania przeglądarki. W poniższym przykładzie przedstawiono konfigurację kluczy i wzorzec pozyskiwania 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();
}

Interfejs API STAC: kolekcje zapytań i elementy

Interfejs API STAC geocatalog udostępnia punkty końcowe do odnajdywania i wykonywania zapytań dotyczących danych geoprzestrzennych. Wszystkie żądania wymagają nagłówka Authorization z tokenem elementu nośnego uzyskanego z uwierzytelniania MSAL.

Listy kolekcji

Zrzut ekranu przedstawiający listę kolekcji STAC w przykładowej aplikacji internetowej.

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
}

Wyświetlanie listy elementów w kolekcji

Zrzut ekranu przedstawiający listę elementów STAC w przykładowej aplikacji internetowej.

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
}

Wyszukiwanie w różnych kolekcjach

Zrzut ekranu pokazujący, jak używać wyszukiwania STAC do uzyskania interesujących wyników.

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 kafelków: Tworzenie adresów URL na potrzeby wizualizacji mapy

Interfejs API GeoCatalog Tiler służy do serwowania danych rastrowych jako kafelki mapy. Skonstruuj adresy URL kafelków przy użyciu następującego wzorca:

Kafelki pojedyncze

Zrzut ekranu przedstawiający sposób wyświetlania kafelków dla pojedynczego elementu.

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

Funkcja konstruktora adresów URL kafelka

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

Kluczowe parametry kafelka

Parameter Wymagane Description
api-version Tak Wersja interfejsu API (2025-04-30-preview)
tileMatrixSetId Tak Używanie WebMercatorQuad do map internetowych
assets Tak Nazwy elementów zawartości do renderowania (na przykład: visual, image)
colormap_name Nie. Nazwana mapa kolorów (przykład: viridis, terrain)
rescale Nie. Zakres wartości do skalowania (na przykład: 0,255)
asset_bidx Nie. Indeksy pasmowe (na przykład: image\|1,2,3 dla RGB)

Uwaga / Notatka

W przypadku kolekcji z obrazami czteropasmowymi (na przykład NAIP z RGB + NIR) użyj asset_bidx=image|1,2,3 polecenia, aby wybrać tylko pasma RGB. Moduł układający nie może zakodować czterech pasm w formacie PNG.


Integracja mapy: wyświetlanie kafelków za pomocą biblioteki MapLibre GL

Biblioteki map, takie jak MapLibre GL, Ulotka i OpenLayers, mogą wyświetlać kafelki rastrowe. Kluczowym wyzwaniem jest dodanie nagłówków autoryzacyjnych do żądań dotyczących kafelków, ponieważ biblioteki te pobierają kafelki bezpośrednio.

Przykład mapLibre GL

MapLibre GL udostępnia transformRequest opcję dodawania nagłówków:

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

Ważne

Funkcja transformRequest jest wywoływana dla każdego żądania kafelka. Zapisz token dostępu w zmiennej, do której transformRequest ma dostęp, i zaktualizuj go, gdy token zostanie odświeżony.


Kafelki mozaikowe: wyświetlanie obrazów w całej kolekcji

Zrzut ekranu przedstawiający sposób wyświetlania kafelków mozaiki dla kolekcji.

Aby wyświetlić wszystkie elementy w kolekcji jako jednolitą warstwę, skonfiguruj wyszukiwanie mozaiki i użyj zwróconego identyfikatora wyszukiwania:

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: pobieranie surowych zasobów

Interfejs API SAS udostępnia tokeny ograniczone czasowo do pobierania surowych plików zasobów (GeoTIFF, COG i inne pliki) bezpośrednio z usługi Azure Blob Storage. Użyj tej opcji, jeśli potrzebujesz oryginalnych plików źródłowych, a nie renderowanych kafelków.

Ważne

Tokeny SAS umożliwiają pobieranie tylko w aplikacjach przeglądarki. Ze względu na zasady CORS usługi Azure Blob Storage przeglądarki nie mogą odczytywać danych obiektów blob za pomocą języka JavaScript fetch(). Zobacz sekcję Ograniczenia przeglądarki .

Zrzut ekranu przedstawiający sposób pobierania zasobów przy użyciu tokenu SAS.

Token podpisu współdzielonego dostępu

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
}

Tworzenie podpisanego adresu URL pobierania

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

Wyzwalanie pobierania pliku

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

Ograniczenia przeglądarki

Tokeny SAS działają inaczej w przeglądarkach w porównaniu z kodem po stronie serwera:

Przypadek użycia Browser Server-side
Pobieranie plików (użytkownik wybiera link) ✅ Działa ✅ Działa
Odczytywanie danych obiektów blob za pośrednictwem fetch() ❌ Zablokowany mechanizm CORS ✅ Działa
Przetwarzanie nieprzetworzonych pikseli w języku JavaScript ❌ Nie można ✅ Działa

Pobieranie w przeglądarce działa, ponieważ nawigacja (kliknięcie linków) pomija CORS. Jednakże żądania do usługi Azure Blob Storage są blokowane, fetch() ponieważ konto magazynu nie uwzględnia pochodzenia twojej aplikacji w swojej polityce CORS.

Jeśli aplikacja musi odczytywać i przetwarzać nieprzetworzone dane zasobów w przeglądarce, zaimplementuj serwer proxy po stronie serwera:

Uwaga / Notatka

Poniższy kod jest uproszczonym przykładem ilustrowania wzorca serwera proxy. W przypadku aplikacji produkcyjnych punkt końcowy serwera proxy powinien uwierzytelniać żądania (na przykład przekazując token Bearer użytkownika lub używając uwierzytelniania sesji) i sprawdzać, czy użytkownik ma autoryzację dostępu do żądanych zasobów.

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

Backend może pobrać blob przy użyciu tokenu SAS i zwrócić przetworzone wyniki.


Zagadnienia dotyczące programowania

Pomoc techniczna CORS

Interfejsy API geocatalog obejmują pełną obsługę mechanizmu CORS za pomocą polecenia Access-Control-Allow-Origin: *. Aplikacje oparte na przeglądarce mogą wysyłać bezpośrednie żądania do usługi GeoCatalog z dowolnego źródła, w tym http://localhost podczas opracowywania. Nie jest wymagany żaden serwer proxy ani obejście problemu.

Interfejs API umożliwia Authorization nagłówek w żądaniach CORS, więc uwierzytelnione fetch() wywołania działają bezpośrednio z poziomu przeglądarki JavaScript.

Wybieranie odpowiedniej metody dostępu do danych

Metoda Przeglądarka fetch() Pobieranie przeglądarki Server-side Najlepsze dla
API Tiler ✅ W pełni obsługiwane ✅ Tak ✅ Tak Wizualizacja mapy
Tokeny sygnatury dostępu współdzielonego ❌ Zablokowany mechanizm CORS ✅ Tak ✅ Tak Nieprzetworzone pliki do pobrania
  • Tiler API: używany do wyświetlania obrazu na mapach. Zwraca renderowane kafelki PNG lub WebP z pełną obsługą mechanizmu CORS. Zobacz Adresy URL kafelków i Integracja Map.

  • Tokeny SAS: służą do pobierania oryginalnych plików źródłowych (GeoTIFF, COG). Pobieranie przeglądarki działa, ale fetch() jest blokowane przez zasady CORS usługi Azure Blob Storage. Aby uzyskać szczegółowe informacje i obejścia, zobacz Tokeny SAS .

Odświeżanie tokenu

Tokeny dostępu wygasają zazwyczaj po godzinie. Aplikacja powinna:

  1. Zarządzaj błędami 401 poprzez uzyskanie nowego tokenu.
  2. Użyj pozyskiwania tokenu w trybie dyskretnym biblioteki MSAL, która automatycznie odświeża wygasłe tokeny.
  3. Zaktualizuj odwołanie do tokenu używane przez mapę transformRequest.

Obsługa błędów

Obsługa typowych scenariuszy błędów:

Status HTTP Przyczyna Rozwiązanie
401 Token wygasł lub jest nieprawidłowy Odświeżanie tokenu dostępu
404 Nie można odnaleźć elementu lub kolekcji Sprawdź, czy istnieją identyfikatory
424 Kafelek poza zakresem danych Oczekiwano - płynna obsługa

Rozwiązywanie problemów

Error Przyczyna Rozwiązanie
"AADSTS50011: Niezgodność adresu URL odpowiedzi" Identyfikator URI przekierowania w kodzie jest niezgodny z rejestracją Microsoft Entra ID Dodaj swój deweloperski adres URL (na przykład http://localhost:3000) jako identyfikator URI przekierowania SPA w rejestracji aplikacji
Błąd "Nieprawidłowy zakres" Używanie adresu URL geokatalogu zamiast zakresu interfejsu API Użyj https://geocatalog.spatio.azure.com/.default jako zakresu
401 Nieautoryzowany dostęp do żądań danych kafelków Biblioteka map nie zawiera nagłówków uwierzytelniania Użyj transformRequest (MapLibre), aby dodać Bearer token; upewnij się, że token jest aktualny
Kafelki nie są wyrównane z mapą bazową Niewłaściwy zestaw macierzy kafelków Użyj tileMatrixSetId=WebMercatorQuad dla projekcji Web Mercator (EPSG:3857)
"Nie można dekodować obrazu" Nieprawidłowa nazwa zasobu, obrazy wielopasmowe lub poza zakresem danych Sprawdź item_assets prawidłowe nazwy; użyj asset_bidx=image\|1,2,3 dla RGB; oczekiwano pokrycia zewnętrznego 404/424

Dalsze kroki