Aracılığıyla paylaş


Hızlı Başlangıç: Microsoft Planet Computer Pro ile web uygulaması oluşturma

Bu hızlı başlangıçta, GeoCatalog'unuzdan alınan uydu görüntüleri ve jeo-uzamsal verileri etkileşimli bir harita üzerinde görüntüleyen bir web uygulaması oluşturacaksınız. Microsoft Entra Id ile kullanıcıların kimliğini doğrular, STAC koleksiyonlarını sorgular ve harita kutucuklarını işlersiniz( hepsi tarayıcı JavaScript'ten).

Öğrendikleri:

  • MSAL.js kullanarak kullanıcıların kimliğini doğrulama ve erişim belirteçleri alma
  • Koleksiyonları ve öğeleri bulmak için STAC API'sini sorgulama
  • MapLibre GL haritasında raster karolarını yetkilendirme üst bilgileriyle görüntüleme
  • Koleksiyonların tamamında sorunsuz mozaik katmanlar oluşturma
  • SAS belirteçlerini kullanarak ham varlıkları indirme

Kod desenleri herhangi bir modern JavaScript çerçevesi (React, Vue, Angular) veya vanilya JavaScript ile çalışır. GeoCatalog API'leri tam CORS desteğine sahiptir, bu nedenle bunları geliştirme sırasında doğrudan localhost ara sunucuya gerek olmadan çağırabilirsiniz.

Bu kodu Microsoft Planetary Computer Pro genel GitHub deposundan indirebilir ve test edebilirsiniz.

Önkoşullar

Mimariye genel bakış

Tipik bir GeoCatalog web uygulaması şu mimariyi izler:

Kimlik doğrulaması için Microsoft Entra Id'ye ve veri erişimi için GeoCatalog API'lerine bağlanan bir tarayıcı istemcisi ile GeoCatalog web uygulamasının mimarisini gösteren diyagram.

Uygulamanızı Microsoft Entra Id'ye kaydetme

Web uygulamanızın kullanıcıların kimliğini doğrulayamadan önce Microsoft Entra Id'ye kaydedin. Bu hızlı başlangıçta, istemci tarafı JavaScript uygulamaları ve yerel geliştirme için ideal olan Tek Sayfalı Uygulama (SPA) kaydı kullanılır. Sonraki adımlarda gösterilen API tümleştirme desenleri herhangi bir uygulama türüyle çalışır.

Uyarı

Arka uç sunucusuna sahip üretim uygulamaları için farklı bir kayıt türü (Web, Yerel vb.) seçmeyi göz önünde bulundurun. Senaryonuz için doğru yaklaşımı seçme yönergeleri için bkz. Uygulama kimlik doğrulamasını yapılandırma .

Tek sayfalı uygulama olarak kaydet

  1. Azure portalında Microsoft Entra Id'ye gidin.
  2. Yan panelden Uygulama kayıtları'nı seçin.
  3. Yeni kayıtseçin.
  4. Uygulamanız için bir ad girin (örneğin, "GeoCatalog Web App").
  5. Desteklenen hesap türleri'nin altında Yalnızca bu kuruluş dizinindeki Hesaplar'ı seçin.
  6. Yeniden Yönlendirme URI'si'nin altında Tek sayfalı uygulama (SPA) öğesini seçin ve geliştirme URL'nizi (örneğin, http://localhost:5173) girin.
  7. Kaydıseçin.

Kayıttan sonra Genel Bakış sayfasında aşağıdaki değerleri not edin:

  • Uygulama (istemci) kimliği
  • Dizin (kiracı) ID'si

Daha fazla bilgi için hızlı başlangıç uygulaması kaydını gözden geçirin.

API izinleri verme

Uygulamanızın oturum açmış kullanıcılar adına GeoCatalog API'sini çağırma izni gerekir:

  1. Uygulama kaydınızda API izinleri>İzin ekle'yi seçin.
  2. Kuruluşumun kullandığı API'leri seçin ve Azure Orbital Spatio araması yapın.
  3. Temsilci izinleri'ne tıklayın ve user_impersonation denetleyin.
  4. İzinler ekle'yi seçin.
  5. Yöneticiyseniz Kiracınızdaki tüm kullanıcılar adına onay vermek için Yönetici onayı ver'i seçin.

Uygulamanızı yapılandırma

Uygulamanız aşağıdaki yapılandırma değerlerine ihtiyaç duyar. Bu değerleri nasıl sağladığınız derleme araçlarınıza (ortam değişkenleri, yapılandırma dosyaları vb.) bağlıdır:

Konfigürasyon Değer Description
Katalog URL'si https://{name}.{region}.geocatalog.spatio.azure.com GeoCatalog uç noktanız
Kiracı Kimliği Uygulama kaydından Microsoft Entra kiracı hesabınız
Müşteri Kimliği Uygulama kaydından Uygulamanızın istemci kimliği
API Kapsamı https://geocatalog.spatio.azure.com/.default Her zaman tam olarak bu değeri kullanın

Bağımlılıkları yükleme

Tarayıcı uygulamaları ve harita kitaplığı için Microsoft Kimlik Doğrulama Kitaplığı'nı (MSAL) yükleyin:

npm install @azure/msal-browser maplibre-gl
  • @azure/msal-browser - Microsoft Entra Id ile OAuth 2.0 kimlik doğrulamasını işler
  • maplibre-gl - Kutucuk görselleştirmesi için açık kaynak harita kitaplığı

Tavsiye

Proje yapısı: Bu hızlı başlangıçtaki kod örnekleri, istediğiniz gibi düzenleyebileceğiniz tek başına işlevlerdir. Yaygın bir desen:

  • auth.js: MSAL yapılandırma ve belirteç işlevleri
  • api.js: STAC API, Tiler API ve SAS belirteci işlevleri
  • map.js: MapLibre başlatma ve kutucuk katmanı yönetimi
  • App.js veya main.js: Kullanıcı arabiriminizle her şeyi birbirine bağlama

Her işlev bağımlılıklarını (erişim belirteçleri, URL'ler) parametre olarak alır ve bu da herhangi bir çerçeve veya proje yapısıyla tümleştirilmesini kolaylaştırır.

MSAL kimlik doğrulamayı uygulama

Örnek bir web uygulamasında kimlik doğrulama akışını gösteren ekran görüntüsü.

Tarayıcı kimlik doğrulaması için MSAL'yi yapılandırın. Aşağıdaki örnekte anahtar yapılandırması ve belirteç alma deseni gösterilmektedir:

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: Sorgu koleksiyonları ve öğeleri

GeoCatalog STAC API'sinde jeo-uzamsal verileri bulmak ve sorgulamak için uç noktalar sağlanır. Tüm istekler, MSAL kimlik doğrulamasının uygulanmasından alınan bir taşıyıcı belirteci içeren Authorization başlık gerektirir.

Listeleri listele

Örnek bir web uygulamasındaKI STAC koleksiyonlarının listesini gösteren ekran görüntüsü.

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
}

Koleksiyondaki öğeleri listeleme

Örnek web uygulamasındaki STAC öğelerinin listesini gösteren ekran görüntüsü.

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
}

Koleksiyonlar arasında arama

İlgi çekici öğeleri döndürmek için STAC aramasının nasıl kullanılacağını gösteren ekran görüntüsü.

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

Kutucuk URL'leri: Harita görselleştirmesi için URL'ler oluşturma

GeoCatalog Tiler API'si, harita kutucukları olarak raster verilerine hizmet eder. Aşağıdaki desenle kutucuk URL'leri oluşturma:

Tek öğe kutucukları

Tek bir öğe için kutucukların nasıl görüntüleneceğini gösteren ekran görüntüsü.

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

Kutucuk URL oluşturucu işlevi

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

Anahtar kutucuğu parametreleri

Parametre Gerekli Description
api-version Yes API sürümü (2025-04-30-preview)
tileMatrixSetId Yes Web haritaları için WebMercatorQuad kullan
assets Yes İşleme için varlık adları (örnek: visual, image)
colormap_name Hayı Adlandırılmış renk haritası (örnek: viridis, terrain)
rescale Hayı Ölçeklendirme için değer aralığı (örnek: 0,255)
asset_bidx Hayı Bant dizinleri (örnek: image\|1,2,3 RGB için)

Uyarı

Dört bantlı görüntüleri olan koleksiyonlar için (RGB + NIR ile NAIP gibi), yalnızca RGB bantlarını seçmek için kullanın asset_bidx=image|1,2,3 . Tiler dört bandı PNG olarak kodlayamaz.


Harita tümleştirmesi: MapLibre GL ile kutucukları görüntüleme

MapLibre GL, Leaflet ve OpenLayers gibi harita kitaplıkları raster kutucuklarını görüntüleyebilir. Bu kitaplıklar kutucukları doğrudan getirdiğinden, temel zorluk kutucuk isteklerine yetkilendirme üst bilgileri eklemektir .

MapLibre GL örneği

MapLibre GL, transformRequest üst bilgileri ekleme seçeneği sağlar:

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

Önemli

İşlev transformRequest , her kutucuk isteği için çağrılır. Erişim belirtecini erişebilecek transformRequest bir değişkende depolayın ve belirteç yenilendiğinde güncelleştirin.


Mozaik kutucuklar: Koleksiyon genelindeki görüntüleri görüntüleme

Bir koleksiyon için mozaik kutucukların nasıl görüntüleneceğini gösteren ekran görüntüsü.

Koleksiyondaki tüm öğeleri sorunsuz bir katman olarak görüntülemek için mozaik arama kaydedin ve döndürülen arama kimliğini kullanı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()}`;
}

SAS belirteçleri: Ham varlıkları indirme

SAS API,ham varlık dosyalarını (GeoTIFFs, COG'ler ve diğer dosyalar) doğrudan Azure Blob Depolama'dan indirmek için zaman sınırlı belirteçler sağlar. İşlenen kutucuklar yerine özgün kaynak dosyalarına ihtiyacınız olduğunda bu seçeneği kullanın.

Önemli

SAS belirteçleri yalnızca tarayıcı uygulamalarında indirmeleri etkinleştirir. Azure Blob Depolama CORS ilkeleri nedeniyle tarayıcılar JavaScript fetch()aracılığıyla blob verilerini okuyamaz. Tarayıcı sınırlamaları bölümüne bakın.

SAS belirteci kullanarak varlıkları indirmeyi gösteren ekran görüntüsü.

SAS belirteci alın

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
}

İmzalı indirme URL'si oluşturma

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

Dosya indirmeyi tetikleme

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

Tarayıcı sınırlamaları

SAS belirteçleri tarayıcılarda sunucu tarafı koda göre farklı çalışır:

Kullanım Örneği Browser Server-side
Dosyaları indirme (kullanıcı bağlantıyı seçer) ✅ Çalışır ✅ Çalışır
Blob verilerini fetch() aracılığıyla okuma ❌ CORS engellendi ✅ Çalışır
JavaScript'te ham pikselleri işleme ❌ Mümkün değil ✅ Çalışır

Gezinme (bağlantılara tıklanması) CORS'yi atlattığı için tarayıcı indirmeleri çalışır. Ancak, fetch() depolama hesabı uygulamanızın kaynağını CORS ilkesine eklemediğinden Azure Blob Depolama istekleri engellenir.

Uygulamanızın tarayıcıda ham varlık verilerini okuması ve işlemesi gerekiyorsa sunucu tarafı ara sunucusu uygulayın:

Uyarı

Aşağıdaki kod, proxy desenini göstermek için basitleştirilmiş bir örnektir. Üretim uygulamaları için proxy uç noktanız isteklerin kimliğini doğrulamalıdır (örneğin, kullanıcının Taşıyıcı belirtecini ileterek veya oturum kimlik doğrulamasını kullanarak) ve kullanıcının istenen kaynaklara erişme yetkisine sahip olduğunu doğrulamalıdır.

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

Arka ucunuz SAS belirtecini kullanarak blobu getirebilir ve işlenen sonuçları döndürebilir.


Geliştirmeyle ilgili dikkat edilmesi gerekenler

CORS desteği

GeoCatalog API'leri Access-Control-Allow-Origin: * ile tam CORS desteği içerir. Tarayıcı tabanlı uygulamalar geliştirme sırasında da dahil olmak üzere http://localhost herhangi bir kaynaktan GeoCatalog'a doğrudan istekte bulunabilir. Ara sunucu veya geçici çözüm gerekmez.

API, CORS isteklerindeki üst bilgiye Authorization izin verdiğinden, kimliği doğrulanmış fetch() çağrılar doğrudan tarayıcı JavaScript'ten çalışır.

Doğru veri erişim yöntemini seçme

Yöntem Tarayıcı fetch() Tarayıcı İndirmeleri Server-side En Uygun
Tiler API'si ✅ Tam olarak desteklenir ✅ Evet ✅ Evet Harita görselleştirmesi
SAS Belirteçleri ❌ CORS engellendi ✅ Evet ✅ Evet Ham dosya indirmeleri
  • Tiler API'si: Haritalarda görüntü görüntülemek için kullanın. Tam CORS desteğine sahip işlenmiş PNG veya WebP kutucuklarını döndürür. Bkz Kitapçık URL'leri ve Harita tümleştirmesi.

  • SAS Belirteçleri: Özgün kaynak dosyaları (GeoTIFFs, COG) indirmek için kullanın. Tarayıcı indirmeleri çalışır, ancak fetch() Azure Blob Depolama CORS ilkeleri tarafından engellenir. Ayrıntılar ve geçici çözümler için bkz. SAS belirteçleri .

Belirteç yenileme

Erişim belirteçlerinin süresi genellikle bir saat sonra dolar. Uygulamanız şu şekilde olmalıdır:

  1. Yeni bir token edinerek 401 hatalarını işleyin.
  2. MSAL'nin süresi dolan belirteçleri otomatik olarak yenileyen sessiz belirteç alma özelliğini kullanın.
  3. Haritanızın tarafından kullanılan belirteç başvurularını güncelleştirin transformRequest.

Hata yönetimi

Yaygın hata senaryolarını işleme:

HTTP Durumu Nedeni Çözüm
401 Belirtecin süresi doldu veya geçersiz Erişim belirtecini yenileme
404 Öğe veya koleksiyon bulunamadı Kimliklerin var olduğunu doğrulama
424 Veri kapsamı dışında kutucuk Beklenen - zarifçe yönetme

Sorun giderme

Hata Nedeni Çözüm
"AADSTS50011: Yanıt URL'si uyuşmazlığı" Koddaki yeniden yönlendirme URI'si Microsoft Entra Id kaydıyla eşleşmiyor Uygulama kaydınıza geliştirme URL'nizi (örneğin, http://localhost:3000) SPA yeniden yönlendirme URI'si olarak ekleyin
"Geçersiz kapsam" hatası API kapsamı yerine GeoCatalog URL'sini kullanma Kapsam olarak https://geocatalog.spatio.azure.com/.default kullan.
401 Kare isteklerinde yetkisiz Kimlik doğrulama üst bilgilerini içermeyen harita kütüphanesi Taşıyıcı belirtecini eklemek için (MapLibre) kullanın transformRequest ; belirtecin güncel olduğundan emin olun
Kutucuklar temel haritayla hizalamıyor Yanlış kutucuk matris kümesi Web Mercator projeksiyonu için tileMatrixSetId=WebMercatorQuad kullanın (EPSG:3857)
"Görüntü çözülemedi" Yanlış varlık adı, çok bantlı görüntüler veya dış veri kapsamı Geçerli adları kontrol edin item_assets; RGB için asset_bidx=image\|1,2,3 kullanın; 404/424 dış kapsama alanı bekleniyor

Sonraki Adımlar