使用Java基于GeoTools读取Shapefile矢量数据属性信息-以某市POI数据为例

前言

        在之前的博客中,我们讲过在GDAL中如何读取空间数据的属性和数据信息,也简单的讲过如何在GeoTools中读取Shapefile文件的属性信息和数据信息。对于空间矢量数据库,就像我们传统的二维数据库的表字段和表数据的关系,在研究表数据的存储和检索时,通常会配套进行空间表表结构的设计。众所周知,在关系型数据库中,关于数据库物理模型的建设至关重要,因此在空间数据存储也是同样的重要。

        本文主要研究使用Java开发语言基于GeoTools地理开发组件来进行空间矢量数据如Shapefile的属性信息的读取,文章首先介绍如何使用GeoTools来打开一个shp文件,在QGIS中展示原始数据的相关信息,然后讲解如何通过GeoTools获取shp文件的空间参考,接着讲解根据空间参考获取我们常见的空间参考编码和代号,其次讲解如何获取空间数据的属性字段。通过本文,您可以了解和掌握如何利用GeoTools来进行Shapefile的属性信息的读取。

一、空间数据说明

        最近开始研究POI数据,因此从互联网获取了POI数据,想实现POI数据的空间分布分析。具体使用POI数据来进行空间属性信息的读取演示。为了让大家对POI数据有一定的了解,这里对POI数据进行一个介绍。

1、空间参考

        这里使用的POI数据是2020年形成长沙市的POI数据,时间过去4年,在时间上有一定的时效性不足,但是不影响我们的学习使用。我们使用Qgis软件打开上面的POI信息之后,我们可以打开数据信息看一下它的空间参考。

        通过上面的截图就可以了解这份空间矢量数据的基础信息,如下表所示: 

序号参数说明
1

编码

UTF-8
2几何图形

Point (Point)

3

坐标参照系(CRS)

EPSG:4490 - China Geodetic Coordinate System 2000 - 地理的

4范围

111.9064691681707870,27.8943275145980074 : 114.2292192675388947,28.6342571928722691

5单位
6要素数量

1848

        以上就是空间参考和编码等基础信息。

2、空间属性字段

        在了解了POI数据的基本信息后,我们还需要了解shapefile的的属性信息,这就好比是关系型数据库的字段,需要维护物理模型。因此这里对POI数据涉及的属性字段进行介绍,为下一步的空间物理建模奠定基础。这里依然以QGIS为例,我们在QGIS中可以打开空间数据的字段表,如下所示:

        为了更好的给大家展示这些POI数据,特意将数据集列表的数据进行示例数据的展示,在QGIS鼠标点击右键,打开属性表,可以看到以下的数据:

        以上是对空数据的属性字段和示例数据进行简单介绍。到此本小节的内容介绍完毕,后面将介绍如何使用GeoTools来进行相关编码、空间参考坐标、属性表格的信息读取。 

 二、Geotools读取空间数据属性信息

        在了解了以上的POI空间信息之后,下面我们调用GeoTools来进行空间数据的属性信息的读取。包括如何加载shp文件、如何获取空间数据的空间参考以及如何获取矢量数据的属性信息列表,如属性名等信息。

1、如何加载空间信息

        在介绍如何使用GeoTools来进行空间信息加载时,必须要介绍必须要设置的Pom.xml来加载相关的依赖,关于Geotools的相关引用如下所示,为了节约篇幅,这里仅列出关键部分:

<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><!-- https://mvnrepository.com/artifact/org.geotools.xsd/gt-xsd-sld --><dependency><groupId>org.geotools.xsd</groupId><artifactId>gt-xsd-sld</artifactId><version>${geotools.version}</version><!--  <version>31.3</version><scope>test</scope>--></dependency><!-- https://mvnrepository.com/artifact/org.geotools.xsd/gt-xsd-core --><dependency><groupId>org.geotools.xsd</groupId><artifactId>gt-xsd-core</artifactId><version>${geotools.version}</version></dependency><!-- https://mvnrepository.com/artifact/org.geotools/gt-xml --><dependency><groupId>org.geotools</groupId><artifactId>gt-xml</artifactId><version>${geotools.version}</version></dependency>

        在Java中读取Shapefile的方式有几种,这里分享一种方式,后面我们可以详细的来介绍不同的打开方式,其实大致的原理都是差不多的。

2、关于空间参考

        这里想分享一个注意的地方,众所周知,在空间计算中,空间参考是一个很重要的标准。我们很多的空间分析都是建立在空间参考之上的。因此首先来介绍一下空间参考信息,首先我们先不修改上面的maven引用,您也可以直接在代码中执行以下的代码:

/**
* gt-epsg-hsql 这里一定要引入epsg的包,这样才能读取相关的信息,否则报错
* 
* @throws NoSuchAuthorityCodeException
* @throws FactoryException
*/
@Test
public void testEpsg() throws NoSuchAuthorityCodeException, FactoryException {CoordinateReferenceSystem tCrs = CRS.decode("EPSG:4490");System.out.println(tCrs);System.out.println("*************************************************");String code = CRS.lookupIdentifier(tCrs, true);System.out.println("code==>" + code);System.out.println("**************************************************");Integer epsgCode = CRS.lookupEpsgCode(tCrs, true);if (epsgCode != null) {System.out.println("EPSG Code: " + epsgCode);} else {System.out.println("EPSG Code not found.");}
}

        这里是获取默认的4490的EPSG空间参考,同时可以获取它对应的代码如:EPSG:4490。运行上述的代码之后,我们发现控制台并没有进行正常的展示,会报以下的错误。

        详细的错误信息如下:

org.opengis.referencing.NoSuchAuthorityCodeException: No code "EPSG:4490" from authority "EPSG" found for object of type "EngineeringCRS".at org.geotools.referencing.factory.epsg.CartesianAuthorityFactory.noSuchAuthorityException(CartesianAuthorityFactory.java:140)at org.geotools.referencing.factory.epsg.CartesianAuthorityFactory.createEngineeringCRS(CartesianAuthorityFactory.java:132)at org.geotools.referencing.factory.epsg.CartesianAuthorityFactory.createCoordinateReferenceSystem(CartesianAuthorityFactory.java:123)at org.geotools.referencing.factory.AuthorityFactoryAdapter.createCoordinateReferenceSystem(AuthorityFactoryAdapter.java:811)at org.geotools.referencing.factory.ThreadedAuthorityFactory.createCoordinateReferenceSystem(ThreadedAuthorityFactory.java:667)at org.geotools.referencing.DefaultAuthorityFactory.createCoordinateReferenceSystem(DefaultAuthorityFactory.java:178)at org.geotools.referencing.CRS.decode(CRS.java:538)at org.geotools.referencing.CRS.decode(CRS.java:459)at com.yelang.project.geotools.TestReadPoiShpWriter2Db.testEpsg(TestReadPoiShpWriter2Db.java:216)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)at org.junit.runners.ParentRunner.run(ParentRunner.java:413)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

        如果你也遇到这个问题,只需要在pom.xml中加入如下依赖:

<!--  增加epsg支持 -->
<dependency><groupId>org.geotools</groupId><artifactId>gt-epsg-hsql</artifactId><version>${geotools.version}</version>
</dependency> 

        在此运行,可以在控制台看到问题解决了。

GEOGCS["China Geodetic Coordinate System 2000", DATUM["China 2000", SPHEROID["CGCS2000", 6378137.0, 298.257222101, AUTHORITY["EPSG","1024"]], AUTHORITY["EPSG","1043"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic latitude", NORTH], AXIS["Geodetic longitude", EAST], AUTHORITY["EPSG","4490"]]
*************************************************
code==>EPSG:4490
**************************************************
EPSG Code: 4490

3、加载shp文件

        这里讲解如何加载shp文件,geotools中加载shp文件的方法很多,这里分享一种方式,关键代码如下所示:

// 指定Shapefile的文件路径
String shpFile = "C:/BaiduDownload/长沙市2020年POI数据集/长沙市2020年POI数据集/长沙POI数据(.shp)/风景名胜.shp";
FileDataStore dataStore = FileDataStoreFinder.getDataStore(new File(shpFile));ShapefileDataStore shapefileDataStore = new ShapefileDataStore(new File(shpFile).toURI().toURL());
System.out.println(shapefileDataStore.getCharset());
String[] typeNames = dataStore.getTypeNames();
System.out.println(typeNames.length);
for (String type : typeNames) {System.out.println(type);
}

        我们通过FileDataStore来加载shp数据,然后通过ShapefileDataStore来设置文件的字符编码。然后我们通过getTypeNames来获取图层信息。

4、属性字段的读取

        在GeoTools中,使用SimpleFeatureType对象类获取矢量数据的属性描述信息,下面讲解如何使用GeoTools来读取矢量信息的属性字段。完整的代码如下:

@Test
public void readShpAttr() throws IOException, FactoryException {// 指定Shapefile的文件路径String shpFile = "C:/BaiduDownload/长沙市2020年POI数据集/长沙市2020年POI数据集/长沙POI数据(.shp)/风景名胜.shp";FileDataStore dataStore = FileDataStoreFinder.getDataStore(new File(shpFile));ShapefileDataStore shapefileDataStore = new ShapefileDataStore(new File(shpFile).toURI().toURL());System.out.println(shapefileDataStore.getCharset());String[] typeNames = dataStore.getTypeNames();System.out.println(typeNames.length);for (String type : typeNames) {System.out.println(type);}// 获取特征类型SimpleFeatureType featureType = dataStore.getSchema(dataStore.getTypeNames()[0]);CoordinateReferenceSystem crs = featureType.getGeometryDescriptor().getCoordinateReferenceSystem();System.out.println("坐标参考系统:" + crs);// 获取SRIDString code = CRS.lookupIdentifier(crs, true);System.out.println("EPSG CODE :" + code);// 获取属性名List<String> attributeNames = featureType.getAttributeDescriptors().stream().map(attr -> attr.getLocalName()).collect(Collectors.toList());System.out.println("Attributes: " + attributeNames);System.out.println("以下是属性信息的深度解析:--------------------------------------");List<AttributeDescriptor> attrDescList = featureType.getAttributeDescriptors();System.out.println(attrDescList.size());for (AttributeDescriptor attrDesc : attrDescList) {System.out.println(attrDesc);System.out.println("属性详情:");AttributeType attrType = attrDesc.getType();System.out.println(attrType);System.out.println("name=" + attrDesc.getName() + "\tLocalName=" + attrDesc.getLocalName() + "\t"+ attrDesc.getMaxOccurs() + "\t" + attrDesc.getMinOccurs());System.out.println("UserData" + attrDesc.getUserData());}
}

        可以看到,上面读取的信息与在QGIS中展示的信息是一致的,说明我们已经成功的读取了POI数据的空间参考、属性信息等重要信息。

 三、总结

        以上就是本文的主要内容,本文主要研究使用Java开发语言基于GeoTools地理开发组件来进行空间矢量数据如Shapefile的属性信息的读取,文章首先介绍如何使用GeoTools来打开一个shp文件,在QGIS中展示原始数据的相关信息,然后讲解如何通过GeoTools获取shp文件的空间参考,接着讲解根据空间参考获取我们常见的空间参考编码和代号,其次讲解如何获取空间数据的属性字段。通过本文,您可以了解和掌握如何利用GeoTools来进行Shapefile的属性信息的读取。行文仓促,定有不足之处,如有不足,还请各位专家博主在评论区留下真知灼见,不胜感激。

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

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

相关文章

14 vue3之内置组件trastion全系列

前置知识 Vue 提供了 transition 的封装组件&#xff0c;在下列情形中&#xff0c;可以给任何元素和组件添加进入/离开过渡: 条件渲染 (使用 v-if)条件展示 (使用 v-show)动态组件组件根节点 自定义 transition 过度效果&#xff0c;你需要对transition组件的name属性自定义。…

jupyter安装与使用——Ubuntu服务器

jupyter安装与使用——Ubuntu服务器 一、安装miniconda3/anaconda31. 下载miniconda32. 安装miniconda33. 切换到bin文件夹4. 输入pwd获取路径5. 打开用户环境编辑页面6. 重新加载用户环境变量7. 初始化conda8.验证是否安装成功9.conda配置 二、安装jupyter2.1 conda安装2.2 配…

国货之光|暴雨携信创新品亮相第八届丝博会

9月20日&#xff0c;第八届丝绸之路国际博览会暨中国东西部合作与投资贸易洽谈会&#xff08;以下简称“丝博会”&#xff09;在西安举行。 本届丝博会以“深化互联互通拓展经贸合作”为主题&#xff0c;会期为9月20日至24日&#xff0c;在西安国际会展中心设置国际交流展、省际…

研一奖学金计划2024/9/23有感

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、需要认真上课的1.应用数理统计&#xff08;开卷考试&#xff09;2.最优化方法&#xff08;开卷考试&#xff09;3.跨文化交际&#xff08;主题演讲20课堂讨…

[系统设计总结] - Proximity Service算法介绍

问题描述 Proximity Service广泛应用于各种地图相关的服务中比如外卖&#xff0c;大众点评&#xff0c;Uber打车&#xff0c;Google地图中&#xff0c;其中比较关键的是我们根据用户的位置来快速找到附近的餐厅&#xff0c;司机&#xff0c;外卖员也就是就近查询算法。 主流的…

小程序面板开发教程|开发照明 Matter 面板步骤(一)

一. 前置知识 前言 出于对 Matter 标准协议及第三方设备接入的可拓展性等方面考虑&#xff0c;照明 Matter 模型面板的功能点定义会与照明的 DP 模型有所不同&#xff0c;因此本文会着重介绍照明 Matter 面板的功能点定义及与 DP 模型的区别&#xff0c;以方便面板小程序开发…

Qt-QLabel 添加图片并设置 GIF 图动态效果

Qt-QLabel 添加图片并设置 GIF 图动态效果 一、添加图片资源并设置图片 选择标签&#xff0c;拖拉到界面上&#xff0c;然后选择器属性 picmap   选择设置&#xff0c;在这里添加图片资源   点击左边的加号符号按钮添加前缀&#xff0c;并设置前缀名&#xff0c;如果已经…

uniapp+renderJS+google map开发安卓版APP非小程序

背景需求 需要在uniapp中接入google地图,研究了一番,都没有找到合适的,现在说一下教程。 效果图 前期工作 这两点缺一不可,否则你啥也看不到。 1、电脑安装L-O-U梯 用于访问G-OO-G-LE的API或者创建google map key。 2、手机安装L-O-U梯 用于显示google地图。我就是手…

数据篇| 关于Selenium反爬杂谈

友情提示:本章节只做相关技术讨论, 爬虫触犯法律责任与作者无关。 LLM虽然如火如荼进行着, 但是没有数据支撑, 都是纸上谈兵, 人工智能的三辆马车:算法-数据-算力,缺一不可。之前写过关于LLM微调文章《微调入门篇:大模型微调的理论学习》、《微调实操一: 增量预训练(Pretrai…

USB 电缆中的信号线 DP、DM 的缩写由来

经常在一些芯片的规格书中看到 USB 的信号对是以 DP 和 DM 命名&#xff1a; 我在想&#xff0c;这些规格书是不是写错了&#xff0c;把 N 写成 M 了&#xff1f;DM 中的 M 到底是什么的缩写&#xff1f; 于是我找了一些资料&#xff0c;终于在《Universal Serial Bus Cables …

xilinx hbm ip运用

AXI-HBM是一个集成的IP核&#xff0c;该核提供高达16个AXI3从PORT的HBM接口&#xff0c;每个使用他自己的独立的时钟。HBM2 GEN存储器也支持&#xff0c;HBM相对传统DDR的方案&#xff0c;带宽得到极大的提高 特征 AXI3从端口存储器接口 -16个独立的256bit存储器接口 -可选的…

Why Is Prompt Tuning for Vision-Language Models Robust to Noisy Labels?

文章汇总 本文的作者针对了提示学习的结构设计进行了分析&#xff0c;发现了一些规律&#xff1a; 1)固定的类名令牌为模型的优化提供了强正则化&#xff0c;减少了由噪声样本引起的梯度。 2)从多样化和通用的web数据中学习到的强大的预训练图像文本嵌入为图像分类提供了强大…

FreeRTOS学习——接口宏portmacro.h

FreeRTOS学习——接口宏portmacro.h&#xff0c;仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 portmacro版本&#xff1a;GCC/ARM_CM7 portmacro.h是什么 portmacro.h头文件&#xff0c;用于定义与特定硬件平台相关的数据类型和常量。 在移植过程中&#xff0c;…

stm32 keil有一些别人的工程在你这打开为什么会乱码?如何解决的

因为别人编辑代码使用的编辑器和你的不一样&#xff0c;要更正可以调一下自己的翻译器编码格式 也可以直接换掉文件的格式&#xff0c; 用记事本打开文件&#xff0c;然后点会另存为&#xff0c;下面有个编码格式选择&#xff0c;换成你自己的就行

结构设计模式 -装饰器设计模式 - JAVA

装饰器设计模式 一. 介绍二. 代码示例2.1 抽象构件&#xff08;Component&#xff09;角色2.2 具体构件&#xff08;Concrete Component&#xff09;角色2.3 装饰&#xff08;Decorator&#xff09;角色2.4 具体装饰&#xff08;Concrete Decorator&#xff09;角色2.5 测试 结…

【鸿蒙HarmonyOS NEXT】用户首选项Preference存储数据

【鸿蒙HarmonyOS NEXT】数据存储之用户首选项Preference 一、环境说明二、Preference运作机制三、示例代码加以说明四、小结 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、Preference运作机制 应用场景&#xff1a; 用户首选项为应用提…

模型Alignment之RLHF与DPO

1. RLHF (Reinforcement Learning from Human Feedback) RLHF 是一种通过人类反馈来强化学习的训练方法&#xff0c;它能够让语言模型更好地理解和执行人类指令。 RLHF 的三个阶段 RLHF 的训练过程一般分为三个阶段&#xff1a; 监督微调&#xff08;Supervised Fine-Tuning,…

TensorRT-LLM——优化大型语言模型推理以实现最大性能的综合指南

引言 随着对大型语言模型 (LLM) 的需求不断增长&#xff0c;确保快速、高效和可扩展的推理变得比以往任何时候都更加重要。NVIDIA 的 TensorRT-LLM 通过提供一套专为 LLM 推理设计的强大工具和优化&#xff0c;TensorRT-LLM 可以应对这一挑战。TensorRT-LLM 提供了一系列令人印…

.net core8 使用JWT鉴权(附当前源码)

说明 该文章是属于OverallAuth2.0系列文章&#xff0c;每周更新一篇该系列文章&#xff08;从0到1完成系统开发&#xff09;。 该系统文章&#xff0c;我会尽量说的非常详细&#xff0c;做到不管新手、老手都能看懂。 说明&#xff1a;OverallAuth2.0 是一个简单、易懂、功能强…

YOLOv8——测量高速公路上汽车的速度

引言 在人工神经网络和计算机视觉领域&#xff0c;目标识别和跟踪是非常重要的技术&#xff0c;它们可以应用于无数的项目中&#xff0c;其中许多可能不是很明显&#xff0c;比如使用这些算法来测量距离或对象的速度。 测量汽车速度基本步骤如下&#xff1a; 视频采集&#x…