跳至主要内容

使用 Kaleidr 底圖

完成本指南後,您的網頁將顯示一張具有指定樣式和相機視角的交互式 Kaleidr 底圖,代碼還能移動相機或切換樣式。所有套餐(包括 Free)均可使用。您需要一個具備 maps 權限範圍的可公開使用的金鑰,新建金鑰預設包含該權限。

開始之前​

  • 從 kaleidr.com/api-keys 取得可公開使用的金鑰(kld_pk_live_…)。參閱取得 API 金鑰。
  • 測試網頁的來源(如 http://localhost:3000)必須在金鑰的允許來源列表中。如果金鑰未限制來源,則可以在任何網站使用。
  • 通過 HTTP 提供網頁的工具,例如 npx serve .。直接從磁盤打開的網頁沒有可用來源,因此會被限制來源的金鑰拒絕。
  • 如果網站設定了內容安全策略,請在 script-src 中允許 https://cdn.kaleidr.com,在 connect-src 中允許 https://api.kaleidr.com,在 frame-src 中允許 https://map-embed.kaleidr.com。參閱內容安全策略。

第 1 步:添加地圖​

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<kaleidr-map product="tile"
publishable-key="kld_pk_live_…"
style-id="kaleidr-morning"
style="display:block; height:480px"></kaleidr-map>

**預期結果:**先出現“Loading map…”提示,隨後顯示明亮的底圖。在 Network 面板中,向 https://api.kaleidr.com/inference-api/b2b/v1/sdk/sessions 傳送的 POST 要求傳回 200,隨後向 https://map-embed.kaleidr.com/ 要求文檔。iframe URL 僅包含樣式 ID,不包含憑據:金鑰只用於會話要求,會話令牌不會出現在 iframe URL 中。

元素必須設定高度,否則地圖會採用固定的 500 像素高度。<kaleidr-map> 預設使用 display:block,因此高度會生效。仍建議顯式寫入 display:block,以兼容 Safari 16.4 之前的版本;舊版本中該元素以行內方式顯示,並忽略 height。

第 2 步:選擇樣式​

將 style-id 設定為以下通用樣式之一:

style-id外觀
kaleidr-morning明亮:白色地面、青色水域、白色道路。
kaleidr-afternoon中等色調的地面、綠色植被和灰色道路。
kaleidr-evening黃金時刻:暖沙色和橄欖色調。
kaleidr-night深海軍藍和炭灰色,主幹道呈琥珀色。
kaleidr-plain白色畫布,保留邊界與地點標籤;縮放級別達到 15 後顯示 3D 建築。
kaleidr-editorial不顯示標籤的午後配色,適合小型或裝飾性地圖。
<kaleidr-map product="tile" publishable-key="kld_pk_live_…"
style-id="kaleidr-night"
style="display:block; height:480px"></kaleidr-map>

**預期結果:**同一地圖區域改用深色配色。

請始終傳入 style-id。如果省略,將使用組織設定的預設底圖;如果未設定預設底圖,iframe 會顯示“Couldn't find a map id in the URL.”。

樣式 ID 必須完全匹配,不支持短別名。例如 night 不能代替 kaleidr-night。

第 3 步:設定相機​

如果未指定相機,地圖會使用樣式的預設視角,通常顯示整個世界。傳入 center(先經度、後緯度)和 zoom 可定位到目標區域。pitch 控制傾斜角,bearing 控制旋轉方向。

<kaleidr-map product="tile" publishable-key="kld_pk_live_…"
style-id="kaleidr-morning"
center="-0.1276,51.5072" zoom="12" pitch="45" bearing="-20"
style="display:block; height:480px"></kaleidr-map>

**預期結果:**傾斜、旋轉的倫敦市中心地圖。

如果沒有同時傳入 center,系統會忽略 zoom。 pitch 和 bearing 可以單獨設定。

第 4 步:通過代碼移動相機並切換樣式​

元素寫法屬於聲明式集成。若要從 JavaScript 控制地圖,請調用 Kaleidr.mount 並保留傳回的控制控制代碼。

<div id="basemap" style="height:480px"></div>
<p>
<button id="paris">Fly to Paris</button>
<button id="night">Night</button>
<button id="day">Morning</button>
</p>

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<script>
const handle = Kaleidr.mount('#basemap', {
product: 'tile',
publishableKey: 'kld_pk_live_…',
styleId: 'kaleidr-morning',
center: [-0.1276, 51.5072],
zoom: 11,
});

document.getElementById('paris').addEventListener('click', () => {
// duration is in milliseconds. Leave it out to jump with no animation.
handle.setCamera({ center: [2.3522, 48.8566], zoom: 12, duration: 1200 });
});
document.getElementById('night').addEventListener('click', () => {
handle.setStyle('kaleidr-night');
});
document.getElementById('day').addEventListener('click', () => {
handle.setStyle('kaleidr-morning');
});
</script>

**預期結果:**每個按鈕都在原位置更新地圖,iframe 不會重新載入,Network 面板也不會新增會話要求。

注意以下事項:

  • setCamera 和 setStyle 屬於控制控制代碼,而非元素本身。
  • setStyle 僅支持 Tile。對其他產品調用時只會打印警告,不執行操作。
  • Kaleidr.mount 傳回後,可以隨時調用控制代碼方法。若 iframe 中的地圖尚未就緒,調用會按順序排隊,在地圖就緒時應用,因此無需等待第 6 步的 kaleidr-embed:ready 消息。初始相機和樣式應通過掛載選項設定。
  • 對已掛載的元素修改 center、zoom、pitch 或 bearing 可以移動地圖,但修改 style-id 不會產生效果。

第 5 步:將聊天面板連接到地圖(可選)​

Kaleidr Chat 面板可以將 Tile 地圖作為目標,在地圖上為回答中的地點繪制標記,並調整相機使其進入視野。將 Tile 元素放入定位容器中,在其上疊加聊天元素,並通過 map-target 指向 Tile 元素。

<div style="position:relative">
<kaleidr-map id="basemap" product="tile"
publishable-key="kld_pk_live_…"
style-id="kaleidr-morning"
center="-0.1276,51.5072" zoom="11"
style="display:block; height:560px"></kaleidr-map>

<kaleidr-map product="chat" publishable-key="kld_pk_live_…" contained
map-target="#basemap"
style="display:block; position:absolute; inset:0; z-index:1; pointer-events:none"></kaleidr-map>
</div>

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>

**預期結果:**聊天面板停靠在地圖左上角。詢問“coffee near Covent Garden”,即可在 Tile 地圖上看到地點標記。

聊天元素的屬性和樣式的作用:

部分作用
map-target="#basemap"指向聊天面板將控制的 Tile 元素的 CSS 選擇器。
contained將面板停靠在聊天元素內部;如果省略,面板固定在瀏覽器窗口左上角。
position:absolute; inset:0將聊天元素覆蓋整張地圖,使面板位於地圖一角。
z-index:1讓聊天層顯示在地圖上方。
pointer-events:none允許用戶在面板之外拖動和縮放地圖,同時保留面板自身的點擊交互。

注意:

  • 預設金鑰同時具有 maps 和 ai 權限,所以兩個元素可以使用同一個金鑰。聊天元素會單獨申請會話,每次提問都會消耗組織的 AI 點數。
  • 兩個元素的排列順序沒有要求,聊天面板會在需要時查找地圖。

面板佈局和主題選項請參閱主題與佈局,助手的功能與限制請參閱功能和限制。

第 6 步:獲知地圖載入完成的時間(可選)​

SDK 不提供 ready Promise,元素也不會觸發事件。iframe 會在地圖繪制完成時向網頁傳送一條消息;如果繪制失敗,還會傳送另一條消息:

const target = document.getElementById('basemap');

window.addEventListener('message', (event) => {
if (event.origin !== 'https://map-embed.kaleidr.com') return;
const frame = target.querySelector('iframe');
if (!frame || event.source !== frame.contentWindow) return;

const msg = event.data;
if (!msg || typeof msg.type !== 'string') return;

if (msg.type === 'kaleidr-embed:ready') {
// { type, id: 'kaleidr-morning', source: 'tile' }
console.log('basemap loaded', msg.id);
} else if (msg.type === 'kaleidr-embed:error') {
// { type, id, code: 'maplibre_error', message }, or
// { type, id: null, code: 'no_id', message } when there is no style
console.warn('basemap problem', msg.code, msg.message);
}
});

如果會話要求失敗,則不會創建 iframe,因此不會收到消息。錯誤只會顯示在控制台。請參閱無法正常工作時。

完整頁面示例​

將檔案保存為 index.html,填入金鑰,並從該金鑰允許的來源通過 HTTP 提供此目錄。

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Kaleidr basemap</title>
<style>
body { font-family: system-ui, sans-serif; margin: 2rem; }
#basemap { height: 480px; }
</style>
</head>
<body>
<h1>Kaleidr basemap</h1>
<p id="status">Loading the map…</p>

<div id="basemap"></div>
<p>
<button id="paris">Fly to Paris</button>
<button id="night">Night</button>
<button id="day">Morning</button>
</p>

<script src="https://cdn.kaleidr.com/embed/v1/kaleidr.js"></script>
<script>
const target = document.getElementById('basemap');
const status = document.getElementById('status');

const handle = Kaleidr.mount(target, {
product: 'tile',
publishableKey: 'kld_pk_live_…',
styleId: 'kaleidr-morning',
center: [-0.1276, 51.5072],
zoom: 11,
});

window.addEventListener('message', (event) => {
if (event.origin !== 'https://map-embed.kaleidr.com') return;
const frame = target.querySelector('iframe');
if (!frame || event.source !== frame.contentWindow) return;
const msg = event.data;
if (msg && msg.type === 'kaleidr-embed:ready') {
status.textContent = 'Map loaded.';
}
});

document.getElementById('paris').addEventListener('click', () => {
handle.setCamera({ center: [2.3522, 48.8566], zoom: 12, duration: 1200 });
});
document.getElementById('night').addEventListener('click', () => {
handle.setStyle('kaleidr-night');
});
document.getElementById('day').addEventListener('click', () => {
handle.setStyle('kaleidr-morning');
});

// In a single-page app, call handle.destroy() when the map leaves the screen.
</script>
</body>
</html>

工作原理​

主題行為
會話SDK 在創建 iframe 之前用金鑰換取短期 Tile 會話,並在掛載期間持續續期。交換過程驗證金鑰並記錄一次地圖載入。會話不傳給 iframe;其 URL 只包含樣式與相機參數。
初始視角使用傳入的相機;若未傳入,使用樣式預設視角。
滾動指標位於地圖上方時滾動會縮放地圖;指標位於地圖之外時,滾動會移動網頁。觸摸屏上拖動可移動地圖,雙指捏合可縮放地圖。
高度掛載時使用容器已有的高度,否則固定為 500 像素。
載入iframe 採用延遲載入,接近可視區域時才開始載入。
移除handle.destroy() 會移除 iframe 並停止會話續期;刪除 <kaleidr-map> 元素效果相同。
重新插入將已移除的元素重新插入或移動到另一個父元素,會重新掛載並建立新會話。

地圖載入次數的計算方式​

SDK 每取得一次 Tile 會話,就計為一次地圖載入:

事件地圖載入次數
掛載地圖1
地圖掛載期間續期會話每次續期計 1
銷毀後重新掛載,或重新插入元素1
setCamera、setStyle、平移或縮放0

會話預設有效期為 15 分鐘,SDK 在到期前 90 秒續期,無論頁面位於前台還是後台。訪客停留幾分鐘通常只消耗一次載入;頁面打開一小時約消耗五次。

降低用量的方法:

  • 地圖永久隱藏時銷毀掛載,例如關閉對話框、切換路由或移除分頁時。
  • 不要在每次渲染時重新創建元素。React、Vue 等框架的用法請參閱框架集成。
  • 切換樣式時使用 setStyle,不要重新掛載。

如果組織在當前週期內用完地圖載入額度,新會話會被拒絕,並傳回 HTTP 429 和 {"detail":"map_load_quota_exceeded"}。已經顯示的地圖仍會保留,新掛載則不會顯示內容。參閱配額和速率限制。

檢查是否正常工作​

  • **網頁中:**地圖可交互,底部顯示地圖版權和來源說明。
  • **控制台中:**沒有包含 [kaleidr 的報錯行。
  • **Network 面板中:**從 https://cdn.kaleidr.com 載入 kaleidr.js 和 tile.js;POST …/sdk/sessions 傳回 200,JSON 中包含 session_token 與 expires_in;還會向 https://map-embed.kaleidr.com/?style=… 發出文檔要求。
  • **事件監聽器中:**收到 kaleidr-embed:ready 消息,其 source 為 "tile"。

無法正常工作時​

SDK 在控制台以 [kaleidr:tile] … 形式記錄掛載失敗。會話被拒絕時只記錄 HTTP 狀態;具體原因需要在 Network 面板中查看 sessions 要求的響應。403 錯誤代碼位於 detail,map_load_quota_exceeded 也在 detail;429 的 rate_limited 代碼位於 error。

現象原因解決方法
頁面無顯示,控制台出現 …/sdk/sessions 的 CORS 錯誤及 [kaleidr:tile] 錯誤金鑰無效或已撤銷,或者網頁來源不在允許範圍;拒絕回應不包含 CORS 頭。檢查金鑰,在 kaleidr.com/api-keys 添加完整來源(協議、主機、連接埠),等待幾分鐘再刷新。Network 中的要求狀態為 401 或 403。
[kaleidr:tile] kaleidr session exchange failed (403)缺少 maps 權限(insufficient_scope)、金鑰僅限其他產品(product_not_allowed)或套餐不允許要求(tier_capability_not_allowed)。在 Network 中查看 detail,建立包含預設權限的金鑰。
[kaleidr:tile] kaleidr session exchange failed (429)地圖額度耗盡(map_load_quota_exceeded)或短時間要求過多(rate_limited)。前者查看 detail,後者查看 error;參閱配額和速率限制。
sessions 傳回 404自定義 api-base 時遺漏了 /inference-api。取消覆蓋,或使用 https://api.kaleidr.com/inference-api。
[kaleidr:tile] Kaleidr: a server key (kld_sk_…) must never be used in the browser…使用了伺服器金鑰,SDK 在傳送任何要求前就會拒絕。使用可公開使用的金鑰。如果伺服器金鑰曾公開,請立即輪換。
[kaleidr:tile] Kaleidr tile: invalid style "…"…style-id 包含空格或 ? 等非法字元。使用第 2 步列出的樣式 ID。
iframe 顯示“Couldn't find a map id in the URL.”,監聽器收到 code: 'no_id' 和 id: null未傳入 style-id,且組織沒有預設底圖。設定 style-id。
iframe 為空,收到帶有 maplibre_error 的 kaleidr-embed:error樣式不存在,通常是 ID 拼寫錯誤。使用第 2 步的樣式 ID。
[kaleidr] <kaleidr-map> requires product="chat|viewer|editor|tile"product 缺失或拼寫錯誤。設定 product="tile"。
地圖始終高 500 像素掛載時元素未設定高度、設定了 display:inline,或 Safari 16.4 之前未使用 display:block。明確設定高度和 display:block。 height
顯示空框,控制台提示內容安全策略違規安全策略阻止腳本、會話要求或 iframe。允許開始之前中列出的三個主機。
setStyle 或 setCamera 沒有反應方法調用在元素上,或地圖仍在載入。對 Kaleidr.mount 傳回的控制代碼調用方法,檢查 kaleidr-embed:error 和控制台;提前調用的方法會在就緒後生效。 若 iframe 載入後經過有限等待時間(通常是 10 秒)仍未回報就緒,保留的呼叫仍會送出,主控台會顯示 [kaleidr] the map frame has not reported ready;若 iframe 正在顯示錯誤,則沒有地圖可供操作。
修改元素上的 style-id 沒有效果預期行為,style-id 只在掛載時讀取一次。使用 handle.setStyle,或插入新元素。

限制​

  • 網頁不能直接向 Tile 地圖添加標記、圖層或彈窗,也無法取得點擊或相機事件。連接的聊天面板可以在地圖上標記地點。
  • 不提供讀取當前相機狀態的方法。
  • Tile 是用於顯示 Kaleidr 底圖的受支持產品。
  • 如果金鑰不允許網頁來源,則無法顯示 Tile 地圖。

後續步驟​