作為一個前端小白,今天要開始學習百度地圖的 JSAPI Three(也叫 mapvthree)了!聽説這是一個超強的 3D 地圖渲染引擎,可以做出很酷炫的三維地圖效果。想想就激動!讓我記錄下學習的過程吧!🚀
第一天:聽説 JSAPIThree
今天在項目裏看到了一個新需求,要用 3D 地圖展示數據。我一開始還以為是普通的百度地圖 API,結果同事説要用 JSAPIThree,這是百度地圖的 3D 渲染引擎。
我的第一反應:3D 地圖?聽起來好高級!但是會不會很難啊?😅
查了一下資料才知道:
- JSAPIThree = 百度地圖 JSAPI Three
- 也叫
mapvthree(這是 npm 包名) - 基於 Three.js 開發
- 可以做二三維一體化的地圖渲染
我的理解:簡單説就是百度地圖的 3D 版本,可以做出那種很酷炫的三維地圖效果,就像遊戲裏的地圖一樣!
第二天:開始安裝
第一步:安裝依賴
按照文檔,第一步是安裝依賴。文檔説需要安裝兩個包:
@baidumap/mapv-three:這是 JSAPIThree 的核心包three:這是 Three.js,底層渲染引擎
npm i -S @baidumap/mapv-three three
我的操作:打開終端,執行命令...等待中...
我的發現:安裝成功了!但是看到依賴列表裏有很多包,看來這個庫還挺大的。
注意:文檔説如果用 pnpm v7 以上版本,可能會有警告,需要執行 pnpm approve-builds。我用的是 npm,所以沒遇到這個問題。
第二步:配置靜態資源
安裝完依賴後,我以為就能直接用了,結果文檔説還要配置靜態資源!
我的困惑:什麼是靜態資源?為什麼要配置?
看了文檔才知道,mapvthree 在初始化時需要加載一些資源文件(比如着色器、紋理等)。如果不配置,運行時會報錯:
"Unable to determine base URL automatically, try defining a global variable called MAPV_BASE_URL."
我的理解:就是告訴引擎,資源文件在哪裏。
我用的是 Vite
文檔説如果用 Vite 或 Rollup,需要這樣配置:
// vite.config.js
import copy from 'rollup-plugin-copy';
const viteConfig = {
plugins: [
copy({
targets: [
{src: 'node_modules/@baidumap/mapv-three/dist/assets', dest: 'public/mapvthree'},
],
verbose: true,
hook: 'buildStart',
}),
// ...其他插件
]
};
我的操作:
- 先安裝
rollup-plugin-copy:npm i -D rollup-plugin-copy - 在
vite.config.js裏添加配置 - 重啓開發服務器
我的感受:配置過程有點複雜,但是按照文檔一步步來,還是能搞定的!
在 HTML 裏聲明全局變量
配置完構建工具後,還要在 index.html 裏聲明全局變量:
<!-- index.html -->
<script>
window.MAPV_BASE_URL = 'mapvthree/';
</script>
我的理解:這個變量告訴引擎,資源文件在 mapvthree/ 目錄下。
我的操作:在 index.html 的 <head> 里加上這段代碼。
第三步:配置百度地圖 AK
文檔説 mapvthree 默認展示百度地圖矢量數據,需要配置百度地圖開發者密鑰(AK)。
我的疑問:什麼是 AK?為什麼要配置?
查了一下才知道,AK 是百度地圖開放平台的密鑰,用來驗證身份和限制訪問量。
我的操作步驟:
- 訪問百度地圖開放平台
- 登錄百度賬號(沒有的話要註冊)
- 點擊"創建應用"
- 填寫應用名稱,選擇"瀏覽器端"
- 創建完成後,獲得一個 AK 密鑰
我的感受:註冊和創建應用的過程還挺順利的,就是要注意選擇"瀏覽器端",不然可能用不了。
在代碼裏配置 AK
拿到 AK 後,要在項目入口文件裏配置:
// 在項目入口文件中配置(比如 main.js)
import * as mapvthree from '@baidumap/mapv-three';
// 配置百度地圖 AK
mapvthree.BaiduMapConfig.ak = '您的AK密鑰';
我的操作:在 main.js 里加上這段代碼,把 '您的AK密鑰' 替換成我申請的 AK。
我的發現:這個配置只需要全局執行一次就行,不用每次都配置。
第三天:第一個 Hello World!
配置完成後,終於可以開始寫代碼了!我按照文檔寫了個最簡單的例子。
第一步:引入庫
文檔説可以一次性引入所有組件,也可以按需引入。我選擇一次性引入,簡單直接:
import * as mapvthree from '@baidumap/mapv-three';
我的想法:先全部引入,等熟悉了再考慮按需引入優化。
第二步:初始化引擎
文檔説通過 Engine 類可以初始化一個三維場景。最簡單的用法是:
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, {
// 可選的配置項
});
我的理解:就像創建一個畫布,container 是容器元素,engine 是引擎實例。
我的第一個嘗試:
import * as mapvthree from '@baidumap/mapv-three';
// 獲取容器元素
const container = document.getElementById('container');
// 創建引擎
const engine = new mapvthree.Engine(container);
我的發現:運行後,頁面上出現了一個 3D 地圖!雖然很簡單,但是能看到地圖了,好激動!🎉
我的觀察:
- 默認有百度矢量底圖
- 默認有天空(看起來像真實的天空)
- 可以鼠標拖動旋轉視角
- 可以滾輪縮放
我的感受:太神奇了!就幾行代碼,就能看到一個 3D 地圖!
第三步:瞭解配置選項
看到效果後,我開始好奇:能不能自定義地圖的位置、視角?
文檔説可以在初始化時傳入配置:
const engine = new mapvthree.Engine(container, {
map: {
center: [116.414, 39.915], // 中心點座標(經度,緯度)
range: 500, // 縮放級別(米)
heading: 225, // 方位角(度)
pitch: 70, // 俯仰角(度)
},
});
我的嘗試:
const engine = new mapvthree.Engine(container, {
map: {
center: [116.404, 39.915], // 北京天安門
range: 1000, // 1000 米高度
heading: 0, // 正北方向
pitch: 60, // 60 度俯視
},
});
我的發現:地圖定位到了天安門,視角也變了!pitch 越大,俯視角度越大,看起來越像從高空往下看。
我的理解:
center:地圖中心點的經緯度range:相機距離地面的高度(米),值越小越近heading:水平旋轉角度,0 是正北,90 是正東pitch:垂直俯仰角,0 是水平,90 是垂直向下
第四步:添加可視化組件
看到地圖後,我想:能不能在地圖上添加一些點?
文檔説可以用 SimplePoint 來展示點數據。但是需要先準備數據源。
我的第一次嘗試:
// 創建數據源
const dataSource = new mapvthree.GeoJSONDataSource.fromGeoJSON({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [116.414, 39.915], // 一個點的座標
},
},
],
});
// 創建點圖層
const point = engine.add(new mapvthree.SimplePoint({
size: 10, // 點的大小
}));
// 關聯數據源
point.dataSource = dataSource;
我的發現:地圖上出現了一個紅色的點!雖然很小,但是能看到!
我的感受:成功添加了點!雖然代碼有點長,但是邏輯很清晰:
- 準備數據(GeoJSON 格式)
- 創建圖層
- 關聯數據
我的改進:我想添加多個點,試試:
const dataSource = new mapvthree.GeoJSONDataSource.fromGeoJSON({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [116.404, 39.915],
},
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: [116.414, 39.925],
},
},
],
});
const point = engine.add(new mapvthree.SimplePoint({
size: 20, // 調大一點,看得清楚
}));
point.dataSource = dataSource;
我的發現:地圖上出現了兩個點!太棒了!
第五步:添加三維模型
看到點數據後,我想:能不能添加 3D 模型?比如建築物?
文檔説可以用 SimpleModel 來加載 3D 模型:
const model = engine.add(new mapvthree.SimpleModel({
name: 'model',
point: [116.414, 39.915], // 模型的位置
url: 'assets/models/building/5_tiyuzhongxin.glb', // 模型文件路徑
}));
我的嘗試:我找了個 GLB 格式的模型文件,按照文檔寫代碼:
const model = engine.add(new mapvthree.SimpleModel({
name: 'myBuilding',
point: [116.404, 39.915], // 天安門附近
url: 'assets/models/building/5_tiyuzhongxin.glb',
}));
我的發現:地圖上出現了一個 3D 建築模型!可以旋轉視角看,太酷了!
我的感受:3D 模型在地圖上看起來特別真實,就像真的建築物一樣!
我的疑問:模型文件格式有什麼要求?
查了文檔才知道,支持常見的 3D 模型格式:
- GLTF/GLB(推薦)
- OBJ
- FBX
我的理解:GLB 是 GLTF 的二進制版本,文件更小,加載更快,所以推薦用 GLB。
第六步:添加交互事件
看到模型後,我想:能不能點擊交互?
文檔説可以添加事件監聽:
point.addEventListener('click', (e) => {
console.log('點擊了!', e);
});
我的嘗試:
point.addEventListener('click', (e) => {
console.log('點擊了點的數據:', e);
alert('你點擊了一個點!');
});
我的發現:點擊點的時候,控制枱輸出了事件信息,還彈出了提示框!
我的感受:交互功能也很簡單,就是標準的 addEventListener!
我的改進:我想在點擊時顯示更多信息:
point.addEventListener('click', (e) => {
const coordinates = e.feature.geometry.coordinates;
console.log('點擊的座標:', coordinates);
alert(`經度:${coordinates[0]}\n緯度:${coordinates[1]}`);
});
我的發現:可以獲取點擊的座標信息!這樣就能做更多交互了!
第四天:深入瞭解引擎
發現引擎的屬性
看了文檔才知道,engine 對象有很多屬性:
engine.map:地圖相關操作(視野控制、座標轉換等)engine.rendering:渲染相關配置(動畫循環、特效等)engine.widgets:UI 控件(指南針、比例尺等)engine.selection:模型選擇控制器engine.clock:時鐘管理(控制時間,影響天空、光照等)engine.camera:相機對象(Three.js 的相機)engine.renderer:渲染器對象(Three.js 的渲染器)engine.scene:場景對象(Three.js 的場景)
我的理解:engine 就像一個總控制器,管理着地圖的各個方面。
嘗試視野操作
文檔説可以通過 engine.map 控制視野:
const center = [116.404, 39.915];
engine.map.lookAt(center, {
heading: 0,
pitch: 60,
range: 2000,
});
我的嘗試:
// 創建一個按鈕,點擊後飛到天安門
document.getElementById('flyToBtn').addEventListener('click', () => {
engine.map.lookAt([116.404, 39.915], {
heading: 0,
pitch: 60,
range: 1000,
});
});
我的發現:點擊按鈕後,地圖會平滑地移動到天安門!就像動畫一樣!
我的感受:這個功能太實用了!可以做場景切換、視角動畫等效果!
嘗試渲染配置
文檔説可以通過 engine.rendering 配置渲染:
// 開啓循環渲染(用於動畫)
engine.rendering.enableAnimationLoop = true;
// 設置幀率
engine.rendering.animationLoopFrameTime = 16; // 約 60 FPS
我的嘗試:
// 開啓循環渲染
engine.rendering.enableAnimationLoop = true;
我的發現:開啓後,如果有動畫效果(比如飛線、粒子等),會持續播放!
我的理解:默認情況下,引擎只在需要時渲染(比如拖動地圖時)。開啓循環渲染後,每幀都會渲染,適合有動畫的場景。
嘗試添加和移除物體
文檔説可以用 engine.add 添加物體,用 engine.remove 移除物體:
// 添加物體
const point = engine.add(new mapvthree.SimplePoint());
const mesh = engine.add(new THREE.Mesh());
// 移除物體
engine.remove(point);
engine.remove(mesh);
我的嘗試:
// 創建一個點
const point = engine.add(new mapvthree.SimplePoint({
size: 20,
}));
point.dataSource = dataSource;
// 5 秒後移除
setTimeout(() => {
engine.remove(point);
console.log('點已移除');
}, 5000);
我的發現:5 秒後,點從地圖上消失了!
我的感受:添加和移除都很簡單,這樣就能動態控制地圖上的元素了!
第五天:完整示例
經過幾天的學習,我想寫一個完整的示例,把學到的都用上:
import * as mapvthree from '@baidumap/mapv-three';
import * as THREE from 'three';
// 獲取容器
const container = document.getElementById('container');
// 創建引擎
const engine = new mapvthree.Engine(container, {
map: {
center: [116.404, 39.915], // 天安門
range: 1000,
heading: 0,
pitch: 60,
},
rendering: {
enableAnimationLoop: true, // 開啓循環渲染
},
});
// 創建數據源(兩個點)
const dataSource = new mapvthree.GeoJSONDataSource.fromGeoJSON({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: { name: '點1' },
geometry: {
type: 'Point',
coordinates: [116.404, 39.915],
},
},
{
type: 'Feature',
properties: { name: '點2' },
geometry: {
type: 'Point',
coordinates: [116.414, 39.925],
},
},
],
});
// 創建點圖層
const point = engine.add(new mapvthree.SimplePoint({
size: 30,
}));
point.dataSource = dataSource;
// 添加點擊事件
point.addEventListener('click', (e) => {
const name = e.feature.properties.name;
const coords = e.feature.geometry.coordinates;
alert(`${name}\n經度:${coords[0]}\n緯度:${coords[1]}`);
});
// 添加 3D 模型
const model = engine.add(new mapvthree.SimpleModel({
name: 'building',
point: [116.404, 39.915],
url: 'assets/models/building/5_tiyuzhongxin.glb',
}));
我的感受:寫一個完整的示例,把學到的都用上,感覺很有成就感!
我的發現:
- 地圖可以正常顯示
- 點數據可以正常顯示
- 點擊事件可以正常觸發
- 3D 模型可以正常加載
雖然代碼還很簡單,但是已經能做出一個基本的 3D 地圖應用了!
我的學習總結
經過這幾天的學習,我掌握了:
-
安裝和配置:
- 安裝依賴包
- 配置靜態資源
- 配置百度地圖 AK
-
基礎使用:
- 初始化引擎
- 配置地圖參數
- 添加可視化組件
- 添加 3D 模型
- 添加交互事件
-
引擎屬性:
engine.map:地圖控制engine.rendering:渲染配置engine.add/engine.remove:添加/移除物體
我的感受:
- JSAPIThree 功能很強大,但是上手不難
- 文檔很詳細,按照文檔一步步來就能學會
- 代碼結構清晰,API 設計合理
- 能做出來的效果很酷炫!
我的下一步計劃:
- 學習更多可視化組件(線、面、熱力圖等)
- 學習數據源的使用(CSV、JSON 等)
- 學習特效和動畫
- 做一個完整的項目
我的建議:
- 初學者可以先從最簡單的例子開始
- 多動手實踐,看文檔不如寫代碼
- 遇到問題先查文檔,再查社區
- 不要怕出錯,多試幾次就會了
學習筆記就到這裏啦!作為一個初學者,我覺得 JSAPIThree 雖然功能強大,但是學習曲線並不陡峭。只要按照文檔一步步來,多動手實踐,很快就能做出酷炫的 3D 地圖效果!大家一起加油!💪