本文将简单介绍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配置如下:
<projectxmlns="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配置设置
// 指定文件的名字和路径StringstrVectorFile="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文件为例StringstrDriverName="ESRI Shapefile"; // 创建一个文件,根据strDriverName扩展名自动判断驱动类型org.gdal.ogr.DriveroDriver=ogr.GetDriverByName(strDriverName); if (oDriver==null) { System.out.println(strDriverName+" 驱动不可用!\n"); return; } DataSourcedataSource=oDriver.Open(strVectorFile);
第四步、获取图层、空间参考、图层范围
//Layer layer = dataSource.GetLayer("test");Layerlayer=dataSource.GetLayer(0); for(inti=0;i<dataSource.GetLayerCount();i++) { LayerlayerIdx=dataSource.GetLayer(i); System.out.println("图层名称:<==>"+layerIdx.GetName()); } StringlayerName=layer.GetName(); System.out.println("图层名称:"+layerName); SpatialReferencespatialReference=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]);
第五步、获取图层属性信息
FeatureDefnfeatureDefn=layer.GetLayerDefn(); intfieldCount=featureDefn.GetFieldCount(); Map<String,String>fieldMap=newHashMap<String,String>(); for (inti=0; i<fieldCount; i++) { FieldDefnfieldDefn=featureDefn.GetFieldDefn(i); // 得到属性字段类型intfieldType=fieldDefn.GetFieldType(); StringfieldTypeName=fieldDefn.GetFieldTypeName(fieldType); // 得到属性字段名称StringfieldName=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 (inti=0; i<featureCount; i++) { Featurefeature=layer.GetFeature(i); Object[] arr=fieldMap.values().toArray(); for (intk=0; k<arr.length; k++) { Stringfvalue=feature.GetFieldAsString(arr[k].toString()); System.out.println(" 属性名称:"+arr[k].toString() +",属性值:"+fvalue); } }
小结:本文首先简单介绍了空间数据shp数据的基本知识,其常见的文件组成形式。使用qgis软件对数据进行常规预览,最后重点介绍了使用gdal对矢量信息进行读取,包括空间信息和属性信息,希望本文对你有帮助。