這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識(shí),希望對(duì)大家有所幫助
風(fēng)格設(shè)置
加載地圖
使用AMapLoader.load
加載地圖,從?控制臺(tái)??申請(qǐng)一個(gè)屬于自己的key
import AMapLoader from '@amap/amap-jsapi-loader'; ... const AMap = await AMapLoader.load({ "key": "您自己申請(qǐng)的KEY", // 申請(qǐng)好的Web端開發(fā)者Key,首次調(diào)用 load 時(shí)必填 "version": "2.0", "plugins": ["AMap.Walking", "AMap.Driving"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等 "Loca": { version: '2.0.0' } })
使用new AMap.Map
實(shí)例化地圖,并設(shè)置mapStyle
為"amap://styles/grey"
,也可以在官網(wǎng)上自己設(shè)計(jì)屬于自己的風(fēng)格,主要講的不是這部分所以大概交代一下就過去了,實(shí)例化Map后返回一個(gè)map實(shí)例,后續(xù)的操作都需要用到。
添加GLCustomLayer圖層
new AMap.GLCustomLayer({ zIndex: 100, init:()=>{}, render: ()=>{} })
threejs的加載和創(chuàng)建需要在init
屬性的方法里操作,render主要是用來渲染一些鏡頭信息和?WebGLRenderer
的重繪。
在init方法中創(chuàng)建一個(gè)THREEJS的透視相機(jī)
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 100, 1 << 30);
鏡頭信息的獲取
前文實(shí)例化Map后獲取一個(gè)map的實(shí)例,其中提供了customCoords
數(shù)據(jù)轉(zhuǎn)換的工具,可以從這里獲取到鏡頭信息,后續(xù)轉(zhuǎn)化經(jīng)緯度到3D世界坐標(biāo)時(shí)候也會(huì)用到,轉(zhuǎn)換工具需要提前獲取到,方便后續(xù)的工作。
var { near, far, fov, up, lookAt, position } = customCoords.getCameraParams();
轉(zhuǎn)換工具提供一個(gè)getCameraParams
方法,其中包含相機(jī)位置等其他屬性
fov — 攝像機(jī)視錐體垂直視野角度
near — 攝像機(jī)視錐體近端面
far — 攝像機(jī)視錐體遠(yuǎn)端面
其中大部分屬性都和threejs的透視相機(jī)屬性相同,在render方法中更新相機(jī),這樣做的作用就是在后續(xù)做巡航功能時(shí)會(huì)實(shí)時(shí)更新相機(jī)位置
camera.near = near; camera.far = far; camera.fov = fov; camera.position.set(...position); camera.up.set(...up); camera.lookAt(...lookAt); camera.updateProjectionMatrix();
初始化loca
可視化圖層需要用到Loca
容器,需要在地圖外繪制的圖層,需要在可視化圖層上繪制,
創(chuàng)建可視化作品前,首先要?jiǎng)?chuàng)建一個(gè) Loca 容器,這個(gè)容器可以幫您加載高德地圖作為底圖,或者幫您關(guān)聯(lián)已有的高德地圖作為底圖。
在使用地圖的時(shí),您可以使用任何一個(gè) JS API 已有的功能,Loca 容器不會(huì)影響原有地圖的任何功能和特性。這里創(chuàng)建的 Loca 容器您可以理解為是可視化圖層的管理器。
注意:創(chuàng)建地圖時(shí)候 Loca 版本要和map的版本一致,否則會(huì)報(bào)錯(cuò)
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
方法。返回一個(gè)GLCustomLayer
實(shí)例,這樣就可以在地圖內(nèi)插入可視化內(nèi)容。
加載模型
回到new AMap.GLCustomLayer
提供的init屬性中,創(chuàng)建一個(gè)3d場(chǎng)景并把模型加載到場(chǎng)景中,
renderer = new THREE.WebGLRenderer({ context: gl, // 地圖的 gl 上下文 }); // 自動(dòng)清空畫布這里必須設(shè)置為 false,否則地圖底圖將無法顯示 renderer.autoClear = false; scene = new THREE.Scene();
gltfloder
api,加載方法返回一個(gè)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) }); }) }
模型添加到場(chǎng)景
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'
我在模型上添加了一個(gè)AxesHelper
輔助線,官網(wǎng)上表示藍(lán)色代表z軸,但是放在地圖中發(fā)生了坐標(biāo)方向不一致的問題,threejs的向上方向是y軸,地圖中z是向上方向,這一點(diǎn)可能要注意一下了
用于簡(jiǎn)單模擬3個(gè)坐標(biāo)軸的對(duì)象.
紅色代表 X 軸. 綠色代表 Y 軸. 藍(lán)色代表 Z 軸.
旋轉(zhuǎn)模型
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) }
計(jì)算軌跡
使用viewControl
現(xiàn)在模型已經(jīng)加載好,接下來就是要獲取軌跡數(shù)據(jù),鏡頭跟蹤在Loca中有相應(yīng)的apiviewControl
,使用這個(gè)api調(diào)用addTrackAnimate
方法,提供對(duì)應(yīng)參數(shù)即可;
loca.viewControl.addTrackAnimate({ path: pathArr, // 鏡頭軌跡,二維數(shù)組,支持海拔 duration: 120000, // 時(shí)長(zhǎng) timing: [[0, 0.3], [1, 0.7]], // 速率控制器 rotationSpeed: 1800, // 每秒旋轉(zhuǎn)多少度 }, function () { console.log('完成',); });
pathArr
是一個(gè)軌跡數(shù)組,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]]
// 導(dǎo)航線 var polyline = new AMap.Polyline({ path: pathArr, // 設(shè)置線覆蓋物路徑 showDir: true, strokeColor: '#3366bb', // 線顏色 strokeWeight: 10, // 線寬 zIndex: 1 }); map.add(polyline)
以上工作做完后,需要調(diào)用一下loca.animate.start();
方法,否則可視化圖層不會(huì)更新,相應(yīng)數(shù)據(jù)也獲取不到,現(xiàn)在畫面變成這樣了
除了以上這種方法去實(shí)現(xiàn)鏡頭的移動(dòng),還可以通過插入坐標(biāo)的方式去實(shí)現(xiàn),也是傳統(tǒng)threejs中使用的方法,就是利用tweenjs
的動(dòng)畫,運(yùn)動(dòng)過程中改變map.setCenter
,實(shí)現(xiàn)跟蹤,這部分代碼在changeObject
方法中,感興趣的可以去 倉庫 查看,
鏡頭跟蹤
移動(dòng)模型
利用requestAnimationFrame
函數(shù)寫一個(gè)循環(huán)渲染的方法,在調(diào)用的同時(shí)獲取鏡頭中心坐標(biāo),通過customCoords
轉(zhuǎn)換工具將經(jīng)緯度轉(zhuǎn)為3D世界的坐標(biāo),并將該坐標(biāo)賦值給object模型,再通過map提供的getRotation
方法,獲取地圖的旋轉(zhuǎn)角度,并將該角度賦值給object模型的y軸,使模型沿著y軸旋轉(zhuǎn),至于旋轉(zhuǎn)的速度,在前面定義addTrackAnimate
時(shí)的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() }
以上文章內(nèi)容有一些關(guān)于threejs的基礎(chǔ)知識(shí),可以先提前了解一下,否則有很多好玩有趣的效果實(shí)現(xiàn)不出來。
其他
關(guān)于飛線,只是作為裝飾,顯得畫面不那么呆板,在官網(wǎng)上也有案例,簡(jiǎn)單貼一個(gè)代碼吧文章來源:http://www.zghlxwxcb.cn/news/detail-508792.html
// 飛線 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)', // 脈沖長(zhǎng)度,0.25 表示一段脈沖占整條路的 1/4 interval: 0.25, // 脈沖線的速度,幾秒鐘跑完整段路,可以通過計(jì)算距離動(dòng)態(tài)改變時(shí)間 duration: 5000, }); // 飛線結(jié)束 loca.add(layer);
本文轉(zhuǎn)載于:
https://juejin.cn/post/7242145254056673335
如果對(duì)您有所幫助,歡迎您點(diǎn)個(gè)關(guān)注,我會(huì)定時(shí)更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進(jìn)步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-508792.html
到了這里,關(guān)于記錄--寫一個(gè)高德地圖巡航功能的小DEMO的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!