cesium 圆墙 wall

效果:
请添加图片描述
核心代码:

/**
 * @desc 通过圆心和半径绘制圆墙
 * @param {Object} options 
 * {
    dataSourceName: 'fence',//围栏source名
    type: 'fence',//围栏类型
    name: "ellipWall",//围栏名称
    id:1,//围栏id
    x:113.97012095140055,//围栏经度 +-180~
    y:22.52298214113242,//围栏纬度 +-90~
    // r:50,//围栏半径 默认为50米
    // height: 15//围栏高度 默认为15
    }
 * @returns 
 */
function createEllipWallGraphic(options={}){
    let dataSource = new Cesium.CustomDataSource(options.dataSourceName || 'dataName');
    let lineFlowMaterial = new LineFlowMaterial({//动画线材质
        color: new Cesium.Color.fromCssColorString("#ff0000"),
        duration: 2000, //时长,控制速度
        url: 'map/textures/fence.png',
        axisY: true
    });
        var ellipse = new Cesium.EllipseOutlineGeometry({
            center : Cesium.Cartesian3.fromDegrees(options.x||113.97012095140055,options.y||22.52298214113242),
            semiMajorAxis : options.r||50,
            semiMinorAxis : options.r||50,
            // granularity:0.5
            // rotation : Cesium.Math.toRadians(60.0)
          });
          var geometry = Cesium.EllipseOutlineGeometry.createGeometry(ellipse);
          var circlepoints =[];
          var values = geometry.attributes.position.values; 
          if (!values) return;
          var ilen = values.length / 3; //数组中以笛卡尔坐标进行存储 每3个值一个坐标
          for (var i = 0; i < ilen; i++) {
          	var xyz = new Cesium.Cartesian3(values[i * 3], values[i * 3 + 1], values[i * 3 + 2]); //笛卡尔
          	circlepoints.push(xyz);
          }
          circlepoints.push(circlepoints[0])
          let maximumHeights=[]
          let minimumHeights=[]
          circlepoints.forEach(item=>{
            maximumHeights.push(options.height||15)
            minimumHeights.push(0)
          })
        dataSource.entities.add(
            {
            name: options.name||"fence",
            prop: options,
            id: `${options.type||"fence"}_${options.id}`,
            wall: {
                positions: circlepoints,
                maximumHeights: maximumHeights,
                minimumHeights: minimumHeights,
                material: lineFlowMaterial
            },
        });
    viewer.dataSources.add(dataSource);
}

使用:

createEllipWallGraphic(
    {
    dataSourceName: 'fence',//围栏source名
    type: 'fence',//围栏类型
    name: "ellipWall",//围栏名称
    id:1,//围栏id
    x:113.97012095140055,//围栏经度 +-180~
    y:22.52298214113242,//围栏纬度 +-90~
    // r:50,//围栏半径 默认为50米
    // height: 15//围栏高度 默认为15
    }
)

核心代码解释:
EllipseOutlineGeometry 先绘制一个线性圆 获取坐标点
Cartesian3 数组中以笛卡尔坐标进行存储 每3个值一个坐标
circlepoints.push(circlepoints[0]) 获取的geom数组不是闭合的(首尾坐标不一样) 需要手动闭合,将最后一个坐标手动填充
最大高度和最低高度:个数需要与笛卡尔坐标数组一一对应 比如有五个点组成的闭合矩形 则需要五个最高和最低的数组 例如maximumHeights:[15,15,15,15,15]
来源:
在这里插入图片描述
所以这里我们需要循环添加最大和最小高度:
circlepoints.forEach(item=>{
maximumHeights.push(options.height||15)
minimumHeights.push(0)
})

======================================
LineFlowMaterial 代码

var createClass = function() {
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }
    return function (Constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
    };
}()

var defaultColor = new Cesium.Color(0, 0, 0, 0);
var defaultBgColor = new Cesium.Color(1, 1, 1);

var LineFlowMaterial = function () {
    //========== 构造方法 ==========
    function LineFlowMaterial(options) {

        options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);

        this._definitionChanged = new Cesium.Event();
        this._color = undefined;
        this._colorSubscription = undefined;

        this.color = Cesium.defaultValue(options.color, defaultColor); //颜色
        this.url = Cesium.defaultValue(options.url, undefined); //背景图片颜色
        if (!this.url) return;

        this.axisY = Boolean(options.axisY);
        this.bgUrl = Cesium.defaultValue(options.bgUrl, undefined); //背景图片颜色
        this.bgColor = Cesium.defaultValue(options.bgColor, defaultBgColor); //背景图片颜色
        this._duration = options.duration || 1000; //时长

        var _material = getImageMaterial(this.url, this.bgUrl, options.repeat, Boolean(options.axisY), this.bgColor);

        this._materialType = _material.type; //材质类型
        this._materialImage = _material.image; //材质图片
        this._time = undefined;
    }

    //========== 对外属性 ==========


    createClass(LineFlowMaterial, [{
        key: "getType",


        //========== 方法 ==========

        /**
         * Gets the {@link Cesium.Material} type at the provided time.
         *
         * @param {JulianDate} time The time for which to retrieve the type.
         * @returns {String} The type of material.
         */
        value: function getType(time) {
            return this._materialType;
        }

        /**
         * Gets the value of the property at the provided time.
         *
         * @param {JulianDate} time The time for which to retrieve the value.
         * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned.
         * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied.
         */

    }, {
        key: "getValue",
        value: function getValue(time, result) {
            if (!Cesium.defined(result)) {
                result = {};
            }
            result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, defaultColor, result.color);
            result.image = this._materialImage;
            if (this._time === undefined) {
                this._time = new Date().getTime();
            }
            result.time = (new Date().getTime() - this._time) / this._duration;
            return result;
        }

        /**
         * Compares this property to the provided property and returns
         * <code>true</code> if they are equal, <code>false</code> otherwise.
         *
         * @param {Cesium.Property} [other] The other property.
         * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
         */

    }, {
        key: "equals",
        value: function equals(other) {
            return this === other || //
                other instanceof LineFlowMaterial && Cesium.Property.equals(this._color, other._color);
        }
    }, {
        key: "isConstant",
        get: function get() {
            return false;
        }
    }, {
        key: "definitionChanged",
        get: function get() {
            return this._definitionChanged;
        }
    }]);

    return LineFlowMaterial;
}();

Object.defineProperties(LineFlowMaterial.prototype, {
    /**
     * Gets or sets the Cesium.Property specifying the {@link Cesium.Color} of the line.
     * @memberof PolylineGlowMaterialProperty.prototype
     * @type {Cesium.Property}
     */
    color: Cesium.createPropertyDescriptor('color')
});

//静态方法,处理材质
var cacheIdx = 0;
var nameEx = "AnimationLine";
function getImageMaterial(imgurl, bgUrl, repeat, axisY, bgColor) {
    cacheIdx++;
    var typeName = nameEx + cacheIdx + "Type";
    var imageName = nameEx + cacheIdx + "Image";

    Cesium.Material[typeName] = typeName;
    Cesium.Material[imageName] = imgurl;
    let source1 = `
        czm_material czm_getMaterial(czm_materialInput materialInput)
        {
            czm_material material = czm_getDefaultMaterial(materialInput);
            vec2 st = repeat * materialInput.st;
            vec4 colorImage = texture2D(image, vec2(fract((axisY?st.t:st.s) - time), st.t));
            if(color.a == 0.0)
            {
                material.alpha = colorImage.a;
                material.diffuse = colorImage.rgb;
            }
            else
            {
                material.alpha = colorImage.a * color.a;
                material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);
            }
            vec4 colorBG = texture2D(image2,materialInput.st);
            if(colorBG.a>0.5){
                material.diffuse = bgColor.rgb;
            }
            return material;
        }
    `
    let source2 = `
        czm_material czm_getMaterial(czm_materialInput materialInput)
        {
            czm_material material = czm_getDefaultMaterial(materialInput);
            vec2 st = repeat * materialInput.st;
            vec4 colorImage = texture2D(image, vec2(fract((axisY?st.t:st.s) - time), st.t));
            if(color.a == 0.0)
            {
                material.alpha = colorImage.a;
                material.diffuse = colorImage.rgb;
            }
            else
            {
                material.alpha = colorImage.a * color.a;
                material.diffuse = max(color.rgb * material.alpha * 3.0, color.rgb);
            }
            return material;
        }
    `
    if (bgUrl) {
        //存在2张url的,用叠加融合的效果

        Cesium.Material._materialCache.addMaterial(Cesium.Material[typeName], {
            fabric: {
                type: Cesium.Material.PolylineArrowLinkType,
                uniforms: {
                    color: new Cesium.Color(1, 0, 0, 1.0),
                    image: Cesium.Material[imageName],
                    time: 0,
                    repeat: repeat || new Cesium.Cartesian2(1.0, 1.0),
                    axisY: axisY,
                    image2: bgUrl,
                    bgColor: bgColor
                },
                source: source1
            },
            translucent: function translucent() {
                return true;
            }
        });
    } else {
        Cesium.Material._materialCache.addMaterial(Cesium.Material[typeName], {
            fabric: {
                type: typeName,
                uniforms: {
                    color: new Cesium.Color(1, 0, 0, 1.0),
                    image: Cesium.Material[imageName],
                    time: 0,
                    repeat: repeat || new Cesium.Cartesian2(1.0, 1.0),
                    axisY: axisY
                },
                source: source2
            },
            translucent: function translucent() {
                return true;
            }
        });
    }

    return {
        type: Cesium.Material[typeName],
        image: Cesium.Material[imageName]
    };
}
export {
    LineFlowMaterial
}

图片:
请添加图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值