gis利器之Gdal(二)shp数据读取
本文将简单介绍shp数据的基本知识,以java语言为例,介绍如何基于java调用gdal完成对shp数据的解析,主要包括空间信息解析、属性信息解析、空间参考信息解析,bbox信息解析等等。
shp文件是一种矢量图形存储文件,可以用于记录矢量数据的空间位置及属性信息。shp是arcgis的常见数据格式,当前,现在许多的开源库也是可以解析的,包括本文要介绍的gdal和geotools都是具备这种能力的。
SHP文件是一种比较原始的矢量数据存储方式,它仅仅能够存储几何体的位置数据,而无法在一个文件之中同时存储这些几何体的属性数据。因此,SHP文件还必须附带一个二维表用于存储文件中每个几何体的属性信息。SHP文件中许多几何体能够代表复杂的地理事物,并为他们提供强大而精确的计算能力。
SHP文件指的是一种文件存储的方法,实际上该种文件格式是由多个文件组成的。其中,要组成一个SHP文件,有三个文件是必不可少的,它们分别是".shp", ".shx"与 ".dbf" 文件。表示同一数据的一组文件其文件名前缀应该相同。例如,存储一个关于湖的几何与属性数据,就必须有lake.shp,lake.shx与 lake.dbf三个文件。而其中“真正”的Shapefile的后缀为shp,然而仅有这个文件数据是不完整的,必须要把其他两个附带上才能构成一组完整的地理数据。除了这三个必需的文件以外,还有八个可选的文件,使用它们可以增强空间数据的表达能力。所有的文件名都必须遵循MS DOS的8.3文件名标准(文件前缀名8个字符,后缀名3个字符,如shapefil.shp),以方便与一些老的应用程序保持兼容性,尽管现在许多新的程序都能够支持长文件名。此外,所有的文件都必须位于同一个目录之中。
shp文件的常见目录如下图所示:
使用QGIS打开shp数据后可以看到空间信息和属性信息如下:
这里看到的乱码,设置好编码后即可。
下面使用gdal解析以上信息。
第一步、新建maven工程,pom.xml配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.yelang</groupId> <artifactId>gdal_demo1</artifactId> <version>0.0.1-SNAPSHOT</version> <name>gdal_demo1</name> <description>gdal的第一次试验</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.gdal</groupId> <artifactId>gdal</artifactId> <version>3.4.3</version> <scope>system</scope> <systemPath>${project.basedir}/lib/gdal.jar</systemPath> </dependency> <dependency> <groupId>net.sf.ucanaccess</groupId> <artifactId>ucanaccess</artifactId> <version>4.0.4</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
第二步、ogr全局注册和gdal配置设置
// 指定文件的名字和路径 String strVectorFile = "F:\\vector_data\\道路中心线.shp"; // 注册所有的驱动 ogr.RegisterAll(); // 为了支持中文路径,请添加下面这句代码 gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 为了使属性表字段支持中文,请添加下面这句 gdal.SetConfigOption("SHAPE_ENCODING", "CP936");
以上设置,不管是操作shp还是其它矢量数据,基本上是必需流程,采用RegisterAll()注册驱动,使用SetConfigOption进行关键参数设置。
第三步、获取shp驱动,打开shp文件。
// 读取数据,这里以ESRI的shp文件为例 String strDriverName = "ESRI Shapefile"; // 创建一个文件,根据strDriverName扩展名自动判断驱动类型 org.gdal.ogr.Driver oDriver = ogr.GetDriverByName(strDriverName); if (oDriver == null) { System.out.println(strDriverName + " 驱动不可用!\n"); return; } DataSource dataSource = oDriver.Open(strVectorFile);
第四步、获取图层、空间参考、图层范围
//Layer layer = dataSource.GetLayer("test"); Layer layer = dataSource.GetLayer(0); for(int i = 0;i<dataSource.GetLayerCount();i++) { Layer layerIdx = dataSource.GetLayer(i); System.out.println("图层名称:<==>" + layerIdx.GetName()); } String layerName = layer.GetName(); System.out.println("图层名称:" + layerName); SpatialReference spatialReference = layer.GetSpatialRef(); //System.out.println(spatialReference); System.out.println("空间参考坐标系:" + spatialReference.GetAttrValue("AUTHORITY", 0) + spatialReference.GetAttrValue("AUTHORITY", 1)); double[] layerExtent = layer.GetExtent(); System.out.println("图层范围:minx:" + layerExtent[0] + ",maxx:" + layerExtent[1] + ",miny:" + layerExtent[2] + ",maxy:" + layerExtent[3]);
第五步、获取图层属性信息
FeatureDefn featureDefn = layer.GetLayerDefn(); int fieldCount = featureDefn.GetFieldCount(); Map<String,String> fieldMap = new HashMap<String,String>(); for (int i = 0; i < fieldCount; i++) { FieldDefn fieldDefn = featureDefn.GetFieldDefn(i); // 得到属性字段类型 int fieldType = fieldDefn.GetFieldType(); String fieldTypeName = fieldDefn.GetFieldTypeName(fieldType); // 得到属性字段名称 String fieldName = fieldDefn.GetName(); fieldMap.put(fieldTypeName, fieldName); } System.out.println(fieldMap);
输出如下:
{Integer=OBJECTID, Real=SHAPE_Leng, String=GB, Date=Date_}
第六步、读取空间空间信息及属性列表
System.out.println(layer.GetFeature(1).GetGeometryRef().ExportToJson()); System.out.println(layer.GetFeature(2).GetGeometryRef().ExportToJson()); System.out.println(layer.GetFeature(3).GetGeometryRef().ExportToJson()); for (int i = 0; i < featureCount; i++) { Feature feature = layer.GetFeature(i); Object[] arr = fieldMap.values().toArray(); for (int k = 0; k < arr.length; k++) { String fvalue = feature.GetFieldAsString(arr[k].toString()); System.out.println(" 属性名称:" + arr[k].toString() + ",属性值:" + fvalue); } }
小结:本文首先简单介绍了空间数据shp数据的基本知识,其常见的文件组成形式。使用qgis软件对数据进行常规预览,最后重点介绍了使用gdal对矢量信息进行读取,包括空间信息和属性信息,希望本文对你有帮助。
- 点赞
- 收藏
- 关注作者
评论(0)