上篇介紹了:three-tile: 一個開源的輕量級三維瓦片庫-CSDN博客
three-tile 是一個開源的輕量級三維瓦片庫,它基于threejs使用typescript開發,提供一個三維地形模型,能輕松給你的應用增加三維瓦片地圖。
項目地址:https://github.com/sxguojf/three-tile
示例地址:https://github.com/sxguojf/three-tile-example
這篇,我們來使用three-tile編寫一個簡單示例,它顯示一張三維地圖,鼠標左鍵平移,右鍵旋轉,滾輪縮放。
廢話不多說,先上代碼:
<!DOCTYPE html>
<html lang="zh-cn"><head><meta charset="utf-8" /><metaname="viewport"content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"/><title>three-tile最小化應用</title></head><style>html,body {background-color: #333;height: 100%;width: 100%;padding: 0;margin: 0;display: flex;}#map {flex: 1;}</style><!-- 因three@v0.150+廢棄了普通導入方式,需要改為使用importmap導入 --><script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.165.0/build/three.module.js","three-tile": "https://unpkg.com/three-tile@0.6.1/dist/three-tile.js"}}</script><body><div id="map"></div><script type="module">import * as THREE from "three";import * as tt from "three-tile";console.log(`three-tile v${tt.version} start!`);// MapBoxToken 請更換為你自己申請的keyconst MAPBOXKEY ="pk.eyJ1Ijoic3ZjLW9rdGEtbWFwYm94LXN0YWZmLWFjY2VzcyIsImEiOiJjbG5sMnBoMm0xeWZzMmtyaWl0b2wyN2FuIn0.-zx1KP3Oy-7YzWcvhbv22Q";// mapbox影像數據源const mapBoxImgSource = new tt.plugin.MapBoxSource({token: MAPBOXKEY,dataType: "image",style: "mapbox.satellite",});// mapbox地形數據源const mapBoxDemSource = new tt.plugin.MapBoxSource({token: MAPBOXKEY,dataType: "terrain-rgb",style: "mapbox.terrain-rgb",maxLevel: 15,});// 創建地圖const map = tt.TileMap.create({// 影像數據源imgSource: mapBoxImgSource,// 地形數據源demSource: mapBoxDemSource,// 地圖投影中心經度lon0: 90,// 最小縮放級別minLevel: 2,// 最大縮放級別maxLevel: 18,});// 地圖旋轉到xz平面map.rotateX(-Math.PI / 2);// 地圖中心坐標(經度,緯度,高度)const centerGeo = new THREE.Vector3(105, 30, 0);// 攝像坐標(經度,緯度,高度)const camersGeo = new THREE.Vector3(105, 0, 5000);// 地圖中心轉為世界坐標const centerPostion = map.localToWorld(map.geo2pos(centerGeo));// 攝像機轉為世界坐標const cameraPosition = map.localToWorld(map.geo2pos(camersGeo));// 初始化場景const viewer = new tt.plugin.GLViewer("#map", { centerPostion, cameraPosition });// 地圖添加到場景viewer.scene.add(map);</script></body>
</html>
將上面代碼保存為html文件,不需要web服務,用瀏覽器打開即可運行。由于地圖數據在墻外,加載可能有點慢,多等一會。
懶得復制?那直接到這里體驗:https://inscode.csdn.net/@hzgjf/HTML-CSS-JS
代碼比較簡單,要理解,需要一些threejs或opengl基礎知識,沒學過也不要緊,我會后面會慢慢講解。
1. 引入three和three-tile
three-tile是基于threejs開發,先引入這兩個包:
<!-- 因three@v0.150+廢棄了普通導入方式,需要改為使用importmap導入 -->
<script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.165.0/build/three.module.js","three-tile": "https://unpkg.com/three-tile@0.6.1/dist/three-tile.js"}}
</script>
引入方式不是常見的寫法,這是由于threejs r150+后,已經廢棄老式寫法了,不得不跟。詳情見:
https://threejs.org/docs/index.html#manual/zh/introduction/Installation
為了簡單,這里采用CDN方式,后面我們講解會用NPM方式。
2. 創建數據源
既然是瓦片地圖,那肯定先要定義數據源,three-tile內建了mapbox、bing、google、天地圖、高德等等數據源定義,這里我們選用mapboxe的:
// MapBoxToken 請更換為你自己申請的keyconst MAPBOXKEY ="pk.eyJ1Ijoic3ZjLW9rdGEtbWFwYm94LXN0YWZmLWFjY2VzcyIsImEiOiJjbG5sMnBoMm0xeWZzMmtyaWl0b2wyN2FuIn0.-zx1KP3Oy-7YzWcvhbv22Q";// mapbox影像數據源const mapBoxImgSource = new tt.plugin.MapBoxSource({token: MAPBOXKEY,dataType: "image",style: "mapbox.satellite",});// mapbox地形數據源const mapBoxDemSource = new tt.plugin.MapBoxSource({token: MAPBOXKEY,dataType: "terrain-rgb",style: "mapbox.terrain-rgb",maxLevel: 15,});
不明白啥意思?沒關系,抄上就行,后面會講解,需要注意的是,mapbox的token最好自己申請,不要用我上面的,用的人多超出限額大家都沒得玩了。
3. 創建地圖
// 創建地圖
const map = tt.TileMap.create({// 影像數據源imgSource: mapBoxImgSource,// 地形數據源demSource: mapBoxDemSource,// 地圖投影中心經度lon0: 90,// 最小縮放級別minLevel: 2,// 最大縮放級別maxLevel: 18,
});
// 地圖旋轉到xz平面
map.rotateX(-Math.PI / 2);
這里,用three-tile的TileMap.create函數,創建了一個地圖模型,類型是threejs的Mesh,然后把模型旋轉-90°到xz平面,函數參數把剛創建的地圖數據源傳進去,其它參數先照抄,后面講解。
4. 初始化三維場景并添加地圖
三維場景的初始化,就是threejs套路,創建場景、渲染器、攝像機、控制器、燈光等等,你從threejs中抄過來就行,但為了降低使用難度,three-tile內置了一個GLViewer類封裝了這些操作,你只需要傳入參數即可:
// 地圖中心坐標(經度,緯度,高度)
const centerGeo = new THREE.Vector3(105, 30, 0);
// 攝像坐標(經度,緯度,高度)
const camersGeo = new THREE.Vector3(105, 0, 5000);
// 地圖中心轉為世界坐標
const centerPostion = map.localToWorld(map.geo2pos(centerGeo));
// 攝像機轉為世界坐標
const cameraPosition = map.localToWorld(map.geo2pos(camersGeo));
// 初始化場景
const viewer = new tt.plugin.GLViewer("#map", { centerPostion, cameraPosition });// 地圖添加到場景
viewer.scene.add(map);
GLViewer構造參數需要在網頁上放置地圖的dom的ID,這里是"#map",對應的html中那唯一的一個div,另外,需要地圖中心坐標和攝像機坐標,用來控制地圖的位置、縮放和旋轉,這兩坐標需要傳入三維場景坐標,我們通過將經緯度高度轉換得來:
centerGeo:地圖中心經緯度高度,就是地圖以哪個點為中心(105°E,30°N,0km)
cameraGeo:攝像機的經緯度高度,就是你站點哪個位置看地圖(105°E,0°,5000km)
這兩參數為可選參數,如果不清楚耶可以省略。
最后,將地圖加入三維場景中,OK,保存看看效果。
第一講,不需要讀懂,復制過去能運行出來就行,后面將持續更新。
雄偉的喜馬拉雅,我咋感覺搞輛鏟車直接能開上去...