這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
風格設定
加載地圖
使用AMapLoader.load加載地圖,從 控制臺 申請一個屬于自己的key
import AMapLoader from '@amap/amap-jsapi-loader';
...
const AMap = await AMapLoader.load({
"key": "您自己申請的KEY", // 申請好的Web端開發者Key,首次呼叫 load 時必填
"version": "2.0",
"plugins": ["AMap.Walking", "AMap.Driving"], // 需要使用的的插件串列,如比例尺'AMap.Scale'等
"Loca": {
version: '2.0.0'
}
})
使用new AMap.Map實體化地圖,并設定mapStyle為"amap://styles/grey",也可以在官網上自己設計屬于自己的風格,主要講的不是這部分所以大概交代一下就過去了,實體化Map后回傳一個map實體,后續的操作都需要用到,
添加GLCustomLayer圖層
new AMap.GLCustomLayer({
zIndex: 100,
init:()=>{},
render: ()=>{}
})
threejs的加載和創建需要在init屬性的方法里操作,render主要是用來渲染一些鏡頭資訊和 WebGLRenderer的重繪,
在init方法中創建一個THREEJS的透視相機
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 30);
鏡頭資訊的獲取
前文實體化Map后獲取一個map的實體,其中提供了customCoords資料轉換的工具,可以從這里獲取到鏡頭資訊,后續轉化經緯度到3D世界坐標時候也會用到,轉換工具需要提前獲取到,方便后續的作業,
var { near, far, fov, up, lookAt, position } = customCoords.getCameraParams();
轉換工具提供一個getCameraParams方法,其中包含相機位置等其他屬性
fov — 攝像機視錐體垂直視野角度
near — 攝像機視錐體近端面
far — 攝像機視錐體遠端面
其中大部分屬性都和threejs的透視相機屬性相同,在render方法中更新相機,這樣做的作用就是在后續做巡航功能時會實時更新相機位置
camera.near = near; camera.far = far; camera.fov = fov; camera.position.set(...position); camera.up.set(...up); camera.lookAt(...lookAt); camera.updateProjectionMatrix();
初始化loca
可視化圖層需要用到Loca容器,需要在地圖外繪制的圖層,需要在可視化圖層上繪制,
創建可視化作品前,首先要創建一個 Loca 容器,這個容器可以幫您加載高德地圖作為底圖,或者幫您關聯已有的高德地圖作為底圖,
在使用地圖的時,您可以使用任何一個 JS API 已有的功能,Loca 容器不會影響原有地圖的任何功能和特性,這里創建的 Loca 容器您可以理解為是可視化圖層的管理器,
注意:創建地圖時候 Loca 版本要和map的版本一致,否則會報錯
var loca = new (window as any).Loca.Container({
map,
zIndex: 9
});
將創建好的AMap.GLCustomLayer添加到map圖層 const customLayer = await createGLCustomLayer(AMap, customCoords)
map.add(customLayer);
createGLCustomLayer方法就是之前定義的初始化AMap.GLCustomLayer方法,回傳一個GLCustomLayer實體,這樣就可以在地圖內插入可視化內容,
加載模型
回到new AMap.GLCustomLayer提供的init屬性中,創建一個3d場景并把模型加載到場景中,
renderer = new THREE.WebGLRenderer({
context: gl, // 地圖的 gl 背景關系
});
// 自動清慷訓布這里必須設定為 false,否則地圖底圖將無法顯示
renderer.autoClear = false;
scene = new THREE.Scene();
加載模型方法跟threejs相同,使用gltfloderapi,加載方法回傳一個promise,再使用// 初始化模型
function initGltf(): Promise<THREE.Object3D> {
return new Promise((resolve, reject) => {
var loader = new GLTFLoader();
loader.load('https://a.amap.com/jsapi_demos/static/gltf/Duck.gltf', (gltf: any) => {
let object = gltf.scene;
resolve(object)
});
})
}
模型添加到場景
const { x, y, z } = setRotation(new THREE.Vector3(90, 90, 0))
object.scale.set(15, 15, 15);
group.add(object)
group.add(new THREE.AxesHelper(100))
scene.add(group)
object.name = 'duck'
我在模型上添加了一個AxesHelper輔助線,官網上表示藍色代表z軸,但是放在地圖中發生了坐標方向不一致的問題,threejs的向上方向是y軸,地圖中z是向上方向,這一點可能要注意一下了
用于簡單模擬3個坐標軸的物件.
紅色代表 X 軸. 綠色代表 Y 軸. 藍色代表 Z 軸.
旋轉模型
const { x, y, z } = setRotation(new THREE.Vector3(90, -90, 0))
group.rotation.set(x, y, z)
獲取旋轉角度的方法export function setRotation(rotation: THREE.Vector3) {
var x = Math.PI / 180 * (rotation.x || 0);
var y = Math.PI / 180 * (rotation.y || 0);
var z = Math.PI / 180 * (rotation.z || 0);
return new THREE.Vector3(x, y, z)
}
計算軌跡
使用viewControl
現在模型已經加載好,接下來就是要獲取軌跡資料,鏡頭跟蹤在Loca中有相應的apiviewControl,使用這個api呼叫addTrackAnimate方法,提供對應引數即可;
loca.viewControl.addTrackAnimate({
path: pathArr, // 鏡頭軌跡,二維陣列,支持海拔
duration: 120000, // 時長
timing: [[0, 0.3], [1, 0.7]], // 速率控制器
rotationSpeed: 1800, // 每秒旋轉多少度
}, function () {
console.log('完成',);
});
pathArr是一個軌跡陣列,
const pathArr = [[116.310348, 39.89702], [116.310541, 39.884855], [116.320963, 39.889154], [116.322894, 39.889608], [116.325542, 39.889822], [116.328074, 39.889761], [116.349104, 39.889429], [116.348517, 39.89747], [116.355205, 39.898413], [116.35656, 39.90021], [116.355802, 39.93225]]為了方便查看,我們在使用Loca提供的繪制引導線功能將這幾個關鍵點連接的引導線畫一下
// 導航線
var polyline = new AMap.Polyline({
path: pathArr, // 設定線覆寫物路徑
showDir: true,
strokeColor: '#3366bb', // 線顏色
strokeWeight: 10, // 線寬
zIndex: 1
});
map.add(polyline)
以上作業做完后,需要呼叫一下loca.animate.start();方法,否則可視化圖層不會更新,相應資料也獲取不到,現在畫面變成這樣了
除了以上這種方法去實作鏡頭的移動,還可以通過插入坐標的方式去實作,也是傳統threejs中使用的方法,就是利用tweenjs的影片,運動程序中改變map.setCenter,實作跟蹤,這部分代碼在changeObject方法中,感興趣的可以去 倉庫 查看,
鏡頭跟蹤
移動模型
利用requestAnimationFrame函式寫一個回圈渲染的方法,在呼叫的同時獲取鏡頭中心坐標,通過customCoords轉換工具將經緯度轉為3D世界的坐標,并將該坐標賦值給object模型,再通過map提供的getRotation方法,獲取地圖的旋轉角度,并將該角度賦值給object模型的y軸,使模型沿著y軸旋轉,至于旋轉的速度,在前面定義addTrackAnimate時的rotationSpeed屬性定義的
const render = () => {
requestAnimationFrame(() => {
render()
})
if (object) {
const center = map.getCenter()
var position = customCoords.lngLatsToCoords([
[center.lng, center.lat]
])[0];
const v3 = new THREE.Vector3(position[1], 0, position[0])
object.position.copy(v3)
const rotation = map.getRotation()
object.rotation.y = rotation * Math.PI / 180
}
map.render();
TWEEN && TWEEN.update()
}
以上文章內容有一些關于threejs的基礎知識,可以先提前了解一下,否則有很多好玩有趣的效果實作不出來,
其他
關于飛線,只是作為裝飾,顯得畫面不那么呆板,在官網上也有案例,簡單貼一個代碼吧
// 飛線
var geo = new (window as any).Loca.GeoJSONSource({
url: 'https://a.amap.com/Loca/static/loca-v2/demos/mock_data/bj_bus.json',
});
var layer = new (window as any).Loca.PulseLineLayer({
// loca,
zIndex: 10,
opacity: 1,
visible: true,
zooms: [1, 30],
});
var headColors = ['#EFBB51', '#7F3CFF', '#4CC19B', '#0B5D74', '#E06AC4', '#223F9B', '#F15C1A', '#7A0FA6'];
layer.setSource(geo);
layer.setStyle({
altitude: 0,
lineWidth: 2,
// 脈沖頭顏色
headColor: (_, feature) => {
return headColors[feature.properties.type - 1];
},
// 脈沖尾顏色
trailColor: 'rgba(128, 128, 128, 0.5)',
// 脈沖長度,0.25 表示一段脈沖占整條路的 1/4
interval: 0.25,
// 脈沖線的速度,幾秒鐘跑完整段路,可以通過計算距離動態改變時間
duration: 5000,
});
// 飛線結束
loca.add(layer);
本文轉載于:
https://juejin.cn/post/7242145254056673335
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/556353.html
標籤:其他
上一篇:CSS基礎-背景
下一篇:返回列表

