maptalks 开发GIS地图(24)maptalks.three.17 - custom-arcline-animation

1. 在飞线的基础上加入移动轨迹,很像飞机飞过的轨迹。这个效果在百度地图里也有。

 

2. 在 ArcLine 对象中,加入了 speed 参数,在 ArcLine 的类中加入 _animation 动画代码。

 

3. 添加 Line。

 1   function loadRoad(geojsonURL, textureURL) {
 2             fetch(geojsonURL).then(function (res) {
 3                 return res.text();
 4             }).then(function (text) {
 5                 return JSON.parse(text);
 6             }).then(function (geojson) {
 7                 const texture = new THREE.TextureLoader().load(textureURL);
 8                 texture.anisotropy = 16;
 9                 texture.wrapS = THREE.RepeatWrapping;
10                 texture.wrapT = THREE.RepeatWrapping;
11                 const camera = threeLayer.getCamera();
12                 const material = new MeshLineMaterial({
13                     map: texture,
14                     useMap: true,
15                     lineWidth: 13,
16                     sizeAttenuation: false,
17                     transparent: true,
18                     near: camera.near,
19                     far: camera.far
20                 });
21                 const multiLineStrings = maptalks.GeoJSON.toGeometry(geojson);
22                 for (const multiLineString of multiLineStrings) {
23                     const lines = multiLineString._geometries.filter(lineString => {
24                         const len = lineLength(lineString);
25                         return len > 800;
26                     }).map(lineString => {
27                         const len = lineLength(lineString)
28                         const line = new ArcLine(lineString, { altitude: 0, height: len / 3, speed: len / 100000 }, material, threeLayer);
29                         line.setToolTip(len);
30                         return line;
31                     });
32                     threeLayer.addMesh(lines);
33                     meshes = meshes.concat(lines);
34                 }
35             });
36         }

 

4.  ArcLine 扩展类

  1  var OPTIONS = {
  2             altitude: 0,
  3             speed: 0.01,
  4             height: 100
  5         };
  6 
  7         class ArcLine extends maptalks.BaseObject {
  8             constructor(lineString, options, material, layer) {
  9                 super();
 10                 options.offset = material.uniforms.offset.value;
 11                 options.clock = new THREE.Clock();
 12                 //geoutil.js getLinePosition
 13                 options = maptalks.Util.extend({}, OPTIONS, options, { layer, lineString });
 14                 this._initOptions(options);
 15 
 16                 const { altitude, height } = options;
 17                 const points = getArcPoints(lineString, layer.distanceToVector3(height, height).x, layer);
 18                 const geometry = new THREE.Geometry();
 19                 geometry.vertices = points;
 20                 const meshLine = new MeshLine();
 21                 meshLine.setGeometry(geometry);
 22 
 23                 const map = layer.getMap();
 24                 const size = map.getSize();
 25 
 26                 material.uniforms.resolution.value.set(size.width, size.height);
 27 
 28                 this._createMesh(meshLine.geometry, material);
 29 
 30                 const z = layer.distanceToVector3(altitude, altitude).x;
 31                 const center = lineString.getCenter();
 32                 const v = layer.coordinateToVector3(center, z);
 33                 this.getObject3d().position.copy(v);
 34                 this._setPickObject3d();
 35                 this._init();
 36             }
 37             
 38             _animation() {
 39                 this.options.offset.x -= this.options.speed * this.options.clock.getDelta();
 40             }
 41 
 42             _init() {
 43                 const pick = this.getLayer().getPick();
 44                 this.on('add', () => {
 45                     pick.add(this.pickObject3d);
 46                 });
 47                 this.on('remove', () => {
 48                     pick.remove(this.pickObject3d);
 49                 });
 50             }
 51 
 52 
 53             _setPickObject3d(ps, linewidth) {
 54                 const geometry = this.getObject3d().geometry.clone();
 55                 const pick = this.getLayer().getPick();
 56                 const color = pick.getColor();
 57                 const {
 58                     lineWidth,
 59                     sizeAttenuation,
 60                     transparent,
 61                     near,
 62                     far
 63                 } = this.getObject3d().material;
 64                 const material = new MeshLineMaterial({
 65                     lineWidth,
 66                     sizeAttenuation,
 67                     transparent,
 68                     near,
 69                     far,
 70                     color
 71                 });
 72                 const map = this.getMap();
 73                 const size = map.getSize();
 74 
 75                 material.uniforms.resolution.value.set(size.width, size.height);
 76                 const mesh = new THREE.Mesh(geometry, material);
 77                 mesh.position.copy(this.getObject3d().position);
 78 
 79                 const colorIndex = color.getHex();
 80                 mesh._colorIndex = colorIndex;
 81                 this.setPickObject3d(mesh);
 82             }
 83 
 84             identify(coordinate) {
 85                 return this.picked;
 86             }
 87         }
 88 
 89         function getArcPoints(lineString, height, layer) {
 90             const lnglats = [];
 91             if (Array.isArray(lineString)) {
 92                 lnglats.push(lineString[0], lineString[lineString.length - 1]);
 93             } else if (lineString instanceof maptalks.LineString) {
 94                 const coordinates = lineString.getCoordinates();
 95                 lnglats.push(coordinates[0], coordinates[coordinates.length - 1]);
 96             }
 97             const [first, last] = lnglats;
 98             let center;
 99             if (Array.isArray(first)) {
100                 center = [first[0] / 2 + last[0] / 2, first[1] / 2 + last[1] / 2];
101             } else if (first instanceof maptalks.Coordinate) {
102                 center = [first.x / 2 + last.x / 2, first.y / 2 + last.y / 2];
103             }
104             const centerPt = layer.coordinateToVector3(lineString.getCenter());
105             const v = layer.coordinateToVector3(first).sub(centerPt);
106             const v1 = layer.coordinateToVector3(last).sub(centerPt);
107             const vh = layer.coordinateToVector3(center, height).sub(centerPt);
108             const ellipse = new THREE.CatmullRomCurve3([v, vh, v1], false, 'catmullrom');
109             const points = ellipse.getPoints(40);
110             return points;
111         }

 

5. 页面显示

 

6. 源码地址

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

 

 
posted @ 2021-05-06 14:15  googlegis  阅读(385)  评论(0编辑  收藏  举报

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