📄 shapefile.java
字号:
// **********************************************************************// // <copyright>// // BBN Technologies// 10 Moulton Street// Cambridge, MA 02138// (617) 873-8000// // Copyright (C) BBNT Solutions LLC. All rights reserved.// // </copyright>// **********************************************************************// // $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/shape/ShapeFile.java,v $// $RCSfile: ShapeFile.java,v $// $Revision: 1.2.2.2 $// $Date: 2005/08/09 21:17:47 $// $Author: dietrick $// // **********************************************************************package com.bbn.openmap.layer.shape;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.util.Vector;import com.bbn.openmap.util.Debug;/** * Class representing an ESRI Shape File. * <p> * <H2>Usage:</H2> * <DT>java com.bbn.openmap.layer.shape.ShapeFile -v shapeFile</DT> * <DD>Verifies a shape file.</DD> * <p> * <DT>java com.bbn.openmap.layer.shape.ShapeFile -a destShapeFile * srcShapeFile</DT> * <DD>Appends records from srcShapeFile to destShapeFile.</DD> * <p> * <DT>java com.bbn.openmap.layer.shape.ShapeFile shapeFile</DT> * <DD>Prints information about the header and the number of records. * </DD> * <p> * * @author Tom Mitchell <tmitchell@bbn.com> * @author Ray Tomlinson * @author Geoffrey Knauth * @version $Revision: 1.2.2.2 $ $Date: 2005/08/09 21:17:47 $ */public class ShapeFile extends ShapeUtils { /** A Shape File's magic number. */ public static final int SHAPE_FILE_CODE = 9994; /** The currently handled version of Shape Files. */ public static final int SHAPE_FILE_VERSION = 1000; /** A default record size. Automatically increased on demand. */ public static final int DEFAULT_RECORD_BUFFER_SIZE = 50000; /** The read/write class for shape files. */ protected RandomAccessFile raf; /** The buffer that holds the 100 byte header. */ protected byte header[]; /** Holds the length of the file, in bytes. */ protected long fileLength; /** Holds the version of the file, as an int. */ protected int fileVersion; /** Holds the shape type of the file. */ protected int fileShapeType; /** Holds the bounds of the file (four doubles). */ protected ESRIBoundingBox fileBounds; /** A buffer for current record's header. */ protected byte recHdr[]; /** A buffer for the current record's data. */ protected byte recBuf[]; /** * Construct a <code>ShapeFile</code> from a file name. * * @exception IOException if something goes wrong opening or * reading the file. */ public ShapeFile(String name) throws IOException { raf = new RandomAccessFile(name, "rw"); recHdr = new byte[ShapeUtils.SHAPE_FILE_RECORD_HEADER_LENGTH]; recBuf = new byte[DEFAULT_RECORD_BUFFER_SIZE]; initHeader(); } /** * Construct a <code>ShapeFile</code> from the given * <code>File</code>. * * @param file A file object representing an ESRI Shape File * * @exception IOException if something goes wrong opening or * reading the file. */ public ShapeFile(File file) throws IOException { this(file.getPath()); } /** * Reads or writes the header of a Shape file. If the file is * empty, a blank header is written and then read. If the file is * not empty, the header is read. * <p> * After this function runs, the file pointer is set to byte 100, * the first byte of the first record in the file. * * @exception IOException if something goes wrong reading or * writing the shape file */ protected void initHeader() throws IOException { int result = raf.read(); if (result == -1) { // File is empty, write a new header into the file writeHeader(); } readHeader(); } /** * Writes a blank header into the shape file. * * @exception IOException if something goes wrong writing the * shape file */ protected void writeHeader() throws IOException { header = new byte[SHAPE_FILE_HEADER_LENGTH]; writeBEInt(header, 0, SHAPE_FILE_CODE); writeBEInt(header, 24, 50); // empty shape file size in 16 bit // words writeLEInt(header, 28, SHAPE_FILE_VERSION); writeLEInt(header, 32, SHAPE_TYPE_NULL); writeLEDouble(header, 36, 0.0); writeLEDouble(header, 44, 0.0); writeLEDouble(header, 52, 0.0); writeLEDouble(header, 60, 0.0); raf.seek(0); raf.write(header, 0, SHAPE_FILE_HEADER_LENGTH); } /** * Reads and parses the header of the file. Values from the header * are stored in the fields of this class. * * @exception IOException if something goes wrong reading the file * @see #header * @see #fileVersion * @see #fileLength * @see #fileShapeType * @see #fileBounds */ protected void readHeader() throws IOException { header = new byte[ShapeUtils.SHAPE_FILE_HEADER_LENGTH]; raf.seek(0); // Make sure we're at the beginning of // the file raf.read(header, 0, ShapeUtils.SHAPE_FILE_HEADER_LENGTH); int fileCode = ShapeUtils.readBEInt(header, 0); if (fileCode != SHAPE_FILE_CODE) { throw new IOException("Invalid file code, " + "probably not a shape file"); } fileVersion = ShapeUtils.readLEInt(header, 28); if (fileVersion != SHAPE_FILE_VERSION) { throw new IOException("Unable to read shape files with version " + fileVersion); } fileLength = ShapeUtils.readBEInt(header, 24); fileLength *= 2; // convert from 16-bit words to 8-bit // bytes fileShapeType = ShapeUtils.readLEInt(header, 32); fileBounds = ShapeUtils.readBox(header, 36); } /** * Returns the length of the file in bytes. * * @return the file length */ public long getFileLength() { return fileLength; } /** * Returns the version of the file. The only currently supported * version is 1000 (which represents version 1). * * @return the file version */ public int getFileVersion() { return fileVersion; } /** * Returns the shape type of the file. Shape files do not mix * shape types; all the shapes are of the same type. * * @return the file's shape type */ public int getShapeType() { return fileShapeType; } /** * Sets the shape type of the file. If the file has a shape type * already, it cannot be set. If it does not have a shape type, it * is set and written to the file in the header. * <p> * Shape types are enumerated in the class ShapeUtils. * * @param newShapeType the new shape type * @exception IOException if something goes wrong writing the file * @exception IllegalArgumentException if file already has a shape * type * @see ShapeUtils */ public void setShapeType(int newShapeType) throws IOException, IllegalArgumentException { if (fileShapeType == SHAPE_TYPE_NULL) { fileShapeType = newShapeType; long filePtr = raf.getFilePointer(); writeLEInt(header, 32, fileShapeType); raf.seek(0); raf.write(header, 0, 100); raf.seek(filePtr); } else { throw new IllegalArgumentException("file already has a valid" + " shape type: " + fileShapeType); } } /** * Returns the bounding box of this shape file. The bounding box * is the smallest rectangle that encloses all the shapes in the * file. * * @return the bounding box */ public ESRIBoundingBox getBoundingBox() { return fileBounds; } /** * Returns the next record from the shape file as an * <code>ESRIRecord</code>. Each successive call gets the next * record. There is no way to go back a record. When there are no * more records, <code>null</code> is returned. * * @return a record, or null if there are no more records * @exception IOException if something goes wrong reading the file */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -