1. 和尾线效果类似的 轨迹追踪功能。线路逐渐显示,更适合做轨迹显示。
2. 使用了 lineTrip 对象,直接处理已有数据。
1 var offset = 500; 2 lineTrips = list.slice(0, offset).map(d => { 3 var line = new LineTrip(d.lineString, { 4 chunkLength: d.len / 100, 5 speed: 1, 6 altitude: 2, 7 }, material, threeLayer) 8 return line; 9 }); 10 threeLayer.addMesh(lineTrips);
3. 自定义 lineTrip 扩展类,
1 class LineTrip 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 } = options; 10 const chunkLines = lineSlice(lineString, chunkLength); 11 12 const centerPt = layer.coordinateToVector3(lineString.getCenter()); 13 //cache position for faster computing,reduce double counting 14 const positionMap = {}; 15 for (let i = 0, len = chunkLines.length; i < len; i++) { 16 const chunkLine = chunkLines[i]; 17 for (let j = 0, len1 = chunkLine.length; j < len1; j++) { 18 const lnglat = chunkLine[j]; 19 const key = lnglat.join(',').toString(); 20 if (!positionMap[key]) { 21 positionMap[key] = layer.coordinateToVector3(lnglat).sub(centerPt); 22 } 23 } 24 } 25 26 let len = 0; 27 chunkLines.forEach(element => { 28 len += element.length; 29 }); 30 len *= 3; 31 //generate geometry 32 const result = getChunkLinesPosition(chunkLines.slice(0, 1), layer, positionMap, centerPt); 33 const positions = result.positions; 34 const geometry = new THREE.BufferGeometry(); 35 const ps = new Float32Array(len); // 3 vertices per point 36 geometry.addAttribute('position', new THREE.BufferAttribute(ps, 3).setDynamic(true)); 37 setLineGeometryAttribute(geometry, positions.slice(0, 6)); 38 39 this._createLine(geometry, material); 40 41 //set object3d position 42 const z = layer.distanceToVector3(altitude, altitude).x; 43 const center = lineString.getCenter(); 44 const v = layer.coordinateToVector3(center, z); 45 this.getObject3d().position.copy(v); 46 47 this._params = { 48 index: 0, 49 len: chunkLines.length, 50 chunkLines, 51 layer, 52 speed: Math.min(1, speed), 53 idx: 0, 54 positions: [], 55 positionMap, 56 centerPt 57 }; 58 this._init(); 59 } 60 61 _init() { 62 const { len, chunkLines, layer, positionMap, centerPt } = this._params; 63 for (let i = 0; i < len; i++) { 64 let ps = []; 65 if (i > 0) { 66 const prePs = this._params.positions[i - 1]; 67 for (let j = 0, len1 = prePs.length; j < len1; j++) { 68 ps.push(prePs[j]); 69 } 70 const nextPs = getChunkLinesPosition([chunkLines[i]], layer, positionMap, centerPt).positions; 71 for (let j = 0, len1 = nextPs.length; j < len1; j++) { 72 ps.push(nextPs[j]); 73 } 74 } else { 75 const result = chunkLines.slice(0, i); 76 ps = getChunkLinesPosition(result, layer, positionMap, centerPt).positions; 77 } 78 this._params.positions[i] = ps; 79 } 80 } 81 82 83 _animation() { 84 const { index, positions, idx, speed, len, chunkLines, layer, positionMap, centerPt } = this._params; 85 const i = Math.round(index); 86 if (i > idx) { 87 this._params.idx++; 88 let ps = positions[i]; 89 if (!ps) { 90 const result = chunkLines.slice(0, i); 91 ps = getChunkLinesPosition(result, layer, positionMap, centerPt).positions; 92 this._params.positions[i] = ps; 93 } 94 setLineGeometryAttribute(this.getObject3d().geometry, ps); 95 this.getObject3d().geometry.attributes.position.needsUpdate = true; 96 } 97 if (index >= len) { 98 this._params.index = -1; 99 this._params.idx = -1; 100 } 101 this._params.index += speed; 102 } 103 }
4. 页面显示
5. 源码地址
https://github.com/WhatGIS/maptalkMap/tree/main/threelayer/demo