在Java中基于GeoTools的Shapefile读取乱码的问题解决办法

目录

前言

1、Shapefile属性字段编码的情况:

一、Shp文件常见的字符集编码

1、System编码

2、ISO-8859-1编码

3、UTF-8编码 

二、GeoTools解析实战

1、未进行字符处理

2、乱码问题的解决

3、转码支持

4、属性字段编码结果

三、总结


前言

        文件编码(File Encoding)是指文件在计算机中存储时所使用的字符编码方式。字符编码是将字符(如字母、数字、标点符号等)转换成计算机可以直接存储和处理的数字或二进制代码的过程。不同的编码方式决定了文件中字符如何被表示和存储,以及这些字符如何被不同的软件或系统正确地读取和显示。在进行空间数据处理的时候,通常会涉及大量的空间数据,为了更加详细且准确的描述这些空间数据,我们通过会配置一些属性数据。

        Shapefile属性字段的编码通常指的是存储在shapefile的dbf(数据库文件)中的属性数据的字符编码方式。Shapefile是一种用于存储地理空间数据的文件格式,它由多个文件组成,其中dbf文件用于存储每个几何形状的属性数据。

1、Shapefile属性字段编码的情况:

默认编码:
        在不同的软件或库中,shapefile的默认编码可能有所不同。例如,ArcGIS Desktop在较新版本(如10.2.1及以后)中,shapefile (.DBF) 的编码页的默认设置为UTF-8(UNICODE)。而在一些其他软件或库中,如Java GDAL库,默认可能使用ISO-8859-1编码,这会导致中文等非西欧字符出现乱码问题。
编码设置:
        在使用某些软件或库处理shapefile时,可以通过设置来改变属性字段的编码方式。例如,在Java GDAL库中,可以通过调GDAL.SetConfigOption("SHAPE_ENCODING","UTF-8")来设置GDAL库的默认编码为UTF-8,从而避免中文属性乱码的问题。在ArcGIS中,虽然默认编码可能是UTF-8,但也可以通过修改注册表中的dbfDefault值来指定不同的编码方式。不过,这种方法主要影响ArcGIS Desktop生成的shapefile和dBASE文件的编码类型,且仅对ArcGIS Desktop生效。
编码转换:
        如果已经存在编码不匹配的shapefile文件,可能需要通过编码转换工具来修改其属性字段的编码方式。例如,可以使用FME Workbench等GIS数据转换工具来转换shapefile的编码。也可以使用编程方式,如利用geotools等库来读取原始编码的shapefile文件,并以新的编码方式重新写入数据,从而实现编码的转换。
注意事项
        在处理shapefile属性字段编码时,需要确保整个处理流程中的编码方式一致,以避免出现乱码或数据丢失等问题。如果shapefile文件是从不同来源获取的,可能需要先确认其编码方式,以便在后续处理中正确读取和写入数据。在进行编码转换时,应谨慎操作,以免损坏原始数据。建议在转换前备份原始文件,并在转换后进行验证以确保数据的完整性和准确性。

        本文主要讲述使用Java编程语言进行地理信息数据解析的时候,遇到Shapefile的属性信息乱码的几种情况,以及根据不同的编码设置来进行属性信息的解析。博文首先介绍采用不同的字符集编码的shapefile文件,然后在Qgis中打开属性表,查看相关的字符展示情况,接着说明在Java当中调用Geotools时,为经过字符编码处理和经过字符编码处理后的对比,让大家熟悉在Geotools的开发过程中,掌握字符编码的设置。

一、Shp文件常见的字符集编码

        为了讲解使用不同的编码来展示空间数据,我们首先来介绍基础的数据,即三份不同的空间数据格式,其格式都是shapefile的。但是在不同的空间记录中,其字段的值是采用不同的编码的。在这里,采用QGIS这款软件来进行属性数据的展示,方便大家了解日常中的数据展示。

1、System编码

        第一种要介绍的就是System的编码方式,这里采用的是用我国的Lake图层信息,首先我们在Qgis中打开这份数据来看一下,文件的本地路径为:

F:\vector_data\地理数据20240912\地理数据20240912\水系河流\1 全国1-5级标准河流-wgs84\主要湖泊面文件\Lake.shp

        将数据在Qgis软件中打开可以看到其主要的源信息描述如下:

        可以在编码一栏中看到,这份文件的编码是System的。 为了看到其里面的属性信息,可以右键点击shp数据,点击打开属性表就可以看到这份数据的完整的数据信息,打开后相关信息如下所示:

        在上图的红线框中很明显可以看到,有一列叫NAME的,它的值是有乱码的,并没有是我们常见的编码。 因此这算是乱码的第一种情况。

2、ISO-8859-1编码

        第二种也是常见的ISO-8859-1编码,这里准备的数据是一份湖南省的乡镇边界数据,其在文件磁盘中目录如下,:

C:\BaiduDownload\湖南省\湖南省_乡镇边界.shp

        同样的,我们使用QGis软件打开上面的乡镇边界.shp文件,打开后可以看到很明确的字符编码信息:

        同样的我们使用QGIS来进行属性数据的打开查看, 详细如下图所示:

3、UTF-8编码 

        这应该算是比较标准的编码方式,如果进行数据制作的时候,都是统一采用UTF-8的模式,那么这种方式无疑是最好的,估计也不存在字符编码的问题了。

        这个时候,在QGIS中打开属性表,其属性字段的内容是正常可以直接预览的,详情如下图所示。

        当然,字符编码的处理方式根据项目的不同,也会有不同的设置,种类繁多,不甚枚举,这里仅以这几项为例作为例子来讲解,如果以后在开发过程中,遇到这种情况,可以根据实际来进行编码的扩充和修复。 

二、GeoTools解析实战

        在上面的一节中,我们简单的对三种不同的编码方式的shapefile文件进行了简单的介绍,本节则重点介绍如何使用Java开发语言,使用GeoTools的开发组件进行编码的处理和转换,将属性数据可以成功读取到我们的应用程序中。在这里需要统一说明的是,在进行数据的处理和转换的时候,为了进行数据的演示,我们仅将数据的前10行数据记载处理,这样如果有乱码的问题,我们就可以直接进行干预,通过修改其它的字符集函数的方式来保证文字的识别与处理。

1、未进行字符处理

        首先我们来加载UTF-8的矢量数据,测试一下使用UTF-8的情况下,如何使用GeoTools的方法来进行属性表格的解析。下面来看如何使用GeoTools来进行空间属性数据的解析与展示,关键代码如下所示:

/**
* * 不做任何处理展示shp文件数据详情
* 
* @param shpFile shp文件地址
* @throws Exception
*/
protected static void showShpDetails(String shpFile) throws Exception {File file = new File(shpFile);if (!file.exists()) {System.out.println("文件不存在");return;}ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());String typeName = store.getTypeNames()[0];// 创建一个Query对象Query query = new Query(typeName);// 设置查询返回的最大特征数为10query.setMaxFeatures(10);SimpleFeatureSource featureSource = store.getFeatureSource();// 执行查询SimpleFeatureCollection simpleFeatureCollection = featureSource.getFeatures(query);SimpleFeatureIterator itertor = simpleFeatureCollection.features();// 遍历featurecollectionwhile (itertor.hasNext()) {SimpleFeature feature = itertor.next();Collection<Property> p = feature.getProperties();Iterator<Property> it = p.iterator();// 遍历feature的propertieswhile (it.hasNext()) {Property pro = it.next();if (null != pro && null != pro.getValue()) {String field = pro.getName().toString();String value = pro.getValue().toString();System.out.println(field + "===" + value);}}System.out.println("-----------------------------------------------------");}
}

        在上面的代码中,需要注意的地方就是,我们想要在查询的时候只查10条,那么就需要使用到GeoTools的查询Query对象,通过结合Query对象来实现只查10条。10条的设置是个经验值,可以根据服务器的速度和性能来进行平衡,可以一次处理更多的数据。运行测试用例来看其读取的结果如下:

        可以看到,在IDE的控制台中,读取出来的空间属性信息都是乱码。 

2、乱码问题的解决

        要想解决乱码的问题,首先要找到根源。我们需要对属性信息字段进行字符集编码的控制。因此我们在互联网上查询一下,时候有相应的方案。在这里哪怕不管具体的方案,也要了解为什么会出现这个问题。我们来看下ShapefileDataStore这个对象,这个对象是有一个关于字符集的编码的,如下所示:

         如果看过源码的话,各位小伙伴会发现,在GeoTools中有默认的编码集,即:Charset charset = DEFAULT_STRING_CHARSET;

public static final Charset DEFAULT_STRING_CHARSET =(Charset) ShapefileDataStoreFactory.DBFCHARSET.getDefaultValue();

        其实现的实际逻辑代码如下:

/**
* Optional - character used to decode strings from the DBF file. If none is provided, the
* factory will instruct {@link ShapefileDataStore} to try to guess a charset from CPG file,
* before using a default value.
*
* @see ShapefileDataStore#setTryCPGFile(boolean)
*/
public static final Param DBFCHARSET =new Param("charset",Charset.class,"character used to decode strings from the DBF file",false,StandardCharsets.ISO_8859_1,new KVP(Param.LEVEL, "advanced")) {/** This is an example of a non simple Param type where a custom parse method is required.** @see org.geotools.data.DataStoreFactorySpi.Param#parse(java.lang.String)*/@Overridepublic Object parse(String text) throws IOException {return Charset.forName(text);}@Overridepublic String text(Object value) {return ((Charset) value).name();}};

        通过上面的代码可以看到,这里使用的默认编码是:StandardCharsets.ISO_8859_1,也就是ISO-8859-1的方式。

3、转码支持

        了解了乱码的产生原理之后,我们来进行相应的代码转换,关于编码的转换有两种方式,第一种统一在Store一层就进行转码。这样比较单一,也比较简单。第二种就是在每一个value中进行编程式转码,这样不仅麻烦,而且效率低。为了支持全局处理编码等,我们将函数进行已统一的封装,增加了自定义编码的支持:

/**
* *展示shp文件数据详情
* 
* @param shpFile      shp文件地址
* @param unifySetting 是否统一设置字符
* @param chartSet     需要设置的字符编码
* @throws Exception
*/
protected static void showShpDetails(String shpFile, boolean unifySetting, String chartSet) throws Exception {File file = new File(shpFile);if (!file.exists()) {System.out.println("文件不存在");return;}ShapefileDataStore store = new ShapefileDataStore(file.toURI().toURL());String typeName = store.getTypeNames()[0];// 创建一个Query对象Query query = new Query(typeName);// 设置查询返回的最大特征数为10query.setMaxFeatures(10);if (unifySetting) {store.setCharset(Charset.forName(chartSet));// 设置中文字符编码}SimpleFeatureSource featureSource = store.getFeatureSource();System.out.println(featureSource);// 执行查询SimpleFeatureCollection simpleFeatureCollection = featureSource.getFeatures(query);SimpleFeatureIterator itertor = simpleFeatureCollection.features();// 遍历featurecollectionwhile (itertor.hasNext()) {SimpleFeature feature = itertor.next();Collection<Property> p = feature.getProperties();Iterator<Property> it = p.iterator();// 遍历feature的propertieswhile (it.hasNext()) {Property pro = it.next();if (null != pro && null != pro.getValue()) {String field = pro.getName().toString();String value = pro.getValue().toString();if (!unifySetting) {// byte[]bytes= value.getBytes("iso8859-1");byte[] bytes = value.getBytes();value = new String(bytes, chartSet);}System.out.println(field + "===" + value);}}System.out.println("-------------------------------------------------------------");}
}

4、属性字段编码结果

        下面对集中情况的属性数据进行解析,将输出的成果在编辑器的控制台进行综合展示。

        可以在控制台中看到以下的数据都是正常的,

org.geotools.data.shapefile.ShapefileFeatureStore@1b6e1eff
the_geom===POINT (113.24947489555838 28.625229546432124)
名称===南门桥(公交站)
大类===交通设施服务
中类===公交车站
小类===公交车站相关
地址===星通2路
省===湖南省
市===长沙市
区===长沙县
WGS84_经===113.249474896
WGS84_纬===28.6252295464

        同理,其它的数据如湖南省乡镇边界数据,我们使用编码后来查看具体的输出。

        同样的,在控制台中可以看到以下的输出,

gml_id===layer_township_pg.15847
Name===星子镇
layer===乡镇
code===441882101000
grade===4
----------------------------------------------------------------------
gml_id===layer_township_pg.15849
Name===三水瑶族乡
layer===乡镇
code===441882201000
grade===4

        同样的,编码方式是ISO-8859-1的数据经过编码后正常显示。 到此,使用Java语言进行GeoTools解析Shp文件的属性信息时乱码的问题得到解决。

三、总结

        以上就是本文的主要内容,本文主要讲述使用Java编程语言进行地理信息数据解析的时候,遇到Shapefile的属性信息乱码的几种情况,以及根据不同的编码设置来进行属性信息的解析。博文首先介绍采用不同的字符集编码的shapefile文件,然后在Qgis中打开属性表,查看相关的字符展示情况,接着说明在Java当中调用Geotools时,为经过字符编码处理和经过字符编码处理后的对比,让大家熟悉在Geotools的开发过程中,掌握字符编码的设置。行文仓促,定有许多不足之处,如有不当之处,还恳请各位专家和博主在评论区留言支持,不胜感激。

        博文在写作过程中,参考以下,在此表示表示:

        1、shapefile与字符集编码设置。

        2、java gdal 创建shapefile属性中文乱码。

        3、shapefile与字符集编码设置。

        4、GeoTools读取shp文件中文乱码解决方案汇总。

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

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

相关文章

分布式锁优化之 使用lua脚本改造分布式锁保证判断和删除的原子性(优化之LUA脚本保证删除的原子性)

文章目录 1、lua脚本入门1.1、变量&#xff1a;弱类型1.2、流程控制1.3、在lua中执行redis指令1.4、实战&#xff1a;先判断是否自己的锁&#xff0c;如果是才能删除 2、AlbumInfoApiController --》testLock()3、AlbumInfoServiceImpl --》testLock() 1、lua脚本入门 Lua 教程…

Linux基础命令以及常识

镜像站点服务器&#xff08;相当于下载的网址&#xff09;也可叫软件源 vim /etc/apt/sources.list 索引文件(网络服务器在本地的缓存) 服务器软件源在本地列出来一个清单&#xff0c;以便于主机进行查询操作 cd /var/lib/apt/lists/ 下载软件包默认存放路径 cd /var/cache/a…

认识NDK

什么是NDK&#xff08;Native Development Kit&#xff09; The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C. &emdp; Android NDK 是一个工具集&#xff0c;可让您使用 C 和 C 等语言以原生代…

重型工程车辆数据集

重型工程车辆数据集&#xff0c;内含Bull_dozer&#xff08;推土机&#xff09;, Dumb_truck&#xff08;卡车&#xff09;, Excavator&#xff08;挖掘机&#xff09;, Grader&#xff08;平地机&#xff09;, Loader&#xff08;转载机&#xff09;, Mobile_crane&#xff08…

『功能项目』QFrameWork拾取道具UGUI【69】

本章项目成果展示 我们打开上一篇68QFrameWork扔到地上UGUI的项目&#xff0c; 本章要做的事情是实现当物品在地上时&#xff0c;点击物品将对应物品转移到道具栏中 制作一个提示UI界面 添加Button组件设置为点击即将父物体隐藏 拖拽到文件夹中在场景中删除 创建脚本&#xf…

架构师:使用 Zookeeper 实现分布式锁的技术指南

1、简述 在分布式系统中,多个节点可能需要访问共享资源或执行需要互斥的操作,为了避免竞争导致数据不一致或资源争用,我们需要一种机制来协调各个节点对资源的访问。分布式锁是用于解决这种竞争问题的关键技术,它确保在同一时间只有一个节点能够访问或修改共享资源。 2、Z…

Ansible部署与应用基础

由于互联网的快速发展导致产品更新换代速度逐步增长&#xff0c;运维人员每天都要进行大量的维护操作&#xff0c;按照传统方式进行维护使得工作效率低下。这时部署自动化运维就 可以尽可能安全、高效的完成这些工作。 一、Ansible概述 1.什么是Ansible Ansible 是基于 Pytho…

Matplotlib绘图基础

1、散点图 绘制散点图是数据可视化中非常常见的操作&#xff0c;它用于显示两组数据之间的关系。Matplotlib 提供了 plt.scatter() 函数&#xff0c;可以轻松绘制散点图。以下是一个基础的散点图示例代码&#xff0c;并包含了一些优化可视化呈现的技巧。 import matplotlib.p…

Python 如何调用讯飞星火大模型API

1 讯飞星火简介 讯飞星火是科大讯飞推出的一款先进的人工智能大模型&#xff0c;它具备强大的语言理解和知识问答能力&#xff0c;能够在多种场景中提供智能化服务。2024年6月27日&#xff0c;科大讯飞发布了讯飞星火大模型V4.0版本&#xff0c;全面对标GPT-4 Turbo。现有的模…

某采招网爬虫数据采集逆向

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 目标网站 aHR0cHM6Ly9zZWFyY2guYmlkY2VudGVyLmNvbS5jbi9zZWFyY2g/a2V5d29yZHM9JWU0…

医院伤员消费点餐限制———未来之窗行业应用跨平台架构

一、点餐上限 医院点餐上限具有以下几方面的意义&#xff1a; 1. 控制成本 - 有助于医院合理规划餐饮预算&#xff0c;避免食物的过度供应造成浪费&#xff0c;从而降低餐饮成本。 2. 保障饮食均衡 - 防止患者或陪护人员过度点餐某一类食物&#xff0c;有利于引导合…

基于51单片机的两路电压检测(ADC0808)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;通过ADC0808获取两路电压&#xff0c;通过LCD1602显示 二、硬件资源 基于KEIL5编写C代码&#xff0c;PROTEUS8.15进行仿真&#xff0c;全部资源在页尾&#xff0c;提供…

大数据Flink(一百二十三):五分钟上手Flink MySQL连接器

文章目录 五分钟上手Flink MySQL连接器 一、创建数据库表 二、​​​​​​创建session集群 三、源表查询 四、​​​​​窗口计算 五、​​​​​​结果数据写回数据库 五分钟上手Flink MySQL连接器 MySQL Connector可以将本地或远程的MySQL数据库连接到Flink中&#x…

【Spring Cloud Alibaba】Nacos

【Spring Cloud Alibaba】Nacos 1. 什么是Nacos&#xff0c;它都能干什么&#xff1f;1.1 注册中心演变及其思想1.2 Nacos Discovery1.3 远程调用流程图1.4 一个微服务的流程1.4 常用注册中心对比 2. Nacos Server部署3. Nacos Client搭建附录 1. 什么是Nacos&#xff0c;它都能…

科研绘图系列:R语言误差连线图(errobar linechart)

文章目录 介绍加载R包导入数据数据预处理画图系统信息介绍 误差连线图是一种在数据可视化中常用的图表,它通过在数据点处添加线段(误差线)来表示数据的变异性或不确定性。这些误差线可以基于不同的统计度量,如标准差(Standard Deviation)、标准误差(Standard Error)或…

docker操作的基本命令加容器的基本命令(仅供自己参考)

1、docker build&#xff1a;本地将一个docker文件打包成镜像 2、docker push&#xff1a;将自己打包的镜像传到镜像服务器上 3、docker pull&#xff1a;将镜像服务器上的镜像拉取到本地 4、docker images&#xff1a; 查看镜像服务器上的镜像 5、docker rmi&#xff1a;删…

lte sss加扰序列c产生 MATLAB和c语言实现

参考3GPP 36.211 今日给大家介绍一下LTE SSS信号产生过程中加扰序列c的产生过程以及用MATLAB 和 c语言给大家实现一下&#xff1a; 加扰序列c产生过程如下&#xff1a; 1 首先产生公共的序列x的生成 X的初始值 两个加扰序列c0和c1 c语言实现 void lte_sss_gen_c(char *c,u…

初始Vitis——ZYNQ学习笔记1

一、Vitis是什么 Vitis 统一软件平台的前身为 Xilinx SDK&#xff0c;从 Vivado 2019.2 版本开始&#xff0c; Xilinx SDK 开发环境已统一整合到全功能一体化的 Vitis 中。 Vitis 开发平台除了启动方式、软件界面、使用方法与 SDK 开发平台略有区别&#xff0c;其他操作几乎一模…

针对 Linux SSH 服务器的新攻击:Supershell 恶意软件危害易受攻击的系统

ASEC 研究人员发现了针对保护不善的 Linux SSH 服务器的新攻击。 在其中&#xff0c;黑客使用了用Go编写的 Supershell恶意软件。 该后门使攻击者能够远程控制受感染的系统。 初次感染后&#xff0c;黑客启动扫描仪来寻找其他易受攻击的目标。 据信这些攻击是使用从已受感…

【多模态大模型】Qwen2-VL基本原理和推理部署实战

文章目录 Qwen2-VL基本原理Qwen-VL简要回顾Qwen2-VL的高级升级统一视觉处理方式原生动态分辨率处理&#xff08;非大图切分方式&#xff09;多模态旋转位置编码 Qwen2-VL推理实现|代码解析单图推理视觉信息预处理找到能被28整除的最合适size最大最小pixel数边界处理 多模态信息…