如何基于GeoToolKit/INT实现矢量流线的聚集动画效果示例

news2024/12/24 21:28:40

      继续在上一篇文章的基础上,利用相同的数据处理方法统一了不同年代地层的数据格式(目前js解析支持的格式有ZMap、TS、XYZ和XYZA等),本文主要基于GeoToolKit/INT组件,针对地质研究经常在二维等值线基础上模拟计算地层中物体流动的模拟仿真可视化诉求,主要在ContourShape背景上,绘制矢量流线和SymbolShape的动画显示,最终实现了某个时期地层的物体流动的矢量流线动画效果,仿真油气的聚集过程的二维可视化,包括前端、后端设计等内容。详细效果如下。

1.前端设计与相关技术:主要采用VUE+JS+GeotoolKit.JS,充分利用VUE的组件化设计思想,以及GeotoolKit.JS的ContourShape、Polyline和SymbolShape组件结合实现。具体前端代码如下,示例效果详见第3部分。

vue组件

<script>
import {ContourPlot} from './vectorstreamline.js';
let contourPlot = null;
const SOURCE_DATA_FILE = 'src/demos/contour/contourplot/data/2018_T28.dat';
export default {
    name: 'ContourPlotDemo',
    components: {IntSnackbar, IntContourToolbar, IntPrintDialog, JsonForms},
    data: function () {
        return {
            showDismissibleAlert: false,
            showPrintDialog: false,
            propertiesDialogData: null,
            propertiesDialogActive: false,
            schema: null,
            uischema: Object.freeze(contourSchema),
            materialRenderers: Object.freeze(materialRenderers),
            ajv: null
        };
    },
    destroyed () {
        this._file = null;
        contourPlot.dispose();
        window.removeEventListener('resize', this.onResize);
    },
    updated () {
        if (!this.componentDidResize) {
            this.onResize();
            this.componentDidResize = true;
        }
    },
    mounted () {
        contourPlot = new ContourPlot({
            'host': this.$refs.host,
            'canvas': this.$refs.plot,
            'ondataload': this.onDataLoad,
            'onchangerubberband': this.onChangeRubberBand
        });
        this.setShowDismissibleAlert(false);
        this.setToolbarEnabled(false);
        this._file = this.$refs.file;
        this._file.addEventListener('change', this.onFileChange);
        contourPlot.loadDataSource(SOURCE_DATA_FILE);
        window.addEventListener('resize', this.onResize);
    },
    methods: {
        onResize () {
            contourPlot.resize();
            this.componentDidResize = false;
            this.$forceUpdate();
        },
        onChangeRubberBand (sender) {
            this.$refs.toolbar.setRubberBand(sender.isEnabled());
        },
        onFileChange (event) {
            this.setToolbarEnabled(true);
            contourPlot.loadFile(event.target)
                .then(this.setShowDismissibleAlert.bind(this, false))
                .catch(this.setShowDismissibleAlert.bind(this, true));
        },
        //绘制矢量流线动画效果
        vectorStreamline () {
            //console.log('in vectorStreamline');
            contourPlot.drawVectorStreamLine(this);
        }
}
</script>

基于二维等值线,用于解析绘制矢量线和动画的js组件(vectorstreamline.js),关于矢量流线数据的计算,后续我会专门写相应的内容分享相关方法。

import {ContourShape} from '@int/geotoolkit/contour/shapes/ContourShape';
import {Polyline} from "@int/geotoolkit/scene/shapes/Polyline";
import {Path} from '@int/geotoolkit/scene/shapes/Path';
import {KnownColors} from "@int/geotoolkit/util/ColorUtil";
import {SymbolShape} from "@int/geotoolkit/scene/shapes/SymbolShape";
import {AnchorType} from "@int/geotoolkit/util/AnchorType";
import {SquarePainter} from "@int/geotoolkit/scene/shapes/painters/SquarePainter";
import {AnimationFill} from "@int/geotoolkit/animation/AnimationFill";
const DEFAULT_CROSS_HAIR_COLOR = 'red';
export class ContourPlot {
    constructor (options) {
        TextMetrics.setCacheLimit(512);
        this._host = options.host;
        this._canvas = options.canvas;
        this._onDataLoad = options.ondataload;
        this._onChangeRB = options.onchangerubberband;
        this._contour = null;
        this._vectorstream=null;
        // Create model to hold the contour shape
        this._contourModel = new Group()
            .setVerticalFlip(true)
            .setCache(new ViewCache());
        // Initialize default properties
        this._numberOfLevels = 20;
        this._showFills = true;
        // Create annotated node model
        this._annotatedNodeModel = new Group()
            .setBounds(new Rect(0, 0, this._canvas.clientWidth, this._canvas.clientHeight))
            .addChild(this._contourModel)
            .setScaleScrollStrategy(new RestrictScaleStrategy({
                'minscale': 1E-3,
                'maxscale': 1E3
            }));
        this._layer = [];
    }
    //绘制矢量流线图动画
    drawVectorStreamLine(obj){
        console.log('drawVectorStreamLine');
        //删除上一次绘制的矢量流线和动画方块,注意,之前在哪里加上child,后续就在哪里removeChild。
        this._vectorstream=this._contour.getRoot();
        if(this._vectorstream.children.length>1){
            for(let i=this._vectorstream.children.length-1;i>0;i--){
                // console.log(i+'='+this._vectorstream.getChild(i));
                this._vectorstream.removeChild(this._vectorstream.getChild(i));
            }
        }
        //1.曲线1路径(曲线路径来自于矢量流线计算得到的数据)
        let pathX1=[280, 390, 400, 410, 490,510,1830];
        let pathY1=[280, 420, 430, 440, 480,430,280];
        const line=this.createLines(pathX1,pathY1);//构建曲线子对象1
        //2.曲线2路径(曲线路径来自于矢量流线计算得到的数据)
        pathX1=[800, 490,1000,1300];
        pathY1=[220, 480, 520,80];
        const line2=this.createLines(pathX1,pathY1);//构建曲线子对象2
        //3.运动方块1 路径(路径来自于曲线1路径)
        pathX1=[260, 390, 400, 410, 485];
        pathY1=[270, 420, 430, 440, 480];
        const rec =this.createRecRun(pathX1,pathY1);//构建运动方块子对象1
        //4.运动方块2 路径(路径来自于曲线2路径)
        let pathX2=[1830, 510,495];
        let pathY2=[280, 430,475];
        const rec2 =this.createRecRun(pathX2,pathY2);//构建运动方块子对象2
        //5.运动方块3 路径(路径来自于曲线1路径)
        pathX2=[800, 495];
        pathY2=[220, 480];
        const rec3 =this.createRecRun(pathX2,pathY2);//构建运动方块子对象3
        //6.运动方块4 路径(路径来自于曲线2路径)
        pathX2=[1300,1000, 495];
        pathY2=[80, 520,485];
        const rec4 =this.createRecRun(pathX2,pathY2);//构建运动方块子对象3
        //增加对象
        this._vectorstream.addChild(line);
        this._vectorstream.addChild(line2);
        this._vectorstream.addChild(rec);
        this._vectorstream.addChild(rec2);
        this._vectorstream.addChild(rec3);
        this._vectorstream.addChild(rec4);
    }
    //构建曲线
    createLines(pathlistX,pathlistY){
        //曲线方式(可以是Polyline,Path或Spline等
        const path = new Polyline({
        'x': pathlistX,//[38, 39, 40, 41, 48,51,53]
        'y': pathlistY,//[41, 42, 43, 44, 42,43,45]
        'linestyle': {
            'color': KnownColors.DarkGreen,
            'width': 4
        }
        });
        return path;
    }
    //构建动画方块
    createRecRun(pathlistX,pathlistY){
        const symbolShape=new SymbolShape(20, 15, 15, 15, AnchorType.Center, false, SquarePainter);
        symbolShape.setFillStyle(new FillStyle(KnownColors.DarkRed));
        symbolShape.setLineStyle(new LineStyle(KnownColors.DarkGreen, 1));
        //设置symbolShape动画的各种属性
        //屏幕横向:x(左小右大),纵向:y(下小上大)
        symbolShape.setAnimationStyle([
            {
                'attributeName': 'x',
                'duration': 2000,
                // 'repeatCount': Infinity,     //多次循环设置
                'fill':AnimationFill.Freeze,    //运行到最后位置冻结
                // 'function': Functions.NoEasing,
                'values':pathlistX
             }, 
             {
                'attributeName': 'y',
                'duration': 2000,
                 // 'repeatCount': Infinity,
                 // 'function': Functions.NoEasing,
                'fill':AnimationFill.Freeze,
                'values': pathlistY 
            }
        ]);
      return symbolShape;
}
}

2.后端设计与相关技术:主要采用NodeJS的微服务接口实现。为了便于js解析地层和矢量流数据。代码详见上一篇文章,后端代码、服务方式和调用方式和数据文件格式类似。

3.矢量流线和动画显示示例效果(不同色标)

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

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

相关文章

【C++3】crontab,ftp

文章目录 1.生成数据&#xff1a;crontab2.ftp&#xff1a;ftp是tcp/ip协议族中一员&#xff0c;分客户端和服务端2.1 安装&#xff1a;linux操作系统的用户也是ftp的用户&#xff0c;可以配置专用的ftp用户&#xff0c;专用的ftp用户只能用于ftp&#xff0c;不能登录操作系统2…

ROS2移动机器人导航仿真

环境&#xff1a;Ubuntu 18.04 ros2 eloquent wget http://fishros.com/install -O fishros && . fishros1.安装turtlebot3相关功能包 sudo apt install ros-eloquent-turtlebot3* ref&#xff1a; https://docs.ros.org/ ROS2导航SLAM建图探索_鱼香ROS的博客-CSD…

蛋白组学 代谢组

https://www.cnblogs.com/yanzhi123/p/11712926.htmlhttps://www.cnblogs.com/yanzhi123/p/11712926.html【3】蛋白质组学鉴定软件之Mascot - 简书 (jianshu.com) 【6】蛋白质组学鉴定定量软件之MaxQuant - 简书 (jianshu.com) 基于Maxquant软件处理的LabelFree蛋白质组学 首…

图灵第4期MySQL调优专题学习笔记

目录 一、首先复习打印的课件 二、Explain中的列 三、解读extra 四、索引最佳实践 五、MySQL的内部组结构 2. bin-log归档&#xff1a; 六、常见SQL深入优化 1. order by 与 group by 优化 2. 索引设计原则 3. 分页查询优化&#xff08;根据非主键字段排序的分页查询…

Verilog基础之十三、ROM实现

目录 一、前言 二、非IP核设计 2.1 工程设计文件读取初始化 2.2 测试代码 2.3 仿真结果 三、IP核创建ROM 3.1 IP核生成ROM 3.2 设计代码 3.3 测试代码 3.4 仿真结果 四、modelsim设置 4.1 模拟信号显示 4.2 信号范围显示设置 五、数据文件 一、前言 对于工程中的…

IMX6ULL系统移植篇-uboot启动Log信息

一. 进入uboot 命令模式 只有启动 uboot&#xff0c;进入 uboot的命令行模式时&#xff0c;才能使用 uboot 的命令。 当开发板启动时&#xff0c;快速按下回车键即可进入 uboot命令行模式。这时&#xff0c;进入 uboot 的命令行模式以后输入“help” 或者 “&#xff1f;” &a…

基因遗传进化算法-找最优路径

import random import matplotlib.pyplot as pltplt.rcParams["font.sans-serif"]["SimHei"] #设置字体 plt.rcParams["axes.unicode_minus"]False #该语句解决图像中的“-”负号的乱码问题# 创建初始种群 def create_initial_population():popu…

1024天,CSDN上的时间之旅

1024天&#xff0c;CSDN上的时间之旅 感想收获未来规划职业规划创作规划 感想 今天是在CSDN这个博客上成为博主已经迈入了1024天。这个数字对于计算机领域来说&#xff0c;具有特殊的含义和重要性。 在计算机科学中&#xff0c;1024是2的十次方&#xff0c;也就是2^10。这意味…

rt-thread------串口V1(三)接收

系列文章目录 rt-thread 之 fal移植 rt-thread 之 生成工程模板 STM32------串口理论篇 rt-thread------串口V1版本&#xff08;一&#xff09;配置 rt-thread------串口V1版本&#xff08;二&#xff09;发送篇 文章目录 系列文章目录一、串口的接收中断接收DMA接收 一、串口…

从一次netty分享漫谈

从一次netty分享漫谈 1.前言 上周五&#xff0c;笔者所在的开发小组&#xff0c;组织了一场分享&#xff0c;内容是netty的入门。笔者所在的团队&#xff0c;基本上就是在各条业务线中活蹦乱跳&#xff0c;有经验的看官&#xff0c;到这里已经可以给出分享效果的总体预测&…

Gradle 各个版本下载

每次都要找下载地址&#xff0c;还是记录一下好找点。 http://services.gradle.org/distributions

Unreal 5 官方在Niagara里模拟大型群体笔记

官方视频地址&#xff1a;https://www.bilibili.com/video/BV1FX4y1T7z2/ 如果需要&#xff0c;请查看官方视频。 性能测试 在讲解Niagara之前&#xff0c;视频首先做了一个性能测试&#xff0c;首先放置了100个AI角色&#xff0c;可以想目标角色移动的ai&#xff0c;然后测试…

C语言:猜凶手

题目&#xff1a; 日本某地发生了一件谋杀案&#xff0c;警察通过排查确定杀人凶手必为4个嫌疑犯的一个。 以下为4个嫌疑犯的供词: A说&#xff1a;不是我。 B说&#xff1a;是C。 C说&#xff1a;是D。 D说&#xff1a;C在胡说 已知3个人说了真话&#xff0c;1个人说的是假话。…

山西电力市场日前价格预测【2023-07-03】

日前价格预测 预测明日&#xff08;2023-07-03&#xff09;山西电力市场全天平均日前电价为333.50元/MWh。其中&#xff0c;最高日前电价为398.66元/MWh&#xff0c;预计出现在15: 15。最低日前电价为280.73元/MWh&#xff0c;预计出现在24: 00。 以上预测仅供学习参考&#x…

Spring第一讲:Spring基础概念和环境搭建

一、Spring是什么 Spring 是 Java EE 编程领域的一款轻量级的开源框架&#xff0c;由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立&#xff0c;它的目标就是要简化 Java 企业级应用程序的开发难度和周期。 Spring 自诞生以来备受青睐&#xff0c;一直被广大开发…

二叉树各种函数的实现

如果你觉得迷茫&#xff0c;那就尽可能选择比较困难的路。 目录 前言&#xff1a; &#x1f340;一.通过前序遍历创建二叉树 &#x1f341;二.二叉树的四种遍历 &#x1f342;1.二叉树的前序遍历 &#x1f33c;2.二叉树的中序遍历 &#x1f34c;3.二叉树的后序遍历 …

Mac VSCode配置运行单个C++文件

题外话&#xff1a;VSCode一键整理代码快捷键&#xff1a;ShiftoptionF 方法一&#xff1a;命令行直接编译 g -o 想创建的可执行文件名 ./cpp文件名 ./可执行文件名 以test.cpp为例&#xff0c;我创建的可执行文件名为test&#xff0c;运行结果如下&#xff1a; 方法二&#…

SpringCloud-Nacos配置管理

文章目录 Nacos配置管理统一配置管理在nacos中添加配置文件从微服务拉取配置 配置热更新方式一方式二 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&#xff0c;使用不同的profile3&#xff09;运…

React教程(由浅到深)

文章目录 1. 基本语法1.1 初体验Hello React1.2 JSX语法的基本使用1.2.1 语句与表达式说明 1.3. React面向组件编程1.3.1 函数组件与类组件 1.4 组件实例的三大特性1.4.1 state数据存储状态1.4.2 props的使用1.4.2.1基本使用1.4.2.2 做限制类型&#xff0c;默认值使用1.4.2.3 简…

2、boostrap 多数据类型表单

fileinput 视频图片文本数据表单 插件下载地址&#xff1a;https://github.com/kartik-v/bootstrap-fileinput/ 1、多类型数据from测试 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</tit…