• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

VUE3-CesiumCesium3DTileStyle-3dtiles样式更改

武飞扬头像
HM-hhxx!
帮助4

目录

1.Cesium3DTileStyle详解

1.1 styling features(样式功能)

1.2 conditions(条件)

1.3  Defining variables(定义变量)

1.4 Meta property(元属性)

2. Expressions-表达式

2.1 Semantics-语义化

2.2 Operators-操作符

2.3 Types-类型

2.3.1 支持类型:

2.3.1 Vector向量:

3. Examples-1设置颜色:

4. Examples-2根据不同条件设置颜色:

4.1 安装dat.GUI插件

4.2 导入dat.gui插件,并实例化:

4.3 设置各种条件,并根据不同条件设置3dtile的不同样式: 

4.4 将不同条件的执行挂在到dat.gui上:

5. Examples-3多条件样式高级设置:

之前的文章讲过通过new Cesium.createOsmBuildings()在Cesium加载Open street map建筑模型,但加载后为白膜,当我们需要对其样式进行更改时,就需要使用Cesium3DTileStyle进行更改。3D 切片样式提供磁贴集要素的简洁声明性样式。样式定义表达式以评估要素的显示,例如(RGB 和半透明性)和属性,通常基于存储在切片的 Batch 表中的要素属性。color show

样式可以应用于不包含要素的切片,在这种情况下,切片将被视为没有属性的隐式单个要素。

虽然可以为切片集创建样式并为其引用属性,但样式独立于切片集,因此任何样式都可以应用于任何切片集。

样式是用JSON定义的,表达式写在JavaScript的一小部分中,为样式进行了扩充。此外,样式语言还提供了一组内置函数来支持常见的数学运算。

下面的示例根据建筑物高度分配颜色。

  1.  
    {
  2.  
    "show" : "${Area} > 0",
  3.  
    "color" : {
  4.  
    "conditions" : [
  5.  
    ["${Height} < 60", "color('#13293D')"],
  6.  
    ["${Height} < 120", "color('#1B98E0')"],
  7.  
    ["true", "color('#E8F1F2', 0.5)"]
  8.  
    ]
  9.  
    }
  10.  
    }

1.Cesium3DTileStyle详解

Cesium3DTileStyle应用于Cesium3DTileset的样式,通过new Cesium.Cesium3DTileStyle ( style )创建并使用。官方文档:3D磁贴/规格/样式在主 ·铯GS/3D瓷砖 ·GitHub

1.1 styling features(样式功能)

可用于设置样式特征的视觉属性是属性,其分配的表达式将计算为确定特征是否可见的布尔值,以及属性,其分配的表达式将计算为对象(RGB 和半透明性),后者确定特征的显示颜色。showcolorColor

以下样式为每个要素指定默认的显示和颜色属性:

  1.  
    {
  2.  
    "show" : "true",
  3.  
    "color" : "color('#ffffff')"
  4.  
    }

 例如,以下表达式将仅显示 19341 邮政编码中的要素,而不是显示所有要素,可以是依赖于要素属性的表达式:show

  1.  
    {
  2.  
    "show" : "${ZipCode} === '19341'"
  3.  
    }

 show也可用于更复杂的查询;例如,此处的复合条件和正则表达式仅用于显示其县以 1970 开头且其建成年份大于或等于 1970 的要素:'Chest'

  1.  
    {
  2.  
    "show" : "(regExp('^Chest').test(${County})) && (${YearBuilt} >= 1970)"
  3.  
    }

 颜色也可以由依赖于要素属性的表达式来定义。例如,以下表达式将温度高于 90 的特征颜色着色为红色,将其他表达式颜色着色为白色:

  1.  
    {
  2.  
    "color" : "(${Temperature} > 90) ? color('red') : color('white')"
  3.  
    }

 颜色的 alpha 分量定义了要素的不透明度。例如,以下命令根据要素的属性设置要素的 RGB 颜色分量,并使体积大于 100 的要素透明:

  1.  
    {
  2.  
    "color" : "rgba(${red}, ${green}, ${blue}, (${volume} > 100 ? 0.5 : 1.0))"
  3.  
    }

1.2 conditions(条件)

除了包含表达式的字符串之外,还可以是定义一系列条件的数组(类似于语句)。例如,条件可用于制作具有任何类型的包含/排除间隔的色彩映射表和色带。colorshowif...else

例如,下面的表达式将 ID 属性映射到颜色。条件按顺序计算,因此如果不是 或 ,则条件返回白色。如果未满足任何条件,则要素的颜色将为:${id}'1''2'"true"undefined

  1.  
    {
  2.  
    "color" : {
  3.  
    "conditions" : [
  4.  
    ["${id} === '1'", "color('#FF0000')"],
  5.  
    ["${id} === '2'", "color('#00FF00')"],
  6.  
    ["true", "color('#FFFFFF')"]
  7.  
    ]
  8.  
    }
  9.  
    }

下一个示例演示如何使用条件,使用具有非独占下限和独占上限的间隔创建色带:

  1.  
    "color" : {
  2.  
    "conditions" : [
  3.  
    ["(${Height} >= 1.0) && (${Height} < 10.0)", "color('#FF00FF')"],
  4.  
    ["(${Height} >= 10.0) && (${Height} < 30.0)", "color('#FF0000')"],
  5.  
    ["(${Height} >= 30.0) && (${Height} < 50.0)", "color('#FFFF00')"],
  6.  
    ["(${Height} >= 50.0) && (${Height} < 70.0)", "color('#00FF00')"],
  7.  
    ["(${Height} >= 70.0) && (${Height} < 100.0)", "color('#00FFFF')"],
  8.  
    ["(${Height} >= 100.0)", "color('#0000FF')"]
  9.  
    ]
  10.  
    }

 由于条件是按顺序计算的,因此可以更简洁地编写以下内容:

  1.  
    "color" : {
  2.  
    "conditions" : [
  3.  
    ["(${Height} >= 100.0)", "color('#0000FF')"],
  4.  
    ["(${Height} >= 70.0)", "color('#00FFFF')"],
  5.  
    ["(${Height} >= 50.0)", "color('#00FF00')"],
  6.  
    ["(${Height} >= 30.0)", "color('#FFFF00')"],
  7.  
    ["(${Height} >= 10.0)", "color('#FF0000')"],
  8.  
    ["(${Height} >= 1.0)", "color('#FF00FF')"]
  9.  
    ]
  10.  
    }

1.3  Defining variables(定义变量

 常用的表达式可以存储在具有变量名称作为键的对象中。如果变量引用了已定义表达式的名称,则会将其替换为引用的计算表达式的结果:defines

  1.  
    {
  2.  
    "defines" : {
  3.  
    "NewHeight" : "clamp((${Height} - 0.5) / 2.0, 1.0, 255.0)",
  4.  
    "HeightColor" : "rgb(${Height}, ${Height}, ${Height})"
  5.  
    },
  6.  
    "color" : {
  7.  
    "conditions" : [
  8.  
    ["(${NewHeight} >= 100.0)", "color('#0000FF') * ${HeightColor}"],
  9.  
    ["(${NewHeight} >= 50.0)", "color('#00FF00') * ${HeightColor}"],
  10.  
    ["(${NewHeight} >= 1.0)", "color('#FF0000') * ${HeightColor}"]
  11.  
    ]
  12.  
    },
  13.  
    "show" : "${NewHeight} < 200.0"
  14.  
    }

 定义表达式不能引用其他定义;但是,它可能引用具有相同名称的功能属性。在下面的样式中,高度为 150 的特征将获得红色:

  1.  
    {
  2.  
    "defines" : {
  3.  
    "Height" : "${Height}/2.0}",
  4.  
    },
  5.  
    "color" : {
  6.  
    "conditions" : [
  7.  
    ["(${Height} >= 100.0)", "color('#0000FF')"],
  8.  
    ["(${Height} >= 1.0)", "color('#FF0000')"]
  9.  
    ]
  10.  
    }
  11.  
    }

1.4 Meta property(元属性

可以使用该属性定义要素的非可视属性。例如,下面将 meta 属性设置为包含功能名称的字符串:metadescription

  1.  
    {
  2.  
    "meta" : {
  3.  
    "description" : "'Hello, ${featureName}.'"
  4.  
    }
  5.  
    }

 元属性表达式的计算结果可以是任何类型。例如:

  1.  
    {
  2.  
    "meta" : {
  3.  
    "featureColor" : "rgb(${red}, ${green}, ${blue})",
  4.  
    "featureVolume" : "${height} * ${width} * ${depth}"
  5.  
    }
  6.  
    }

2. Expressions-表达式

表达式的语言是 JavaScript (EMCAScript 5) 的一小部分,加上本机矢量和正则表达式类型,以及以只读变量形式访问 tileset 功能属性。

2.1 Semantics-语义化

点表示法用于按名称访问属性,例如 。building.name

括号表示法 () 也用于访问属性,例如 building['name']或数组,例如temperatures[1]

调用函数时带有括号 () 和逗号分隔的参数,例如 (isNaN(0.0),color('cyan',0.5))

2.2 Operators-操作符

支持以下运算符,其语义和优先级与JavaScript相同。

一元的: , -, !
 不支持。~
二元的:||, &&, ===, ! ==, <, >, <=, >=, , -, *, /, %, =~, ! ~
  不支持。|, ^, &, <<, >>, 和>>>.
三元组: ? :
( )也支持对表达式进行分组,以达到清晰和优先的目的。

逻辑运算符 || 和 && 实现了简化流程;true || expression 不评估右边的表达式,而false && expression不评估右边的表达。

同样,true ? leftExpression : rightExpression只执行左边的表达式,而false ? leftExpression : rightExpression只执行右边的表达式。

2.3 Types-类型

2.3.1 支持类型:

  • Boolean
  • Null
  • Undefined
  • Number
  • String
  • Array
  • vec2
  • vec3
  • vec4
  • RegExp

 除了vec2、vec3、vec4和RegExp,所有类型的语法和运行时行为都与JavaScript相同。颜色源于CSS3的颜色,并以vec4的形式实现。正则(RegExp)源自JavaScript,在正则部分有描述。

不同类型的示例表达式包括:

  • true,false
  • null
  • undefined
  • 1.0, NaN,Infinity
  • 'Cesium',"Cesium"
  • [0, 1, 2]
  • vec2(1.0, 2.0)
  • vec3(1.0, 2.0, 3.0)
  • vec4(1.0, 2.0, 3.0, 4.0)
  • color('#00FFFF')
  • regExp('^Chest'))

下面主要讲解Vector向量类型(vec2 ,vec3 ,vec4),其他数据类型与JS一致,正则表达也与JS一致:

2.3.1 Vector向量:


styling语言包括2、3和4组成的浮点向量类型:vec2、vec3和vec4。向量构造函数与GLSL共享相同的规则。

1)vec2

vec2(xy : Number) - 用数字初始化每个分量
vec2(x : Number, y : Number) - 使用两个数字进行初始化
vec2(xy : vec2) - 用另一个vec2进行初始化
vec2(xyz : vec3) - 丢弃vec3的第三个分量。
vec2(xyzw : vec4) - 丢弃vec4的第三和第四部分。

2)vec3

vec3(xyz : Number) - 用数字初始化每个分量。
vec3(x : Number, y : Number, z : Number) - 使用三个数字进行初始化
vec3(xyz : vec3) - 用另一个vec3进行初始化
vec3(xyzw : vec4) - 丢弃vec4的第四个分量。
vec3(xy : vec2, z : Number) - 用vec2和数字进行初始化。
vec3(x : Number, yz : vec2) - 使用vec2和数字进行初始化。

3)vec4

vec4(xyzw : Number) - 用数字初始化每个组件
vec4(x : Number, y : Number, z : Number, w : Number) - 使用四个数字进行初始化
vec4(xyzw : vec4) - 用另一个vec4进行初始化
vec4(xy : vec2, z : Number, w : Number) - 用一个vec2和两个数字进行初始化。
vec4(x : Number, yz : vec2, w : Number) - 用一个vec2和两个数字进行初始化。
vec4(x : Number, y : Number, zw : vec2) - 用一个vec2和两个数字进行初始化。
vec4(xyz : vec3, w : Number) - 初始化一个vec3和数字。
vec4(x : Number, yzw : vec3) - 初始化一个vec3和数字。

4)向量的使用
vec2组件可以用

.x, .y
.r, .g
[0], [1]

vec3组件可以用 

.x, .y, .z
.r, .g, .b
[0], [1], [2]

vec4组件可以用 

.x, .y, .z, .w
.r, .g, .b, .a
[0], [1], [2], [3]

与GLSL不同,styling语言不支持swizzling。例如,不支持vec3(1.0).xy。

向量支持以下单项运算符。-, .

向量支持以下二进制运算符,通过执行分母操作:===,!==, ,-,*,/,和%。例如,vec4(1.0) === vec4(1.0)是真的,因为x、y、z和w分量相等。对于vec2、vec3和vec4,操作符基本上是重载的。

vec2、vec3和vec4有一个toString函数,用于显式(和隐式)转换为格式为'(x,y)'、'(x,y,z)'和'(x,y,z,w)的字符串。

toString() : 字符串
vec2、vec3和vec4没有暴露任何其他函数或原型对象。

3. Examples-1设置颜色:

根据建筑物的不同属性设置颜色,办公楼为红色、商业楼为橙色、居民楼为黄色、0.8透明度,其他为天空蓝、0.8透明度。

  1.  
    // Cesium全球3.5亿做建筑物,数据来源openStreetMap地图
  2.  
    let tiles3d = new Cesium.createOsmBuildings();
  3.  
    tiles3d.style = new Cesium.Cesium3DTileStyle({
  4.  
    color: {
  5.  
    conditions: [
  6.  
    ["${feature['building']} === 'office'", "color('red')"],
  7.  
    ["${feature['building']} === 'commercial'", "color('orange')"],
  8.  
    ["${feature['building']} === 'residential'", "color('yellow',0.8)"],
  9.  
    ["true", "color('skyblue',0.8)"],
  10.  
    ],
  11.  
    },
  12.  
    });
  13.  
    console.log(tiles3d);
  14.  
    var buildings = viewer.scene.primitives.add(tiles3d);

实现效果:

学新通

4. Examples-2根据不同条件设置颜色:

根据不同条件切换颜色:

4.1 安装dat.GUI插件

首先可以根据需求安装一个小的切换插件dat.gui,一个轻量级的图形用户界面,用于在JavaScript中更改变量。dat.GUI 是一个轻量级的图形用户界面库(GUI 组件),使用这个库可以很容易地创建出能够改变代码变量的界面组件。

安装

  1.  
    npm install --save dat.gui
  2.  
     
  3.  
    yarn add dat.gui
  4.  
     
  5.  
    <script src="https://cdn.bootcdn.net/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script>

使用

  1.  
    const dat = require('dat.gui');
  2.  
     
  3.  
    // ES6:
  4.  
    import * as dat from 'dat.gui';
  5.  
     
  6.  
    const gui = new dat.GUI();

api文档

https://github.com/dataarts/dat.gui/blob/master/API.md

4.2 导入dat.gui插件,并实例化:

  1.  
    import * as dat from "dat.gui";//一个轻量级的图形用户界面,用于在JavaScript中更改变量。
  2.  
    const gui = new dat.GUI();

4.3 设置各种条件,并根据不同条件设置3dtile的不同样式: 

条件一:根据建筑物的不同高度设置不同的颜色;

条件二:根据距离中心点距离的远近,由近至远色调逐渐变化;

  1.  
    //点击切换条件并更改颜色
  2.  
    let params = {
  3.  
    //根据高度不同设置不同颜色
  4.  
    heightColor: function () {
  5.  
    tiles3d.style = new Cesium.Cesium3DTileStyle({
  6.  
    color: {
  7.  
    conditions: [
  8.  
    ["${feature['cesium#estimatedHeight']} > 300", "color('#0000CD')"],
  9.  
    ["${feature['cesium#estimatedHeight']} > 200", "color('#4169E1')"],
  10.  
    ["${feature['cesium#estimatedHeight']} > 100", "color('#1E90FF')"],
  11.  
    ["${feature['cesium#estimatedHeight']} > 50", "color('#00BFFF')"],
  12.  
    ["${feature['cesium#estimatedHeight']} > 20", "color('#87CEEB')"],
  13.  
    ["true", "color('#ADD8E6',0.8)"],
  14.  
    ],
  15.  
    },
  16.  
    });
  17.  
    },
  18.  
    //根据距离中心点位置距离设置不同颜色
  19.  
    distanceColor: function () {
  20.  
    tiles3d.style = new Cesium.Cesium3DTileStyle({
  21.  
    defines: {
  22.  
    distance:
  23.  
    //设置以广州塔为中心判断距离远近
  24.  
    "distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']}),vec2(113.3191, 23.109))",
  25.  
    },
  26.  
    color: {
  27.  
    conditions: [
  28.  
    ["${distance} < 0.005", "color('#0000CD')"],
  29.  
    ["${distance} < 0.01", "color('#4169E1')"],
  30.  
    ["${distance} < 0.015", "color('#1E90FF')"],
  31.  
    ["${distance} < 0.02", "color('#00BFFF')"],
  32.  
    ["${distance} < 0.025", "color('#87CEEB')"],
  33.  
    ["true", "color('#ADD8E6',0.8)"],
  34.  
    ],
  35.  
    },
  36.  
    });
  37.  
    },
  38.  
    };

4.4 将不同条件的执行挂在到dat.gui上:

  1.  
    gui.add(params, "heightColor");
  2.  
    gui.add(params, "distanceColor");

实现效果:

1.根据建筑物的不同高度设置不同的颜色;

学新通

2. 根据距离中心点距离的远近,由近至远色调逐渐变化;(中心点为广州塔)

学新通

5. Examples-3多条件样式高级设置:

设置显示距离中心点位置小于0.04且建筑物特征为公寓的建筑显示,且颜色从近至远(0.01,0.02,0.04为节点)逐渐变浅。

实现代码:

  1.  
    <template>
  2.  
    <div id="cesiumContainer" ref="cesiumContainer"></div>
  3.  
    </template>
  4.  
     
  5.  
    <script setup>
  6.  
    // yarn add cesium
  7.  
    // 将cesium目录下的Build/Cesium4个目录拷贝到public,然后将widgets目录拷贝一份到src下
  8.  
    import * as Cesium from "cesium";
  9.  
    import "./Widgets/widgets.css";
  10.  
    import { onMounted } from "vue";
  11.  
     
  12.  
    // 设置cesium token
  13.  
    Cesium.Ion.defaultAccessToken =
  14.  
    "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";
  15.  
     
  16.  
    // 设置cesium静态资源路径
  17.  
    window.CESIUM_BASE_URL = "/";
  18.  
    onMounted(() => {
  19.  
    var viewer = new Cesium.Viewer("cesiumContainer", {
  20.  
    // 是否显示信息窗口
  21.  
    // infoBox: false,
  22.  
     
  23.  
    shouldAnimate: true,
  24.  
    });
  25.  
     
  26.  
    // 设置沙箱允许使用js
  27.  
    var iframe = document.getElementsByClassName("cesium-infoBox-iframe")[0];
  28.  
    iframe.setAttribute(
  29.  
    "sandbox",
  30.  
    "allow-same-origin allow-scripts allow-popups allow-forms"
  31.  
    );
  32.  
    iframe.setAttribute("src", "");
  33.  
     
  34.  
    // 隐藏logo
  35.  
    viewer.cesiumWidget.creditContainer.style.display = "none";
  36.  
    // 添加3D建筑
  37.  
    let tiles3d = new Cesium.createOsmBuildings();
  38.  
    const osmBuildings = viewer.scene.primitives.add(tiles3d);
  39.  
    // 广州塔
  40.  
    var postion = Cesium.Cartesian3.fromDegrees(
  41.  
    // 经度
  42.  
    113.3191,
  43.  
    // 纬度
  44.  
    23.109,
  45.  
    // 高度
  46.  
    1000
  47.  
    );
  48.  
    viewer.camera.flyTo({
  49.  
    destination: postion,
  50.  
    duration: 2,
  51.  
    });
  52.  
     
  53.  
    tiles3d.style = new Cesium.Cesium3DTileStyle({
  54.  
    defines: {
  55.  
    distance:
  56.  
    "distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']}),vec2(113.3191,23.109))",//距离计算
  57.  
    },
  58.  
    color: {
  59.  
    conditions: [
  60.  
    ["${distance} < 0.01", "color('rgba(92,167,186, 1)')"],
  61.  
    ["${distance} < 0.02", "color('rgba(175,215,237, 1)')"],
  62.  
    ["${distance} < 0.04", "color('rgba(199,237,233, 1)')"],
  63.  
    ["true", "color('white')"],
  64.  
    ],
  65.  
    },//颜色条件判断
  66.  
    show: "${distance} < 0.04 && ${feature['building']} === 'apartments'",//并列条件设置
  67.  
    });
  68.  
    });
  69.  
    </script>
  70.  
     
  71.  
    <style>
  72.  
    * {
  73.  
    margin: 0;
  74.  
    padding: 0;
  75.  
    }
  76.  
    #cesiumContainer {
  77.  
    width: 100vw;
  78.  
    height: 100vh;
  79.  
    }
  80.  
    </style>

实现效果:

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfibiea
系列文章
更多 icon
同类精品
更多 icon
继续加载