基于GeoTools使用JavaFx进行矢量数据可视化实战
目录
前言
一、JavaFx展示原理说明
二、GeoTools的Maven依赖问题
三、引入Geotools相关的资源包
四、创建JavaFx的Canvas实例
五、JavaFx的Scene和Node的绑定
六、总结
前言
众所周知,JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然,现在已经是Web的时代,很多以前需要用桌面软件来支撑的软件,现在都可以使用Web的工具来完成。Web是一个大的趋势,同时现在在这里谈论JavaFx,也并不是说要深入研究。首先还是要根据市场需求来,作为Java开发人员,有可能在实际工作过程中,我们的需求方想要开发一个简单的工具。尤其是面向GIS这样的工具,首先不想像Arcgis那么大,甚至像SuperMap或者MapGIS这样的桌面端软件都不要,需求也是非常简单的,只是进行空间数据的简单可视化,或者做简单的空间分析。同时要求我们的软件是可以在跨平台的环境下运行的。当然除了Java,跨平台的可选择性还有许多。不是说跨平台只有Java能做。
本文以全球各个国家的矢量数据的展示为例,重点讲解如何在JavaFx中进行展示,结合GeoTools来进行展示为需求背景。大家知道,geotools自身的组件框架中,gt_swing是实现桌面应用的一个可视化展示层,虽然在JavaFx中可以将Swing的一些控件进行集成,把Swing的按钮或者表格等放在JavaFx中进行渲染。但是很少把底图放在JavaFx中进行渲染的。当然,哪些使用JavaFx中的WebView嵌入了本地浏览器的不算在内。通过本文,会讲解如何将Geotools的地图在JavaFx中进行展示,大家在实际应用建设过程当中有这个需求的,可以看看博文。
一、JavaFx展示原理说明
本节将对如何使用JavaFx进行空间数据的可视化进行说明,与Swing组件的机制不同。这里将重点讲解这两者是如何结合在一起,最终实现空间数据的可视化的。

上图是一张JavaFx的组件架构图,最下面的是JavaFx的两个基石,Jvm和Java的相关API,这些其实都是它的底层依赖基础。 然后构建在JVM和JDK API基础之上的是相关的组件和开发工具包。这是对不同实现需求的组件封装。最上层是JavaFx的展示层,通过JavaAPI和Scene进行展示,其中Scene场景是JavaFx中一个很重要的对象。因此本文的重点也是围绕Scene来进行,通过Scene的构建和展示,帮助我们来实现空间数据的可视化展示。在实现可视化的过程中,还有一个很重要的对象,就是Canvas画布,我们在JavaFx当中实现可视化的基础,是中间渲染的桥梁。
二、GeoTools的Maven依赖问题
关于GeoTools的Maven依赖问题,由于GeoTools工程项目的相关包不是都在Maven的中央仓库中的,因此我们在配置它的Maven依赖来就跟普通的工程是不一样的。关于GeoTools的maven依赖,其它的很多博主也有相应的文章进行介绍。这里就不再进行赘述。需要申明的是,博客编写过程中,我们的JDK使用的1.8的版本,而对应的Geotools我使用的是28.2的版本。现在Geotools的最新版本应该到31了,大家感兴趣可以到Github中查看一下GeoTools的官方仓库的信息传送门。

应该是31.x的版本是最新的版本。不过为了兼容我们的Jdk的版本,大家用1.8的Jdk,还是可以使用28.x的版本。因此博客提供的案例都是使用28.x版本。
如果我们的maven仓库引用的是阿里云的maven私服的话,那么在仓库的定义上要设置好,否则可能导致geotools的依赖包不能下下来。来看下项目工程的Pom.xml配置。
<repositories>
<!--从22.x后geotools由OSGeo管理--><repository><id>osgeo</id><name>OSGeo Release Repository</name><url>https://repo.osgeo.org/repository/release/</url><snapshots><enabled>false</enabled></snapshots><releases><enabled>true</enabled></releases></repository><repository><id>osgeo-snapshot</id><name>OSGeo Snapshot Repository</name><url>https://repo.osgeo.org/repository/snapshot/</url><snapshots><enabled>true</enabled></snapshots><releases><enabled>false</enabled></releases></repository><repository><id>GeoSolutions</id><url>http://maven.geo-solutions.it/</url></repository>
</repositories>
三、引入Geotools相关的资源包
在pom.xml中定义了Geotools的依赖仓库地址后,我们来正式引入Geotools的相关依赖。这里为了简化,只提供其具体的配置代码,具体的每个组件的功能,在后面的博客中会进行逐一介绍。
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-swing</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools.xsd</groupId><artifactId>gt-xsd-sld</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools.xsd</groupId><artifactId>gt-xsd-core</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-xml</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.jfree</groupId><artifactId>fxgraphics2d</artifactId><version>1.3</version></dependency></dependencies>
经过上面的步骤,我们基本完成了Geotools官方仓库的定义以及相关依赖包的引用申明,在正常有网络的情况下,系统在后台就会自动帮助我们下载依赖的包。接下来我们来进行具体的功能开发即可。
四、创建JavaFx的Canvas实例
由于在Jdk1.8当中,Javafx还是绑定在一起的,因此我们不需要单独针对JavaFx来进行配置,但是在1.8后面的版本中,jdk就将javaFx和jdk进行了分离,因此要单独进行配置。在引用相应的geotools的资源包之后,我们就可以来创建最重要的Canvas对象,这个Canvas对象是JavaFx的Canvas对象。通过Canvas对象,实现将Map和画布的融合,从而让数据显示处理。因此这里我们定义Canvas对象,并进行地图的初始化等操作。
首先我们创建一个Node对象,这个Node对象包括Canvas、Map和GraphicsContext。同时我们提供两个方法,第一个是进行地图初始化的方法,第二个是进行地图数据绘制的方法。下面是定义Node类的属性和方法。
package tutorial1;import java.awt.Rectangle;
import java.io.IOException;import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.map.FeatureLayer;
import org.geotools.map.MapContent;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.jfree.fx.FXGraphics2D;import javafx.scene.Node;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;public class MapCanvas {private Canvas canvas;private MapContent map;private GraphicsContext gc;public MapCanvas(int width, int height) {canvas = new Canvas(width, height);gc = canvas.getGraphicsContext2D();initMap();drawMap(gc);}public Node getCanvas() {return canvas;}private void initMap() {}private void drawMap(GraphicsContext gc) {}
}
Canvas负责进行展示,而Map对象负责提供显示的数据源。在上述的方法中,我们要先创建一个Canvas对象,在进行对象构造时,指定Canvas对象的高和宽,按照这个尺寸要求来创建。下面我们来看一下如何进行地图的初始化,也就是上面的initMap这个方法。
private void initMap() {try {FileDataStore store = FileDataStoreFinder.getDataStore(this.getClass().getClassLoader().getResource("maps/countries.shp"));SimpleFeatureSource featureSource = store.getFeatureSource();map = new MapContent();map.setTitle("Quickstart");Style style = SLD.createSimpleStyle(featureSource.getSchema());FeatureLayer layer = new FeatureLayer(featureSource, style);map.addLayer(layer);map.getViewport().setScreenArea(new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight()));} catch (IOException e) {e.printStackTrace();}
}
在进行空间矢量数据的展示时,首先要告诉可视化渲染器,具体的文件在什么位置。接下来是使用样式,为了简单起见,这里使用默认样式来进行可视化,创建样式的时候,样式构建器会根据数据的类型来进行分别构建,比如不同的点、线、面,它的默认样式都是不一样的。这里的数据是面,因此会勾画出边界的线信息。代码如下:
Style style = SLD.createSimpleStyle(featureSource.getSchema());
最后将样式和数据源进行绑定,然后将图层对象设置到map当中。MapContent这个对象就承载着双发的一个展示容器,最后通过返回这个node,将node和JavaFx的scene场景进行融合。再来看一下绘制地图的方法:
private void drawMap(GraphicsContext gc) {StreamingRenderer draw = new StreamingRenderer();draw.setMapContent(map);FXGraphics2D graphics = new FXGraphics2D(gc);graphics.setBackground(java.awt.Color.WHITE);Rectangle rectangle = new Rectangle((int) canvas.getWidth(), (int) canvas.getHeight());draw.paint(graphics, rectangle, map.getViewport().getBounds());
}
在这里,通过JavaFx的Graphics对象就可以实现地图的绘制。
public Node getCanvas() {return canvas;
}
五、JavaFx的Scene和Node的绑定
虽然在上面的代码中已经实现了将Node对象进行创建,但是还是没有将Node和JavaFx的容器进行绑定,没有Scene的搭载就像没有舞台的演员,想展示自己的才艺都没有舞台。因此最后我们要将Node对象和Scene进行绑定即可。
package tutorial1;import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;public class MainTutorial1 extends Application {@Overridepublic void start(Stage primaryStage) {MapCanvas canvas = new MapCanvas(1090, 670);Pane pane = new Pane(canvas.getCanvas());Scene scene = new Scene(pane);primaryStage.setScene(scene);primaryStage.setTitle("JavaFx结合Geotools展示地图");primaryStage.show();}public static void main(String[] args) {launch(args);}
}
上面的代码非常简单,通过创建的Canvas对象,然后设置一个地图展示的高度和宽度。将创建的对象和JavaFx的Scene进行绑定,最后设置好JavaFx的应用窗口的标题后,调用Show方法实现空间数据的可视化展示,最后运行的可视化效果如下:

经过以上的步骤,我们就实现了在JavaFx中调用Geotools的相关库实现空间矢量数据的快速预览。 当然,这里只展示了空间可视化的效果。这个程序还是有很多进步的空间,比如需要增加鼠标的拖动和缩放、还要支持样式的定制等操作。时间缘故,下次再深入的来将这些设置,本文到此结束。
六、总结
以上就是本文的主要内容, 本文以全球各个国家的矢量数据的展示为例,重点讲解如何在JavaFx中进行展示,结合GeoTools来进行展示为需求背景。大家知道,geotools自身的组件框架中,gt_swing是实现桌面应用的一个可视化展示层,虽然在JavaFx中可以将Swing的一些控件进行集成,把Swing的按钮或者表格等放在JavaFx中进行渲染。但是很少把底图放在JavaFx中进行渲染的。当然,哪些使用JavaFx中的WebView嵌入了本地浏览器的不算在内。通过本文,会讲解如何将Geotools的地图在JavaFx中进行展示,大家在实际应用建设过程当中有这个需求的,可以看看博文。
本文行文仓促,难免有许多不足之处,还恳请各位专家和朋友们在阅读本文时在评论区留下宝贵意见,鄙人不胜感激。GeoTools非常值得学习,在Java进行GIS开发,一定要掌握这个组件库,提高我们的GIS技术开发能力。
相关文章:
基于GeoTools使用JavaFx进行矢量数据可视化实战
目录 前言 一、JavaFx展示原理说明 二、GeoTools的Maven依赖问题 三、引入Geotools相关的资源包 四、创建JavaFx的Canvas实例 五、JavaFx的Scene和Node的绑定 六、总结 前言 众所周知,JavaFx是Java继Swing之后的又一款用于桌面应用的开发利器。当然࿰…...
zabbix的setup无法进入第二步
注意-部署时,报错要看的日志不止一个,php日志的报错也要看的,nginx接收到请求后是转发到php-fpm的 [rootweb01-84-41 ~]# chmod -R 777 /var/lib/php/session chmod: 无法访问"/var/lib/php/session": 没有那个文件或目录 [rootweb…...
代码随想录算法训练营第四十六天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离、编辑距离总结篇
一、115. 不同的子序列 题目链接:115. 不同的子序列 - 力扣(LeetCode) 文章讲解:代码随想录 (programmercarl.com)——115. 不同的子序列 视频讲解:动态规划之子序列,为了编辑距离做铺垫 | LeetCode&#x…...
宝塔安装nginx失败报错“检测到系统组件wget不存在,无法继续安装”
宝塔安装nginx失败报错“检测到系统组件wget不存在,无法继续安装” 问题描述解决方案 问题描述 在宝塔中安装lnmp环境时,安装nginx失败报错:检测到系统组件wget不存在,无法继续安装 如下图所示 通过检查发现系统是已经安装了wge…...
C++之运算符重载系列深入学习:从入门到精通!
为什么需要对运算符进行重载 C预定义中的运算符的操作对象只局限于基本的内置数据类型,但是对于我们自定义的类型是没有办法操作的。但是大多时候我们需要对我们定义的类型进行类似的运算,这个时候就需要我们对这么运算符进行重新定义,赋予其…...
国赛分析。。。。
山东 6散落2两元素 浙江 8散落两元素 安徽不公布 4散落2元素 120s 华南 8散落两元素 西部 8散落两元素 华北 8 2.。。。 华东 东北 路边6张两元素...
无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案
无缝融入,即刻智能[一]:Dify-LLM大模型平台,零编码集成嵌入第三方系统,42K+星标见证专属智能方案 1.Dify 简介 1.1 功能情况 Dify,一款引领未来的开源大语言模型(LLM)应用开发平台,革新性地融合了后端即服务(Backend as a Service,BaaS)与LLMOps的精髓,为开发者铺…...
PLSQL导入导出ORACLE数据提示失败问题修改PLSQL配置
oracle中plsql导入提示无法导入问题 1.首先看下是否环境变量已经配置(具体配置看下面环境变量配置) 2.plsql数据导入中tools-->Preferences中配置如下框中的内容 3.设置 tnsnames.ora文件中看下是否设置有问题 4.PLSQL乱码问题 NLS_LANG SIMPLIFIED CHINESE_CHINA.ZHS16…...
从Shift+F6到雪花算法:IDEA开发中的那些坑与解法
在日常开发中,提升代码质量和开发效率是每个开发者追求的目标。作为 Java 开发者常用的集成开发环境,IntelliJ IDEA 提供了丰富的功能与快捷键,帮助我们更快速、更高效地完成日常工作。然而,即便是如此强大的工具,也会…...
Linux知识点总结
学习目标 常见的快捷键 Linux 是一个开源的类 Unix 操作系统,广泛应用于服务器、桌面和嵌入式系统。以下是一些重要的 Linux 知识点总结: 基础概念 文件系统:Linux 使用层次化的文件系统结构,根目录为 /,其他目录如 …...
Gradio 快速开发网页应用
Gradio 是一个开源的 Python 框架,可以快速开发页面,Gradio 主要用于 AI 模型 Demo 的开发,通过几行代码可以快速生成一个 Web Demo,由于 AI 算法工程师使用的都是 Python 语言,使用 Python 开发 Demo 会相对简单&…...
spring使用validation参数及全局异常检测
1.validation参数验证工具 1.1.validation-api技术链 validation-api是一个Java的数据校验规范,它定义了一套用于校验Java Bean的API。它是JSR 303规范的一部分,也被称为Bean Validation。validation-api提供了一系列的注解,用于在Java类的…...
学习笔记 韩顺平 零基础30天学会Java(2024.8.8)
P492 第三代日期使用 P493 第三代日期方法 P495 String翻转 作业代码见chapter12homework 对于需要异常处理的情况,可以通过这种想法得到: P495 注册处理题 P496 字符串统计 P497 String内存布局测试题 P498 常见类阶段梳理 P499 集合介绍 集合的使用并不…...
45.跳跃游戏
:双层for。复杂度n*n n class Solution {public int jump(int[] nums) {// 找到所有的条约方法,返回其中的最小次数// 从后向前,依次记录到最后的次数int n nums.length;if(n 1) return 0;// int[] temp new int[n];// temp[n-1] 0;fo…...
Golang | Leetcode Golang题解之第328题奇偶链表
题目: 题解: func oddEvenList(head *ListNode) *ListNode {if head nil {return head}evenHead : head.Nextodd : headeven : evenHeadfor even ! nil && even.Next ! nil {odd.Next even.Nextodd odd.Nexteven.Next odd.Nexteven even.N…...
【ARM】CMSIS 软件标准接口
目录 CMSIS:Cortex Microcontroller Software Interface Standard1. 概述2. CMSIS-Core2.1 概述2.2 关键组件2.3 示例代码2.4 详细解释 3. CMSIS-DSP3.1 概述3.2 关键组件3.3 示例代码3.4 详细解释 4. CMSIS-RTOS4.1 概述4.2 关键组件4.3 示例代码4.4 详细解释 5. C…...
Qt 小功能:加载等待动画——转圈圈
加载等待动画实现——转圈圈 效果图:(看封面最好) 关键要点 流畅的动画: 使用 QTimer 每 50 毫秒更新一次动画,确保动画流畅。 视觉效果: 使用 QPainter 的平滑像素转换和抗锯齿选项,提高动画…...
【Linux进程篇】进程终章:POSIX信号量线程池线程安全的单例模式自旋锁读者写者问题
W...Y的主页 😊 代码仓库分享 💕 前言:在之前的进程间通信时我们就讲到过信号量,他的本质就是一个计数器,用来描述临界资源的一个计数器。我们当时使用电影院的例子来说明信号量。电影院的座位被我们称为临界资源&a…...
MathType7.5破解版下载安装激活图文详细教程(附激活秘钥)
🌟 引言:揭秘MathType,数学编辑的瑞士军刀! 嘿,各位小伙伴,今天我要给你们安利一个我超级喜欢的数学神器——MathType!如果你跟我一样,在处理数学公式时常常感到头疼,那你…...
2-62 基于MATLAB gui 编制短波通信系统
基于MATLAB gui 编制短波通信系统,录制一段语音信号,分别通过AM SSB DSB 等调制信号,加入噪声,然后解调出来,可比较各种调制解调方式的优劣。程序已调通,可直接运行。 2-62 matlab gui - 小红书 (xiaohongs…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
