cesium按照参数绘制不同形状的船舶

news2025/1/11 2:45:32

俺们公司之前有个自创的所谓前端GIS框架,是用Cesium搞的。我对该框架不熟悉,用它在地图上作画,画船舶符号,看以前的代码,感觉十分艰深晦涩,什么材质、纹理,令人头大如斗。我4年前用过一阵Cesium,后来荒废了,到现在已经完全失忆。

一、不知道怎么判断船舶类型

最难点在于,原先的代码,不知道是怎么判断船舶类型,因而画相应的形状的。比如说我们有一个变量type,0代表渔船,1代表货船,2代表海盗船。按照一般思维,就是我判断这个type,是1就怎么怎么画,2就如何如何涂。但是,在我们那个框架代码里,这个type传着传着,就不知道变成啥样了,像这样

在这里插入图片描述
在这里插入图片描述
这个 i_type 貌似就是我们想用于判断船舶类型的type,但由于Cesium作画独树一帜,我们当初设好的type,命名是个整数,到了这里就变成这个鬼样子,是个奇怪的小数,似乎是256种颜色的等分的其中之一。如上图所示,根本就没办法判断类型,也不知道这个小数是怎么来的。

这里面的对象关联很复杂,我试着描述一下:

const targetPrimitiveCollection: Cesium.PrimitiveCollection = props.context.scene.primitives.add(new Cesium.PrimitiveCollection());

let shipGeometryInstances = [];
shipGeometryInstances.push(new Cesium.GeometryInstance({
	。。。type:。。。{value: [type]}
}));
targetPrimitiveCollection.add(ShipPrimitive(。。。, shipGeometryInstances));

而上面说的判断type类型的方法

czm_material czm_getMaterial(czm_materialInput materialInput, vec4 i_color, vec4 i_outColor, float i_type){}

是ShipPrimitive()内的某个着色器定义里的方法。晕吧?

二、努力判断船舶类型

可以说,不能判断船舶类型,绘制不同形状就无从谈起。必须能判断。由于我基本靠AI指导才调试成功,而还没有完全理解,只能贴代码,而说不出一个子丑寅卯。
在这里插入图片描述

import image1 from '@/assets/target_icon/渔船.png'
import image2 from '@/assets/target_icon/货船.png';
import image3 from '@/assets/target_icon/海盗船.png';

const image01 = new Image();
image01.src = image1;
const image02 = new Image();
image02.src = image2;
const image03 = new Image();
image03.src = image3;

let uniforms = {
    image1: image1,//三角形
    image2: image2, //圆形
    image3: image3 //三角形 + 圆形
};

const targetPrimitiveCollection: Cesium.PrimitiveCollection = props.context.scene.primitives.add(new Cesium.PrimitiveCollection());

let type = 。。。//得到0,1,2

let shipGeometryInstances = [];
shipGeometryInstances.push(new Cesium.GeometryInstance({
    id: 。。。,
    geometry: 。。。,
    modelMatrix: 。。。,
    attributes: {
        type: new Cesium.GeometryInstanceAttribute({
            componentDatatype: Cesium.ComponentDatatype.FLOAT,
            componentsPerAttribute: 1,
            value: [type]
        }),
        outWidth: 。。。,
        color: 。。。,
        outColor: 。。。
    },
}));

targetPrimitiveCollection.add(ShipPrimitive(uniforms, shipGeometryInstances));

const ShipPrimitive = (uniforms: any = {}, shipGeometryInstances: Cesium.GeometryInstance[]) => {
    /**
     * fragmentShaderSource属性在Cesium的MaterialAppearance或WebGL编程中起到了核心作用,
     * 它定义了片段着色器(Fragment Shader)的源代码。片段着色器是图形管线中的一个关键阶段,
     * 负责计算场景中每个像素的最终颜色。
     *
     * 顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)是图形渲染管线中的两个核心着色器阶段
     *
     * 先顶点后片段
     */

    //片段着色器
    const fragmentShaderSource = `
    varying vec4 v_color;
    varying vec4 v_outColor;
    varying vec3 v_positionEC;
    varying vec3 v_normalEC;
    varying vec2 v_outWidth;
    varying vec2 v_st;
    varying float v_type;

    uniform sampler2D image1; // 第一个纹理
    uniform sampler2D image2; // 第二个纹理
    uniform sampler2D image3; // 

    czm_material getMaterial(czm_materialInput materialInput){
        czm_material material = czm_getDefaultMaterial(materialInput);

        materialInput.st.t = 1.0 - materialInput.st.t; //将图片坐标轴调整成和纹理坐标轴一致
        vec4 textureValue;
        vec4 i_color = v_color;
        if (v_type == 2.0) {//海盗船
            textureValue = texture2D(image3, materialInput.st);
            i_color.rgb = textureValue.rgb;//颜色来自图片
        } else if (v_type == 1.0) {//货船
            textureValue = texture2D(image2, materialInput.st);
            i_color.rgb = textureValue.rgb;//颜色来自图片
        } else{//渔船
            textureValue = texture2D(image1, materialInput.st);
            i_color.rgb = textureValue.rgb;
        }
        i_color.a = i_color.a * textureValue.a;//颜色相与
        material.diffuse = i_color.rgb;
        material.alpha = i_color.a;        

        return material;
    }
    void main() {
        vec3 positionToEyeEC = -v_positionEC;
        vec3 normalEC = normalize(v_normalEC);

        #ifdef FACE_FORWARD
        normalEC = faceforward(normalEC, vec3(0.0, 0.0, 1.0), -normalEC);
        #endif

        czm_materialInput materialInput;
        materialInput.normalEC = normalEC;
        materialInput.positionToEyeEC = positionToEyeEC;
        materialInput.st = v_st;

        czm_material material = getMaterial(materialInput);

        #ifdef FLAT
        gl_FragColor = vec4(material.diffuse + material.emission, material.alpha);
        #else
        gl_FragColor = czm_phong(normalize(positionToEyeEC), material, czm_lightDirectionEC);
        #endif
    }`;

    //顶点着色器
    const vertexShaderSource = `
        attribute vec3 position3DHigh;
        attribute vec3 position3DLow;
        attribute vec3 normal;
        attribute vec2 st;
        attribute float batchId;
        varying vec4 v_color;
        varying vec4 v_outColor;
        varying vec3 v_positionEC;
        varying vec3 v_normalEC;
        varying vec2 v_outWidth;
        varying vec2 v_st;
        varying float v_type;
        void main() {
            vec4 p = czm_computePosition();
            v_positionEC = (czm_modelViewRelativeToEye * p).xyz;
            v_normalEC = czm_normal * normal;
            v_st = st;
            v_outWidth = czm_batchTable_outWidth(batchId);
            v_color = czm_batchTable_color(batchId);
            v_outColor = czm_batchTable_outColor(batchId);
            v_type = czm_batchTable_type(batchId);
            vec4 positionPC = czm_modelViewProjectionRelativeToEye * p;
            gl_Position = positionPC;
        }
    `;

    let shipPrimitive = new Cesium.Primitive({
        asynchronous: false,
        geometryInstances: shipGeometryInstances,
        appearance: new Cesium.MaterialAppearance({
            flat: true,
            material: new Cesium.Material({
                fabric: {
                    type: "image2D",
                    uniforms: uniforms,
                    //source: imageSource,// <------- 
                    //-------------修改关键点,上面说的方法czm_getMaterial()就定义在imageSource里面
                },
            }),
            vertexShaderSource: vertexShaderSource,
            fragmentShaderSource: fragmentShaderSource,
        })
    });

    let fps = 5;
    let oldUpdate = shipPrimitive.update;
    shipPrimitive.update = function (frameState: { context: any; }) {
        oldUpdate.call(this, frameState);
        if (this._colorCommands[0] && fps > 0) {
            fps--;
            let uniformMap = this._colorCommands[0].uniformMap;
            uniformMap.image1 = function () {
                return new Cesium.Texture({//渔船,绿底圆形
                    context: frameState.context,
                    source: image01,
                    sampler: new Cesium.Sampler()
                });
            }
            uniformMap.image2 = function () {//货船,绿底三角形
                return new Cesium.Texture({
                    context: frameState.context,
                    source: image02,
                    sampler: new Cesium.Sampler()
                });
            }
            uniformMap.image3 = function () {//海盗船,绿底三角形 + 白底圆形
                return new Cesium.Texture({
                    context: frameState.context,
                    source: image03,
                    sampler: new Cesium.Sampler()
                });
            }
        }
    }

    return shipPrimitive;
}

三、成果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1836825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Multi-Head RAG:多头注意力的激活层作为嵌入进行文档检索

现有的RAG解决方案可能因为最相关的文档的嵌入可能在嵌入空间中相距很远&#xff0c;这样会导致检索过程变得复杂并且无效。为了解决这个问题&#xff0c;论文引入了多头RAG (MRAG)&#xff0c;这是一种利用Transformer的多头注意层的激活而不是解码器层作为获取多方面文档的新…

mysql分析常用锁

这里写自定义目录标题 1.未提交事物&#xff0c;阻塞DDL&#xff0c;继而阻塞所有同表的后续操作,查看未提交事务的进程2.存着正在进行的线程数据。3.根据processlist表中的id杀掉未释放的线程4.查看正在使用的表5.mysql为什么state会有waiting for handler commit6.什么情况导…

处理耗时任务

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 处理耗时任务 {public partial class Form1 : Form{public Form1(){InitializeComponent();}bool IsRun false;private string path Directory.GetCurrentDirectory() "\\古诗词.txt";private…

虚拟机怎么额外搭建两个Redis节点,配置多个 Redis 实例

前提条件 在开始之前&#xff0c;请确保你已经具备以下条件&#xff1a; 一台已安装 Redis 的虚拟机。虚拟机上已安装基本的 Linux 工具&#xff08;例如 FinalShell&#xff09;。 步骤二&#xff1a;配置额外的 Redis 实例 接下来&#xff0c;我们将配置两个新的 Redis 实…

鸿蒙原生应用元服务开发-位置服务申请权限

申请位置权限开发指导 场景概述 应用在使用位置服务系统能力前&#xff0c;需要检查是否已经获取用户授权访问设备位置信息。如未获得授权&#xff0c;可以向用户申请需要的位置权限。 系统提供的定位权限有&#xff1a; ohos.permission.LOCATION&#xff1a;用于获取精准位置…

机器学习python实践——由特征选择引发的关于卡方检验的一些个人思考

最近在用python进行机器学习实践&#xff0c;在做到特征选择这一部分时&#xff0c;对于SelectPercentile和SelectKBest方法有些不理解&#xff0c;所以去了查看了帮助文档&#xff0c;但是在帮助文档的例子中出现了"chi2"&#xff0c;没接触过&#xff0c;看过去就更…

垃圾佬的狂欢!3元/月开Minecraft国际服务器全流程教程

大家好&#xff01;我是ErikTse&#xff0c;一名生活在捡垃圾区的UP主&#xff0c;相信不少点进本文的朋友们跟我一样&#xff0c;在小时候都有一个当腐竹&#xff08;MC服主&#xff09;的梦&#xff0c;可惜那时还小&#xff0c;不懂网络更不懂技术&#xff0c;只有一颗爱玩的…

c++里 lamda 表达式,其实被编译器处理为匿名类,并实例化为匿名对象

该匿名对象定义了括号 () 运算符函数&#xff0c;所以可以像函数一样被调用。 lamda 表达式必须在函数作用域中定义。通过按值捕获或按引用捕获&#xff0c;可以使用所在函数中定义的变量。在类的成员函数中定义的 lamda 表达式&#xff0c;若捕获了 this &#xff0c;则可以修…

配置OSPF认证(华为)

#交换设备 配置OSPF认证-基于华为路由器 OSPF&#xff08;开放最短路径优先&#xff09;是一种内部网关协议&#xff08;IGP&#xff09;&#xff0c;用于在单一自治系统&#xff08;AS&#xff09;内决策路由。OSPF认证功能是路由器中的一项安全措施&#xff0c;它的主要用途…

B-splines曲线的绘制(Matlab)

虽然在这个链接三次 Bspline(B样条曲线) NURBS曲线的绘制 matlab_三次b样条曲线的绘制-CSDN博客中我们介绍了NURBS曲线&#xff0c;然而有时候我们通过B-spline曲线也能够解决问题。B-spline曲线作为NURBS曲线的一种特例&#xff0c;这里给出均匀B-spline曲线的表达式&#xff…

基于PHP的草莓种植信息管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的草莓种植管理系统 一 介绍 此草莓种植管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端采用jquery.js和kindeditor在线HTML编辑器。系统角色分为用户和管理员。 技术栈&#xff1a;phpmysqljquery.jsphpstudyvsco…

【Windows系统】文件操作出现“文件访问被拒绝”弹窗问题

环境 系统&#xff1a;win10x64 版本&#xff1a;1709 问题 重命名系统文件夹文件&#xff0c;有时会出现【文件访问被拒绝】的弹窗&#xff0c;导致操作失败。 如何才能避免弹窗&#xff0c;成功操作&#xff1f; 解决方法 前提&#xff1a;实施以下解决&#xff0c;首先…

Vue自定义长按指令

新建文件longpress.ts文件 // longpress.ts import { DirectiveBinding } from vue const longpress {beforeMount(el: any, binding: DirectiveBinding) {const cb binding.valueconst duration binding.arg || 800 // 长按等待时间let timer: number | null nulllet is…

这些数据可被Modbus采集,你还不知道???

为什么要用Modbus采集模块 Modbus采集模块之所以被广泛使用&#xff0c;是因为它提供了标准化的通信协议&#xff0c;确保了不同设备间的兼容性。它支持多种通信方式&#xff0c;易于实现&#xff0c;并且能够适应不同的网络环境。Modbus模块能够收集和传输各种工业数据&#x…

从荒漠到绿洲:可视化技术助力可持续农业

运用图扑可视化技术优化荒漠农业管理&#xff0c;通过实时监控与数据分析提高土地资源利用和生产效率&#xff0c;实现生态可持续发展。

解决Java项目运行时错误:“Command line is too long”

在开发Java应用的过程中&#xff0c;你可能偶尔会遇到“Error running ‘Application’: Command line is too long”的问题。这是因为Java虚拟机&#xff08;JVM&#xff09;在启动时&#xff0c;如果传递给它的类路径&#xff08;classpath&#xff09;过长&#xff0c;超过了…

Docker overlay磁盘使用100%处理方法overlay 100%

一、问题描述 服务器上运行了几个docker容器,运行个一周就会出现overlay 100%的情况&#xff0c;经查找&#xff0c;是容器里生成了很多core.xxx的文件导致的。 二、解决方法 首先通过以下命令查看&#xff1a; df -h 可以看的overlay已经100%了&#xff0c;进入到/var/lib/d…

springmvc拦截器 和 异常拦截器

springmvc拦截器的配置使用&#xff1a; 自定义监听器实现HandlerInterceptor接口&#xff1a; 在springmvc的配置文件中引入自定义拦截器对象及拦截目标 拦截器的方法调用 自定义一个拦截器&#xff1a; Component public class LoginInterceptor implements HandlerIntercept…

系统架构设计师 - 操作系统(2)

操作系统 操作系统&#xff08;5-6分&#xff09;文件管理绝对路径与相对路径 ★索引文件 ★★★位示图 ★ 存储管理段页式存储 ★★★页式存储段式存储段页式存储&#xff08;了解&#xff09; 页面置换算法 ★ 微内核操作系统嵌入式操作系统 ★★★ 大家好呀&#xff01;我是…

基于Spring Boot的工具迭代

1. 申请git权限 2. git项目中点击我的-Settings-SSH Keys添加公钥 3. 公钥生成步骤 ssh-keygen -o -t rsa -b 4096 -C "your email" cd ~/.ssh/ cat id_rsa.pub 把公钥内容粘贴到SSH Keys 4. 创建本地分支git checkout -b branchname git远程仓库创建远程分支 …