cesium实现道路穿梭线效果


Cesium实战系列文章总目录传送门

1.实现效果

请添加图片描述

2.实现方法

2.1加载GeoJson道路线状数据

使用Cesium的GeoJsonDataSource接口添加线状道路geojson文件。

  // 道路穿梭线
  Cesium.GeoJsonDataSource.load("./data/road1.geojson").then(function(dataSource) {
      this.viewer.dataSources.add(dataSource);
      const entities = dataSource.entities.values;
      for (let i = 0; i < entities.length; i++) {
          let entity = entities[i];
          entity.polyline.width = 1.7;
          entity.polyline.material = new Cesium.Spriteline1MaterialProperty(1000, './data/pictures/spriteline1.png');
      }
  });

2.2设置每个entity的样式

遍历加载后文件的entity,将其材质设置为自定义的传输线材质。

2.3材质设置

参考gitee上的开源代码,将材质文件保存为单独的js文件,在进行entity材质赋值时直接调用即可。主要的逻辑实现代码是下文中的几行WebGL代码。

/**
 *  精灵穿梭路光效果,
 *  参考gitee开源
 *  entity的材质使用MaterialProperty,而primitive使用的是material。
 *  @Data:2022-01-11
 */

function Spriteline1MaterialProperty(duration, image) {
    this._definitionChanged = new Cesium.Event()
    this.duration = duration
    this.image = image
    this._time = performance.now()
}
Object.defineProperties(Spriteline1MaterialProperty.prototype, {
    isConstant: {
        get: function() {
            return false
        },
    },
    definitionChanged: {
        get: function() {
            return this._definitionChanged
        },
    },
    color: Cesium.createPropertyDescriptor('color'),
    duration: Cesium.createPropertyDescriptor('duration')
})
Spriteline1MaterialProperty.prototype.getType = function(time) {
    return 'Spriteline1'
}
Spriteline1MaterialProperty.prototype.getValue = function(
    time,
    result
) {
    if (!Cesium.defined(result)) {
        result = {}
    }
    result.image = this.image
    result.time =
        ((performance.now() - this._time) % this.duration) / this.duration
    return result
}
Spriteline1MaterialProperty.prototype.equals = function(e) {
    return (
        this === e ||
        (e instanceof Spriteline1MaterialProperty && this.duration === e.duration)
    )
}
Cesium.Spriteline1MaterialProperty = Spriteline1MaterialProperty
Cesium.Material.Spriteline1Type = 'Spriteline1'
Cesium.Material.Spriteline1Source = `
czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));
material.alpha = colorImage.a;
material.diffuse = colorImage.rgb * 1.5 ;
return material;
}
`
    // st :二维纹理坐标
    // czm_material:保存可用于照明的材质信息
Cesium.Material._materialCache.addMaterial(Cesium.Material.Spriteline1Type, {
    fabric: {
        type: Cesium.Material.Spriteline1Type,
        uniforms: {
            color: new Cesium.Color(1, 0, 0, 0.5),
            image: '',
            transparent: true,
            time: 20,
        },
        source: Cesium.Material.Spriteline1Source,
    },
    translucent: function(material) {
        return true
    },
})
要在Cesium实现抛物线效果,可以使用贝塞尔曲线来模拟抛物线的路径。以下是实现抛物线效果的步骤: 1. 使用entity方式创建一个新的实体对象。 2. 设置实体的position为抛物线的起始点。 3. 使用polyline实例化一个新的PolylineGraphics对象。 4. 将PolylineGraphics对象的positions属性设置为一个包含抛物线路径上的点的数组。 5. 设置PolylineGraphics对象的material为所需的抛物线材质。 6. 将PolylineGraphics对象添加到viewer。 下面是一个示例代码,展示了如何在Cesium实现抛物线效果: ```javascript // 创建起始点和终点 var start = Cesium.Cartesian3.fromDegrees(113.9236839, 22.528061); var end = Cesium.Cartesian3.fromDegrees(113.925, 22.53); // 计算控制点 var controlPoint = new Cesium.Cartesian3( (start.x + end.x) / 2, (start.y + end.y) / 2, (start.z + end.z) / 2 + 1000 ); // 计算抛物线路径上的点 var numberOfPoints = 100; var positions = []; for (var i = 0; i <= numberOfPoints; i++) { var t = i / numberOfPoints; var x = (1 - t) * (1 - t) * start.x + 2 * (1 - t) * t * controlPoint.x + t * t * end.x; var y = (1 - t) * (1 - t) * start.y + 2 * (1 - t) * t * controlPoint.y + t * t * end.y; var z = (1 - t) * (1 - t) * start.z + 2 * (1 - t) * t * controlPoint.z + t * t * end.z; positions.push(new Cesium.Cartesian3(x, y, z)); } // 创建实体对象 viewer.entities.add({ polyline: { positions: positions, width: 10, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.5, color: Cesium.Color.YELLOW }) } }); ```
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值