Shape文件由ESRI开发。一个ESRI(Environmental Systems Research Institute)的shape文件包含一个主文件,一个索引文件,和一个dBASE表。

当中主文件的后缀就是.shp。

Shape文件已经是一种开源的文件格式。官方早在2006年就出版了对应的白皮书,对整个文件的读写进行了具体的说明,这样也使得Shape文件应用的更加广泛。本人在移动GIS开发的过程中,借机对.shp文件进行了研究,并简单实现了通过JAVA语言对.shp文件的读写操作功能。

================================================ 我是分隔线==============================================

1、Shape文件

ESRI 的shape 文件由一个主文件、一个索引文件和一个dBASE 表构成。主文件是一个可变记录长度的随机文件。文件里的每一个记录描写叙述一个包括多个顶点的shape。在索引文件里,每一个记录内容包括着与主文件里记录相相应的从主文件開始处的偏移量。

dBASE
表中包括着与每一个要素相相应的一条要素属性记录。

几何数据与属性的一一相应关系是基于记录号来相应的。dBASE 文件里属性记录的顺序必须与主文件里的记录顺序同样。

详见白皮书。

。。。

。。。

。。。。。

。。。。

。。

2、java实现shape文件的读取

import java.io.File;
import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.database.Cursor;
import android.os.Environment;
import android.widget.Toast; public class ReadShapeFile_DAL {
//分别用于存放shp文件和dbs文件。要求一一相应
private List<File> g_shpFileName;
private List<File> g_dbfFileName;
private List<VectorOcupy> g_shpAndDbfFiles;
private Activity g_at;
private String SDPATH;//离线矢量文件存储路径 public ReadShapeFile_DAL()
{ } public void SetSDPath(String _path)
{
SDPATH=_path;
} /**
* 推断机器中是否有存储卡
* @return
*/
private static boolean haveSDCARD() {
String status = Environment.getExternalStorageState();
if (status.equals(Environment.MEDIA_MOUNTED))
{
return true;
}
else
{
return false;
}
} //读取文件夹中的.shp和.dbf文件
public boolean ListFile(Activity _at)
{
boolean flag=false;
g_at=_at;
g_shpFileName=new ArrayList<File>();
g_dbfFileName=new ArrayList<File>();
g_shpAndDbfFiles=new ArrayList<VectorOcupy>();
if(haveSDCARD()){
//得到当前外部存储设备的文件夹( /SDCARD )
SDPATH = Environment.getExternalStorageDirectory() + "/LandMonitoringCollectionSystem";
}else{
//手机中文件放置路径
SDPATH = "/data/data/featuredata";
}
try
{
File dirs = new File(SDPATH);
File [] filenames=dirs.listFiles();
if(filenames.length==0)
{
return flag;
}
else
{
for(int i =0;i<filenames.length;i++)
{
File file = filenames[i];
if(file.isFile())
{
if(file.getName().endsWith(".shp"))
{
g_shpFileName.add(file);
}
else
{
if(file.getName().endsWith(".dbf"))
{
g_dbfFileName.add(file);
}
}
}
}
}
//推断矢量文件是否存在
if(g_shpFileName.size()<1)
{
Toast.makeText(g_at, "数据读取失败,请确定离线数据存在",Toast.LENGTH_SHORT).show();
return false;
}
else
{
g_shpAndDbfFiles=fileConfig(g_shpFileName,g_dbfFileName);
}
if(shpDataInsert())
return true;
}
catch(Exception e)
{
e.printStackTrace();
g_shpAndDbfFiles=new ArrayList<VectorOcupy>();
Toast.makeText(g_at,"数据读取失败,请确定离线数据存储的文件夹正确",Toast.LENGTH_SHORT).show();
}
return flag;
} private boolean shpDataInsert()
{
boolean flag=true; DataTableManagement g_myTableExcute=new DataTableManagement(g_at);
//在此删除全部的矢量数据表
String selectsql = "select * from sqlite_master"; g_myTableExcute = new DataTableManagement(g_at); Cursor cs = g_myTableExcute.excuteCursorTable(selectsql); while(cs.moveToNext())
{
String tableName = cs.getString(cs.getColumnIndex("name"));
if(tableName.contains("_shp"))
{
String str="DROP TABLE IF EXISTS "+tableName+";";
g_myTableExcute.ExcuteTable(str);
}
} for(int i=0;i<g_shpAndDbfFiles.size();i++)
{
try
{
ReadShapeFile_Analysis myShapeFileAnalysis;
/**
* 同一时候包括shp与dbf文件
*/
if(g_shpAndDbfFiles.get(i).getFlag())
{
myShapeFileAnalysis=new ReadShapeFile_Analysis(g_shpAndDbfFiles.get(i).getShpFile(),g_shpAndDbfFiles.get(i).getDbfFile(),g_at);
}
else
{
myShapeFileAnalysis=new ReadShapeFile_Analysis(g_shpAndDbfFiles.get(i).getShpFile(),g_at);
}
if(!myShapeFileAnalysis.read())
flag=false;
/*for(int j=0;j<dbfFileName.size();j++)
{
File dbfFile=dbfFileName.get(j);
String filename=shpFileName.get(i).getName().substring(0, shpFileName.get(i).getName().lastIndexOf("."));
if(dbfFile.getName().substring(0, dbfFile.getName().lastIndexOf(".")).equals(filename))
{ }
}
ShapeFileAnalysis myShapeFileAnalysis=new ShapeFileAnalysis(shpFileName.get(i),at);
myShapeFileAnalysis.read();
if(myShapeFileAnalysis.getifChanged())
flag=true;*/
}
catch(Exception e)
{
e.printStackTrace();
System.out.println("解析shapefile失败");
flag=false;
}
}
return flag;
} private List<VectorOcupy> fileConfig(List<File> shpfiles,List<File> dbffiles)
{
List<VectorOcupy> vectorocupy=new ArrayList<VectorOcupy>();
try
{
for(int i=0;i<shpfiles.size();i++)
{
boolean flag=false;
for(int j=0;j<dbffiles.size();j++)
{
String filename=shpfiles.get(i).getName().substring(0, shpfiles.get(i).getName().lastIndexOf("."));
if(dbffiles.get(j).getName().substring(0, dbffiles.get(j).getName().lastIndexOf(".")).equals(filename))
{
vectorocupy.add(new VectorOcupy(shpfiles.get(i),dbffiles.get(j),true));
flag=true;
break;
//j=dbffiles.size();
}
}
//针对仅仅有.shp文件的数据
if(flag == false)
{
vectorocupy.add(new VectorOcupy(shpfiles.get(i),false));
}
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
return vectorocupy;
} class VectorOcupy
{
private File shpdatafile;
private File dbfdatafile;
private boolean flag; public VectorOcupy(File shpfile,File dbffile,boolean flag)
{
this.flag=flag;
this.dbfdatafile=dbffile;
this.shpdatafile=shpfile;
} public VectorOcupy(File shpfile,boolean flag)
{
this.flag=flag;
this.shpdatafile=shpfile;
this.dbfdatafile=null;
} public File getShpFile()
{
return shpdatafile;
} public File getDbfFile()
{
return dbfdatafile;
} public boolean getFlag()
{
return flag;
}
}
}

3、DBF文件读取

package landmonitoring.mobilegismodels;

import java.io.*;

//Referenced classes of package cn.edu.sut.oa.workadmin.sjcl:
// JDBFException, JDBField public class DBFReader
{ public DBFReader(String s)
throws JDBFException
{
stream = null;
fields = null;
nextRecord = null;
nFieldCount = 0;
try
{
init(new FileInputStream(s));
}
catch(FileNotFoundException filenotfoundexception)
{
throw new JDBFException(filenotfoundexception);
}
} public DBFReader(FileInputStream inputstream)
throws JDBFException
{
stream = null;
fields = null;
nextRecord = null;
init(inputstream);
} private void init(InputStream inputstream)
throws JDBFException
{
try
{
stream = new DataInputStream(inputstream);
int i = readHeader();
fields = new JDBField[i];
int j = 1;
for(int k = 0; k < i; k++)
{
fields[k] = readFieldHeader();
if(fields[k] != null)
{
nFieldCount++;
j += fields[k].getLength();
}
} nextRecord = new byte[j];
try
{
stream.readFully(nextRecord);
}
catch(EOFException eofexception)
{
nextRecord = null;
stream.close();
}
int l = 0;
for(int i1 = 0; i1 < j; i1++)
{
if(nextRecord==null)
break;
else
{
if(nextRecord[i1] != 32 && nextRecord[i1] != 42)
continue;
l = i1;
break;
} } if(l > 0)
{
byte abyte0[] = new byte[l];
stream.readFully(abyte0);
for(int j1 = 0; j1 < j - l; j1++)
nextRecord[j1] = nextRecord[j1 + l]; for(int k1 = 0; k1 < l; k1++)
nextRecord[j - k1 - 1] = abyte0[l - k1 - 1]; }
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
} private int readHeader()
throws IOException, JDBFException
{
byte abyte0[] = new byte[16];
try
{
stream.readFully(abyte0);
}
catch(EOFException eofexception)
{
throw new JDBFException("Unexpected end of file reached.");
}
int i = abyte0[8];
if(i < 0)
i += 256;
i += 256 * abyte0[9];
i = --i / 32;
i--;
try
{
stream.readFully(abyte0);
}
catch(EOFException eofexception1)
{
throw new JDBFException("Unexpected end of file reached.");
}
return i;
} private JDBField readFieldHeader()
throws IOException, JDBFException
{
byte abyte0[] = new byte[16];
try
{
stream.readFully(abyte0);
}
catch(EOFException eofexception)
{
throw new JDBFException("Unexpected end of file reached.");
}
if(abyte0[0] == 13 || abyte0[0] == 0)
{
stream.readFully(abyte0);
return null;
}
StringBuffer stringbuffer = new StringBuffer(10);
int i = 0;
for(i = 0; i < 10; i++)
if(abyte0[i] == 0)
break; stringbuffer.append(new String(abyte0, 0, i,"GB2312"));
char c = (char)abyte0[11];
try
{
stream.readFully(abyte0);
}
catch(EOFException eofexception1)
{
throw new JDBFException("Unexpected end of file reached.");
}
int j = abyte0[0];
int k = abyte0[1];
if(j < 0)
j += 256;
if(k < 0)
k += 256;
return new JDBField(stringbuffer.toString(), c, j, k);
} public int getFieldCount()
{
return nFieldCount;
} public JDBField getField(int i)
{
return fields[i];
} public boolean hasNextRecord()
{
return nextRecord != null;
} public Object[] nextRecord()
throws JDBFException
{
if(!hasNextRecord())
throw new JDBFException("No more records available.");
Object aobj[] = new Object[nFieldCount];
int i = 1;
for(int j = 0; j < aobj.length; j++)
{
int k = fields[j].getLength();
StringBuffer stringbuffer = new StringBuffer(k);
try {
stringbuffer.append(new String(nextRecord, i, k,"GB2312"));
aobj[j] = fields[j].parse(stringbuffer.toString());
i += fields[j].getLength();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} try
{
stream.readFully(nextRecord);
}
catch(EOFException eofexception)
{
nextRecord = null;
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
return aobj;
} public String[] nextRecordString()
throws JDBFException
{
if(!hasNextRecord())
throw new JDBFException("No more records available.");
String as[] = new String[nFieldCount];
int i = 1;
for(int j = 0; j < as.length; j++)
{
int k = fields[j].getLength();
StringBuffer stringbuffer = new StringBuffer(k); try {
stringbuffer.append(new String(nextRecord, i, k,"GB2312"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
as[j] = stringbuffer.toString();
i += fields[j].getLength();
} try
{
stream.readFully(nextRecord);
}
catch(EOFException eofexception)
{
nextRecord = null;
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
return as;
} public void close()
throws JDBFException
{
nextRecord = null;
try
{
stream.close();
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
} private DataInputStream stream;
private JDBField fields[];
private byte nextRecord[];
private int nFieldCount;
}

4、DBF写入

package landmonitoring.mobilegismodels;

import java.io.*;
import java.util.Calendar; public class DBFWriter
{ public DBFWriter(String s, JDBField ajdbfield[])
throws JDBFException
{
stream = null;
recCount = 0;
fields = null;
fileName = null;
dbfEncoding = null;
fileName = s;
try
{
init(new FileOutputStream(s), ajdbfield);
}
catch(FileNotFoundException filenotfoundexception)
{
throw new JDBFException(filenotfoundexception);
}
} public DBFWriter(OutputStream outputstream, JDBField ajdbfield[])
throws JDBFException
{
stream = null;
recCount = 0;
fields = null;
fileName = null;
dbfEncoding = null;
init(outputstream, ajdbfield);
} public DBFWriter(String s, JDBField ajdbfield[], String s1)
throws JDBFException
{
stream = null;
recCount = 0;
fields = null;
fileName = null;
dbfEncoding = null;
fileName = s;
try
{
dbfEncoding = s1;
init(new FileOutputStream(s), ajdbfield);
}
catch(FileNotFoundException filenotfoundexception)
{
throw new JDBFException(filenotfoundexception);
}
} private void init(OutputStream outputstream, JDBField ajdbfield[])
throws JDBFException
{
fields = ajdbfield;
try
{
stream = new BufferedOutputStream(outputstream);
writeHeader();
for(int i = 0; i < ajdbfield.length; i++)
writeFieldHeader(ajdbfield[i]); stream.write(13);
stream.flush();
}
catch(Exception exception)
{
throw new JDBFException(exception);
}
} private void writeHeader()
throws IOException
{
byte abyte0[] = new byte[16];
abyte0[0] = 3;
Calendar calendar = Calendar.getInstance();
abyte0[1] = (byte)(calendar.get(1) - 1900);
abyte0[2] = (byte)calendar.get(2);
abyte0[3] = (byte)calendar.get(5);
abyte0[4] = 0;
abyte0[5] = 0;
abyte0[6] = 0;
abyte0[7] = 0;
int i = (fields.length + 1) * 32 + 1;
abyte0[8] = (byte)(i % 256);
abyte0[9] = (byte)(i / 256);
int j = 1;
for(int k = 0; k < fields.length; k++)
j += fields[k].getLength(); abyte0[10] = (byte)(j % 256);
abyte0[11] = (byte)(j / 256);
abyte0[12] = 0;
abyte0[13] = 0;
abyte0[14] = 0;
abyte0[15] = 0;
stream.write(abyte0, 0, abyte0.length);
for(int l = 0; l < 16; l++)
abyte0[l] = 0; stream.write(abyte0, 0, abyte0.length);
} private void writeFieldHeader(JDBField jdbfield)
throws IOException
{
byte abyte0[] = new byte[16];
/*定义一个新数组。用来接收新构造的字符串字节数组*/
byte abytem[];
String s = jdbfield.getName();
String news = new String(); int j = 0;
/*循环从新组成字符串。此字符串的字节长度不能大于10*/
for(int k = 0; k<s.length();k++)
{
if((s.substring(k,k+1).getBytes().length+j)>10) /*字节长度大于1的时候为汉字*/
{
break;
}
else
{
j = j + s.substring(k,k+1).getBytes().length;
news = news + s.charAt(k);
}
} /*接收字节数组*/
abytem = news.getBytes();
/*将字数组数据合并到文件头数据组*/
for(int k = 0; k<abytem.length;k++)
{
abyte0[k] = abytem[k];
}
/*在没有地方补空*/
for(int k = j; k <= 10; k++)
abyte0[k] = 0; abyte0[11] = (byte)jdbfield.getType();
abyte0[12] = 0;
abyte0[13] = 0;
abyte0[14] = 0;
abyte0[15] = 0; stream.write(abyte0, 0, abyte0.length); for(int l = 0; l < 16; l++)
abyte0[l] = 0; abyte0[0] = (byte)jdbfield.getLength();
abyte0[1] = (byte)jdbfield.getDecimalCount();
stream.write(abyte0, 0, abyte0.length);
} public void addRecord(Object aobj[])
throws JDBFException
{
if(aobj.length != fields.length)
throw new JDBFException("Error adding record: Wrong number of values. Expected " + fields.length + ", got " + aobj.length + ".");
int i = 0;
for(int j = 0; j < fields.length; j++)
i += fields[j].getLength(); byte abyte0[] = new byte[i];
int k = 0;
for(int l = 0; l < fields.length; l++)
{
String s = fields[l].format(aobj[l]);
byte abyte1[];
try
{
if(dbfEncoding != null)
abyte1 = s.getBytes(dbfEncoding);
else
abyte1 = s.getBytes();
}
catch(UnsupportedEncodingException unsupportedencodingexception)
{
throw new JDBFException(unsupportedencodingexception);
}
for(int i1 = 0; i1 < fields[l].getLength(); i1++)
abyte0[k + i1] = abyte1[i1]; k += fields[l].getLength();
} try
{
stream.write(32);
stream.write(abyte0, 0, abyte0.length);
stream.flush();
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
recCount++;
} public void close()
throws JDBFException
{
try
{
stream.write(26);
stream.close();
RandomAccessFile randomaccessfile = new RandomAccessFile(fileName, "rw");
randomaccessfile.seek(4L);
byte abyte0[] = new byte[4];
abyte0[0] = (byte)(recCount % 256);
abyte0[1] = (byte)((recCount / 256) % 256);
abyte0[2] = (byte)((recCount / 0x10000) % 256);
abyte0[3] = (byte)((recCount / 0x1000000) % 256);
randomaccessfile.write(abyte0, 0, abyte0.length);
randomaccessfile.close();
}
catch(IOException ioexception)
{
throw new JDBFException(ioexception);
}
} private BufferedOutputStream stream;
private int recCount;
private JDBField fields[];
private String fileName;
private String dbfEncoding;
}

空间矢量数据(.shp文件)之JAVA操作的更多相关文章

  1. java操作office和pdf文件java读取word,excel和pdf文档内容

    在平常应用程序中,对office和pdf文档进行读取数据是比较常见的功能,尤其在很多web应用程序中.所以今天我们就简单来看一下Java对word.excel.pdf文件的读取.本篇博客只是讲解简单应 ...

  2. Java IO_001.File类--文件或文件夹相关操作

    Java IO之File对象常用操作 File类:用于文件或文件夹或网址相关联的操作.可以关联或不关联文件(即关联不存在的文件).构造函数有: public File(String pathname) ...

  3. java io流 对文件夹的操作

    java io流 对文件夹的操作 检查文件夹是否存在 显示文件夹下面的文件 ....更多方法参考 http://www.cnblogs.com/phpyangbo/p/5965781.html ,与文 ...

  4. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  5. properties文件简介及其常用Java操作

    一.properties文件简介 java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"键=值&q ...

  6. Java操作文件夹的工具类

    Java操作文件夹的工具类 import java.io.File; public class DeleteDirectory { /** * 删除单个文件 * @param fileName 要删除 ...

  7. Java操作属性文件,支持新增或更新多个属性

    Java操作属性文件.支持新增或更新多个属性 一.更新或新增单个属性的方法 /** * 写入properties信息 * @param filePath 绝对路径(包含文件名称和后缀名) * @par ...

  8. JAVA操作properties文件

    va中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"键=值"的格式,在properties ...

  9. java文件的读写操作

    java文件的读写操作主要是对输入流和输出流的操作,由于流的分类很多,所以概念很容易模糊,基于此,对于流的读写操作做一个小结. 1.根据数据的流向来分: 输出流:是用来写数据的,是由程序(内存)--- ...

随机推荐

  1. pandas dataframe 做机器学习训练数据=》直接使用iloc或者as_matrix即可

    样本示意,为kdd99数据源: 0,udp,private,SF,105,146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.0 ...

  2. 6.CPU调度

    总论:所有的程序都是CPU和I/O等待交替执行 CPU调度器的操作时机 调用CPU调度器的时机,通常发生在 某一进程从执行状态转化为等待状态 某一进程从执行状态转化为就绪状态 某一进程从等待状态转为就 ...

  3. Android--Fragment与Activity通信

    package com.example.testfragment; import com.example.testfragment.MainFargment.BackString; import an ...

  4. 监控rman备份

    1.服务会话关联通道设置 set COMMAND ID 命令 2.查询V$PROCESS和V$SESSION 决定会话对应的RMAN的通道 3.查询V$session_LONGGOPS监控备份集和复制 ...

  5. MySql语句中select可以嵌套么,字段的重命名可以用中文么

    今天文档中看到的查询语句,SELECT后面又跟了一个SELECT嵌套,而且把字段重命名为中文,请问可以这样做么 MySql语句中select可以嵌套么,字段的重命名可以用中文么 >> my ...

  6. Python常用目录操作(Python2)

    Python获取当前路径   Python查看指定路径下的文件和文件夹 Python修改当前工作目录(在读取文件等时需要) Python添加import路径(有时候为了import自己写的py文件,且 ...

  7. IBM主机上清除告警黄灯方法

    机器亮黄灯告警一般是有硬件问题(单电源等可能有安全隐患的硬件配置也可能造成黄灯亮起),见到后首先进行下硬件诊断,方法如下: 诊断系统,判断是否硬件故障:1.Root用户执行diag: 2.回车后,进第 ...

  8. lhgDialog使用--loading提示(不自动关闭)

    使用lhgDialog时,发现有一个$.dialog.tips()方法可以实现loading样式的提示,但是存在默认关闭时间.方法如下图所示, 为了实现不自动关闭的方法,查看了相应的源码后,实现不关闭 ...

  9. 解决zabbix容器中文无法选择的问题

    1.查看zabbiz-web运行的容器 2.进入容器 3.安装语言包(针对centos7) yum install -y kde-l10n-chinese 4.更新gitbc包(因为镜像阉割了该包的部 ...

  10. CMSIS-RTOS 信号量

    信号量Semaphores 和信号类似,信号量也是一种同步多个线程的方式,简单来讲,信号量就是装有一些令牌的容器.当一个线程在执行过程中,就可能遇到一个系统调用来获取信号量令牌,如果这个信号量包含多个 ...