VUE3-CesiumCesium3DTileStyle-3dtiles样式更改
目录
4.3 设置各种条件,并根据不同条件设置3dtile的不同样式:
之前的文章讲过通过new Cesium.createOsmBuildings()在Cesium加载Open street map建筑模型,但加载后为白膜,当我们需要对其样式进行更改时,就需要使用Cesium3DTileStyle进行更改。3D 切片样式提供磁贴集要素的简洁声明性样式。样式定义表达式以评估要素的显示,例如(RGB 和半透明性)和属性,通常基于存储在切片的 Batch 表中的要素属性。color
show
样式可以应用于不包含要素的切片,在这种情况下,切片将被视为没有属性的隐式单个要素。
虽然可以为切片集创建样式并为其引用属性,但样式独立于切片集,因此任何样式都可以应用于任何切片集。
样式是用JSON定义的,表达式写在JavaScript的一小部分中,为样式进行了扩充。此外,样式语言还提供了一组内置函数来支持常见的数学运算。
下面的示例根据建筑物高度分配颜色。
-
{
-
"show" : "${Area} > 0",
-
"color" : {
-
"conditions" : [
-
["${Height} < 60", "color('#13293D')"],
-
["${Height} < 120", "color('#1B98E0')"],
-
["true", "color('#E8F1F2', 0.5)"]
-
]
-
}
-
}
1.Cesium3DTileStyle详解
Cesium3DTileStyle应用于Cesium3DTileset的样式,通过new Cesium.Cesium3DTileStyle ( style )创建并使用。官方文档:3D磁贴/规格/样式在主 ·铯GS/3D瓷砖 ·GitHub
1.1 styling features(样式功能)
可用于设置样式特征的视觉属性是属性,其分配的表达式将计算为确定特征是否可见的布尔值,以及属性,其分配的表达式将计算为对象(RGB 和半透明性),后者确定特征的显示颜色。show
color
Color
以下样式为每个要素指定默认的显示和颜色属性:
-
{
-
"show" : "true",
-
"color" : "color('#ffffff')"
-
}
例如,以下表达式将仅显示 19341 邮政编码中的要素,而不是显示所有要素,可以是依赖于要素属性的表达式:show
-
{
-
"show" : "${ZipCode} === '19341'"
-
}
show
也可用于更复杂的查询;例如,此处的复合条件和正则表达式仅用于显示其县以 1970 开头且其建成年份大于或等于 1970 的要素:'Chest'
-
{
-
"show" : "(regExp('^Chest').test(${County})) && (${YearBuilt} >= 1970)"
-
}
颜色也可以由依赖于要素属性的表达式来定义。例如,以下表达式将温度高于 90 的特征颜色着色为红色,将其他表达式颜色着色为白色:
-
{
-
"color" : "(${Temperature} > 90) ? color('red') : color('white')"
-
}
颜色的 alpha 分量定义了要素的不透明度。例如,以下命令根据要素的属性设置要素的 RGB 颜色分量,并使体积大于 100 的要素透明:
-
{
-
"color" : "rgba(${red}, ${green}, ${blue}, (${volume} > 100 ? 0.5 : 1.0))"
-
}
1.2 conditions(条件)
除了包含表达式的字符串之外,还可以是定义一系列条件的数组(类似于语句)。例如,条件可用于制作具有任何类型的包含/排除间隔的色彩映射表和色带。color
show
if...else
例如,下面的表达式将 ID 属性映射到颜色。条件按顺序计算,因此如果不是 或 ,则条件返回白色。如果未满足任何条件,则要素的颜色将为:${id}
'1'
'2'
"true"
undefined
-
{
-
"color" : {
-
"conditions" : [
-
["${id} === '1'", "color('#FF0000')"],
-
["${id} === '2'", "color('#00FF00')"],
-
["true", "color('#FFFFFF')"]
-
]
-
}
-
}
下一个示例演示如何使用条件,使用具有非独占下限和独占上限的间隔创建色带:
-
"color" : {
-
"conditions" : [
-
["(${Height} >= 1.0) && (${Height} < 10.0)", "color('#FF00FF')"],
-
["(${Height} >= 10.0) && (${Height} < 30.0)", "color('#FF0000')"],
-
["(${Height} >= 30.0) && (${Height} < 50.0)", "color('#FFFF00')"],
-
["(${Height} >= 50.0) && (${Height} < 70.0)", "color('#00FF00')"],
-
["(${Height} >= 70.0) && (${Height} < 100.0)", "color('#00FFFF')"],
-
["(${Height} >= 100.0)", "color('#0000FF')"]
-
]
-
}
由于条件是按顺序计算的,因此可以更简洁地编写以下内容:
-
"color" : {
-
"conditions" : [
-
["(${Height} >= 100.0)", "color('#0000FF')"],
-
["(${Height} >= 70.0)", "color('#00FFFF')"],
-
["(${Height} >= 50.0)", "color('#00FF00')"],
-
["(${Height} >= 30.0)", "color('#FFFF00')"],
-
["(${Height} >= 10.0)", "color('#FF0000')"],
-
["(${Height} >= 1.0)", "color('#FF00FF')"]
-
]
-
}
1.3 Defining variables(定义变量)
常用的表达式可以存储在具有变量名称作为键的对象中。如果变量引用了已定义表达式的名称,则会将其替换为引用的计算表达式的结果:defines
-
{
-
"defines" : {
-
"NewHeight" : "clamp((${Height} - 0.5) / 2.0, 1.0, 255.0)",
-
"HeightColor" : "rgb(${Height}, ${Height}, ${Height})"
-
},
-
"color" : {
-
"conditions" : [
-
["(${NewHeight} >= 100.0)", "color('#0000FF') * ${HeightColor}"],
-
["(${NewHeight} >= 50.0)", "color('#00FF00') * ${HeightColor}"],
-
["(${NewHeight} >= 1.0)", "color('#FF0000') * ${HeightColor}"]
-
]
-
},
-
"show" : "${NewHeight} < 200.0"
-
}
定义表达式不能引用其他定义;但是,它可能引用具有相同名称的功能属性。在下面的样式中,高度为 150 的特征将获得红色:
-
{
-
"defines" : {
-
"Height" : "${Height}/2.0}",
-
},
-
"color" : {
-
"conditions" : [
-
["(${Height} >= 100.0)", "color('#0000FF')"],
-
["(${Height} >= 1.0)", "color('#FF0000')"]
-
]
-
}
-
}
1.4 Meta property(元属性)
可以使用该属性定义要素的非可视属性。例如,下面将 meta 属性设置为包含功能名称的字符串:meta
description
-
{
-
"meta" : {
-
"description" : "'Hello, ${featureName}.'"
-
}
-
}
元属性表达式的计算结果可以是任何类型。例如:
-
{
-
"meta" : {
-
"featureColor" : "rgb(${red}, ${green}, ${blue})",
-
"featureVolume" : "${height} * ${width} * ${depth}"
-
}
-
}
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透明度。
-
// Cesium全球3.5亿做建筑物,数据来源openStreetMap地图
-
let tiles3d = new Cesium.createOsmBuildings();
-
tiles3d.style = new Cesium.Cesium3DTileStyle({
-
color: {
-
conditions: [
-
["${feature['building']} === 'office'", "color('red')"],
-
["${feature['building']} === 'commercial'", "color('orange')"],
-
["${feature['building']} === 'residential'", "color('yellow',0.8)"],
-
["true", "color('skyblue',0.8)"],
-
],
-
},
-
});
-
console.log(tiles3d);
-
var buildings = viewer.scene.primitives.add(tiles3d);
实现效果:
4. Examples-2根据不同条件设置颜色:
根据不同条件切换颜色:
4.1 安装dat.GUI插件
首先可以根据需求安装一个小的切换插件dat.gui,一个轻量级的图形用户界面,用于在JavaScript中更改变量。dat.GUI 是一个轻量级的图形用户界面库(GUI 组件),使用这个库可以很容易地创建出能够改变代码变量的界面组件。
- GitHub 主页:https://github.com/dataarts/dat.gui
安装
-
npm install --save dat.gui
-
-
yarn add dat.gui
-
-
<script src="https://cdn.bootcdn.net/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script>
使用
-
const dat = require('dat.gui');
-
-
// ES6:
-
import * as dat from 'dat.gui';
-
-
const gui = new dat.GUI();
api文档
https://github.com/dataarts/dat.gui/blob/master/API.md
4.2 导入dat.gui插件,并实例化:
-
import * as dat from "dat.gui";//一个轻量级的图形用户界面,用于在JavaScript中更改变量。
-
const gui = new dat.GUI();
4.3 设置各种条件,并根据不同条件设置3dtile的不同样式:
条件一:根据建筑物的不同高度设置不同的颜色;
条件二:根据距离中心点距离的远近,由近至远色调逐渐变化;
-
//点击切换条件并更改颜色
-
let params = {
-
//根据高度不同设置不同颜色
-
heightColor: function () {
-
tiles3d.style = new Cesium.Cesium3DTileStyle({
-
color: {
-
conditions: [
-
["${feature['cesium#estimatedHeight']} > 300", "color('#0000CD')"],
-
["${feature['cesium#estimatedHeight']} > 200", "color('#4169E1')"],
-
["${feature['cesium#estimatedHeight']} > 100", "color('#1E90FF')"],
-
["${feature['cesium#estimatedHeight']} > 50", "color('#00BFFF')"],
-
["${feature['cesium#estimatedHeight']} > 20", "color('#87CEEB')"],
-
["true", "color('#ADD8E6',0.8)"],
-
],
-
},
-
});
-
},
-
//根据距离中心点位置距离设置不同颜色
-
distanceColor: function () {
-
tiles3d.style = new Cesium.Cesium3DTileStyle({
-
defines: {
-
distance:
-
//设置以广州塔为中心判断距离远近
-
"distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']}),vec2(113.3191, 23.109))",
-
},
-
color: {
-
conditions: [
-
["${distance} < 0.005", "color('#0000CD')"],
-
["${distance} < 0.01", "color('#4169E1')"],
-
["${distance} < 0.015", "color('#1E90FF')"],
-
["${distance} < 0.02", "color('#00BFFF')"],
-
["${distance} < 0.025", "color('#87CEEB')"],
-
["true", "color('#ADD8E6',0.8)"],
-
],
-
},
-
});
-
},
-
};
4.4 将不同条件的执行挂在到dat.gui上:
-
gui.add(params, "heightColor");
-
gui.add(params, "distanceColor");
实现效果:
1.根据建筑物的不同高度设置不同的颜色;
2. 根据距离中心点距离的远近,由近至远色调逐渐变化;(中心点为广州塔)
5. Examples-3多条件样式高级设置:
设置显示距离中心点位置小于0.04且建筑物特征为公寓的建筑显示,且颜色从近至远(0.01,0.02,0.04为节点)逐渐变浅。
实现代码:
-
<template>
-
<div id="cesiumContainer" ref="cesiumContainer"></div>
-
</template>
-
-
<script setup>
-
// yarn add cesium
-
// 将cesium目录下的Build/Cesium4个目录拷贝到public,然后将widgets目录拷贝一份到src下
-
import * as Cesium from "cesium";
-
import "./Widgets/widgets.css";
-
import { onMounted } from "vue";
-
-
// 设置cesium token
-
Cesium.Ion.defaultAccessToken =
-
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhMzNkNTE5Zi1mMjY4LTRiN2QtOTRlZC1lOTUyM2NhNDYzNWYiLCJpZCI6NTU0OTYsImlhdCI6MTYyNTAyNjMyOX0.a2PEM4hQGpeuMfeB9-rPp6_Gkm6O-02Dm4apNbv_Dlk";
-
-
// 设置cesium静态资源路径
-
window.CESIUM_BASE_URL = "/";
-
onMounted(() => {
-
var viewer = new Cesium.Viewer("cesiumContainer", {
-
// 是否显示信息窗口
-
// infoBox: false,
-
-
shouldAnimate: true,
-
});
-
-
// 设置沙箱允许使用js
-
var iframe = document.getElementsByClassName("cesium-infoBox-iframe")[0];
-
iframe.setAttribute(
-
"sandbox",
-
"allow-same-origin allow-scripts allow-popups allow-forms"
-
);
-
iframe.setAttribute("src", "");
-
-
// 隐藏logo
-
viewer.cesiumWidget.creditContainer.style.display = "none";
-
// 添加3D建筑
-
let tiles3d = new Cesium.createOsmBuildings();
-
const osmBuildings = viewer.scene.primitives.add(tiles3d);
-
// 广州塔
-
var postion = Cesium.Cartesian3.fromDegrees(
-
// 经度
-
113.3191,
-
// 纬度
-
23.109,
-
// 高度
-
1000
-
);
-
viewer.camera.flyTo({
-
destination: postion,
-
duration: 2,
-
});
-
-
tiles3d.style = new Cesium.Cesium3DTileStyle({
-
defines: {
-
distance:
-
"distance(vec2(${feature['cesium#longitude']},${feature['cesium#latitude']}),vec2(113.3191,23.109))",//距离计算
-
},
-
color: {
-
conditions: [
-
["${distance} < 0.01", "color('rgba(92,167,186, 1)')"],
-
["${distance} < 0.02", "color('rgba(175,215,237, 1)')"],
-
["${distance} < 0.04", "color('rgba(199,237,233, 1)')"],
-
["true", "color('white')"],
-
],
-
},//颜色条件判断
-
show: "${distance} < 0.04 && ${feature['building']} === 'apartments'",//并列条件设置
-
});
-
});
-
</script>
-
-
<style>
-
* {
-
margin: 0;
-
padding: 0;
-
}
-
#cesiumContainer {
-
width: 100vw;
-
height: 100vh;
-
}
-
</style>
实现效果:
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfibiea
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01