Esercitazione: Creare una mappa statica usando le API REST e Python

Fabric Maps sono definite da una definizione pubblica (map.json) che descrive la mappa di base, le origini dati, le origini dei livelli e il comportamento di rendering.

Questa esercitazione illustra uno scenario di dati statici usando i file archiviati in una Lakehouse. Per scenari di streaming in tempo reale che usano Eventstream e Eventhouse, vedere Creare una mappa in tempo reale usando le API REST e Python.

Il modo più affidabile per automatizzare la creazione della mappa consiste nel fornire la definizione della mappa inline, quindi la mappa è completamente configurata e pronta per il rendering alla creazione.

Per altre informazioni sulla struttura di definizione della mappa, vedere Definizione dell'elemento mappa.

Usando l'API REST Fabric, è possibile:

  • Creare un lakehouse usando l'API REST Fabric
  • Caricare un file GeoJSON in OneLake
  • Caricare un'icona di marcatore SVG personalizzata in OneLake
  • Creare una definizione di map.json che fa riferimento ai dati lakehouse
  • Creare una mappa con la definizione fornita in linea

Questa esercitazione segue un modello di automazione comune in Fabric: creare un'infrastruttura → caricare i dati → definire la visualizzazione → mappa di rendering.

Quando usare questo approccio

Questo modello è ideale per:

  • Set di dati geospaziali statici
  • Livelli di riferimento (ad esempio, punti di interesse, limiti)
  • Dati storici o elaborati in modalità batch

Per gli scenari che richiedono l'aggiornamento continuo dei dati (ad esempio, rilevamento live o telemetria), vedere Creare una mappa in tempo reale usando le API REST e Python.

Prerequisiti

  • Python 3.10 o versione successiva
  • Interfaccia della riga di comando di Azure
  • ID spazio di lavoro tessuto
  • Autorizzazioni per chiamare Fabric API REST, ad esempio:
    • Item.ReadWrite.All

Note

Gli ambiti delegati come Item.ReadWrite.All vengono concessi all'identità connessa tramite il proprio ruolo nell'area di lavoro. Assicurarsi che all'identità utilizzata con az login sia assegnato il ruolo Contributor, Member o Admin nell'area di lavoro Fabric di destinazione prima di eseguire lo script.

Authentication

Questa esercitazione usa DefaultAzureCredential, che può autenticarsi usando diverse fonti di credenziali locali o di sviluppo. Per i lettori alla prima esperienza, l'approccio più semplice è l'accesso tramite interfaccia della riga di comando di Azure.

  1. Aprire un terminale.
  2. Run:
az login

DefaultAzureCredential può utilizzare l'identità autenticata per acquisire token di accesso per:

  • API REST Fabric (risorsa: https://api.fabric.microsoft.com/.default)
  • Accesso a OneLake tramite API e SDK di ADLS Gen2, inclusi indirizzi basati su GUID per aree di lavoro ed elementi.

Suggerimento

Informazioni su https://api.fabric.microsoft.com/.default Questo valore è un ambito di richiesta di token, non un URL chiamato direttamente. Indica a Microsoft Entra che il token di accesso deve essere rilasciato per l'API REST di Microsoft Fabric e deve includere tutte le autorizzazioni di Fabric già concesse all'identità autenticata, ad esempio Item.ReadWrite.All o Workspace.ReadWrite.All.

L'ambito .default viene usato solo durante l'acquisizione del token e non viene mai inviato agli endpoint dell'API REST di Fabric.

Per altre informazioni sul funzionamento dell'ambito .default in Microsoft Identity Platform, vedere Ambiti e autorizzazioni in Microsoft Identity Platform.

Prima di eseguire questa esercitazione, è consigliabile accedere almeno una volta a Microsoft Fabric:

https://app.fabric.microsoft.com

L'accesso garantisce che l'identità di Fabric, l'appartenenza ai ruoli dell'area di lavoro e le assegnazioni di capacità vengano sottoposte a provisioning completo prima di acquisire programmaticamente un token di accesso Microsoft Entra.

Questo passaggio è particolarmente utile se:

  • Sei nuovo di Microsoft Fabric
  • L'area di lavoro è stata creata di recente
  • L'assegnazione di ruolo è stata aggiunta di recente

Note

Questa esercitazione esegue l'autenticazione usando l'ID Microsoft Entra tramite DefaultAzureCredential. Le Fabric REST APIs non richiedono una sessione del browser, ma accedere all'esperienza web di Fabric può prevenire problemi di autorizzazione alla prima esecuzione causati da un provisioning ritardato del ruolo.

Creare il file GeoJSON

Il file GeoJSON in questa esercitazione viene usato come livello dati della mappa. Dopo aver creato il file, aggiornare la local_geojson_path variabile in modo da riflettere il percorso corretto.

Copiare il codice GeoJSON seguente in un file di testo vuoto e salvare il file come starbucks-seattle.geojson:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 999 3rd Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.334389, 47.605278] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 1201 3rd Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.335167, 47.608040] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 221 Pike St" },
      "geometry": { "type": "Point", "coordinates": [-122.340057, 47.609450] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 800 5th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.330048, 47.604550] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 1420 5th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.334091, 47.610041] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 1524 7th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.334915, 47.614498] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 2011 7th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.338165, 47.616341] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 2001 8th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.338806, 47.616848] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 4147 University Way NE" },
      "geometry": { "type": "Point", "coordinates": [-122.313873, 47.658298] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 2200 NW Market St" },
      "geometry": { "type": "Point", "coordinates": [-122.384056, 47.668581] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 101 Broadway E" },
      "geometry": { "type": "Point", "coordinates": [-122.320457, 47.620480] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 824 E Pike St" },
      "geometry": { "type": "Point", "coordinates": [-122.320282, 47.614212] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 6501 California Ave SW" },
      "geometry": { "type": "Point", "coordinates": [-122.387016, 47.545376] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 1501 4th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.336212, 47.610325] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 701 5th Ave" },
      "geometry": { "type": "Point", "coordinates": [-122.330704, 47.604298] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 2344 Eastlake Ave E" },
      "geometry": { "type": "Point", "coordinates": [-122.325874, 47.640884] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 5221 15th Ave NW" },
      "geometry": { "type": "Point", "coordinates": [-122.376595, 47.668210] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 4408 Fauntleroy Way SW" },
      "geometry": { "type": "Point", "coordinates": [-122.377693, 47.564991] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 7303 35th Ave NE" },
      "geometry": { "type": "Point", "coordinates": [-122.290611, 47.682518] }
    },
    {
      "type": "Feature",
      "properties": { "name": "Starbucks - 2742 Alki Ave SW" },
      "geometry": { "type": "Point", "coordinates": [-122.408028, 47.579311] }
    }
  ]
}

Importante

Assicurati che il percorso del file utilizzato in local_geojson_path corrisponda alla posizione in cui hai salvato il file sul computer.

Passaggio 1: Creare un nuovo file di progetto Python

In questo passaggio si crea un file Python vuoto che verrà compilato in base alla sezione.

Creare un nuovo file denominato:

create_map_from_geojson.py

Aprire il file nell'editor.

Passaggio 2: Installare le librerie necessarie e aggiungere le istruzioni di importazione necessarie

In questo passaggio si installano le dipendenze e si aggiungono le importazioni usate dallo script.

Installare le librerie necessarie

Run:

pip install httpx azure-identity azure-storage-file-datalake

A cosa serve ogni libreria

  • httpx: effettua richieste HTTP alle API REST di Fabric.
  • azure-identity: fornisce DefaultAzureCredential per l'autenticazione Microsoft Entra.
  • azure-storage-file-datalake: carica i file in OneLake usando le API compatibili con ADLS Gen2.

Aggiungere istruzioni import al file .py

Nella parte superiore di create_map_from_geojson.py aggiungere:

import base64
import json
import os
import time
import uuid
from pathlib import Path

import httpx
from azure.identity import DefaultAzureCredential
from azure.storage.filedatalake import DataLakeServiceClient

Passaggio 3: Aggiungere una sezione di configurazione

In questo passaggio si definiscono le variabili usate dall'applicazione, inclusi l'ID dell'area di lavoro, i percorsi dei file e gli interruttori delle funzionalità.

La centralizzazione della configurazione in una singola Config classe, anziché la dispersione dei valori hardcoded tra le funzioni, offre tre vantaggi concreti:

  • Portabilità dell'ambiente: gli ID dell'area di lavoro, i percorsi di file e i nomi delle risorse si trovano in un'unica posizione, quindi è possibile rieseguire lo script in un'area di lavoro o in un computer diverso modificando alcune righe (o una variabile di ambiente) invece di cercare il codice.
  • Signature di funzione più pulite: le funzioni di passaggio accettano un unico oggetto cfg invece di lunghi elenchi di parametri, il che rende l'orchestrazione in main() facile da leggere.
  • Gestione dei segreti più sicura: i valori sensibili, ad esempio l'ID dell'area di lavoro, vengono caricati dalle variabili di ambiente, quindi non viene mai eseguito il commit insieme allo script.

Aggiungere quanto segue sotto le istruzioni import:

# =========================================================
# Configuration (centralized)
# =========================================================

class Config:
    """
    Central configuration: workspace ID, file paths, resource names, and
    toggles for the optional custom SVG marker. A single instance is built
    in main() and passed to each step function.
    """
    def __init__(self):
        # Workspace
        self.workspace_id = os.environ.get("FABRIC_WORKSPACE_ID", "")
        if not self.workspace_id:
            raise RuntimeError("Set FABRIC_WORKSPACE_ID environment variable before running the script.")

        # Local file (source) and OneLake destination paths (inside Lakehouse Files/)
        self.local_geojson_path = Path(r"C:\tutorial\starbucks-seattle.geojson")
        self.geojson_relative_path = "Files/vector/starbucks-seattle.geojson"

        # Optional SVG marker settings
        self.svg_relative_path = "Files/icons/starbucks-marker.svg"
        self.use_custom_svg_marker = True
        self.builtin_icon_name_fallback = "BuildingShop"

        # SVG content (kept < 1 MB, scales cleanly)
        self.starbucks_marker_svg = """\
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64">
  <path d="M32 2C20.4 2 11 11.4 11 23c0 15.6 18.7 36.6 19.5 37.5a2 2 0 0 0 3 0C34.3 59.6 53 38.6 53 23 53 11.4 43.6 2 32 2z"
        fill="#006241" stroke="#ffffff" stroke-width="2"/>
  <circle cx="32" cy="23" r="13" fill="#ffffff" opacity="0.95"/>
  <path d="M26 20h12v10c0 3-2.5 5-6 5s-6-2-6-5V20z" fill="#006241"/>
</svg>
"""

        # Resource display names / descriptions
        self.lakehouse_display_name = "lh_starbucks_seattle"
        self.lakehouse_description = "Stores Starbucks Seattle GeoJSON + marker icon for a Fabric Maps tutorial"

        self.map_display_name = "My Fabric Map"
        self.map_description = "Created using Fabric Maps REST API"


Impostare l'ID dell'area di lavoro usando una variabile di ambiente

Invece di codificare direttamente l'ID dell'area di lavoro nello script, questo tutorial lo legge da una variabile di ambiente. In questo modo i valori specifici dell'ambiente non sono disponibili nel codice sorgente e consentono di riutilizzare lo script tra aree di lavoro o computer senza modificarli.

Prima di eseguire lo script, creare una variabile di ambiente denominata FABRIC_WORKSPACE_ID.

Importante

Una variabile di ambiente impostata da un terminale esiste solo all'interno di tale singola sessione del terminale. Non viene condiviso con altre finestre del terminale, con un tipo di shell diverso o con processi avviati all'esterno del terminale, inclusi gli script avviati dal pulsante di esecuzione di VS Code, che spesso genera il proprio terminale. Se lo script non riesce a trovare la variabile, ha esito negativo con Set FABRIC_WORKSPACE_ID environment variable before running the script.

Per evitare questo problema, eseguire lo script dalla sessione del terminale same in cui si imposta la variabile o impostarla in modo permanente (vedere le sezioni Windows e macOS/Linux che seguono) in modo che ogni nuova sessione del terminale lo rilevi automaticamente.

Impostare la variabile di ambiente in Windows

In Windows, è possibile impostare la variabile in qualsiasi terminale che supporti le variabili d’ambiente: PowerShell, Windows PowerShell, le finestre PowerShell o del Prompt dei comandi integrate in Visual Studio e Visual Studio Code, Terminale Windows e la maggior parte delle altre shell.

Eseguire quanto segue in PowerShell o nel terminale integrato di VS Code:

$env:FABRIC_WORKSPACE_ID="<WORKSPACE_ID>"

Per verificare che la variabile sia impostata:

echo $env:FABRIC_WORKSPACE_ID

In questo modo viene impostata solo la variabile per la sessione del terminale corrente.

Impostare una variabile di ambiente permanente (Windows)

Per rendere disponibile la variabile nelle sessioni future, usare una delle opzioni seguenti:

  • PowerShell (one-liner): Esegui setx FABRIC_WORKSPACE_ID "<WORKSPACE_ID>". Il setx comando scrive nell'ambiente utente ma non aggiorna il terminale corrente, chiudere e riaprire il terminale (o aprirne uno nuovo) prima di eseguire lo script.
  • GUI:
    1. Aprire Proprietà di sistema.
    2. Selezionare Impostazioni di sistema avanzate.
    3. Scegliere Variabili di ambiente.
    4. In Variabili utente selezionare Nuovo.
    5. Inserisci:
      • Nome: FABRIC_WORKSPACE_ID
      • Valore: ID della tua area di lavoro
    6. Selezionare OK per salvare.
    7. Chiudere e riaprire il terminale prima di eseguire di nuovo lo script.

Impostare la variabile di ambiente in macOS o Linux

In macOS e Linux è possibile impostare la variabile da qualsiasi shell che supporta export- Bash, Zsh (impostazione predefinita in macOS moderno), Fish (con una sintassi leggermente diversa) e i terminali integrati in Visual Studio Code e altri editor.

Run:

export FABRIC_WORKSPACE_ID="<WORKSPACE_ID>"

Per verificare che la variabile sia impostata:

echo $FABRIC_WORKSPACE_ID

In questo modo viene impostata la variabile solo per la sessione della shell corrente.

Impostare una variabile di ambiente permanente (macOS o Linux)

Per rendere disponibile la variabile nelle sessioni future, aggiungere la export riga al profilo della shell:

  • Zsh (impostazione predefinita in macOS): ~/.zshrc
  • Bash: ~/.bashrc (Linux) o ~/.bash_profile (macOS)
  • Pesce: eseguire set -Ux FABRIC_WORKSPACE_ID "<WORKSPACE_ID>" invece di modificare un file

Dopo l'aggiornamento del profilo, aprire un nuovo terminale o eseguire source ~/.zshrc (o il file appropriato) in modo che la modifica venga applicata.

Note

I geojson_relative_path valori e svg_relative_path definiscono la posizione all'interno dell'area Lakehouse Files. Questi percorsi sono relativi alla radice lakehouse e vengono usati sia per il caricamento dei file che per farvi riferimento nella definizione della mappa.

Passaggio 4: Aggiungere funzioni di supporto

In questo passaggio vengono evidenziate le problematiche trasversali, ovvero l'autenticazione, la costruzione dell'intestazione, il polling delle operazioni a esecuzione prolungata e i caricamenti del piano dati riprovabili, in un piccolo set di helper riutilizzabili che ogni funzione passo può chiamare.

Centralizzare questi aspetti negli helper, anziché incorporarli direttamente in ogni punto di chiamata, offre tre vantaggi concreti:

  • Unica fonte di riferimento per gli aspetti trasversali: l'autenticazione, le intestazioni e il polling LRO sono necessari per quasi ogni chiamata API. Centralizzarli consente a ogni funzione di step di concentrarsi sulle risorse di propria competenza invece di reimplementare l'acquisizione del token e la logica di ritentativo.
  • Resilienza senza ingombro: gli helper assorbono condizioni transitorie — provisioning asincrono, ritardi di propagazione del back-end, errori di caricamento risolvibili con un nuovo tentativo — così le funzioni step restano brevi e si leggono come una checklist.
  • Più facile da insegnare e modificare: ogni helper viene introdotto una volta e riutilizzato. Se Fabric modifica un modello LRO o un ambito di autenticazione, è possibile correggerlo in un'unica posizione.

Gli helper aggiunti in questo passaggio sono:

  • Helper di autenticazione: creano intestazioni per le API REST di Fabric (e gli endpoint LRO del cluster di Power BI)
  • FabricClient: wrapper leggero per chiamate API coerenti
  • Gestore LRO: eseguire il polling delle operazioni a esecuzione prolungata usando Location / x-ms-operation-id / Retry-After, incluse le risposte 200-with-Running, gli endpoint del cluster Power BI e i payload di completamento con solo stato (risolto da displayName)
  • Helper del payload di definizione: codifica in base64 map.json per definizioni inline
  • Utilità di caricamento di OneLake: caricamento di file GeoJSON e SVG in Lakehouse Files con ritentativo automatico

Note

Questa esercitazione si estende su due piani:

  • Piano di controllo (API REST di Fabric): creare elementi Lakehouse e Map
  • Piano dati (OneLake DFS): caricare file nel Lakehouse

Entrambi sono necessari per configurare completamente la mappa.

Creare funzioni di supporto per l'autenticazione

Ogni chiamata REST di Fabric effettuata in questa esercitazione include un token di accesso Microsoft Entra (token bearer) nell'intestazione Authorization. Anziché acquisire token ad hoc, questo passaggio racchiude DefaultAzureCredential in un piccolo TokenProvider e mette a disposizione un generatore di intestazioni specifico per il pubblico per ogni famiglia di endpoint richiamata dallo script.

Centralizzare l'acquisizione dei token e la costruzione delle intestazioni nelle funzioni helper, anziché acquisire i token in ogni punto di chiamata, offre tre vantaggi concreti:

  • Credenziale centralizzata: una singola DefaultAzureCredential viene racchiusa in TokenProvider e riutilizzata per ogni chiamata API, quindi il rilevamento dell'identità (interfaccia della riga di comando di Azure, VS Code, identità gestita e così via) avviene una sola volta.
  • Token specifici per il destinatario: le API REST di Fabric e gli endpoint LRO del cluster di Power BI richiedono token emessi per destinatari diversi. Un costruttore di header separato per ciascun pubblico mantiene l'ambito corretto accanto al punto di chiamata, così è chiaro a quale endpoint è destinata ogni funzione.
  • Aggiornato a ogni richiesta: i generatori di intestazioni costruiscono l'intestazione Authorization su richiesta anziché memorizzare nella cache il token stesso. Le credenziali sottostanti vengono aggiornate in modo trasparente, quindi i siti di chiamata non devono mai pensare alla scadenza.

Questa esercitazione chiama Fabric API REST usando ambiti delegati, ad esempio Item.ReadWrite.All (o Lakehouse.ReadWrite.All per le operazioni specifiche di Lakehouse).

Aggiungere quanto segue dopo la Config classe :

# =========================================================
# Auth helpers
#
# Authentication utilities built on `DefaultAzureCredential` that acquire and
# construct Authorization headers for calling Fabric REST APIs.
# =========================================================

class TokenProvider:
    """
    Thin wrapper around `DefaultAzureCredential` that acquires Entra access
    tokens. `_fabric_headers()` and `_pbi_headers()` call `get()` per
    request so the Authorization header is always fresh; the underlying
    credential refreshes transparently.
    """
    def __init__(self):
        self._cred = DefaultAzureCredential()

    def get(self, scope: str) -> str:
        return self._cred.get_token(scope).token


_tokens = TokenProvider()


def _fabric_headers() -> dict[str, str]:
    """
    Build headers for Fabric REST API calls.

    This function is called each time we make a Fabric REST call so the token is fresh.
    """
    return {
        "Authorization": f"Bearer {_tokens.get('https://api.fabric.microsoft.com/.default')}",
        "Content-Type": "application/json"
    }


def _pbi_headers() -> dict[str, str]:
    """
    Build headers for polling Power BI cluster LRO endpoints
    (e.g., df-*.analysis.windows.net) that require a Power BI audience token.
    """
    return {
        "Authorization": f"Bearer {_tokens.get('https://analysis.windows.net/powerbi/api/.default')}",
        "Content-Type": "application/json"
    }

Note

Alcune operazioni a esecuzione prolungata (LRO) Fabric sono ospitate in endpoint cluster Power BI (*.analysis.windows.net) anziché in api.fabric.microsoft.com. Questi endpoint richiedono un token audience di Power BI, quindi l'helper LRO passa automaticamente a _pbi_headers() quando rileva quell'URL di polling.

Crea un wrapper del client Fabric

La maggior parte delle chiamate REST di Fabric in questa esercitazione include le stesse intestazioni Authorization e Content-Type. Anziché ripeterli in ogni punto di chiamata, questa esercitazione incapsula httpx.Client in un piccolo FabricClient che aggiunge automaticamente le intestazioni, continuando però a restituire il httpx.Response grezzo così che ogni chiamante possa esaminare i codici di stato (ad esempio, per distinguere 201 da 202).

Racchiudere httpx.Client in questo modo, invece di passare headers=_fabric_headers() a ogni punto di chiamata, offre due vantaggi concreti:

  • Header in un unico punto: ogni punto di chiamata utilizza automaticamente l'ultimo _fabric_headers(), quindi una nuova richiesta non può essere inviata per errore senza l'header Authorization.
  • I codici di stato restano visibili: request() restituisce il valore grezzo httpx.Response invece del JSON decodificato, così i punti di chiamata possono comunque diramare la logica in base al codice di stato (201 vs 202) e controllare header come Location o Retry-After per la gestione delle LRO.

Aggiungere quanto segue dopo le funzioni helper di autenticazione:

# =========================================================
# FabricClient (minimal wrapper so call sites stay clean)
# =========================================================

class FabricClient:
    """
    Small wrapper around httpx.Client so we don't repeat headers everywhere.

    Keeps the tutorial behavior:
    - request() returns the raw httpx.Response so the caller can handle 201 vs 202.
    """
    def __init__(self, http_client: httpx.Client):
        self._http = http_client

    def request(self, method: str, url: str, *, json_body=None) -> httpx.Response:
        return self._http.request(method, url, headers=_fabric_headers(), json=json_body)

Creare una funzione di supporto LRO

Diverse API REST Fabric usate in questa esercitazione, ad esempio Create Lakehouse e Create Map, supportano le operazioni long-running operations (LROs).

Queste API possono restituire risposte in diversi modelli:

  • 201 Created con il corpo della risorsa in linea (sincrono)
  • 202 Accepted con un'intestazione Location che punta a un URL di stato dell'operazione (asincrono)
  • 202 Accepted con un'intestazione x-ms-operation-id anziché Location (modulo asincrono, alternativo)
  • 200 OK con status: "Running" o status: "NotStarted" durante il polling (ancora in corso)
  • 200 OK con status: "Succeeded" ma senza ID della risorsa nel corpo (operazione riuscita; risolvere elencando e facendo corrispondere displayName)

Per gestire tutti questi elementi in modo coerente, creare una singola funzione helper che:

  1. Restituisce immediatamente l'ID risorsa se la risposta iniziale lo contiene già.
  2. In caso contrario, interroga periodicamente l'URL dell'operazione (costruito a partire da Location o x-ms-operation-id) usando Retry-After.
  3. Considera 200 OK con status: "Running" / "NotStarted" come ancora in corso e continua il polling.
  4. In caso di esito positivo, restituisce l'ID della risorsa dal corpo oppure ripiega sull'elenco delle risorse e sulla corrispondenza con displayName (con tentativi ripetuti) quando il corpo è solo di stato.
  5. Usa _pbi_headers() quando l'URL di polling si trova in un cluster di Power BI (*.analysis.windows.net), altrimenti usa le intestazioni di Fabric.

Questo unico helper elimina la necessità di helper "resolve by name" specifici per risorsa: ogni funzione create_* in questo tutorial chiama _handle_lro con i valori appropriati list_url e match_display_name.

Aggiungere quanto segue dopo la FabricClient classe :

# =========================================================
# LRO handler 
# =========================================================

def _handle_lro(
    client: httpx.Client,
    initial_response: httpx.Response,
    *,
    list_url: str | None = None,
    match_display_name: str | None = None,
    id_field: str = "id",
    max_attempts: int = 10,
    delay: int = 5,
) -> str:
    """
    Handle a Fabric long-running operation (LRO) and return the resource id.

    Supports the response patterns used by Fabric REST APIs:
    - 200/201 with the resource body inline (synchronous).
    - 202 with a `Location` header or `x-ms-operation-id` (asynchronous).
    - 200 with `status: "Running"` / `"NotStarted"` while polling.
    - 200 with `status: "Succeeded"` but no id (resolve by listing and matching `displayName`).

    Polling uses `Retry-After` and switches to a Power BI audience token when
    the operation URL is on `*.analysis.windows.net`.
    """
    # Sync 200/201 with body: return the id immediately.
    if initial_response.status_code in (200, 201):
        try:
            body = initial_response.json() if initial_response.content else {}
        except ValueError:
            body = {}
        if isinstance(body, dict) and body.get(id_field):
            return body[id_field]

    # Location header, with x-ms-operation-id fallback.
    op_url = initial_response.headers.get("Location")
    if not op_url:
        op_id = initial_response.headers.get("x-ms-operation-id")
        if op_id:
            op_url = f"https://api.fabric.microsoft.com/v1/operations/{op_id}"
        else:
            raise RuntimeError(
                f"Missing LRO Location/x-ms-operation-id. "
                f"status={initial_response.status_code} body={initial_response.text[:500]!r}"
            )

    # Audience-aware polling: Power BI cluster endpoints need a different token.
    poll_headers = _pbi_headers() if "analysis.windows.net" in op_url else _fabric_headers()
    retry_after = int(initial_response.headers.get("Retry-After", "5"))

    while True:
        time.sleep(retry_after)
        poll = client.get(op_url, headers=poll_headers)

        if poll.status_code == 202:
            retry_after = int(poll.headers.get("Retry-After", "5"))
            continue

        poll.raise_for_status()
        body = poll.json() if poll.content else {}
        status = body.get("status") if isinstance(body, dict) else None

        if status in ("Running", "NotStarted"):
            retry_after = int(poll.headers.get("Retry-After", "5"))
            continue
        if status == "Failed":
            raise RuntimeError(f"LRO failed. Body: {body}")

        if isinstance(body, dict) and body.get(id_field):
            return body[id_field]

        # Status-only success: list and match by displayName, with retries.
        if status == "Succeeded" and list_url and match_display_name:
            for attempt in range(max_attempts):
                r = client.get(list_url, headers=_fabric_headers())
                r.raise_for_status()
                match = next(
                    (i for i in r.json().get("value", []) if i.get("displayName") == match_display_name),
                    None,
                )
                if match and match.get(id_field):
                    return match[id_field]
                time.sleep(delay)
            raise RuntimeError(
                f"LRO succeeded but resource not visible after retries. "
                f"match_display_name={match_display_name!r}"
            )

        raise RuntimeError(f"LRO completed but no resource id was returned. Body: {body}")

Note

Le risorse appena create potrebbero non essere visualizzate immediatamente quando si chiamano le API dell'elenco a causa di ritardi di propagazione back-end. La funzione di supporto ritenta automaticamente finché la risorsa non diventa visibile.

Assistente per il carico utile della definizione

Quando si crea una mappa con una definizione pubblica, l'API REST per la creazione della mappa prevede che ogni parte di definition.parts possa contenere un payload con codifica Base64 con "payloadType": "InlineBase64". L'helper _json_to_b64 codifica un dict Python (map.json) in quel formato, in modo che create_map possa inserirlo direttamente nel corpo della richiesta.

Aggiungere quanto segue dopo la _handle_lro funzione :

# =========================================================
# Definition payload helper
#
# Encodes map.json as base64 for inline Create map payloads.
# =========================================================

def _json_to_b64(obj: dict) -> str:
    """
    Convert a Python dict to base64-encoded JSON text.

    Fabric Map "Create map with definition inline" requires:
    - definition.parts[].payloadType = InlineBase64
    - definition.parts[].payload     = base64(json(map_json))
    """
    return base64.b64encode(json.dumps(obj).encode("utf-8")).decode("utf-8")

Assistenti di caricamento OneLake

OneLake supporta LE API ADLS/BLOB e consente l'indirizzamento basato su GUID per aree di lavoro ed elementi:

https://onelake.dfs.fabric.microsoft.com/<workspaceGUID>/<itemGUID>/<path>/<fileName>

Aggiungi:

# ===============================================================================================
# ONE LAKE UPLOAD HELPERS
# OneLake supports GUID-based addressing:
#   https://onelake.dfs.fabric.microsoft.com/<workspaceGUID>/<itemGUID>/<path>/<fileName> 
# We use the ADLS Gen2 SDK (DataLakeServiceClient) to upload files into the Lakehouse Files area.
# ===============================================================================================

def _onelake_client() -> DataLakeServiceClient:
    """
    Build a DataLakeServiceClient against the OneLake DFS endpoint,
    authenticated with `DefaultAzureCredential`. Used by `_upload_with_retry`
    to write files into the Lakehouse Files area.
    """
    return DataLakeServiceClient(
        account_url="https://onelake.dfs.fabric.microsoft.com",
        credential=DefaultAzureCredential()
    )


def _upload_with_retry(
    workspace_guid: str,
    item_guid: str,
    dest_relative_path: str,
    content: bytes,
    attempts: int = 6
) -> None:
    """
    Upload bytes into OneLake at `<workspace GUID>/<item GUID>/<relative path>`.
    Retries with linear backoff because a newly created Lakehouse can
    briefly return errors before its `Files/` area is provisioned.
    """
    service = _onelake_client()
    fs = service.get_file_system_client(file_system=workspace_guid)

    dest_path = f"{item_guid}/{dest_relative_path}".replace("\\", "/")

    last_exc = None
    for i in range(attempts):
        try:
            fs.get_file_client(dest_path).upload_data(content, overwrite=True)
            return
        except Exception as exc:
            last_exc = exc
            time.sleep(2 + i)

    raise RuntimeError(f"Upload failed after {attempts} attempts: {last_exc}")


Suggerimento

È possibile verificare che il file sia stato caricato correttamente passando all'area Lakehouse Files nel portale di Fabric.

Creare funzioni primarie

Aggiungere quindi le funzioni primarie che definiscono il flusso di lavoro. Questi vengono tutti chiamati da main().

  1. Creare un lakehouse
  2. Carica GeoJSON nel Lakehouse
  3. Caricare un marcatore SVG personalizzato (facoltativo)
  4. Compilare la definizione della mappa (map.json)
  5. Crea la mappa con la sua definizione in linea

Creare un lakehouse

create_lakehouse crea il Lakehouse che archivia il file GeoJSON e il marcatore SVG facoltativo usato dalla mappa.

Questa funzione:

  • Invia un POST all'endpoint REST di Lakehouse con displayName e description dalla tua configurazione
  • Passa la risposta a _handle_lro, che gestisce in modo uniforme le risposte sincrone (201), asincrone (202/LRO) e solo stato
  • Restituisce l'ID Lakehouse da usare nei passaggi successivi

Aggiungere quanto segue dopo la _upload_with_retry funzione :

# =========================================================
# Step 1: Create a Lakehouse
# =========================================================

def create_lakehouse(client: httpx.Client, fabric: FabricClient, cfg: Config) -> str:
    """
    Create a Lakehouse and return its item ID.
    """
    lakehouse_url = f"https://api.fabric.microsoft.com/v1/workspaces/{cfg.workspace_id}/lakehouses"
    lakehouse_payload = {
        "displayName": cfg.lakehouse_display_name,
        "description": cfg.lakehouse_description
    }

    lh_resp = fabric.request("POST", lakehouse_url, json_body=lakehouse_payload)

    lakehouse_id = _handle_lro(
        client,
        lh_resp,
        list_url=lakehouse_url,
        match_display_name=cfg.lakehouse_display_name,
    )

    print("Lakehouse created. Lakehouse ID:", lakehouse_id)
    return lakehouse_id

Carica GeoJSON nel Lakehouse

upload_geojson carica il file GeoJSON locale nell'area Lakehouse Files , in cui diventa l'origine dati spaziale che la mappa legge in fase di rendering.

Questo è il primo passaggio che passa dal piano di controllo Fabric (REST) al piano dati OneLake (ADLS Gen2). La funzione legge il file locale in memoria e delega a _upload_with_retry, che esegue il caricamento DFS in blocchi e ripete il tentativo in caso di errori temporanei.

Aggiungere quanto segue dopo la create_lakehouse funzione :

# =========================================================
# Step 2: Upload GeoJSON to the Lakehouse
# =========================================================

def upload_geojson(cfg: Config, lakehouse_id: str) -> None:
    """
    Upload the local GeoJSON file to the Lakehouse Files area at
    `cfg.geojson_relative_path` using the OneLake DFS endpoint.
    """
    _upload_with_retry(
        workspace_guid=cfg.workspace_id,
        item_guid=lakehouse_id,
        dest_relative_path=cfg.geojson_relative_path,
        content=cfg.local_geojson_path.read_bytes()
    )
    print("Uploaded GeoJSON to:", cfg.geojson_relative_path)

Caricare un marcatore SVG personalizzato

upload_svg_marker carica un'icona SVG personalizzata nella stessa lakehouse, in modo che la mappa possa eseguire il rendering di ogni caratteristica con tale marcatore anziché un elemento predefinito. Il passaggio è facoltativo e gestito da cfg.use_custom_svg_marker , quando il flag è False, la funzione restituisce immediatamente e la mappa esegue il fallback a un marcatore predefinito.

Come upload_geojson, questa funzione delega il caricamento effettivo in _upload_with_retry.

Aggiungere quanto segue dopo la upload_geojson funzione :

# =========================================================
# Step 3: Upload a custom SVG marker (optional)
# =========================================================

def upload_svg_marker(cfg: Config, lakehouse_id: str) -> None:
    """
    Upload a custom SVG marker to the Lakehouse at
    `cfg.svg_relative_path` when `cfg.use_custom_svg_marker` is True;
    otherwise return without uploading.
    """
    if not cfg.use_custom_svg_marker:
        return

    _upload_with_retry(
        workspace_guid=cfg.workspace_id,
        item_guid=lakehouse_id,
        dest_relative_path=cfg.svg_relative_path,
        content=cfg.starbucks_marker_svg.encode("utf-8")
    )
    print("Uploaded custom SVG marker to:", cfg.svg_relative_path)

Suggerimento

I marcatori SVG vengono ridimensionati in modo pulito tra livelli di zoom e DPI dello schermo, che li rende adatti alle icone della mappa.

Genera map.json

compila e restituisce il payload /> dataSources (da cui provengono i dati), iconSources (marcatori personalizzati facoltativi), layerSources (cosa viene letto e con quale frequenza) e layerSettings (come viene eseguito il rendering del risultato sulla mappa).

Per questa esercitazione, dataSources punta a Lakehouse (itemType: "Lakehouse") creato in precedenza e la singola voce in layerSources è un livello di file GeoJSON (type: "geojson") che legge il file caricato tramite relativePath. refreshIntervalMs è impostato su 0 perché il file di origine è statico. La mappa esegue il rendering del file una sola volta e non esegue il polling delle modifiche.

L'elemento corrispondente layerSettings visualizza ogni feature come un marker e mostra la proprietà GeoJSON name nei suggerimenti. Quando cfg.use_custom_svg_marker è True, viene aggiunta una iconSources voce che fa riferimento al formato SVG caricato e il livello usa la chiave iconOptions.image composita per associare l'indicatore <layerSettingId>:<iconId> a tale icona. Quando è False, il livello ripiega su un marcatore predefinito (cfg.builtin_icon_name_fallback) con un riempimento verde Starbucks.

Per altre informazioni sull'API REST per la definizione della mappa, vedere Definizione dell'elemento mappa. Per un esempio di map.json, vedere Esempio di MapDetails.

Aggiungere quanto segue dopo la upload_svg_marker funzione :

# =========================================================
# Step 4: Build map.json
# =========================================================

def build_map_json(cfg: Config, lakehouse_id: str) -> dict:
    """
    Build and return the map.json payload for the Fabric Map.

    Wires `dataSources` to the Lakehouse created earlier, defines a
    single GeoJSON layer in `layerSources` that reads the uploaded file
    via `cfg.geojson_relative_path` with `refreshIntervalMs: 0` (the
    source is static), and configures `layerSettings` to render each
    feature as a marker. When `cfg.use_custom_svg_marker` is True, adds
    an `iconSources` entry for the uploaded SVG and binds the layer to
    it via a `<layerSettingId>:<iconId>` composite key; otherwise falls
    back to a built-in marker.
    """
    layer_source_id = str(uuid.uuid4())
    layer_setting_id = str(uuid.uuid4())
    icon_source_id = str(uuid.uuid4())

    custom_svg_marker = f"{layer_setting_id}:{icon_source_id}"
    icon_source_name = "Starbucks Marker"

    map_json = {
        "$schema": "https://developer.microsoft.com/json-schemas/fabric/item/map/definition/2.0.0/schema.json",
        "basemap": {},

        "dataSources": [
            {"itemType": "Lakehouse", "workspaceId": cfg.workspace_id, "itemId": lakehouse_id}
        ],

        "iconSources": (
            [
                {
                    "id": icon_source_id,
                    "name": icon_source_name,
                    "type": "svg",
                    "itemId": lakehouse_id,
                    "relativePath": cfg.svg_relative_path
                }
            ] if cfg.use_custom_svg_marker else []
        ),

        "layerSources": [
            {
                "id": layer_source_id,
                "name": "starbucks_seattle_geojson",
                "type": "geojson",
                "itemId": lakehouse_id,
                "relativePath": cfg.geojson_relative_path,
                "refreshIntervalMs": 0
            }
        ],

        "layerSettings": [
            {
                "id": layer_setting_id,
                "name": "Starbucks (Seattle)",
                "sourceId": layer_source_id,
                "options": {
                    "type": "vector",
                    "visible": True,
                    "tooltipKeys": ["name"],
                    "pointLayerType": "marker",

                    "markerOptions": (
                        {
                            "iconOptions": {
                                "image": custom_svg_marker,
                                "anchor": "bottom",
                                "opacity": 1.0,
                                "rotation": 0,
                                "allowOverlap": False,
                                "rotationAlignment": "viewport",
                                "pitchAlignment": "viewport"
                            },
                            "icon": icon_source_id
                        }
                        if cfg.use_custom_svg_marker
                        else
                        {
                            "size": 22,
                            "fillColor": "#006241",
                            "strokeColor": "#FFFFFF",
                            "strokeWidth": 2,
                            "icon": cfg.builtin_icon_name_fallback,
                            "iconOptions": {
                                "image": f"{layer_setting_id}:{cfg.builtin_icon_name_fallback}",
                                "anchor": "bottom",
                                "opacity": 1.0,
                                "rotation": 0,
                                "allowOverlap": False,
                                "rotationAlignment": "viewport",
                                "pitchAlignment": "viewport"
                            }
                        }
                    )
                }
            }
        ]
    }

    return map_json


Suggerimento

Suggerimenti correlati alla definizione della mappa:

  • La proprietà image usa una chiave composita nel formato <layerSettingId>:<iconId> per fare riferimento all'icona del livello. Questo associa la configurazione di rendering del marcatore alla sorgente dell'icona definita in precedenza nella definizione della mappa.
  • Impostando refreshIntervalMs su 0 si disabilita l'aggiornamento automatico. Questa opzione è appropriata per i file GeoJSON statici archiviati in una Lakehouse.

Crea una mappa con definizione in linea

create_map crea la mappa inviando tramite POST la definizione inline che hai creato e restituisce l'ID elemento della nuova mappa. Per questa esercitazione, la richiesta include una singola parte con codifica Base64, map.json sottoposta a wrapping come payloadType: "InlineBase64" e codificata tramite _json_to_b64. Il payload map.json fa già riferimento all'origine dati di Lakehouse e, quando presente, all'icona SVG fornita da relativePath, quindi il livello viene configurato completamente dalla chiamata Create Map senza un successivo round trip updateDefinition. Se si desidera impostare metadati degli elementi diversi da quelli predefiniti o fissare un logicalId compatibile con Git, si aggiungerebbe una parte .platform alla stessa matrice parts; Fabric applica i metadati predefiniti quando .platform viene omesso, ed è proprio ciò che fa questa esercitazione.

L'API REST Create map può restituire 201 Created (sincrona, con ID inline), 202 Accepted (LRO asincrona tramite Location o x-ms-operation-id) oppure 200 OK con un payload di completamento contenente solo lo stato, in cui la mappa non è ancora visibile in List Maps a causa di un ritardo di propagazione del backend. _handle_lro copre tutti questi casi, inclusi l'elenco e la corrispondenza tramite displayName, quindi questa funzione gli delega l'intera gestione della risposta con un'unica chiamata.

Per altre informazioni, vedere Definizione dell'elemento mappa.

Aggiungere quanto segue dopo la build_map_json funzione :

# =========================================================
# Step 5: Create a map with inline definition
# =========================================================

def create_map(client: httpx.Client, fabric: FabricClient, cfg: Config, map_json: dict) -> str:
    """
    Create the Fabric map with its definition inline and return its item ID.

    Sends a single Create map request whose `parts` array carries one
    base64-encoded payload, `map.json`. The map definition already
    references the Lakehouse data source (and, when present, the SVG
    icon) by `relativePath`, so the layer is wired by the Create Map
    call without a follow-up update. Delegates response handling to
    `_handle_lro`, which covers synchronous, asynchronous, and
    status-only completions.
    """
    create_map_url = f"https://api.fabric.microsoft.com/v1/workspaces/{cfg.workspace_id}/maps"

    create_map_payload = {
        "displayName": cfg.map_display_name,
        "description": cfg.map_description,
        "definition": {
            "parts": [
                {
                    "path": "map.json",
                    "payload": _json_to_b64(map_json),
                    "payloadType": "InlineBase64"
                }
            ]
        }
    }

    map_resp = fabric.request("POST", create_map_url, json_body=create_map_payload)

    return _handle_lro(
        client, map_resp,
        list_url=create_map_url,
        match_display_name=cfg.map_display_name,
    )

Orchestrare il flusso di lavoro

main è l'unico punto di ingresso che esegue il tutorial dall'inizio alla fine. Crea un'istanza di Config, apre un httpx.Client riutilizzato da ogni helper, lo incapsula in un FabricClient, quindi chiama ogni funzione di step nell'ordine delle dipendenze: create_lakehouseupload_geojson (scrive il GeoJSON in OneLake nel nuovo Lakehouse) → upload_svg_marker (facoltativo; viene eseguito solo quando cfg.use_custom_svg_marker è impostato) → build_map_jsoncreate_map.

L'ordinamento è importante perché ogni passaggio utilizza un elemento creato da un passaggio upload_geojson precedente e upload_svg_marker richiede l'ID dell'elemento Lakehouse e build_map_json fa riferimento a entrambi i caricamenti in relativePath modo che Crea mappa possa risolverli in fase di rendering. Il blocco finale print espone l'ID lakehouse, l'ID mappa e i percorsi relativi degli asset caricati in modo da poterli trovare nel portale di Fabric.

Aggiungere quanto segue dopo la create_map funzione :

# =========================================================
# main(): orchestrates the full workflow
# =========================================================

def main():
    """
    Orchestrate the tutorial workflow.

    1) Create a Lakehouse
    2) Upload GeoJSON to the Lakehouse
    3) Upload a custom SVG marker (optional)
    4) Build the map definition (map.json)
    5) Create the map with its definition inline
    """
    cfg = Config()

    print("Initializing clients...")
    with httpx.Client(timeout=60) as client:
        fabric = FabricClient(client)

        # Step 1
        lakehouse_id = create_lakehouse(client, fabric, cfg)

        # Step 2
        upload_geojson(cfg, lakehouse_id)

        # Step 3 (optional)
        upload_svg_marker(cfg, lakehouse_id)

        # Step 4
        map_json = build_map_json(cfg, lakehouse_id)

        # Step 5
        map_id = create_map(client, fabric, cfg, map_json)

        print("\nDONE")
        print("Lakehouse ID:", lakehouse_id)
        print("Map ID:", map_id)
        print("GeoJSON layer path:", cfg.geojson_relative_path)
        if cfg.use_custom_svg_marker:
            print("Custom SVG marker path:", cfg.svg_relative_path)


if __name__ == "__main__":
    main()

A questo punto sono stati definiti tutti i codici e la configurazione.

Nel passaggio successivo si esegue lo script per creare Lakehouse, caricare i dati e generare la mappa.

Eseguire l'applicazione

Note

I nomi visualizzati dei lakehouse e delle mappe devono essere univoci in un'area di lavoro. Prima di eseguire nuovamente lo script, eliminare gli elementi creati nell'esecuzione precedente dall'area di lavoro Fabric oppure modificare lakehouse_display_name / map_display_name in Config. In caso contrario, le chiamate create hanno esito negativo con 409 ItemDisplayNameAlreadyInUse.

Eseguire lo script:

python create_map_from_geojson.py

Se lo script viene eseguito correttamente, viene visualizzato un output simile al seguente:

DONE
Lakehouse ID: <Lakehouse ID>
Map ID: <Map ID>
GeoJSON layer path: Files/vector/starbucks-seattle.geojson
Custom SVG marker path: Files/icons/starbucks-marker.svg

In Microsoft Fabric la mappa dovrebbe essere simile alla seguente:

Screenshot di Microsoft Fabric Maps che mostra Seattle con più icone di indicatori di Starbucks verdi raggruppate nell'area centrale. La mappa mostra le strade e le caratteristiche dell'acqua con uno sfondo grigio chiaro. Il pannello Livelli dati a sinistra visualizza il livello Starbucks (Seattle). La mappa si trova nel centro di Seattle, tra cui Elliott Bay sul lungomare con marcatori che indicano le singole posizioni di Starbucks a cui si fa riferimento nel file GeoJSON dell'esercitazione.

Suggerimento

Se la mappa non viene visualizzata immediatamente, aggiornare l’area di lavoro o attendere alcuni secondi per consentire il completamento della propagazione nel backend.

Sommario

In questa esercitazione è stata creata una soluzione geospaziale automatizzata usando Microsoft Fabric mappe e dati Lakehouse.

Sono state usate Fabric API REST e Python per effettuare il provisioning e configurare tutte le risorse necessarie, quindi visualizzare i dati spaziali archiviati in OneLake.

Sono state eseguite le operazioni seguenti:

  • Dati spaziali caricati in un Lakehouse
  • Configurato un set di dati per la visualizzazione geospaziale
  • Creata una mappa Fabric con una definizione in linea
  • Connessione della mappa ai dati di Lakehouse
  • Livelli mappa configurati per il rendering delle funzionalità spaziali

Questa architettura illustra un comune modello di analisi spaziale batch e storica in Fabric:

  • I dati vengono archiviati in OneLake (Lakehouse)
  • Maps interroga e visualizza set di dati spaziali
  • I livelli forniscono informazioni visive sui dati geografici

Automatizzando la creazione di risorse usando le API REST e Python, è ora disponibile un approccio ripetibile per la creazione di applicazioni geospaziali basate su set di dati statici o cronologici.

Passaggi successivi

Ora che si è appreso come visualizzare i dati spaziali da un Lakehouse, è possibile estendere questa soluzione:

  • Combinare più set di dati per un'analisi geospaziale più completa
  • Applicare stili e filtri per evidenziare tendenze e modelli
  • Aggiungere livelli di riferimento, ad esempio limiti o route
  • Integrare automaticamente le pipeline di dati per aggiornare i set di dati
  • Esplorare gli scenari di streaming in tempo reale usando Eventstream e Eventhouse

Per altre informazioni sull'uso di dati spaziali e mappe in Fabric, vedere:

Per un'esercitazione che illustra la creazione di una mappa in tempo reale usando le API REST, vedere: