maptalks 开发GIS地图(37)maptalks.three.30- custom-linetrail

1. 尾线效果,很适合做轨迹追踪或者路线动画。

 

2. 数据使用 ./data/lines.json 

 

 

3. 处理数据

1 var lineStrings = geojson.map(function (feature) {
2                     var coordinates = feature.coordinates;
3                     var [from, to] = coordinates;
4                     var lnglats = [[parseFloat(from[0]), parseFloat(from[1])], [parseFloat(to[0]), parseFloat(to[1])]]
5                     return new maptalks.LineString(lnglats);
6                 });

 

4. 将数据处理为 linetrail 并添加到 图层。

 1                 var offset = 2000;
 2                 lineTrails = list.slice(0, offset).map(d => {
 3                     var line = new LineTrail(d.lineString, {
 4                         chunkLength: d.len / 100,
 5                         trail: 5,
 6                         speed: 1,
 7                         altitude: 100,
 8                     }, material, threeLayer)
 9                     return line;
10                 });
11                 var lines = list.slice(0, offset).map(d => {
12                     return threeLayer.toLine(d.lineString, {}, lineMaterial);
13                 });

 

5. lineTrail 的自定义扩展类

  1 //default values
  2         var OPTIONS = {
  3             trail: 5,
  4             chunkLength: 50,
  5             speed: 1,
  6             altitude: 0,
  7             interactive: false
  8         };
  9 
 10         const MAX_POINTS = 1000;
 11 
 12         /**
 13          * custom component
 14          * */
 15 
 16         class LineTrail extends maptalks.BaseObject {
 17             constructor(lineString, options, material, layer) {
 18                 options = maptalks.Util.extend({}, OPTIONS, options, { layer, lineString });
 19                 super();
 20                 //Initialize internal configuration
 21                 // https://github.com/maptalks/maptalks.three/blob/1e45f5238f500225ada1deb09b8bab18c1b52cf2/src/BaseObject.js#L135
 22                 this._initOptions(options);
 23 
 24                 const { altitude, chunkLength, speed, trail } = options;
 25                 const chunkLines = lineSlice(lineString, chunkLength);
 26 
 27 
 28                 const centerPt = layer.coordinateToVector3(lineString.getCenter());
 29                 //cache position for  faster computing,reduce double counting
 30                 const positionMap = {};
 31                 for (let i = 0, len = chunkLines.length; i < len; i++) {
 32                     const chunkLine = chunkLines[i];
 33                     for (let j = 0, len1 = chunkLine.length; j < len1; j++) {
 34                         const lnglat = chunkLine[j];
 35                         const key = lnglat.join(',').toString();
 36                         if (!positionMap[key]) {
 37                             positionMap[key] = layer.coordinateToVector3(lnglat).sub(centerPt);
 38                         }
 39                     }
 40                 }
 41 
 42                 const positions = getChunkLinesPosition([chunkLines[0]], layer, positionMap, centerPt).positions;
 43                 const geometry = new THREE.BufferGeometry();
 44                 const ps = new Float32Array(MAX_POINTS * 3); // 3 vertices per point
 45                 geometry.addAttribute('position', new THREE.BufferAttribute(ps, 3).setDynamic(true));
 46                 setLineGeometryAttribute(geometry, positions);
 47                 this._createLine(geometry, material);
 48 
 49                 //set object3d position
 50                 const z = layer.distanceToVector3(altitude, altitude).x;
 51 
 52                 const center = lineString.getCenter();
 53                 const v = layer.coordinateToVector3(center, z);
 54                 this.getObject3d().position.copy(v);
 55 
 56                 this._params = {
 57                     trail: Math.max(1, trail),
 58                     index: 0,
 59                     len: chunkLines.length,
 60                     chunkLines,
 61                     layer,
 62                     speed: Math.min(1, speed),
 63                     idx: 0,
 64                     positions: [],
 65                     positionMap,
 66                     centerPt
 67                 };
 68                 // this._init();
 69             }
 70 
 71 
 72             _init() {
 73                 const { len, chunkLines, layer, trail, positionMap, centerPt } = this._params;
 74                 for (let i = 0; i < len; i++) {
 75                     const result = chunkLines.slice(i, i + trail);
 76                     const ps = getChunkLinesPosition(result, layer, positionMap, centerPt).positions;
 77                     this._params.positions[i] = ps;
 78                 }
 79             }
 80 
 81 
 82             _animation() {
 83                 const { index, positions, idx, speed, len, chunkLines, layer, trail, positionMap, centerPt } = this._params;
 84                 const i = Math.round(index);
 85                 if (i > idx) {
 86                     this._params.idx++;
 87                     let ps = positions[i];
 88                     if (!ps) {
 89                         const result = chunkLines.slice(i, i + trail);
 90                         ps = getChunkLinesPosition(result, layer, positionMap, centerPt).positions;
 91                         this._params.positions[i] = ps;
 92                     }
 93                     setLineGeometryAttribute(this.getObject3d().geometry, ps);
 94                     this.getObject3d().geometry.attributes.position.needsUpdate = true;
 95                 }
 96                 if (index >= len) {
 97                     this._params.index = -1;
 98                     this._params.idx = -1;
 99                 }
100                 this._params.index += speed;
101             }
102         }

 

6. 页面效果

 

7. 源码地址

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

 
posted @ 2021-05-07 09:34  googlegis  阅读(222)  评论(0编辑  收藏  举报

坐标合肥,非典型GIS开发人员 GitHub