maptalks 开发GIS地图(32)maptalks.three.25- custom-flight-path
1. 使用飞线,加上飞机的移动,第一眼看过去和前面的 arcline-animation 很类似。
但是内部的代码内容完全不一样。
2. 使用了 Bloom 效果,看起来很不错。
3. 材质
1 var lines = [], lineTrails = []; 2 var material = new THREE.LineBasicMaterial({ 3 linewidth: 1, 4 color: 'rgb(5,203,87)', 5 opacity: 0.12, 6 // blending: THREE.AdditiveBlending, 7 transparent: true 8 }); 9 var highlightmaterial = new THREE.LineBasicMaterial({ 10 linewidth: 1, 11 color: '#fff', 12 opacity: 1, 13 blending: THREE.AdditiveBlending, 14 transparent: true, 15 });
4. LineTrails
1 class LineTrail extends maptalks.BaseObject { 2 constructor(lineString, options, material, layer) { 3 options = maptalks.Util.extend({}, OPTIONS, options, { layer, lineString }); 4 super(); 5 //Initialize internal configuration 6 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135 7 this._initOptions(options); 8 9 const { altitude, chunkLength, speed, trail } = options; 10 const chunkLines = lineSlice(lineString, chunkLength); 11 12 const positions = _getChunkLinesPosition([chunkLines[0]], layer).positions; 13 const geometry = new THREE.BufferGeometry(); 14 const ps = new Float32Array(MAX_POINTS * 3); // 3 vertices per point 15 geometry.addAttribute('position', new THREE.BufferAttribute(ps, 3).setDynamic(true)); 16 setLineGeometryAttribute(geometry, positions); 17 this._createLine(geometry, material); 18 19 //set object3d position 20 const z = layer.distanceToVector3(altitude, altitude).x; 21 this.getObject3d().position.z = z; 22 23 this._params = { 24 trail: Math.max(1, trail), 25 index: 0, 26 len: chunkLines.length, 27 chunkLines, 28 layer, 29 speed: Math.min(1, speed), 30 idx: 0, 31 positions: [] 32 }; 33 // this._init(); 34 } 35 36 37 _init() { 38 const { len, chunkLines, layer, trail } = this._params; 39 for (let i = 0; i < len; i++) { 40 const result = chunkLines.slice(i, i + trail); 41 const ps = _getChunkLinesPosition(result, layer).positions; 42 this._params.positions[i] = ps; 43 } 44 } 45 46 47 _animation() { 48 const { index, positions, idx, speed, len, chunkLines, layer, trail } = this._params; 49 const i = Math.round(index); 50 if (i > idx) { 51 this._params.idx++; 52 let ps = positions[i]; 53 if (!ps) { 54 const result = chunkLines.slice(i, i + trail); 55 ps = _getChunkLinesPosition(result, layer).positions; 56 this._params.positions[i] = ps; 57 } 58 setLineGeometryAttribute(this.getObject3d().geometry, ps); 59 this.getObject3d().geometry.attributes.position.needsUpdate = true; 60 } 61 if (index >= len) { 62 this._params.index = -1; 63 this._params.idx = -1; 64 } 65 this._params.index += speed; 66 } 67 }
5. TextSprite
1 class TextSprite extends maptalks.BaseObject { 2 constructor(coordinate, options, layer) { 3 options = maptalks.Util.extend({}, OPTIONS2, options, { layer, coordinate }); 4 super(); 5 //Initialize internal configuration 6 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135 7 this._initOptions(options); 8 const { altitude, fontSize, color, text } = options; 9 10 11 //Initialize internal object3d 12 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L140 13 this._createGroup(); 14 const textsprite = new THREE_Text2D.SpriteText2D(text, { align: THREE_Text2D.textAlign.center, font: `${fontSize * 2}px Arial`, fillStyle: color, antialias: false }); 15 this.getObject3d().add(textsprite); 16 17 //set object3d position 18 const z = layer.distanceToVector3(altitude, altitude).x; 19 const position = layer.coordinateToVector3(coordinate, z); 20 this.getObject3d().position.copy(position); 21 } 22 23 24 25 _animation() { 26 const scale = this.getMap().getScale() / 2000 / 15 * this.getOptions().fontSize; 27 this.getObject3d().children[0].scale.set(scale, scale, scale); 28 } 29 30 31 }
6. 线路
1 function addLines() { 2 fetch('./data/flight-path.txt').then(function (res) { 3 return res.text(); 4 }).then(function (geojson) { 5 geojson = LZString.decompressFromBase64(geojson); 6 geojson = JSON.parse(geojson); 7 geojson.forEach(lnglats => { 8 const ps = lnglats.map(l => { 9 const [lng, lat, height] = l; 10 const z = threeLayer.distanceToVector3(height, height).x; 11 return threeLayer.coordinateToVector3([lng, lat], z); 12 }); 13 const line = new Line(ps, {}, material, threeLayer); 14 line.getObject3d().layers.enable(1); 15 lines.push(line); 16 // console.log(lineSlice(lnglats, 20000)); 17 const lineTrail = new LineTrail(lnglats, { chunkLength: 5000, altitude: 200, trail: 1 }, highlightmaterial, threeLayer); 18 lineTrail.getObject3d().layers.enable(1); 19 lineTrails.push(lineTrail); 20 21 const lineTrail1 = new LineTrail(lnglats.reverse(), { chunkLength: 5000, altitude: 200, trail: 1 }, highlightmaterial, threeLayer); 22 lineTrail1.getObject3d().layers.enable(1); 23 lineTrails.push(lineTrail1); 24 }); 25 threeLayer.addMesh(lines); 26 threeLayer.addMesh(lineTrails); 27 initGui(); 28 animation(); 29 addNames(); 30 }) 31 }
7. 页面显示
8. 源码地址
https://github.com/WhatGIS/maptalkMap/tree/main/threelayer/demo