หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
Fabric Maps ถูกกําหนดโดย คําจํากัดความสาธารณะ (map.json) ที่อธิบายแผนที่ฐาน แหล่งข้อมูล แหล่งที่มาของเลเยอร์ และลักษณะการแสดงผล
บทช่วยสอนนี้สาธิต สถานการณ์ข้อมูลแบบคงที่ โดยใช้ไฟล์ที่จัดเก็บไว้ในเลคเฮาส์ สําหรับสถานการณ์การสตรีมแบบเรียลไทม์โดยใช้ Eventstream และ Eventhouse โปรดดู สร้างแผนที่แบบเรียลไทม์โดยใช้ REST API และ Python
วิธีที่น่าเชื่อถือที่สุดในการสร้างแผนที่โดยอัตโนมัติคือการระบุคําจํากัดความแผนที่แบบอินไลน์ เพื่อให้แผนที่ได้รับการกําหนดค่าอย่างสมบูรณ์และพร้อมที่จะแสดงผลเมื่อสร้าง
หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับโครงสร้างข้อกําหนดแผนที่ โปรดดู ข้อกําหนดรายการแผนที่
เมื่อใช้ Fabric REST API คุณจะทําสิ่งต่อไปนี้
- สร้างเลคเฮาส์โดยใช้ Fabric REST API
- อัปโหลดไฟล์ GeoJSON ไปยัง OneLake
- อัปโหลดไอคอนเครื่องหมาย SVG ที่กําหนดเองไปยัง OneLake
- สร้างคําจํากัดความ map.json ที่อ้างอิงข้อมูล Lakehouse
- สร้างแผนที่ด้วยคําจํากัดความที่ให้ไว้ในบรรทัด
บทช่วยสอนนี้เป็นไปตามรูปแบบระบบอัตโนมัติทั่วไปใน Fabric: สร้างโครงสร้างพื้นฐาน→อัปโหลดข้อมูล→กําหนดการแสดงภาพ→แสดงแผนที่
เมื่อใดที่ควรใช้วิธีนี้
รูปแบบนี้เหมาะที่สุดสําหรับ:
- ชุดข้อมูลเชิงพื้นที่แบบคงที่
- เลเยอร์อ้างอิง (เช่น จุดสนใจ ขอบเขต)
- ข้อมูลในอดีตหรือข้อมูลที่ประมวลผลเป็นชุด
สําหรับสถานการณ์ที่ต้องอัปเดตข้อมูลอย่างต่อเนื่อง (เช่น การติดตามแบบสดหรือการวัดและส่งข้อมูลทางไกล) โปรดดู สร้างแผนที่แบบเรียลไทม์โดยใช้ REST API และ Python
ข้อกำหนดเบื้องต้น
- Python 3.10 หรือใหม่กว่า
- Azure CLI
- รหัสพื้นที่ทํางาน Fabric
- สิทธิ์ในการเรียก Fabric REST API เช่น:
Item.ReadWrite.All
Note
ขอบเขตที่ได้รับมอบหมาย เช่น Item.ReadWrite.All มอบให้กับข้อมูลประจําตัวที่ลงชื่อเข้าใช้ผ่านบทบาทพื้นที่ทํางาน ตรวจสอบให้แน่ใจว่าข้อมูลประจําตัวที่คุณใช้กับ az login ถูกกําหนดบทบาท Contributor, Member หรือ Admin บนพื้นที่ทํางาน Fabric เป้าหมายก่อนที่จะเรียกใช้สคริปต์
การรับรองความถูกต้อง
บทช่วยสอนนี้ใช้ DefaultAzureCredentialซึ่งสามารถรับรองความถูกต้องโดยใช้แหล่งข้อมูลข้อมูลประจําตัวภายใน/ผู้พัฒนาหลายแหล่ง สําหรับผู้อ่านครั้งแรก วิธีที่ง่ายที่สุดคือการลงชื่อเข้าใช้ Azure CLI
ตรวจสอบสิทธิ์ภายในเครื่อง (แนะนําสําหรับการทํางานครั้งแรก)
- เปิดเทอร์มินัล
- วิ่ง:
az login
DefaultAzureCredential สามารถใช้ข้อมูลประจําตัวที่ลงชื่อเข้าใช้เพื่อรับโทเค็นเพื่อการเข้าถึงสําหรับสิ่งต่อไปนี้
- Fabric REST API (ทรัพยากร:
https://api.fabric.microsoft.com/.default) - การเข้าถึง OneLake ผ่าน ADLS Gen2 API และ SDK รวมถึงการกําหนดที่อยู่ตาม GUID สําหรับพื้นที่ทํางานและรายการ
Tip
เกี่ยวกับ https://api.fabric.microsoft.com/.default ค่านี้เป็น ขอบเขตคําขอโทเค็น ไม่ใช่ URL ที่คุณเรียกใช้โดยตรง จะบอก Microsoft Entra ว่าควรออกโทเค็นการเข้าถึงสําหรับ Microsoft Fabric REST API และควรรวม สิทธิ์ Fabric ทั้งหมดที่มอบให้กับ ข้อมูลประจําตัวที่รับรองความถูกต้องแล้ว (เช่น Item.ReadWrite.All หรือ Workspace.ReadWrite.All)
ขอบเขตจะใช้ .default เฉพาะระหว่างการรับโทเค็น และจะไม่ถูกส่งไปยังตําแหน่งข้อมูล Fabric REST API
สําหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธี.defaultการทํางานของขอบเขตในแพลตฟอร์มข้อมูลประจําตัวของ Microsoft ให้ดูที่ ขอบเขตและสิทธิ์ในแพลตฟอร์มข้อมูลประจําตัวของ Microsoft
ลงชื่อเข้าใช้ Microsoft Fabric (แนะนํา)
ก่อนที่คุณจะเรียกใช้บทช่วยสอนนี้ เราขอแนะนําให้ลงชื่อเข้าใช้ Microsoft Fabric อย่างน้อยหนึ่งครั้ง:
https://app.fabric.microsoft.com
การลงชื่อเข้าใช้ช่วยให้แน่ใจว่าข้อมูลประจําตัว Fabric การเป็นสมาชิกบทบาทพื้นที่ทํางาน และการกําหนดความจุของคุณได้รับการจัดเตรียมอย่างสมบูรณ์ก่อนที่จะได้รับโทเค็นการเข้าถึง Microsoft Entra โดยทางโปรแกรม
ขั้นตอนนี้มีประโยชน์อย่างยิ่งในกรณีต่อไปนี้
- คุณเพิ่งเริ่มใช้ Microsoft Fabric
- พื้นที่ทํางานเพิ่งสร้างขึ้น
- เพิ่มการมอบหมายบทบาทของคุณเมื่อเร็วๆ นี้
Note
บทช่วยสอนนี้รับรองความถูกต้องโดยใช้ Microsoft Entra ID ผ่านDefaultAzureCredential Fabric REST API ไม่จําเป็นต้องมีเซสชันเบราว์เซอร์ แต่การลงชื่อเข้าใช้ประสบการณ์เว็บ Fabric สามารถป้องกันปัญหาการอนุญาตการเรียกใช้ครั้งแรกที่เกิดจากการเตรียมใช้งานบทบาทที่ล่าช้า
สร้างไฟล์ GeoJSON
ไฟล์ GeoJSON ในบทแนะนําสอนการใช้งานนี้ใช้เป็นเลเยอร์ข้อมูลของแผนที่ เมื่อคุณสร้างไฟล์แล้ว ให้อัปเดต local_geojson_path ตัวแปรเพื่อแสดงเส้นทางที่ถูกต้อง
คัดลอก GeoJSON ต่อไปนี้ลงในไฟล์ข้อความเปล่า และบันทึกไฟล์เป็น 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] }
}
]
}
สำคัญ
ตรวจสอบให้แน่ใจว่าเส้นทางไฟล์ที่ใช้ใน local_geojson_path ตรงกับตําแหน่งที่คุณบันทึกไฟล์บนเครื่องของคุณ
ขั้นตอนที่ 1 - สร้างไฟล์โปรเจ็กต์ Python ใหม่
ในขั้นตอนนี้ คุณจะสร้างไฟล์ Python เปล่าที่คุณจะสร้างทีละส่วน
สร้างไฟล์ใหม่ที่มีชื่อว่า
create_map_from_geojson.py
เปิดไฟล์ในเครื่องมือแก้ไข
ขั้นตอนที่ 2 - ติดตั้งไลบรารีที่จําเป็นและเพิ่มคําสั่งนําเข้าที่จําเป็น
ในขั้นตอนนี้ คุณติดตั้งการขึ้นต่อกัน และเพิ่มการนําเข้าที่สคริปต์ของคุณใช้
ติดตั้งไลบรารีที่จําเป็น
วิ่ง:
pip install httpx azure-identity azure-storage-file-datalake
แต่ละห้องสมุดมีไว้เพื่ออะไร
- httpx: ส่งคําขอ HTTP ไปยัง Fabric REST API
-
azure-identity: ให้
DefaultAzureCredentialสําหรับการรับรองความถูกต้อง Microsoft Entra - azure-storage-file-datalake: อัปโหลดไฟล์ไปยัง OneLake โดยใช้ API ที่เข้ากันได้กับ ADLS Gen2
เพิ่มคําสั่งนําเข้าลงในไฟล์ .py ของคุณ
ที่ด้านบนของ create_map_from_geojson.py ให้เพิ่มสิ่งต่อไปนี้
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
ขั้นตอนที่ 3 - เพิ่มส่วนการกําหนดค่า
ในขั้นตอนนี้ คุณกําหนดตัวแปรที่แอปพลิเคชันของคุณใช้ รวมถึงรหัสพื้นที่ทํางาน เส้นทางไฟล์ และการสลับคุณลักษณะ
การรวมศูนย์การกําหนดค่าในคลาสเดียว Config — แทนที่จะกระจายค่าฮาร์ดโค้ดข้ามฟังก์ชัน — ให้ข้อได้เปรียบที่เป็นรูปธรรมสามประการแก่คุณ:
- การเคลื่อนย้ายสภาพแวดล้อม: รหัสพื้นที่ทํางาน เส้นทางไฟล์ และชื่อทรัพยากรอยู่ในที่เดียว คุณจึงสามารถเรียกใช้สคริปต์ซ้ํากับพื้นที่ทํางานหรือเครื่องอื่นได้โดยการเปลี่ยนสองสามบรรทัด (หรือตัวแปรสภาพแวดล้อม) แทนการค้นหาโค้ด
-
ลายเซ็นฟังก์ชันที่สะอาดขึ้น: ฟังก์ชันขั้นตอนยอมรับวัตถุเดียว
cfgแทนรายการพารามิเตอร์ที่ยาว ซึ่งช่วยให้การประสานงานอ่านmain()ง่าย - การจัดการข้อมูลลับที่ปลอดภัยยิ่งขึ้น: ค่าที่ละเอียดอ่อน เช่น รหัสพื้นที่ทํางาน ถูกโหลดจากตัวแปรสภาพแวดล้อม ดังนั้นจึงไม่เคยถูกส่งไปพร้อมกับสคริปต์
เพิ่มข้อความต่อไปนี้ด้านล่างคําสั่ง นําเข้า :
# =========================================================
# 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"
ตั้งค่ารหัสพื้นที่ทํางานโดยใช้ตัวแปรสภาพแวดล้อม
แทนที่จะฮาร์ดโค้ดรหัสพื้นที่ทํางานโดยตรงในสคริปต์บทช่วยสอนนี้จะอ่านจากตัวแปรสภาพแวดล้อม วิธีนี้จะเก็บค่าเฉพาะสภาพแวดล้อมออกจากซอร์สโค้ด และช่วยให้คุณสามารถนําสคริปต์กลับมาใช้ใหม่ในพื้นที่ทํางานหรือเครื่องได้โดยไม่ต้องแก้ไข
ก่อนเรียกใช้สคริปต์ ให้สร้างตัวแปรสภาพแวดล้อมชื่อ FABRIC_WORKSPACE_ID.
สำคัญ
ตัวแปรสภาพแวดล้อมที่ตั้งค่าจากเทอร์มินัลมีอยู่ภายในเซสชันเทอร์มินัลเดียวเท่านั้น ไม่ได้แชร์กับหน้าต่างเทอร์มินัลอื่น ๆ ด้วยประเภทเชลล์อื่น หรือกับกระบวนการที่เปิดตัวนอกเทอร์มินัลนั้น รวมถึงสคริปต์ที่เริ่มต้นจากปุ่มเรียกใช้ของ VS Code ซึ่งมักจะสร้างเทอร์มินัลของตัวเอง หากสคริปต์ไม่พบตัวแปร แสดงว่าสคริปต์ล้มเหลวด้วยSet FABRIC_WORKSPACE_ID environment variable before running the script
เพื่อหลีกเลี่ยงปัญหานี้ ให้เรียกใช้สคริปต์จาก เซสชันเทอร์มินัลเดียวกัน ที่คุณตั้งค่าตัวแปร หรือตั้งค่าอย่างต่อเนื่อง (ดูส่วน Windows และ macOS/Linux ที่ตามมา) เพื่อให้ทุกเซสชันเทอร์มินัลใหม่รับโดยอัตโนมัติ
ตั้งค่าตัวแปรสภาพแวดล้อมบน Windows
บน Windows คุณสามารถตั้งค่าตัวแปรจากเทอร์มินัลใดก็ได้ที่รองรับตัวแปรสภาพแวดล้อม เช่น PowerShell, Windows PowerShell, PowerShell หรือ Command Prompt windows ที่สร้างขึ้นใน Visual Studio และ Visual Studio Code, เทอร์มินัล Windows และส่วนใหญ่ เปลือกหอยอื่น ๆ
เรียกใช้สิ่งต่อไปนี้ใน PowerShell หรือเทอร์มินัลแบบรวม VS Code:
$env:FABRIC_WORKSPACE_ID="<WORKSPACE_ID>"
เพื่อยืนยันว่าตัวแปรถูกตั้งค่า:
echo $env:FABRIC_WORKSPACE_ID
สิ่งนี้จะตั้งค่าตัวแปรสําหรับเซสชันเทอร์มินัลปัจจุบันเท่านั้น
ตั้งค่าตัวแปรสภาพแวดล้อมถาวร (Windows)
หากต้องการให้ตัวแปรพร้อมใช้งานในเซสชันในอนาคต ให้ใช้วิธีใดวิธีหนึ่งต่อไปนี้
-
PowerShell (บรรทัดเดียว): เรียกใช้
setx FABRIC_WORKSPACE_ID "<WORKSPACE_ID>"setxคําสั่งจะเขียนไปยังสภาพแวดล้อมของผู้ใช้ แต่จะไม่อัปเดตเทอร์มินัลปัจจุบัน ให้ปิดและเปิดเทอร์มินัลอีกครั้ง (หรือเปิดเทอร์มินัลใหม่) ก่อนเรียกใช้สคริปต์ -
จีโอ:
- เปิด คุณสมบัติของระบบ
- เลือก การตั้งค่าระบบขั้นสูง
- เลือกตัวแปรสภาพแวดล้อม
- ภายใต้ ตัวแปรผู้ใช้ ให้เลือก สร้าง
- ป้อน:
- ชื่อ:
FABRIC_WORKSPACE_ID - ค่า: รหัสพื้นที่ทํางานของคุณ
- ชื่อ:
- เลือก ตกลง เพื่อบันทึก
- ปิดและเปิดเทอร์มินัลของคุณอีกครั้งก่อนที่จะเรียกใช้สคริปต์อีกครั้ง
ตั้งค่าตัวแปรสภาพแวดล้อมบน macOS หรือ Linux
บน macOS และ Linux คุณสามารถตั้งค่าตัวแปรจากเชลล์ใดก็ได้ที่รองรับ export—Bash, Zsh (ค่าเริ่มต้นใน macOS สมัยใหม่), Fish (ด้วยไวยากรณ์ที่แตกต่างกันเล็กน้อย) และเทอร์มินัลในตัวใน Visual Studio Code และตัวแก้ไขอื่นๆ
วิ่ง:
export FABRIC_WORKSPACE_ID="<WORKSPACE_ID>"
เพื่อยืนยันว่าตัวแปรถูกตั้งค่า:
echo $FABRIC_WORKSPACE_ID
สิ่งนี้ตั้งค่าตัวแปรสําหรับเซสชันเชลล์ปัจจุบันเท่านั้น
ตั้งค่าตัวแปรสภาพแวดล้อมถาวร (macOS หรือ Linux)
หากต้องการให้ตัวแปรพร้อมใช้งานในเซสชันในอนาคต ให้เพิ่มบรรทัดลงใน export โปรไฟล์เชลล์ของคุณ:
-
Zsh (ค่าเริ่มต้นบน macOS):
~/.zshrc -
ทุบตี:
~/.bashrc(Linux) หรือ~/.bash_profile(macOS) -
ปลา: เรียกใช้
set -Ux FABRIC_WORKSPACE_ID "<WORKSPACE_ID>"แทนการแก้ไขไฟล์
หลังจากอัปเดตโปรไฟล์แล้ว ให้เปิดเทอร์มินัลใหม่หรือเรียกใช้ source ~/.zshrc (หรือไฟล์ที่เหมาะสม) เพื่อให้การเปลี่ยนแปลงมีผล
Note
ค่า geojson_relative_path และ svg_relative_path กําหนดตําแหน่งภายในพื้นที่ ไฟล์เลคเฮาส์ เส้นทางเหล่านี้สัมพันธ์กับรากของ Lakehouse และใช้ทั้งสําหรับการอัปโหลดไฟล์และการอ้างอิงในคําจํากัดความของแผนที่
ขั้นตอนที่ 4 - เพิ่มฟังก์ชันตัวช่วย
ในขั้นตอนนี้ คุณจะแยกข้อกังวลข้ามด้านออก เช่น การรับรองความถูกต้อง การสร้างส่วนหัว การสํารวจการดําเนินการที่ยาวนาน และการอัปโหลดระนาบข้อมูลที่ลองใหม่ได้เป็นชุดตัวช่วยที่นํากลับมาใช้ใหม่ได้ขนาดเล็ก ซึ่งทุกขั้นตอนของฟังก์ชันสามารถเรียกใช้ได้
การรวมศูนย์ข้อกังวลเหล่านี้ไว้ในผู้ช่วย แทนที่จะรวมไว้ในทุกไซต์การโทร ให้ข้อดีที่เป็นรูปธรรมสามประการแก่คุณ:
- แหล่งข้อมูลเดียวสําหรับข้อกังวลข้ามด้าน: การรับรองความถูกต้อง ส่วนหัว และการสํารวจ LRO เป็นสิ่งจําเป็นสําหรับการเรียก API เกือบทุกครั้ง การรวมศูนย์ทําให้ฟังก์ชันแต่ละขั้นตอนมุ่งเน้นไปที่ทรัพยากรของตัวเองแทนที่จะใช้ตรรกะการรับโทเค็นและลองใหม่อีกครั้ง
- ความยืดหยุ่นโดยไม่ยุ่งเหยิง: ตัวช่วยดูดซับเงื่อนไขชั่วคราว เช่น การจัดเตรียมแบบอะซิงโครนัส ความล่าช้าในการเผยแพร่แบ็กเอนด์ ความล้มเหลวในการอัปโหลดที่ลองใหม่ได้ ดังนั้นฟังก์ชันขั้นตอนจึงสั้นและอ่านเหมือนรายการตรวจสอบ
- สอนและแก้ไขได้ง่ายขึ้น: ตัวช่วยแต่ละคนจะถูกนํามาใช้เพียงครั้งเดียวและนํากลับมาใช้ใหม่ หาก Fabric เปลี่ยนรูปแบบ LRO หรือขอบเขตการรับรองความถูกต้อง คุณจะแก้ไขได้ในที่เดียว
ตัวช่วยที่คุณเพิ่มในขั้นตอนนี้คือ:
- ตัวช่วยการรับรองความถูกต้อง: สร้างส่วนหัวสําหรับ REST API Fabric (และปลายทาง LRO ของคลัสเตอร์ Power BI)
- FabricClient: ตัวห่อหุ้มน้ําหนักเบาสําหรับการเรียก API ที่สอดคล้องกัน
-
ตัวจัดการ LRO: สํารวจการดําเนินการที่ทํางานเป็นเวลานานโดยใช้
Location/x-ms-operation-id/Retry-Afterรวมถึงการตอบสนอง200-with-Runningจุดสิ้นสุดคลัสเตอร์ Power BI และเพย์โหลดการเสร็จสมบูรณ์ตามสถานะเท่านั้น (แก้ไขโดยdisplayName) -
ตัวช่วยเพย์โหลดคําจํากัดความ: base64-encode
map.jsonสําหรับคําจํากัดความแบบอินไลน์ - ตัวช่วยอัปโหลด OneLake: อัปโหลดไฟล์ GeoJSON และ SVG ไปยังไฟล์ Lakehouse ด้วยการลองอีกครั้ง
Note
บทช่วยสอนนี้ครอบคลุมสองระนาบ:
- Control plane (Fabric REST API): สร้างไอเท็มเลคเฮาส์และแผนที่
- ระนาบข้อมูล (OneLake DFS): อัปโหลดไฟล์ไปยังเลคเฮาส์
ทั้งสองจะต้องตั้งค่าแผนที่อย่างสมบูรณ์
สร้างฟังก์ชันตัวช่วยการรับรองความถูกต้อง
ทุก Fabric REST ที่บทช่วยสอนนี้ทําจะมีโทเค็นการเข้าถึง Microsoft Entra (โทเค็นผู้ถือ) ในส่วนหัว Authorization แทนที่จะได้มาซึ่งโทเค็นเฉพาะกิจขั้นตอนนี้จะห่อหุ้ม DefaultAzureCredential ด้วยขนาดเล็ก TokenProvider และเปิดเผยตัวสร้างส่วนหัวเฉพาะกลุ่มเป้าหมายสําหรับแต่ละตระกูลปลายทางที่สคริปต์เรียกใช้
การรวมศูนย์การได้มาซึ่งโทเค็นและการสร้างส่วนหัวในตัวช่วย — แทนที่จะรับโทเค็นในทุกไซต์การโทร — ให้ข้อได้เปรียบที่เป็นรูปธรรมสามประการแก่คุณ:
-
ข้อมูลประจําตัวแบบรวมศูนย์:
DefaultAzureCredentialเดียวถูกห่อไว้ในTokenProviderและนํามาใช้ซ้ําสําหรับการเรียก API ทุกครั้ง ดังนั้นการค้นพบข้อมูลประจําตัว (Azure CLI, VS Code, ข้อมูลประจําตัวที่มีการจัดการ ฯลฯ) จะเกิดขึ้นเพียงครั้งเดียว - โทเค็นที่รับรู้กลุ่มเป้าหมาย: Fabric REST API และตําแหน่งข้อมูล LRO ของคลัสเตอร์ Power BI ต้องการโทเค็นที่ออกสําหรับกลุ่มเป้าหมายที่แตกต่างกัน เครื่องมือสร้างส่วนหัวแยกต่างหากต่อกลุ่มเป้าหมายจะเก็บขอบเขตที่ถูกต้องไว้ถัดจากไซต์การโทร ดังนั้นจึงเห็นได้ชัดว่าแต่ละฟังก์ชันกําหนดเป้าหมายปลายทางใด
-
สดใหม่ในทุกคําขอ: ผู้
Authorizationสร้างส่วนหัวสร้างส่วนหัวตามความต้องการแทนที่จะแคชโทเค็นเอง ข้อมูลประจําตัวพื้นฐานจะรีเฟรชอย่างโปร่งใส ดังนั้นไซต์การโทรจึงไม่ต้องคิดถึงวันหมดอายุ
บทช่วยสอนนี้เรียกใช้ REST API Fabric โดยใช้ขอบเขตที่ได้รับมอบหมาย เช่น Item.ReadWrite.All (หรือ Lakehouse.ReadWrite.All สําหรับการดําเนินการเฉพาะของ Lakehouse)
เพิ่มสิ่งต่อไปนี้หลัง Config ชั้นเรียน
# =========================================================
# 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
การดําเนินการที่ทํางานเป็นเวลานาน (LRO) Fabric บางรายการโฮสต์บนจุดสิ้นสุดคลัสเตอร์ Power BI (*.analysis.windows.net) แทนที่จะเป็นบน api.fabric.microsoft.com ปลายทางเหล่านั้นต้องใช้โทเค็นผู้ชม Power BI ดังนั้นตัวช่วย LRO จะเปลี่ยนเป็น _pbi_headers() โดยอัตโนมัติเมื่อตรวจพบ URL การสํารวจนั้น
สร้าง Fabric Client Wrapper
การเรียก REST Fabric ส่วนใหญ่ในบทช่วยสอนนี้ส่งส่วนหัว Authorization และ Content-Type เดียวกัน แทนที่จะทําซ้ําในทุกไซต์การโทรบทช่วยสอนนี้จะห่อหุ้มhttpx.ClientFabricClientในส่วนหัวขนาดเล็กที่แนบส่วนหัวโดยอัตโนมัติในขณะที่ยังคงส่งคืนดิบhttpx.Responseเพื่อให้ผู้โทรแต่ละคนสามารถตรวจสอบรหัสสถานะได้ (ตัวอย่างเช่นเพื่อแยกความแตกต่าง201จาก 202)
การห่อแบบ httpx.Client นี้ — แทนที่จะส่งผ่าน headers=_fabric_headers() ทุกไซต์การโทร — ให้ข้อได้เปรียบที่เป็นรูปธรรมสองประการแก่คุณ:
-
ส่วนหัวในที่เดียว: ทุกไซต์การโทรจะรับคําขอล่าสุด
_fabric_headers()โดยอัตโนมัติ ดังนั้นจึงไม่สามารถส่งคําขอใหม่โดยไม่ได้ตั้งใจหากไม่มีAuthorizationส่วนหัว -
รหัสสถานะยังคงมองเห็นได้:
request()ส่งคืน JSON ดิบhttpx.Responseแทน JSON ที่ถอดรหัส ดังนั้นไซต์การโทรจึงยังคงสามารถแยกสาขาตามสถานะ (201เทียบกับ202) และตรวจสอบส่วนหัว เช่นLocationหรือRetry-Afterสําหรับการจัดการ LRO
เพิ่มสิ่งต่อไปนี้หลังจากฟังก์ชันตัวช่วยการรับรองความถูกต้อง:
# =========================================================
# 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)
สร้างฟังก์ชันตัวช่วย LRO
REST API Fabric หลายตัวที่ใช้ในบทช่วยสอนนี้ เช่น Create Lakehouse และ Create Map รองรับ long-running operations (LROs)
API เหล่านี้สามารถส่งคืนการตอบกลับได้หลายรูปแบบ:
-
201 Createdด้วยเนื้อหาทรัพยากรแบบอินไลน์ (ซิงโครนัส) -
202 AcceptedโดยมีLocationส่วนหัวชี้ไปที่ URL สถานะการทํางาน (อะซิงโครนัส) -
202 Acceptedด้วยx-ms-operation-idส่วนหัวแทนLocation(อะซิงโครนัส, รูปแบบอื่น) -
200 OKมีstatus: "Running"หรือstatus: "NotStarted"ขณะทําโพล (ยังอยู่ระหว่างดําเนินการ) -
200 OKโดยมีstatus: "Succeeded"แต่ไม่มีรหัสทรัพยากรในเนื้อหา (สําเร็จ แก้ไขโดยการแสดงรายการและการจับคู่displayName)
เมื่อต้องการจัดการกับสิ่งเหล่านี้อย่างสม่ําเสมอ ให้สร้างฟังก์ชันตัวช่วยเดียวที่:
- ส่งคืนรหัสทรัพยากรทันทีหากการตอบกลับเริ่มต้นมีอยู่แล้ว
- มิฉะนั้นจะสํารวจ URL การดําเนินการ (สร้างจาก
Locationorx-ms-operation-id) โดยใช้Retry-After. - ปฏิบัติ
200 OKต่อstatus: "Running"/"NotStarted"การที่ยังอยู่ในระหว่างดําเนินการและดําเนินการสํารวจความคิดเห็นต่อไป - เมื่อสําเร็จ จะส่งคืนรหัสทรัพยากรจากเนื้อหา หรือย้อนกลับไปแสดงรายการทรัพยากรและการจับคู่ตาม
displayName(ด้วยการลองใหม่) เมื่อเนื้อหาเป็นสถานะเท่านั้น - ใช้
_pbi_headers()เมื่อ URL การสํารวจอยู่บนคลัสเตอร์ Power BI (*.analysis.windows.net) และส่วนหัว Fabric
ตัวช่วยตัวเดียวนี้แทนที่ความต้องการตัวช่วย "แก้ไขตามชื่อ" ต่อทรัพยากร — ทุกcreate_*ฟังก์ชันในบทช่วยสอนนี้เรียก_handle_lroด้วยตัวlist_urlmatch_display_nameช่วยและ .
เพิ่มสิ่งต่อไปนี้หลัง FabricClient ชั้นเรียน
# =========================================================
# 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
ทรัพยากรที่สร้างขึ้นใหม่อาจไม่ปรากฏขึ้นทันทีเมื่อเรียกใช้ API รายการ เนื่องจากความล่าช้าในการเผยแพร่แบ็กเอนด์ ฟังก์ชันตัวช่วยจะลองใหม่โดยอัตโนมัติจนกว่าทรัพยากรจะปรากฏให้เห็น
ตัวช่วยเพย์โหลดคําจํากัดความ
เมื่อคุณสร้างแผนที่ด้วยคําจํากัดความสาธารณะ REST API สร้างแผนที่คาดหวังให้แต่ละส่วนมีdefinition.partsเพย์โหลดที่เข้ารหัส base64 ด้วย"payloadType": "InlineBase64" ตัวช่วย _json_to_b64 เข้ารหัส Python dict (map.json) ของคุณในรูปแบบนั้น เพื่อให้ create_map สามารถวางลงในเนื้อหาคําขอได้โดยตรง
เพิ่มสิ่งต่อไปนี้หลัง _handle_lro ฟังก์ชัน:
# =========================================================
# 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")
ตัวช่วยอัปโหลด OneLake
OneLake รองรับ ADLS/Blob API และอนุญาตให้กําหนดที่อยู่ตาม GUID สําหรับพื้นที่ทํางานและรายการ:
https://onelake.dfs.fabric.microsoft.com/<workspaceGUID>/<itemGUID>/<path>/<fileName>
เพิ่ม:
# ===============================================================================================
# 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}")
Tip
คุณสามารถตรวจสอบว่าไฟล์ถูกอัปโหลดสําเร็จโดยการเรียกดูพื้นที่ไฟล์ Lakehouse ในพอร์ทัล Fabric
สร้างฟังก์ชันหลัก
ถัดไป คุณเพิ่มฟังก์ชันหลักที่กําหนดเวิร์กโฟลว์ ทั้งหมดนี้เรียกว่า main().
- สร้างเลคเฮ้าส์
- อัปโหลด GeoJSON ไปยังเลคเฮาส์
- อัปโหลดเครื่องหมาย SVG ที่กําหนดเอง (ไม่บังคับ)
- สร้างคําจํากัดความแผนที่ (
map.json) - สร้างแผนที่ด้วยคําจํากัดความแบบอินไลน์
สร้างเลคเฮ้าส์
create_lakehouse สร้างเลคเฮาส์ที่จัดเก็บไฟล์ GeoJSON และเครื่องหมาย SVG เสริมที่ใช้โดยแผนที่
ฟังก์ชั่นนี้:
- ส่ง POST ไปยังปลายทาง Lakehouse REST ด้วย
displayNameและdescriptionจากการกําหนดค่าของคุณ - ส่งการตอบสนองไปยัง
_handle_lroซึ่งจัดการการตอบสนองแบบซิงโครนัส (201) อะซิงโครนัส (202/LRO) และสถานะอย่างเดียวอย่างสม่ําเสมอ - ส่งคืน Lakehouse ID เพื่อใช้ในขั้นตอนต่อมา
เพิ่มสิ่งต่อไปนี้หลัง _upload_with_retry ฟังก์ชัน:
# =========================================================
# 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
อัปโหลด GeoJSON ไปยังเลคเฮาส์
upload_geojson อัปโหลดไฟล์ GeoJSON ในเครื่องไปยังพื้นที่ Lakehouse Files ซึ่งจะกลายเป็นแหล่งข้อมูลเชิงพื้นที่ที่แผนที่อ่านในเวลาที่แสดงผล
นี่เป็นขั้นตอนแรกที่ข้ามจากระนาบควบคุม Fabric (REST) ไปยังระนาบข้อมูล OneLake (ADLS Gen2) ฟังก์ชันจะอ่านไฟล์โลคัลลงในหน่วยความจําและมอบหมายให้ _upload_with_retryซึ่งดําเนินการอัปโหลด DFS แบบแบ่งกลุ่มและลองใหม่ในข้อผิดพลาดชั่วคราว
เพิ่มสิ่งต่อไปนี้หลัง create_lakehouse ฟังก์ชัน:
# =========================================================
# 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)
อัปโหลดเครื่องหมาย SVG ที่กําหนดเอง
upload_svg_marker อัปโหลดไอคอน SVG ที่กําหนดเองลงในเลคเฮาส์เดียวกัน เพื่อให้แผนที่สามารถแสดงคุณลักษณะแต่ละรายการด้วยเครื่องหมายนั้นแทนที่จะเป็นไอคอนในตัว ขั้นตอนนี้เป็นทางเลือกและรั้วรอบขอบชิดโดย cfg.use_custom_svg_marker — เมื่อธงเป็น Falseฟังก์ชันจะส่งคืนทันทีและแผนที่จะกลับไปที่เครื่องหมายในตัว
เช่นเดียวกับupload_geojsonฟังก์ชันนี้มอบหมายการอัปโหลดจริงให้กับ_upload_with_retry
เพิ่มสิ่งต่อไปนี้หลัง upload_geojson ฟังก์ชัน:
# =========================================================
# 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)
Tip
เครื่องหมาย SVG ปรับขนาดได้อย่างหมดจดในระดับการซูมและ DPI ของหน้าจอ ซึ่งทําให้เหมาะอย่างยิ่งสําหรับไอคอนแผนที่
สร้าง map.json
build_map_json สร้างและส่งคืนเพย์โหลด map.json ที่กําหนดเนื้อหาของ Fabric Map เพย์โหลดเป็นไปตามสคีมาข้อกําหนดของรายการแผนที่และประกอบด้วยสี่ส่วน: dataSources (ที่มาของข้อมูล) iconSources (เครื่องหมายที่กําหนดเองเพิ่มเติม) layerSources (สิ่งที่อ่านและความถี่) และ layerSettings (วิธีแสดงผลลัพธ์บนแผนที่)
สําหรับบทช่วยสอนนี้ ให้dataSourcesชี้ไปที่ Lakehouse (itemType: "Lakehouse") ที่สร้างขึ้นก่อนหน้านี้ และรายการเดียวคือlayerSourcesเลเยอร์ไฟล์ GeoJSON (type: "geojson") ที่อ่านไฟล์ที่คุณอัปโหลดผ่านrelativePath
refreshIntervalMs ถูกตั้งค่าเป็น 0 เนื่องจากไฟล์ต้นฉบับเป็นแบบคงที่ — แผนที่จะแสดงไฟล์เพียงครั้งเดียวและไม่สํารวจการเปลี่ยนแปลง
รายการที่ layerSettings ตรงกันจะแสดงคุณลักษณะแต่ละรายการเป็น a marker และแสดงคุณสมบัติ GeoJSON name ในคําแนะนําเครื่องมือ เมื่อcfg.use_custom_svg_markerเป็น TrueiconSources จะมีการเพิ่มรายการที่อ้างอิง SVG ที่คุณอัปโหลด และเลเยอร์iconOptions.imageจะใช้คีย์<layerSettingId>:<iconId>คอมโพสิตเพื่อผูกเครื่องหมายกับไอคอนนั้น เมื่อเป็น Falseเลเยอร์จะถอยกลับไปที่เครื่องหมายในตัว (cfg.builtin_icon_name_fallback) ที่จัดสไตล์ด้วยการเติมสีเขียวสตาร์บัคส์
สําหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อกําหนดแผนที่ REST API โปรดดู คําจํากัดความของรายการแผนที่ สําหรับตัวอย่างของ โปรดดูmap.jsonตัวอย่าง MapDetails
เพิ่มสิ่งต่อไปนี้หลัง upload_svg_marker ฟังก์ชัน:
# =========================================================
# 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
Tip
เคล็ดลับที่เกี่ยวข้องกับคําจํากัดความของแผนที่:
- คุณสมบัตินี้
imageใช้คีย์รวมในรูปแบบ<layerSettingId>:<iconId>เพื่ออ้างอิงไอคอนสําหรับเลเยอร์ สิ่งนี้เชื่อมโยงการกําหนดค่าการแสดงผลเครื่องหมายกับแหล่งที่มาของไอคอนที่กําหนดไว้ก่อนหน้านี้ในข้อกําหนดแผนที่ - การตั้งค่า
refreshIntervalMsเพื่อ0ปิดใช้งานการรีเฟรชอัตโนมัติ วิธีนี้เหมาะสําหรับไฟล์ GeoJSON แบบคงที่ที่จัดเก็บไว้ในเลคเฮาส์
สร้างแผนที่ด้วยคําจํากัดความแบบอินไลน์
create_map สร้างแผนที่โดยการลงรายการบัญชีข้อกําหนดแบบอินไลน์ที่คุณได้ประกอบไว้ และส่งคืนรหัสไอเท็มของแผนที่ใหม่ สําหรับบทช่วยสอนนี้ คําขอมีส่วนที่เข้ารหัส base64 เพียงส่วนเดียว — map.json — ห่อเป็นpayloadType: "InlineBase64"และเข้ารหัสผ่าน_json_to_b64
map.jsonเพย์โหลดอ้างอิงแหล่งข้อมูล Lakehouse อยู่แล้ว และเมื่อมี ไอคอน SVG โดย relativePathดังนั้นเลเยอร์จึงต่อสายอย่างสมบูรณ์โดยการเรียก Create Map โดยไม่ต้องติดตามผลupdateDefinitionไปกลับ หากคุณต้องการตั้งค่าข้อมูลเมตาของรายการที่ไม่ใช่ค่าเริ่มต้นหรือปักหมุด logicalId ที่เป็นมิตรกับ Git คุณจะต้องเพิ่มส่วน .platform ลงในอาร์เรย์ parts เดียวกัน Fabric ใช้ข้อมูลเมตาเริ่มต้นเมื่อละเว้น .platform ซึ่งเป็นสิ่งที่บทช่วยสอนนี้ทํา
สร้างแผนที่ REST API สามารถตอบด้วย 201 Created (ซิงโครนัส, ID แบบอินไลน์), 202 Accepted (LRO แบบอะซิงโครนัสผ่าน Location หรือ x-ms-operation-id) หรือ 200 OK ด้วยเพย์โหลดการเสร็จสมบูรณ์แบบสถานะเท่านั้นที่แผนที่ยังไม่ปรากฏใน List Maps เนื่องจากความล่าช้าในการเผยแพร่แบ็กเอนด์
_handle_lro ครอบคลุมกรณีเหล่านี้ทั้งหมด รวมถึงการแสดงรายการและการจับคู่ตาม displayName ดังนั้นฟังก์ชันนี้จึงมอบหมายการจัดการการตอบกลับแบบเต็มในการเรียกครั้งเดียว
สําหรับข้อมูลเพิ่มเติม โปรดดู ข้อกําหนดของรายการแผนที่
เพิ่มสิ่งต่อไปนี้หลัง build_map_json ฟังก์ชัน:
# =========================================================
# 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,
)
ประสานเวิร์กโฟลว์
main เป็นจุดเริ่มต้นเดียวที่เรียกใช้บทช่วยสอนแบบ end-to-end มันสร้างConfigอินสแตนซ์ , เปิดหนึ่งตัวhttpx.Clientที่ใช้ซ้ําในทุกตัวช่วย ห่อเป็น FabricClientจากนั้นเรียกใช้ฟังก์ชันแต่ละขั้นตอนตามลําดับการขึ้นต่อกัน: create_lakehouse → upload_geojson (เขียน GeoJSON ไปยัง OneLake ภายใต้ Lakehouse ใหม่) → upload_svg_marker (ไม่บังคับ ทํางานเมื่อcfg.use_custom_svg_markerตั้งค่าเท่านั้น) → build_map_json → create_map
การเรียงลําดับมีความสําคัญเนื่องจากแต่ละขั้นตอนใช้บางสิ่งที่สร้างขึ้นโดยขั้นตอนก่อนหน้านี้ และ upload_geojsonupload_svg_marker ต้องการรหัสรายการ Lakehouse และ build_map_json อ้างอิงการอัปโหลดทั้งสองโดย relativePath เพื่อให้ Create map สามารถแก้ไขได้ในเวลาแสดงผล บล็อก print สุดท้ายจะแสดง Lakehouse ID, รหัสแผนที่ และเส้นทางสัมพัทธ์ของเนื้อหาที่อัปโหลด เพื่อให้คุณสามารถค้นหาได้ในพอร์ทัล Fabric
เพิ่มสิ่งต่อไปนี้หลัง create_map ฟังก์ชัน:
# =========================================================
# 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()
ณ จุดนี้ การกําหนดค่าและรหัสทั้งหมดได้รับการกําหนดแล้ว
ในขั้นตอนต่อไป คุณเรียกใช้สคริปต์เพื่อสร้าง Lakehouse อัปโหลดข้อมูล และสร้างแผนที่
เรียกใช้แอปพลิเคชัน
Note
ชื่อที่แสดงของเลคเฮาส์และแผนที่ต้องไม่ซ้ํากันภายในพื้นที่ทํางาน ก่อนที่จะเรียกใช้สคริปต์อีกครั้ง ให้ลบรายการที่สร้างขึ้นในการเรียกใช้ครั้งก่อนออกจากพื้นที่ทํางาน Fabric หรือเปลี่ยน lakehouse_display_name / map_display_name ใน Config มิฉะนั้น สร้างการเรียกจะล้มเหลวด้วย409 ItemDisplayNameAlreadyInUse
เรียกใช้สคริปต์ที่:
python create_map_from_geojson.py
หากสคริปต์ทํางานสําเร็จ คุณจะเห็นผลลัพธ์ที่คล้ายกับ:
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
ใน Microsoft Fabric แผนที่ของคุณควรมีลักษณะคล้ายกับสิ่งนี้:
Tip
หากแผนที่ไม่ปรากฏขึ้นทันที ให้รีเฟรชพื้นที่ทํางานหรือรอสักครู่เพื่อให้การเผยแพร่แบ็กเอนด์เสร็จสมบูรณ์
Summary
ในบทช่วยสอนนี้ คุณได้สร้างโซลูชันเชิงพื้นที่อัตโนมัติโดยใช้ Microsoft Fabric Maps และข้อมูล Lakehouse
คุณใช้ Fabric REST API และ Python เพื่อเตรียมใช้งานและกําหนดค่าทรัพยากรที่จําเป็นทั้งหมด จากนั้นแสดงภาพข้อมูลเชิงพื้นที่ที่จัดเก็บไว้ใน OneLake
คุณทําสิ่งต่อไปนี้สําเร็จ:
- อัปโหลดข้อมูลเชิงพื้นที่ไปยัง เลคเฮาส์
- กําหนดค่าชุดข้อมูลสําหรับการแสดงภาพเชิงพื้นที่
- สร้างแผนที่ Fabric พร้อมคําจํากัดความแบบอินไลน์
- เชื่อมต่อแผนที่กับข้อมูล Lakehouse
- เลเยอร์แผนที่ที่กําหนดค่าเพื่อแสดงคุณลักษณะเชิงพื้นที่
สถาปัตยกรรมนี้แสดงให้เห็นถึงรูปแบบการวิเคราะห์เชิงพื้นที่ในอดีตและชุดงานทั่วไปใน Fabric:
- ข้อมูลจะถูกเก็บไว้ใน OneLake (Lakehouse)
- แผนที่สืบค้นและแสดงชุดข้อมูลเชิงพื้นที่
- เลเยอร์ให้ข้อมูลเชิงลึกที่มองเห็นได้เกี่ยวกับข้อมูลทางภูมิศาสตร์
ด้วยการสร้างทรัพยากรโดยอัตโนมัติโดยใช้ Python และ REST API ตอนนี้คุณมีแนวทางที่ทําซ้ําได้สําหรับการสร้างแอปพลิเคชันเชิงพื้นที่ตามชุดข้อมูลแบบคงที่หรือในอดีต
ขั้นตอนถัดไป
เมื่อคุณเข้าใจวิธีแสดงภาพข้อมูลเชิงพื้นที่จาก Lakehouse แล้ว คุณสามารถขยายโซลูชันนี้ได้:
- รวมชุดข้อมูลหลายชุดเพื่อการวิเคราะห์เชิงพื้นที่ที่สมบูรณ์ยิ่งขึ้น
- ใช้สไตล์และการกรองเพื่อเน้นเทรนด์และรูปแบบ
- เพิ่มเลเยอร์อ้างอิง เช่น ขอบเขตหรือเส้นทาง
- รวมไปป์ไลน์ข้อมูลเพื่อรีเฟรชชุดข้อมูลโดยอัตโนมัติ
- สํารวจสถานการณ์การสตรีมแบบเรียลไทม์โดยใช้ Eventstream และ Eventhouse
สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการทํางานกับข้อมูลเชิงพื้นที่และแผนที่ใน Fabric ให้ดู:
สําหรับบทช่วยสอนที่สาธิตการสร้างแผนที่แบบเรียลไทม์โดยใช้ REST API โปรดดู: