001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/shpapi/FileHeader.java $ 002 003 /*---------------------------------------------------------------------------- 004 This file is part of deegree, http://deegree.org/ 005 Copyright (C) 2001-2009 by: 006 Department of Geography, University of Bonn 007 and 008 lat/lon GmbH 009 010 This library is free software; you can redistribute it and/or modify it under 011 the terms of the GNU Lesser General Public License as published by the Free 012 Software Foundation; either version 2.1 of the License, or (at your option) 013 any later version. 014 This library is distributed in the hope that it will be useful, but WITHOUT 015 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 016 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 017 details. 018 You should have received a copy of the GNU Lesser General Public License 019 along with this library; if not, write to the Free Software Foundation, Inc., 020 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 021 022 Contact information: 023 024 lat/lon GmbH 025 Aennchenstr. 19, 53177 Bonn 026 Germany 027 http://lat-lon.de/ 028 029 Department of Geography, University of Bonn 030 Prof. Dr. Klaus Greve 031 Postfach 1147, 53001 Bonn 032 Germany 033 http://www.geographie.uni-bonn.de/deegree/ 034 035 e-mail: info@deegree.org 036 ----------------------------------------------------------------------------*/ 037 038 package org.deegree.io.shpapi; 039 040 import java.io.IOException; 041 import java.io.RandomAccessFile; 042 043 import org.deegree.model.spatialschema.ByteUtils; 044 045 /** 046 * Class representing an ESRI Index File Header. 047 * <p> 048 * Uses class ByteUtils ShapeUtils modified from the original package com.bbn.openmap.layer.shape 049 * <br> 050 * Copyright (C) 1998 BBN Corporation 10 Moulton St. Cambridge, MA 02138 <br> 051 * 052 * @version 16.08.2000 053 * @author Andreas Poth 054 * 055 */ 056 057 public class FileHeader { 058 059 /* 060 * The buffer that holds the 100 byte header. 061 */ 062 private byte[] header; 063 064 /* 065 * Holds the length of the file, in bytes. 066 */ 067 private long fileLength; 068 069 /* 070 * Holds the version of the file, as an int. 071 */ 072 private int fileVersion; 073 074 /* 075 * Holds the shape type of the file. 076 */ 077 private int fileShapeType; 078 079 /* 080 * Holds the bounds of the file (four pairs of doubles). 081 */ 082 private SHPEnvelope fileMBR; 083 084 /* 085 * local copy of the index-file randomaccess variable; 086 */ 087 private RandomAccessFile rafShp = null; 088 089 /** 090 * Construct a IndexFileHeader from a file name. 091 * 092 * @param rafShp_ 093 * @throws IOException 094 */ 095 public FileHeader( RandomAccessFile rafShp_ ) throws IOException { 096 097 rafShp = rafShp_; 098 099 initHeader( false ); 100 } 101 102 /** 103 * Construct a IndexFileHeader from a file name. 104 * 105 * @param rafShp_ 106 * @param newHeader 107 * @throws IOException 108 */ 109 public FileHeader( RandomAccessFile rafShp_, boolean newHeader ) throws IOException { 110 111 rafShp = rafShp_; 112 113 initHeader( newHeader ); 114 } 115 116 /** 117 * method: getFileMBR();<BR> 118 * Returns the bounding box of this shape file. The bounding box<BR> 119 * is the smallest rectangle that encloses all the shapes in the<BR> 120 * file.<BR> 121 * 122 * @return the bounding box of this shape file. The bounding box<BR> 123 * is the smallest rectangle that encloses all the shapes in the<BR> 124 * file.<BR> 125 */ 126 127 public SHPEnvelope getFileMBR() { 128 129 return fileMBR; 130 131 } 132 133 /** 134 * method: getFileLength()<BR> 135 * returns the length of the shape file in bytes<BR> 136 * 137 * @return the length of the shape file in bytes<BR> 138 */ 139 public long getFileLength() { 140 141 return fileLength; 142 143 } 144 145 /** 146 * method: getFileVersion()<BR> 147 * returns the version of the shape file<BR> 148 * 149 * @return the version of the shape file<BR> 150 */ 151 public int getFileVersion() { 152 153 return fileVersion; 154 155 } 156 157 /** 158 * method: getFileShapeType()<BR> 159 * returns the code for the shape type of the file<BR> 160 * 161 * @return the code for the shape type of the file<BR> 162 */ 163 public int getFileShapeType() { 164 return fileShapeType; 165 } 166 167 /** 168 * Reads the header of a Shape file. If the file<BR> 169 * is empty, a blank header is written and then read. If the<BR> 170 * file is not empty, the header is read.<BR> 171 * After this function runs, the file pointer is set to byte 100,<BR> 172 * the first byte of the first record in the file.<BR> 173 */ 174 175 private void initHeader( boolean newHeader ) 176 throws IOException { 177 178 if ( newHeader ) 179 writeHeader(); 180 /* 181 * if (rafShp.read() == -1) { //File is empty, write a new one (what else???) writeHeader(); } 182 */ 183 readHeader(); 184 } 185 186 /** 187 * method: writeHeader()<BR> 188 * Writes a blank header into the shape file.<BR> 189 * 190 * @throws IOException 191 */ 192 public void writeHeader() 193 throws IOException { 194 195 header = new byte[ShapeConst.SHAPE_FILE_HEADER_LENGTH]; 196 197 ByteUtils.writeBEInt( header, 0, ShapeConst.SHAPE_FILE_CODE ); 198 ByteUtils.writeBEInt( header, 24, 50 ); 199 200 // empty shape file size in 16 bit words 201 ByteUtils.writeLEInt( header, 28, ShapeConst.SHAPE_FILE_VERSION ); 202 ByteUtils.writeLEInt( header, 32, ShapeConst.SHAPE_TYPE_NULL ); 203 ByteUtils.writeLEDouble( header, 36, 0.0 ); 204 ByteUtils.writeLEDouble( header, 44, 0.0 ); 205 ByteUtils.writeLEDouble( header, 52, 0.0 ); 206 ByteUtils.writeLEDouble( header, 60, 0.0 ); 207 208 rafShp.seek( 0 ); 209 rafShp.write( header, 0, ShapeConst.SHAPE_FILE_HEADER_LENGTH ); 210 211 } 212 213 /** 214 * method: writeHeader(int filelength, byte shptype,SHPEnvelope mbr)<BR> 215 * Writes a header into the shape file.<BR> 216 * 217 * @param filelength 218 * @param shptype 219 * @param mbr 220 * @throws IOException 221 */ 222 public void writeHeader( int filelength, int shptype, SHPEnvelope mbr ) 223 throws IOException { 224 225 header = new byte[ShapeConst.SHAPE_FILE_HEADER_LENGTH]; 226 227 ByteUtils.writeBEInt( header, 0, ShapeConst.SHAPE_FILE_CODE ); 228 ByteUtils.writeBEInt( header, 24, filelength / 2 ); 229 ByteUtils.writeLEInt( header, 28, ShapeConst.SHAPE_FILE_VERSION ); 230 ByteUtils.writeLEInt( header, 32, shptype ); 231 ShapeUtils.writeBox( header, 36, mbr ); 232 233 rafShp.seek( 0 ); 234 rafShp.write( header, 0, ShapeConst.SHAPE_FILE_HEADER_LENGTH ); 235 } 236 237 /** 238 * Reads and parses the header of the file. Values from the header<BR> 239 * are stored in the fields of this class.<BR> 240 */ 241 private void readHeader() 242 throws IOException { 243 244 header = new byte[ShapeConst.SHAPE_FILE_HEADER_LENGTH]; 245 246 /* 247 * Make sure we're at the beginning of the file 248 */ 249 rafShp.seek( 0 ); 250 251 rafShp.read( header, 0, ShapeConst.SHAPE_FILE_HEADER_LENGTH ); 252 253 int fileCode = ByteUtils.readBEInt( header, 0 ); 254 255 if ( fileCode != ShapeConst.SHAPE_FILE_CODE ) { 256 257 throw new IOException( "Invalid file code, " + "probably not a shape file" ); 258 259 } 260 261 fileVersion = ByteUtils.readLEInt( header, 28 ); 262 263 if ( fileVersion != ShapeConst.SHAPE_FILE_VERSION ) { 264 265 throw new IOException( "Unable to read shape files with version " + fileVersion ); 266 267 } 268 269 fileLength = ByteUtils.readBEInt( header, 24 ); 270 271 /* 272 * convert from 16-bit words to 8-bit bytes 273 */ 274 fileLength *= 2; 275 276 fileShapeType = ByteUtils.readLEInt( header, 32 ); 277 278 /* 279 * read ESRIBoundingBox and convert to SHPEnvelope 280 */ 281 fileMBR = new SHPEnvelope( ShapeUtils.readBox( header, 36 ) ); 282 283 } 284 285 }