/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.data.shapefile.shp;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
/**
*
* @author jamesm
* @author Ian Schneider
* @source $URL:
* http://svn.geotools.org/geotools/trunk/gt/modules/plugin/shapefile/src/main/java/org/geotools/data/shapefile/shp/ShapefileHeader.java $
*/
public class ShapefileHeader {
public static final int MAGIC = 9994;
public static final int VERSION = 1000;
private int fileCode = -1;
private int fileLength = -1;
private int version = -1;
private ShapeType shapeType = ShapeType.UNDEFINED;
private double minX;
private double maxX;
private double minY;
private double maxY;
private void checkMagic(boolean strict) throws java.io.IOException {
if (fileCode != MAGIC) {
String message = "Wrong magic number, expected " + MAGIC + ", got "
+ fileCode;
if (!strict) {
System.err.println(message);
} else {
throw new java.io.IOException(message);
}
}
}
private void checkVersion(boolean strict) throws java.io.IOException {
if (version != VERSION) {
String message = "Wrong version, expected " + MAGIC + ", got "
+ version;
if (!strict) {
System.err.println(message);
} else {
throw new java.io.IOException(message);
}
}
}
public void read(ByteBuffer file, boolean strict)
throws java.io.IOException {
file.order(ByteOrder.BIG_ENDIAN);
fileCode = file.getInt();
checkMagic(strict);
// skip 5 ints...
file.position(file.position() + 20);
fileLength = file.getInt();
file.order(ByteOrder.LITTLE_ENDIAN);
version = file.getInt();
checkVersion(strict);
shapeType = ShapeType.forID(file.getInt());
minX = file.getDouble();
minY = file.getDouble();
maxX = file.getDouble();
maxY = file.getDouble();
// skip remaining unused bytes
file.order(ByteOrder.BIG_ENDIAN);// well they may not be unused
// forever...
file.position(file.position() + 32);
}
public void write(ByteBuffer file, ShapeType type, int numGeoms,
int length, double minX, double minY, double maxX, double maxY)
throws IOException {
file.order(ByteOrder.BIG_ENDIAN);
file.putInt(MAGIC);
for (int i = 0; i < 5; i++) {
file.putInt(0); // Skip unused part of header
}
file.putInt(length);
file.order(ByteOrder.LITTLE_ENDIAN);
file.putInt(VERSION);
file.putInt(type.id);
// write the bounding box
file.putDouble(minX);
file.putDouble(minY);
file.putDouble(maxX);
file.putDouble(maxY);
// skip remaining unused bytes
file.order(ByteOrder.BIG_ENDIAN);
for (int i = 0; i < 8; i++) {
file.putInt(0); // Skip unused part of header
}
}
public ShapeType getShapeType() {
return shapeType;
}
public int getVersion() {
return version;
}
public int getFileLength() {
return fileLength;
}
public double minX() {
return minX;
}
public double minY() {
return minY;
}
public double maxX() {
return maxX;
}
public double maxY() {
return maxY;
}
public String toString() {
String res = new String("ShapeFileHeader[ size " + fileLength
+ " version " + version + " shapeType " + shapeType
+ " bounds " + minX + "," + minY + "," + maxX + "," + maxY
+ " ]");
return res;
}
public static void main(String[] args) throws Exception {
FileChannel channel = new FileInputStream(new File(args[0]))
.getChannel();
System.out.println(ShapefileReader.readHeader(channel, true));
channel.close();
}
}