草庐IT

JAVA 如何绘制三维地形图 —— Matplot3D for java V4.0教程:DataGridProcessor处理器详解

tanling8334 2024-05-09 原文

文章目录

一、Matplot3D for JAVA V4.0 概述

二、什么是处理器

三、DataGridProcessor处理器

四、基本使用方法

五、举个栗子:绘制高程地形图



一、Matplot3D for JAVA V4.0 概述

    Matplot3D for JAVA  是一个基于JAVA SE 1.8环境开发的数学科学数据三维可视化组件。 这是一个纯JAVA实现的类似matplotlib可视化三维库(内含纯java实现的3维软引擎),封装为一个jar包,jar文件大小只有200多KB,直接引用即可。无需再安装和配置第三方库或者环境,无需依赖OpenGL、DriectX、JAVA 3D或JAVAFX等等。

下载地址 

码云:        https://gitee.com/tanling8334/Matplot3D-for-Java

Github:    https://github.com/tanling8334/Matplot3D-for-Java


二、什么是处理器

    Matplot3D for JAVA 的处理器(Processor)是一类对象,它们的作用是将数据转换成对应图表的三维模型,负责数据处理和建模,无需使用者直接编写具体模型的代码,只需要将数据加入到处理器中,再通过Matplot3D4JMgr对象将图表直接在绘制到界面上或者输出为图像文件即可。一个Matplot3D4JMgr对象可以“持有”多个不同类型的处理器对象。


三、DataGridProcessor处理器

    DataGridProcessor是数据网格处理器,可以绘制连续的曲面。数据网格是指一个在x,y方向都均匀排列的点阵列。使用一个Double[][]表示数据,数组中的值为z(高度)值。x,y方向由于均匀分布,在指定了各自的取值范围后即可换算为空间坐标的x,y坐标。需要注意的是Double[][]中存放的为数据,和显示的分段数不一定相等(譬如说数据数组是100*100的,但3维曲面模型的分段数可以使90*80)。


四、基本使用方法

DataGridProcessor的编程模式如下:

DataGridProcessor processor = new DataGridProcessor();  //创建一个数据处理器

Matplot3D4JMgr mgr=new Matplot3D4JMgr(processor);	//创建图形管理器

Double[][] datas=new Double[20][20]; //数据阵列

//......准备数据

//向pricessor对象加入数据
processor.addData(datas, "Name", new Range(0, 300), new Range(0, 300), 100, 100, cs, 1f);

mgr.show();

    其中datas表示用户的数据,上面的代码中并没有数据。 现生成一些演示数据如下:

    DataGridProcessor processor = new DataGridProcessor();
		
    Matplot3D4JMgr mgr=new Matplot3D4JMgr(processor);		
		
    //----------以下生成一些演示数据
    Double[][] datas=new Double[20][20];
		
    Random random=new Random();
		
    for(int i=0;i<datas.length;i++) {
	    for(int j=0;j<datas[0].length;j++) {
				
		    if(i+j<20)
			    datas[i][j]=(double)i+j+random.nextDouble();
		    else 
			    datas[i][j]=40d-i-j-random.nextDouble();
				
	    }
	}

	processor.setClose3DObject(true); //设置是否是封闭三维对象

	mgr.setScaleZ(1.2); //z方向伸拉至原始的1.2倍

	mgr.setTitle("Demo 数据阵列");

	processor.setShowGrid(false);//不显示辅助网格线


    //创建一个颜色风格
	ColorStyle cs = new TopBottomColorStyle(ColorStyle.DEFAULT_COLORS_ARRAY);

	processor.addData(datas, "", new Range(0, 100), new Range(100, 200), 20, 20, cs, 1f);
		
	mgr.show();

    运行效果如下:

主要方法介绍:

public void setClose3DObject(boolean flag)

设置是否封闭三维对象,如果为false则只显示数据曲面,如果为true则将曲面、和自适应的水平的矩形平面和四周的垂直面将三维图形围蔽。

public void addData(Double[][] data, String name, Color color, Range rangeX, Range rangeY, int  stepX, int stepY, float alpha)

加入一组数据阵列数据,并指定x,y范围,显示分段,颜色和不透明度。参数说明如下:

1、data:数据阵列二维数组,第一个下标代表X方向,第二个下标代表Y方向;

2、name:名字;

3、color:颜色;

4、rangeX:数据在X方向的分布范围;

5、rangeY:数据在Y方向的分布范围;

6、stepX :X方向的显示分段;

7、stepY:Y方向的显示分段;

8、alpha:不透明度(0为完全透明,1.0为完全不透明)。

public void addData(Double[][] data, String name, Range rangeX, Range rangeY, int stepX, int stepY, ColorStyle cs, float alpha)

此方法与前一个方法类似,只是使用ColorStyle 最为参填充而不是用一种纯色填充。注意参数的顺序是和上面的方法不一样的。


五、举个栗子:绘制高程地形图

     现在我们来写一个稍微高级一点点的栗子:绘制高程地形图。就像下面这样:

     是不是看起来还挺酷的,实际上DataGridProcessord的使用方法和上面简单的栗子并没有多少差别,差别在于数据。同时根据数据的分布密度设置合理的分段数进行建模和绘制。

    需要特别指出的是,由于这是一个JAVA纯软件实现的三维引擎,完全依靠JVM和CPU运算以及靠内存存储数据,当模型数据过多时会占用较多内存,“刷新时”也会占用较多CPU时间。所以根据自己电脑的实际配置和性能来决定模型的精细度。根据我的4年前的破电脑的使用经验,如果是需要实时刷新我觉得最好把模型的片面数控制在10W个以内,例如分段数设定为300*300时,模型的片面数就会超过9W个。大家可以根据自己电脑的实际配置测试一下在可接受的刷新效率下的极限精细度。

    关于性能方面的底层问题,我还在还在持续改进中,看看使用CPU计算时JAVA的极限能达到什么程度。

    言归正传,地形数据怎么生成。首先从互联网上找到高程数据,高程数据一般都是测绘卫星测绘获得的,有多种格式,大家有兴趣可以研究研究。我是从下面这个网站下载高程数据的:

http://viewfinderpanoramas.org/Coverage%20map%20viewfinderpanoramas_org3.htm

    选择某一个方格可以下载那一区域的高程数据,下载后解压可以得到一堆后缀是 .hgt的文件。文件是以一个方格区域的右上角的经纬度命名的,每个文件代表的方格跨度分别是经度的1度和纬度的1度。例如N08E036.hgt文件包含的就是北纬8度到北纬9度,东经36度到东经37度这一区域的地形高程数据。每个文件的大小是一致的,共包含1442401个采样点的高程数据,可以看到每个文件的大小是2884802字节,就是说每个采样点数据占用了两个字节。

    同时可以按照地球的半径换算:​,结果大约是90m,也就是说这些hgt文件的数据精度是90米。每一个文件涵盖的区域长宽大概是108km,而我们知道地球最高的海拔也只有8800多米,所以整块绘制体现不出地形高度起伏,可以只提取其中的一个子区域绘制。

    例如提取文件“ N27E086.hgt ” 文件其中300*300个点表示的区域进行绘制。这个区域位于喜马拉雅山脉,因此地形起伏会比较明显。  

    hgt文件数据提取代码如下:

/**
* @param fileName 文件名
* @param offsetU  提取区域右上角的经度偏移量
* @param offsetV  提取区域右上角的维度偏移量
* @param countU   经度提取点数量
* @param countV   维度提取点数量
* @return         高程数据数组
*/
Double[][] readHgtFile(String fileName,int offsetU,int offsetV,int countU,int countV) throws Exception{
		
	File file = new File(fileName);
		
	DataInputStream dio = new DataInputStream(new FileInputStream(file));
		
	int x=0,y=0;
	Double[][] datas=new Double[countU][countV];
	byte[] buf=new byte[2402];
		
	for(int i=0;i<1201;i++) {
			
		dio.read(buf);
			
		if(i<offsetU||i>=offsetU+countU)
			continue;
			
		for(int k=0;k<buf.length;k+=2) {
				
			if(k/2<offsetV||k/2>=offsetV+countV)
				continue;
				
			datas[x][y]=(double)((buf[k] << 8) | (buf[k+1] & 0xff));
			y++;
		}
			
		y=0;
		x++;
	}
		
	dio.close();
		
	return datas;
}

    接下来是主程序,因为我们需要取纵横300个点,按照点间90米计算,跨度大约为27公里,因此绘图范围的跨度应该设置为27000,分段数可随意,这里设置为270,使片面数不至于很大。主程序如下:

	public static void main(String[] args) throws Exception {

		final Double[][] datas = readHgtFile("./demo_data/N27E086.hgt",139,100,301,300);

		DataGridProcessor processor = new DataGridProcessor();
		
		Matplot3D4JMgr mgr=new Matplot3D4JMgr(processor);

		mgr.setTitle("高程地形");
		mgr.setShowReferencePlanes(false); //不显示坐标系

		processor.setShowGrid(false); //不显示网格线

		processor.addData(datas, "",Color.LIGHT_GRAY, new Range(0, 27000), new Range(0, 27000), 270, 270, 1f);
		
		processor.setClose3DObject(true);
		
		mgr.show();
	}

执行程序显示如图:

    是不是已经有点意思了。但是颜色只有灰色,我们希望可以根据高度显示不同的颜色,就是高度用颜色也能体现出来。 还有高光感看起来感觉有一点像金属表面。那么就做一下细节调整。用颜色数组创建ColorStyle对象,并在添加数据时设置,同时关闭高光渲染。调整代码调整如下: 

ColorStyle cs = new TopBottomColorStyle(new Color[] {Color.BLUE,Color.GREEN,Color.YELLOW,Color.RED.brighter(),Color.RED.darker()});

processor.addData(datas, "", new Range(0, 27000), new Range(0, 27000), 270, 270, cs, 1f);

processor.setHighlight(false);
		

    注意使用ColorStyle的 addData 方法的参数顺序和使用Color作为参数的方法是不一样的,效果如下:

 关闭高光渲染时效果如下:

    是不是挺酷

有关JAVA 如何绘制三维地形图 —— Matplot3D for java V4.0教程:DataGridProcessor处理器详解的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  3. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  4. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  5. ruby - 在 RUBY 上的 PADRINO 框架上使用 RSPEC 进行测试的教程 - 2

    我是Ruby新手,并被要求在我们的新项目中使用它。我们还被要求使用Padrino(Sinatra)作为后端/框架。我们被要求使用Rspec进行测试。我一直在寻找可以指导在Padrino上使用RspecforRuby的教程。我得到的主要是引用RoR。但是,我需要RubyonPadrino。请在任何入门/指南/引用/讨论等方面指导我。如有不妥之处请指正。可能是我没有针对我的问题搜索正确的词/短语组合。我正在使用Ruby1.9.3和Padrinov.0.10.6。注意:我还提到了SOquestion,但它没有帮助。 最佳答案 我没用过Pa

  6. ruby - 在 StockChart (highchart) 中以编程方式显示柱形图的工具提示 - 2

    我有一个Highstock图表(带有标记和阴影的线条),并且想以编程方式显示一个highstock工具提示,例如,当我选择某个表上的一行(包含图表数据)我想显示相应的highstock工具提示。这可能吗? 最佳答案 股票图表thissolution不起作用:在thisexample你必须更换这个:chart.tooltip.refresh(chart.series[0].data[i]);为此:chart.tooltip.refresh([chart.series[0].points[i]]);解决方案可用here.

  7. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  8. 物联网MQTT协议详解 - 2

    一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su

  9. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

  10. ruby-on-rails - 带有自定义处理器的 CarrierWave 未注册 - 2

    我正在使用carrierwave上传视频然后有一个名为thumb的版本,带有自定义处理器,可以获取视频并使用streamio-ffmpeg创建屏幕截图。视频和文件都已正确上传,但在调用uploader.url(:thumb)时我得到:ArgumentError:Versionthumbdoesn'texist!VideoUploader.rbrequire'carrierwave/processing/mime_types'require'streamio-ffmpeg'classVideoUploader5)File.renamethumb_path,current_pathendd

随机推荐