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

news2024/9/25 5:23:43

前言

        在之前的博客中,我们讲过在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);
	// 获取SRID
	String 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.coloradmin.cn/o/2162555.html

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

相关文章

BERT训练之数据集处理(代码实现)

目录 1读取文件数据 2.生成下一句预测任务的数据 3.预测下一个句子 4.生成遮蔽语言模型任务的数据 5.从词元中得到遮掩的数据 6.将文本转化为预训练数据集 7.封装函数类 8.调用 import os import random import torch import dltools 1读取文件数据 def _read_wiki(data_d…

Java框架学习(Spring)(ioc)(01)

简介&#xff1a;以本片记录在尚硅谷学习ssm-spring-ioc时遇到的小知识 详情移步&#xff1a;想参考的朋友建议全部打开相互配合学习&#xff01; 视频&#xff1a; 014-spring-框架概念理解_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1AP411s7D7?p14&vd_sou…

SpringBoot框架在文档管理中的创新应用

第3章 系统分析 3.1 需求分析 在线文档管理系统主要是为了提高工作人员的工作效率和更方便快捷的满足员工&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑员工的可操作性&#xff0c;遵循…

峟思助力堤防工程安全:构建多功能防洪屏障

堤防工程&#xff0c;作为水利建设中至关重要的防护体系&#xff0c;不仅守护着江河、湖泊及滨海区域的安全&#xff0c;更是确保人民生命财产安全的坚固防线。在现代社会&#xff0c;随着技术的进步与安全意识的提升&#xff0c;堤防工程不仅限于传统的防洪功能&#xff0c;更…

SpringBoot和JPA初探

目录 SpringBoot和JPA初探0.准备条件1.创建JPA项目2.项目3.总结 SpringBoot和JPA初探 我们使用SpringBootJPA做一个简单的API接口演示&#xff0c;通过一个简单的例子让大家对Spring Data JPA有一个整体的认知。 0.准备条件 IntelliJ IDEAjdk 1.8mysql 8.0maven 3.8.x 1.创…

代码随想录算法训练营第三十九天 | 198.打家劫舍 ,213.打家劫舍II,337.打家劫舍III

第三十九天打卡&#xff0c;今天解决打家劫舍系列问题&#xff0c;树形dp比较难。 198.打家劫舍 题目链接 解题过程 dp[i]&#xff1a;考虑下标i&#xff08;包括i&#xff09;以内的房屋&#xff0c;最多可以偷窃的金额为dp[i]。 要么不偷这一间&#xff0c;那就是前面那间…

开源链动 2+1 模式、AI 智能名片与 S2B2C 商城小程序:以问题解决为导向的盈利新模式

摘要&#xff1a;本文探讨了问题解决盈利模式的重要性&#xff0c;并结合开源链动 21 模式、AI 智能名片以及 S2B2C 商城小程序等创新工具&#xff0c;阐述了如何以用户为中心&#xff0c;通过深刻洞察用户需求&#xff0c;解决用户问题&#xff0c;实现盈利增长。强调了在当今…

[利用python进行数据分析01] “来⾃Bitly的USA.gov数据” 分析出各个地区的 windows和非windows用户

2011 年&#xff0c; URL 缩短服务 Bitly 跟美国政府⽹站 USA.gov 合作&#xff0c;提供 了⼀份从⽣成 .gov 或 .mil 短链接的⽤户那⾥收集来的匿名数据。 在 2011 年&#xff0c;除实时数据之外&#xff0c;还可以下载⽂本⽂件形式的每⼩时 快照。 数据集下载&#xff1a;通…

LabVIEW项目编码器选择

在LabVIEW项目中&#xff0c;选择增量式&#xff08;Incremental Encoder&#xff09;和绝对式&#xff08;Absolute Encoder&#xff09;编码器取决于项目的具体需求。增量式编码器和绝对式编码器在工作原理、应用场景、精度和成本等方面存在显著差异。以下从多方面详细阐述两…

通过service访问Pod

假设Pod中的容器可能因为各种原因发生故障而死掉&#xff0c;Deployment等controller会通过动态创建和销毁Pod来保证应用整体的健壮性&#xff0c;换句话说&#xff0c;Pod是脆弱的&#xff0c;但应用是健壮的 每个Pod都有自己的Ip&#xff0c;当controller用新的Pod替代发生故…

SDK(2 note)

复习上一次内容&#xff1a; 把前一次笔记中的代码&#xff0c;简写一下 #include <windows.h> #include<tchar.h> #include <stdio.h> #include <strsafe.h> VOID showerrormassage() {LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFF…

TS-AI:一种用于多模态个体化脑区划分的深度学习管道,并结合任务对比合成|文献速递-Transformer架构在医学影像分析中的应用

Title 题目 TS-AI: A deep learning pipeline for multimodal subject-specific parcellation with task contrasts synthesis TS-AI&#xff1a;一种用于多模态个体化脑区划分的深度学习管道&#xff0c;并结合任务对比合成 01 文献速递介绍 人类大脑在结构和功能组织上表…

nfs版本问题导致挂载失败

一、系统环境 环境版本操作系统Linux Mint 22 Wilma内核版本6.8.0-44-genericgcc 版本arm-none-linux-gnueabihf-gcc (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025uboot 版本2020.01开发板Linux版本5.4.31 二、问题描述 内核通过…

拒绝信息泄露!VMD滚动分解 + Informer-BiLSTM并行预测模型

前言 在时间序列预测任务中&#xff0c;像 EMD&#xff08;经验模态分解&#xff09;、CEEMDAN&#xff08;完全集合经验模态分解&#xff09;、VMD&#xff08;变分模态分解&#xff09; 等分解算法的使用有可能引入信息泄露&#xff0c;具体情况取决于这些方法的应用方式。信…

通过WebTopo在ARMxy边缘计算网关上实现系统集成

随着工业互联网技术的发展&#xff0c;边缘计算成为了连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。边缘计算网关作为数据采集、处理与传输的核心设备&#xff0c;在智能制造、智慧城市等领域发挥着关键作用。 1. BL340系列概述 BL340系列是基于全志科技T507-…

yolov8/9关键点检测模型检测俯卧撑动作并计数【源码免费+数据集+python环境+GUI系统】

yolov89模型检测俯卧撑动作并计数【源码免费数据集python环境GUI系统】 yolov8/9关键点检测模型检测俯卧撑动作并计数【源码免费数据集python环境GUI系统】 YOLO算法原理 YOLO&#xff08;You Only Look Once&#xff09;关键点检测的算法原理主要基于YOLO目标检测算法进行改进…

R包:VennDiagram韦恩图

加载R包 library(VennDiagram)数据 # Prepare character vectors v1 <- c("DKK1", "NPC1", "NAPG", "ERG", "VHL", "BTD", "MALL", "HAUS1") v2 <- c("SMAD4", "DKK1…

VMware虚拟网络的连接模式探究与实践

VMware安装完成虚拟机后&#xff0c;大多要进行网络配置&#xff0c;实现网络的互联互联&#xff0c;初学者往往感觉与一台实体主机的网络配置不同&#xff0c;局域网中一台实体主机一个物理网卡&#xff0c;配置一个IP地址&#xff1b;或直接通过WAN上网&#xff0c;比较直观&…

基于python的django微博内容网络分析系统,实现文本划分词结构

本项目旨在开发一个基于Python的Django框架的微博内容网络分析系统&#xff0c;聚焦于微博文本的分词处理、名词提取和主成分分析。该系统通过数据收集与预处理、分词及结构化文本分析&#xff0c;为舆情监测、话题分析和用户行为研究提供了一体化的解决方案。 主要功能包括&a…

数据分析学习之学习路线

前言 我们之前通过cda认证了解到数据分析行业&#xff0c;但是获取到证书&#xff0c;并不代表着&#xff0c;我们已经拥有的数据分析的能力&#xff0c;所以通过系统的学习数据分析需要掌握的能力&#xff0c;并学习大佬们的分析经验、分析思路&#xff0c;才是成为数据分析师…