World Wind Java开发之六——解析shape文件(上)

最近一直忙于导师项目的事情了,几天没更新了,昨天和今天研究了下WWJ解析shp文件的源代码,现在记录下,希望可以帮到更多的人!

上一篇博客:World Wind Java开发之五——读取本地shp文件只讲了如何加载shp文件,没有涉及到shp文件的解析,我们这篇博客紧接上一篇博客,利用WWJ来解析shp文件。首先来看用到的源码包和相关类,如下图所示。解析shp文件主要用到Shapefile(shapefile文件类)、ShapefileRecord(shape文件记录类)、DBaseRecord类以及DBaseField(字段类)

1、读取shapefile文件

由上图可以看出有要实例化一个shapefile对象有六种方法,以其中的两种为例,看下源码:

(1)

/**
	 * Opens a Shapefile from an InputStream, and InputStreams to its optional
	 * resources.
	 * <p/>
	 * The source Shapefile may be accompanied optional streams to an index
	 * resource stream, an attribute resource stream, and a projection resource
	 * stream. If any of these streams are null or cannot be read for any
	 * reason, the Shapefile opens without that information.
	 * <p/>
	 * This throws an exception if the shapefile's coordinate system is
	 * unsupported.
	 *
	 * @param shpStream
	 *            the shapefile geometry file stream.
	 * @param shxStream
	 *            the index file stream, can be null.
	 * @param dbfStream
	 *            the attribute file stream, can be null.
	 * @param prjStream
	 *            the projection file stream, can be null.
	 * @throws IllegalArgumentException
	 *             if the shapefile geometry stream <code>shpStream</code> is
	 *             null.
	 * @throws WWRuntimeException
	 *             if the shapefile cannot be opened for any reason, or if the
	 *             shapefile's coordinate system is unsupported.
	 */
	public Shapefile(InputStream shpStream, InputStream shxStream,
			InputStream dbfStream, InputStream prjStream)
	{
		this(shpStream, shxStream, dbfStream, prjStream, null);
	}

输入文件流分别对应着.shp .shx .dbf .prj文件

(2)

/**
	 * Opens an Shapefile from a general source. The source type may be one of
	 * the following:
	 * <ul>
	 * <li>{@link java.io.InputStream}</li>
	 * <li>{@link java.net.URL}</li>
	 * <li>{@link File}</li>
	 * <li>{@link String} containing a valid URL description or a file or
	 * resource name available on the classpath.</li>
	 * </ul>
	 * <p/>
	 * The source Shapefile may be accompanied by an optional index file,
	 * attribute file, and projection file. To be recognized by this Shapefile,
	 * accompanying files must be in the same logical folder as the Shapefile,
	 * have the same filename as the Shapefile, and have suffixes ".shx",
	 * ".dbf", and ".prj" respectively. If any of these files do not exist, or
	 * cannot be read for any reason, the Shapefile opens without that
	 * information.
	 * <p/>
	 * This throws an exception if the shapefile's coordinate system is
	 * unsupported, or if the shapefile's coordinate system is unsupported.
	 *
	 * @param source
	 *            the source of the shapefile.
	 * @throws IllegalArgumentException
	 *             if the source is null or an empty string.
	 * @throws WWRuntimeException
	 *             if the shapefile cannot be opened for any reason.
	 */
	public Shapefile(Object source)
	{
		this(source, null);
	}

这种方法秩序给出shp文件的路径即可,但是若只有shp文件,缺少shx等文件则无法解析shape文件。

根据以上两种方法来实例化一个shapefile对象,源码如下:

String shpFilePath = "D:\\Users\\wwj_data\\states.shp";
		String shxFilePath = "D:\\Users\\wwj_data\\states.shx";
		String dbfFilePath = "D:\\Users\\wwj_data\\states.dbf";
		String prjFilePath = "D:\\Users\\wwj_data\\states.prj";

		Shapefile shapefile = new Shapefile(shpFilePath);
		System.out.println(shapefile.getShapeType());

或者:---------------------------------------------------------------------------------------

String shpFilePath = "D:\\Users\\wwj_data\\states.shp";
		String shxFilePath = "D:\\Users\\wwj_data\\states.shx";
		String dbfFilePath = "D:\\Users\\wwj_data\\states.dbf";
		String prjFilePath = "D:\\Users\\wwj_data\\states.prj";

		InputStream shpInputStream = new FileInputStream(shpFilePath);
		InputStream shxInputStream = new FileInputStream(shxFilePath);
		InputStream dbfInputStream = new FileInputStream(dbfFilePath);
		InputStream prjInputStream = new FileInputStream(prjFilePath);

		// 实例化一个shapefile类
		 Shapefile shapefile = new Shapefile(shpInputStream, shxInputStream,
		 dbfInputStream, prjInputStream);
		System.out.println(shapefile.getShapeType()); // shape类型

这里需要说明的一点是,一开始的时候我是用的Shapefile(Object source)方法,但是报错:Source is NULL,不知是什么原因;用下面这种方法就可以,这个可以不必太纠结。

2、获取shapefile文件的属性表信息

在shapefile.java文件中可以找到 attributeFile字段,包含shapefile文件的属性信息,但是其权限是protected,只需在原java文件中添加一个方法返回改字段值即可。改完源码,重新导出jar文件覆盖引用即可。

protected DBaseFile				attributeFile;
/**
	 *
	 * @方法名称: getAttributesTable ;
	 * @方法描述:  获取属性表 ;
	 * @参数 :@return
	 * @返回类型: DBaseFile ;
	 * @创建人:奔跑的鸡丝 ;
	 * @创建时间:2014-12-1 下午12:55:33;
	 * @throws
	 */
	public DBaseFile getAttributesTable()
	{
		return this.attributeFile;
	}

获取属性表后,首先要获取属性表的基本信息,如:shape文件的类型、字段个数以及记录个数。另外输出所有字段名

	// 获取shp属性表
		DBaseFile dBaseFile = shapefile.getAttributesTable();
		int fieldCount = dBaseFile.getNumberOfFields(); // 字段数
		int recordsCount = dBaseFile.getNumberOfRecords(); // 记录数
		System.out.println("字段数为:" + fieldCount);
		System.out.println("记录数为:" + recordsCount);
		System.out.println(shapefile.getShapeType()); // shape类型
		//获取字段集合
		DBaseField [] dBaseFields=dBaseFile.getFields();

		for (int i = 0; i < fieldCount; i++)
		{
			System.out.println(dBaseFields[i].getName());
		}

运行结果如下:

在ArcMap下打开shp文件的属性表,对比可知输出的结果是正确的。

3、获取字段值

// 解析shape文件
		try
		{
			while (shapefile.hasNext())
			{
				ShapefileRecord record = shapefile.nextRecord(); // 获取一条记录
				DBaseRecord dBaseRecord = record.getAttributes(); // 获取该记录的属性信息

				Object[] values = dBaseRecord.getValues().toArray();//获取字段值集合

				for (int i = 0; i < values.length; i++)
				{
					System.out.println(values[i].toString());
				}
				System.out.println("------------------");
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			System.out.println("解析shapefile文件出错!");
		}
		finally
		{
			WWIO.closeStream(shapefile, shpFilePath);
			WWIO.closeStream(shapefile, shxFilePath);
			WWIO.closeStream(shapefile, dbfFilePath);
			WWIO.closeStream(shapefile, prjFilePath);

		}

思路很简单:shapefile文件—>获取一条记录—>获取记录的属性信息-->获取字段值集合。但是有一个问题:不支持中文字段值

调整后运行结果如下:

ArcMap下的属性表如下图所示:

通过对比,发现字段值虽然都读取了,但是顺序却是乱的。目前还未发现是什么原因,下一篇博客再来解决这个问题字段值与字段不对应的问题。下面给出完整的代码:

/**
	 * @方法名称: shapeFileReader ;
	 * @方法描述: 读取sh文件 ;
	 * @参数 :@throws FileNotFoundException
	 * @返回类型: void ;
	 * @创建人:奔跑的鸡丝 ;
	 * @创建时间:2014-12-1 下午12:50:11;
	 * @throws
	 */
	private void shapeFileReader() throws FileNotFoundException
	{
		String shpFilePath = "D:\\Users\\wwj_data\\states.shp";
		String shxFilePath = "D:\\Users\\wwj_data\\states.shx";
		String dbfFilePath = "D:\\Users\\wwj_data\\states.dbf";
		String prjFilePath = "D:\\Users\\wwj_data\\states.prj";

		InputStream shpInputStream = new FileInputStream(shpFilePath);
		InputStream shxInputStream = new FileInputStream(shxFilePath);
		InputStream dbfInputStream = new FileInputStream(dbfFilePath);
		InputStream prjInputStream = new FileInputStream(prjFilePath);

		// 实例化一个shapefile类
		 Shapefile shapefile = new Shapefile(shpInputStream, shxInputStream,
		 dbfInputStream, prjInputStream);

		// 获取shp属性表
		DBaseFile dBaseFile = shapefile.getAttributesTable();
		int fieldCount = dBaseFile.getNumberOfFields(); // 字段数
		int recordsCount = dBaseFile.getNumberOfRecords(); // 记录数
		System.out.println("字段数为:" + fieldCount);
		System.out.println("记录数为:" + recordsCount);
		System.out.println(shapefile.getShapeType()); // shape类型
		//获取字段集合
		DBaseField [] dBaseFields=dBaseFile.getFields();

		for (int i = 0; i < fieldCount; i++)
		{
			System.out.print(dBaseFields[i].getName()+"    ");
		}
		System.out.println();
		// 解析shape文件
		try
		{
			while (shapefile.hasNext())
			{
				ShapefileRecord record = shapefile.nextRecord(); // 获取一条记录
				DBaseRecord dBaseRecord = record.getAttributes(); // 获取该记录的属性信息

				Object[] values = dBaseRecord.getValues().toArray();//获取字段值集合

				for (int i = 0; i < values.length; i++)
				{
					System.out.print(values[i].toString()+"        ");
				}
				System.out.println("------------------");
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			System.out.println("解析shapefile文件出错!");
		}
		finally
		{
			WWIO.closeStream(shapefile, shpFilePath);
			WWIO.closeStream(shapefile, shxFilePath);
			WWIO.closeStream(shapefile, dbfFilePath);
			WWIO.closeStream(shapefile, prjFilePath);

		}

	}

时间: 2024-12-19 19:07:59

World Wind Java开发之六——解析shape文件(上)的相关文章

iOS开发- 生成/解析.vcf文件

vcf, 通讯录导出的一种格式. 一.生成vcf文件 如果要把我们iPhone通讯录里的数据, 生成vcf格式文件. 我们可以借助iCloud. 小技巧:通过iCloud导出iPhone通讯录的方法 当然, 如果你想在应用中, 利用代码生成, 完全可以.先导出通讯录数据, 再解析, 再生成vcf文件即可. 参考下面代码: -(NSString*)generateVCardStringWithContacts:(CFArrayRef)contacts { NSInteger counter = 0

World Wind Java开发之一

参照<World wind Java三维地理信息系统开发指南随书光盘>以及官网论坛,开始学习World Wind Java开发. 第一个demo //基础类 public class VGE_GFBasicClass extends JFrame { protected WorldWindowGLCanvas worldWindowGLCanvas; //WorldWind 画布 protected StatusBar statusBar; //状态栏 protected Model mode

NSURLSession(Get &amp; Post,JSON、XML数据解析,文件上传下载)

NSURLSession(Get & Post,JSON.XML数据解析,文件上传下载) 一.NSURLSession概述 NSURLSession是iOS7中新的网络接口,支持后台网络操作,除非用户强行关闭. NSURLSession使用步骤: 1. 新建NSURLSessionConfiguration,用于NSURLSession的配置 2. 新建NSURLSession 3. 新建NSURLSessionTask对象 4. 执行task 其中NSURLSessionConfigurati

Java实现HTML5拖拽文件上传

这是主页面 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+reques

JSch - Java实现的SFTP(文件上传详解篇) 转

JSch是Java Secure Channel的缩写.JSch是一个SSH2的纯Java实现.它允许你连接到一个SSH服务器,并且可以使用端口转发,X11转发,文件传输等,当然你也可以集成它的功能到你自己的应用程序. 本文只介绍如何使用JSch实现的SFTP功能. SFTP是Secure File Transfer Protocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法.SFTP 为 SSH的一部份,是一种传输文件到服务器的安全方式.SFTP是使用加密传输认证信息和传输

关于Java网络爬虫---模拟txt文件上传操作。

业务需求是这样的,公司400业务中客户使用的,400电话号码,可以添加多个目的码你可以理解为转接号码: 这些配置的目的码我们会在网关服务器上配置成白名单,既拥有某些权限.先提出的要求是先添加或者变动目的码要及时同步到网关. 场景: 1.我们的网关服务器接受的白名单(目的码)是已txt文件上传的,数据按照制定的格式保存在txt里面. 2.利用Java网络爬虫模拟txt文件上传.------2018-4-7现在不写了,代码在公司电脑上明天总结一下在写. 原文地址:https://www.cnblog

[转]World Wind Java开发之五——读取本地shp文件

World Wind Java 使用IconLayer图层类表现点和多点数据,使用RenderableLayer图层表现线和面数据,一个图层只能对应一组shape文件.World Wind Java首先使用ShapefileLoader类完成对shape文件的读取和加载,再通过createLayerFromSource方法创建RenderableLayer,最后将创建的Layer加在layers上.源码如下: /** * * 方法名称: AddShapeData : * 方法描述: 添加本地sh

World Wind Java开发之五——读取本地shp文件

World Wind Java 使用IconLayer图层类表现点和多点数据,使用RenderableLayer图层表现线和面数据,一个图层只能对应一组shape文件.World Wind Java首先使用ShapefileLoader类完成对shape文件的读取和加载,再通过createLayerFromSource方法创建RenderableLayer,最后将创建的Layer加在layers上.源码如下: /** * * 方法名称: AddShapeData : * 方法描述: 添加本地sh

Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)

JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. 本文是项目中用到的一个实例,先通过上传xls文件(包含日期),再通过jxl进行读取上传的xls文件(文件格式见下user.xls),解析不为空的行与列,写入数据库. 文件user.xls格式为: 下面来看代码实例演示: 一.前端jsp页面(本来内容很多,这里精简了) <%@ page language="java" contentType="text/htm