基于GeoTools的GIS专题图自适应边界及高宽等比例生成实践

目录

前言

一、原来的生成方案问题

1、无法自动读取数据的Bounds

2、专题图高宽比例不协调

二、专题图生成优化

1、直接读取矢量数据的Bounds

2、专题图成果抗锯齿

3、专题成果高宽比例自动调节

三、总结


前言

        在当今数字化浪潮中,地理信息系统(GIS)的应用场景日益丰富,从城市规划到环境监测,从交通运输到资源管理,GIS 技术为各领域提供了强大的空间数据分析与可视化支持。而专题图作为 GIS 表达的重要形式,其生成质量直接影响着信息传达的准确性和直观性。以下图为例,要求绘制与湖南省相邻的其它市级行政区划的专题图:

        传统的 GIS 专题图制作往往面临着诸多挑战。一方面,地图边界固定,当面对不同尺度或范围的数据时,要么出现数据超出边界的情况,要么导致画面留白过多,严重影响视觉效果与信息呈现完整性。另一方面,高宽比例的把控难度较大,不同数据集或应用场景下,要确保地图在各种尺寸的屏幕和页面布局中保持协调的比例展示,避免图形拉伸或压缩变形,这需要耗费大量的时间和精力进行手动调整,极大地降低了工作效率,也难以满足批量生产与动态更新的需求。

        GeoTools 作为一款功能强大的开源 GIS 工具库,为解决上述问题提供了丰富的 API 和灵活的开发框架。利用 GeoTools,开发者能够深入底层数据处理与图形渲染流程,实现对专题图生成过程的精细化管控。通过自定义投影变换、数据裁剪算法以及图形布局策略,可以轻松应对各种复杂场景,让专题图自动适应不同边界,并始终保持高宽等比例的精准呈现。

        本文将深入探讨基于 GeoTools 实现 GIS 专题图自适应边界及高宽等比例生成的实践方法。从 GeoTools 的环境搭建与核心模块介绍入手,详细讲解如何利用其数据访问、样式定义和渲染引擎等功能,结合实际案例代码演示,逐步剖析实现自动适应边界和等比例生成的关键技术要点与优化技巧。同时,还会分享在实际项目应用中的经验教训,以及如何根据业务需求进行扩展定制,旨在为广大 GIS 开发者提供一份实用、高效的解决方案参考资料,助力提升 GIS 专题图制作的自动化水平与质量,使其能够更好地服务于各行业的空间信息分析与决策支持工作。

一、原来的生成方案问题

        在之前的博客中曾经介绍过,如何使用Geotools来生成shapefile的缩略图,原文地址:基于Java和GeoTools的Shapefile矢量数据缩略图生成实践,虽然实现了基本的功能。可以使用Geotools来渲染SLD样式,并且生成本地的缩略图。但是也还是存在一些点没有优化,比如以下两点。第一是没有实现自动的从待生成的Shapefile数据中获取数据的Bounds边界,而是使用Qgis软件来进行手动设置的模式。第二个是对于生成的专题图结果,专题图的高度和宽度比例跟shapefile的原始尺寸没有很好的兼容,从实际效果上来看,就是比较不协调,很生硬。下面将对这两点来进行深入说明。

1、无法自动读取数据的Bounds

        为了让第一次看到博客的朋友也有一个简单的认识,这里我将原来生成图片的关键方法贴出来公共大家参考:

public static void createUSA() {long start = System.currentTimeMillis();Shp2Image shp2img = new Shp2Image();shp2img.setMap(new MapContent());String shpPath = "F:/xxx/maps/countries.shp";String sldPath = "F:/xxx/maps/countries1.1.0-2.sld";String imgPath = "D:/countries0228-美国.png";Map<String, Object> paras = new HashMap<String, Object>();double[] bbox_usa = new double[] { -145.40999, 9.93976, -65.062300,81.12722 };paras.put("bbox", bbox_usa);paras.put("width", 1020);paras.put("height", 800);shp2img.addShapeLayer(shpPath, sldPath);shp2img.getMapContent(paras, imgPath);System.out.println("生成完成,共耗时" + (System.currentTimeMillis() - start) + "ms");
}

        在以上的代码中就包含了两个关键的信息。第一个就是bbox_usa,这表示漂亮国的Bbox值,也就是Bounds边界信息。 关于Bounds,可以使用Qgis或者Arcgis等软件进行获取,以Qgis为例,当我们打开一份shapefile矢量数据之后,右键属性可以看到数据的Bounds值,如下图所示:

        这里的范围值就是我们需要的目标值,将上述值复制到代码中的bbox_usa数组中即可。如果是处理单张缩略图生成,使用qgis等辅助软件来帮助提取固然没有问题,如果需要批量作业,这么大量的人工干预无疑降低了工作效率。

2、专题图高宽比例不协调

        关于专题图的高度和宽度比例不协调的原因其实跟边界范围差不多,但是又存在一定的差异即边界值使用qgis获取的值是非常固定的,但是生成的专题图的高度和宽度是我们通过硬编码的方式指定的,因此具体的比例与原始的数据无法实现对应,从而导致将数据渲染到图片后,整体效果是失真的,即比例非常不协调,比如在指定宽度和高度为:1068*749的设置下,湖南省的乡镇区划专题图效果如下:

        通过上图可以看到,通过预设的高度和宽度不能很好的进行专题图渲染。这也是第二个需要解决的问题。 

二、专题图生成优化

        那么如何优化专题图的生成,让专题图做的更加美观,符合我们的业务需要呢?主要的优化方向也是包含一下三点。第一个是为了提高效率,需要使用Geotools来自动读取矢量文件的边界,以此来达到自动计算范围的目的。第二个是为了在地图放大时也能保持一定的清晰度,因此在生成PNG图片时需要抗锯齿,以此满足图片的方法需求。第三是可以根据自动读取的边界范围自动进行高度和宽度的比例自适应调整。本节将主要介绍这三点优化内容。

1、直接读取矢量数据的Bounds

        在GeoTools中,要想实现自动读取Shapefile的地图边界数据,可以通过以下两种形式获取,第一个是通过Layer对象,第二个是从mapContent对象的视图对象中获取。首先来介绍如何从Layer图层对象获取,关键代码如下:

Layer layer = new FeatureLayer(featureSource, style);
this.map.addLayer(layer);
//这里这是范围
this.setEnvelope(layer.getBounds());

        第二种是可以通过mapContent对象来获取,关键代码如下:

renderer.setMapContent(map);
// 从MapContent中获取地图边界范围
ReferencedEnvelope bounds = map.getViewport().getBounds();

        以上者两种方法都是可以的,大家可以根据实际情况使用。 

2、专题图成果抗锯齿

        针对专题图生成后,如果有图片放大的需求,在放大的时候就会失真,这时候就需要进行抗锯齿的设置。这要求在进行专题图的图片渲染输出时,设置图片渲染的参数,以此来进行图片的抗锯齿效果,实现关键代码如下:

/**
* 设置抗锯齿以及其他相关渲染提示。
* @param g2d 绘制目标的 {@link Graphics2D} 上下文。
*/
private static void setAntiAliasing(Graphics2D g2d,int width,int height) {g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));g2d.setColor(Color.WHITE);g2d.fillRect(0, 0, width,height);// 启用抗锯齿g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}

3、专题成果高宽比例自动调节

        要想实现专题成果图的尺寸比例自动调节,最关键的操作是需要知道本身数据的高宽比,通过固定的高宽比来求解实际生成图片的高宽,这样设置的效果应该是比较符合实际需要的专题图的。所以问题的关键就是自动计算高宽比,而矢量文件的高宽我们可以通过bounds来获取。因此高宽比可以通过bounds的高度和宽度的计算得到。

// 输出图像大小(例如:宽度x高度)
int width = 1920; // 可根据需求调整
// 计算地理宽高比
double aspectRatio = bounds.getWidth() / bounds.getHeight();
//根据比例计算新高度
int height = (int) Math.round(width / aspectRatio);

        上面代码中的1920只是一个示意,实际情况可以设置成一个范围值,固定了宽度后,可以根据宽高比自动计算另一个参数,在得到Height后,再进行画布的渲染和出图。关键代码如下:

// 创建一个缓冲区用于接收渲染的结果
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics2D gr = image.createGraphics();
// 设置渲染提示以提高质量和减少锯齿
setAntiAliasing(gr,width,height);

        最终可以得到一张比较符合我们业务需要的专题图,如下图所示,可以看到,专题图的边界范围是自动获取、图片放大后锯齿感比较小,经过计算高宽比之后的图片尺寸,看起来也比较协调:

三、总结

        以上就是本文的主要内容,本文将深入探讨基于 GeoTools 实现 GIS 专题图自适应边界及高宽等比例生成的实践方法。从 GeoTools 的环境搭建与核心模块介绍入手,详细讲解如何利用其数据访问、样式定义和渲染引擎等功能,结合实际案例代码演示,逐步剖析实现自动适应边界和等比例生成的关键技术要点与优化技巧。同时,还会分享在实际项目应用中的经验教训,以及如何根据业务需求进行扩展定制,旨在为广大 GIS 开发者提供一份实用、高效的解决方案参考资料,助力提升 GIS 专题图制作的自动化水平与质量,使其能够更好地服务于各行业的空间信息分析与决策支持工作。行文仓促,定有不当之处,恳请各位专家学者博友在评论区留下宝贵的意见,万分感激。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

aardio - 虚表 + 数据库 操作例程

import godking.vlistEx; import fonts.fontAwesome import win.ui; /*DSG{{*/ mainForm win.form(text"客户信息管理";right967;bottom556;border"none") mainForm.add( addData{cls"plus";text\uF067 新增;left8;top80;right77;bottom110;bgc…

SQLAlchemy系列教程:理解SQLAlchemy元数据

SQLAlchemy是Python开发人员的强大ORM工具。SQLAlchemy中的元数据是对象-关系映射配置的集合&#xff0c;允许开发人员无缝地定义和使用数据库模式。 使用元数据 SQLAlchemy中的元数据充当各种数据库描述符&#xff08;如表、列和索引&#xff09;的容器。这使开发人员能够通…

Soul 1.4.60 | 清爽版浏览器,内置广告拦截与多功能集成,保护隐私

Soul浏览器是一款专注于内容浏览体验的安卓浏览器&#xff0c;去除广告与追踪器&#xff0c;集成视频下载、PDF查看、手势控制等实用功能。支持无痕模式与黑暗主题&#xff0c;内置清洁器自动过滤广告&#xff0c;优化网页加载速度&#xff0c;提供流畅的浏览体验与隐私保护。支…

最短路问题

Problem - D - Codeforces&#xff08;最短路&#xff0c;反向bfs&#xff09; 题目&#xff1a; 思路&#xff1a; bfs版本&#xff1a;参考自Codeforces Round 1002 (Div. 2) A - D - 知乎 代码&#xff1a; dijstra&#xff1a; void solve() {int n;cin>>n;int s…

【论文阅读】多模态——LSeg

文献基本信息 标题&#xff1a;Language-Driven Semantic Segmentation作者&#xff1a;Boyi Li、Kilian Q. Weinberger、Serge Belongie、Vladlen Koltun、Ren Ranftl单位&#xff1a;Cornell University、University of Copenhagen、Apple、Intel Labs会议/期刊&#xff1a;…

Docker Desktop常见问题记录

1.docker pull报错&#xff0c;无法连接https://registry-1.docker.io/v2/ 报错信息如下&#xff1a; Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection(Client.Timeout exceeded …

Java 大视界 -- Java 大数据在智能政务公共服务资源优化配置中的应用(118)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…

Python快捷手册

Python快捷手册 后续会陆续更新Python对应的依赖或者工具使用方法 文章目录 Python快捷手册[toc]1-依赖1-词云小工具2-图片添加文字3-BeautifulSoup网络爬虫4-Tkinter界面绘制5-PDF转Word 2-开发1-多线程和队列 3-运维1-Requirement依赖2-波尔实验室3-Anaconda3使用教程4-CentO…

Javaweb后端spring事务管理 事务四大特性ACID

2步操作&#xff0c;只能同时成功&#xff0c;同时失败&#xff0c;要放在一个事务中&#xff0c;最后提交事务或者回滚事务 事务控制 事务管理进阶 事务的注解 这是所有异常都会回滚 事务注解 事务的传播行为 四大特性

AI绘画软件Stable Diffusion详解教程(2):Windows系统本地化部署操作方法(专业版)

一、事前准备 1、一台配置不错的电脑&#xff0c;英伟达显卡&#xff0c;20系列起步&#xff0c;建议显存6G起步&#xff0c;安装win10或以上版本&#xff0c;我的显卡是40系列&#xff0c;16G显存&#xff0c;所以跑大部分的模型都比较快&#xff1b; 2、科学上网&#xff0…

光伏电池输出功率模型

1.光伏电池输出功率 1.1光伏电池的效率 温度对光伏电池/组件电效率的影响可以追溯到温度对电流I和电压V的影响&#xff0c;因为最大功率表达式为&#xff1a; 其中&#xff0c;Pm为最大输出功率&#xff1b;Vm为最大输出功率点电压&#xff1b;Im为最大输出功率点电流&#xf…

【大模型基础_毛玉仁】1.4 语言模型的采样方法

【大模型基础_毛玉仁】1.4 语言模型的采样方法 1.4 语言模型的采样方法1.4.1 概率最大化方法1&#xff09;贪心搜索&#xff08;GreedySearch&#xff09;2&#xff09;波束搜索&#xff08;BeamSearch&#xff09; 1.4.2 随机采样方法1&#xff09;Top-K 采样2&#xff09;Top…

MyBatis - XML CRUD 其他查询

1. XML 配置文件 使用 MyBatis 操作数据库的方式有两种: 注解 (在注解中定义 SQL 语句)XML 配置文件 (在 XML 文件中定义 SQL 语句) 在上一篇博客中, 已经讲解了如何使用注解操作数据库, 本篇文章来讲解如何使用 XML 进行 MyBatis 开发. 使用 XML 的步骤, 和使用注解的步骤…

DeepSeek + 飞书多维表格搭建你的高效工作流

众所周知&#xff0c;大模型DeepSeek擅长于处理大规模语言模型推理任务&#xff0c;特别是在成本降低和思维链推理方面表现出色‌&#xff0c;我们一般把大模型必做我们的大脑&#xff0c;但是一个人不能只有大脑&#xff0c;还需要其他输入输出以及操作支配的眼耳鼻嘴手足等。…

跨域-告别CORS烦恼

跨域-告别CORS烦恼 文章目录 跨域-告别CORS烦恼[toc]1-参考网址2-思路整理1-核心问题2-个人思考3-脑洞打开4-个人思考-修正版1-个人思考2-脑洞打开 3-知识整理1-什么是跨域一、同源策略简介什么是源什么是同源是否是同源的判断哪些操作不受同源策略限制跨域如何跨域 二、CORS 简…

基于Django创建一个WEB后端框架(DjangoRestFramework+MySQL)流程

一、Django项目初始化 1.创建Django项目 Django-admin startproject 项目名 2.安装 djangorestframework pip install djangorestframework 解释: Django REST Framework (DRF) 是基于 Django 框架的一个强大的 Web API 框架&#xff0c;提供了多种工具和库来构建 RESTf…

基于多目标向日葵优化算法(Multi-objective Sunflower Optimization,MOSFO)的移动机器人路径规划研究,MATLAB代码

一、机器人路径规划介绍 移动机器人路径规划是机器人研究的重要分支&#xff0c;是对其进行控制的基础。根据环境信息的已知程度不同&#xff0c;路径规划分为基于环境信息已知的全局路径规划和基于环境信息未知或局部已知的局部路径规划。随着科技的快速发展以及机器人的大量…

cursor使用经验分享(java后端服务开发向)

前言 cursor是一款基于vscode&#xff0c;并集成AI能力的代码编辑器&#xff0c;其功能包括但不限于代码生成及补全、AI对话&#xff08;能够直接将代码环境作为上下文&#xff09;、即时应用建议等等&#xff0c;是一款面向未来的代码编辑器。 对于vscode&#xff0c;最先想…

【Java学习】异常

一、异常的处理过程 异常类的似复刻变量被throw时&#xff0c;会立即中止当前所在的这层方法&#xff0c;即当层方法里throw异常类似复刻变量之后的语句就不会执行了&#xff0c;如果throw异常语句在当层方法中被try{}包裹&#xff0c;则中止就先发生被包裹在了try{}层&#xf…

双足机器狗开发:Rider - Pi

双足机器狗开发:Rider - Pi https://github.com/YahboomTechnology/Rider-Pi-Robot 项目介绍 Rider - Pi是一款为开发者、教育工作者和机器人爱好者设计的桌面双轮腿式机器人,它基于树莓派CM4核心模块构建,具备多种先进功能和特点: 硬件特性 核心模块:采用树莓派CM4核…