maptalks 开发GIS地图(38)maptalks.three.31- custom-linetrip

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. 页面显示

maptalks 开发GIS地图(38)maptalks.three.31- custom-linetrip

 

5. 源码地址

https://github.com/WhatGIS/maptalkMap/tree/main/threelayer/demo

上一篇:Javascript高级编程学习笔记(63)—— 事件(7)鼠标及滚轮事件


下一篇:torch.matmul