空间矢量数据(.shp文件)之JAVA操作
来源:互联网 发布:淘宝小号查询 编辑:程序博客网 时间:2024/05/07 14:04
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, JDBFieldpublic 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 blocke.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 blocke.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;}
0 0
- 空间矢量数据(.shp文件)之JAVA操作
- ENVI栅格裸数据生成shp和kml矢量文件
- android开发——使用java读取.shp(shapefile)矢量文件
- 全国shp矢量数据分享(精确到区县)
- ArcMap:CAD数据转为shp矢量数据
- 空间数据库之矢量数据上载方法
- Erdas:将shp文件保存为Erdas中适用的AOI文件 矢量数据裁剪栅格
- GDAL矢量(.shp)文件读写与创建
- [ArcGIS] 空间分析(二) 矢量数据
- C#+ArcEngine:加载打开Shp矢量数据和栅格数据(VS2010窗体+代码)
- C#+ArcEngine:txt点数据转Shp矢量数据
- 空间数据矢量模型之DIME模型与PLOYVRT模型
- GDAL修改shp矢量数据的属性值
- 由坐标数据生成点SHP文件,并由多组点生成线SHP文件(上)
- 由坐标数据生成点SHP文件,并由多组点生成线SHP文件(下)
- shp文件数据导入数据库
- bat脚本自动扫描制定文件夹下shp文件,并导入数据库,然后执行空间操作
- ArcEngine对shp文件的操作(代码总结)
- recordset.editmode
- 使用select函数改进客户端/服务器端程序
- 测试步骤中设置断言
- CSS实现跨浏览器兼容性的盒阴影效果
- 关于私有继承
- 空间矢量数据(.shp文件)之JAVA操作
- BestCoder Round #51 (div.2) Zball in Tina Town
- 设备中如何实现类似gopro给iphone分配ip但是不修改dns的功能
- UVA 10651 Pebble Solitaire
- Gensim学习笔记-1--理解corpora.Dictionary
- BaseAdapter java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 dispatchTouchEvent
- 老胡的共享
- Android友盟判断手机是否存在微博客户端
- Oracle Apex 实用笔记系列 6 - 可编辑交互报告 Editable Interactive Report