package com.revolsys.gis.esri.gdb.file.test; import java.nio.channels.ReadableByteChannel; import com.revolsys.datatype.DataType; import com.revolsys.record.schema.RecordDefinitionImpl; import com.revolsys.spring.resource.FileSystemResource; public class FgdbReader { public static void main(final String[] args) { // new FgdbReader().run(); } // public static long readVarInt(final EndianInput in) throws IOException { // long value = 0; // int shift = 0; // int b; // int next; // do { // b = in.read(); // if (shift == 0) { // value += (b & 0x3f) << shift; // shift = 6; // } else { // value += (b & 0x7f) << shift; // shift += 7; // } // next = b & 0x80; // } while (next == 0x80); // return value; // // } // // public static long readVarUInt(final EndianInput in) throws IOException { // long value = 0; // int shift = 0; // int b; // int next; // do { // b = in.read(); // value += (b & 0x7f) << shift; // shift += 7; // next = b & 0x80; // } while (next == 0x80); // return value; // // } private int fieldDescriptionOffset; private DataType geometryType; private final ReadableByteChannel in; private int numValidRows; private int optionalFieldCount; private final RecordDefinitionImpl recordDefinition = new RecordDefinitionImpl(); public FgdbReader() { this.in = new FileSystemResource( "/Users/paustin/Downloads/KSRD_20140306.gdb/a0000000d.gdbtable").newReadableByteChannel(); } // // private boolean isNull(final byte[] nullFields, final int fieldIndex) { // final int flagByte = fieldIndex / 8; // if (flagByte < nullFields.length) { // final byte flags = nullFields[flagByte]; // final int bit = fieldIndex % 8; // // return (flags & 1 << bit) != 0; // } else { // return false; // } // } // // private void readData() throws IOException { // int objectId = 1; // final int x = this.in.readLEInt(); // if (x != -272716322) { // return; // } // for (int i = 0; i < this.numValidRows; i++) { // final int recordSize = this.in.readLEInt(); // final ByteBuffer buffer = ByteBuffer.allocate(recordSize); // Buffers.readAll(this.in, buffer) // final double opt = Math.ceil(this.optionalFieldCount / 8.0); // final byte[] nullFields = new byte[(int)opt]; // this.in.read(nullFields); // final Record record = new ArrayRecord(this.recordDefinition); // record.setIdentifier(Identifier.newIdentifier(objectId++)); // int fieldIndex = 0; // int optionalFieldIndex = 0; // final int idIndex = this.recordDefinition.getIdFieldIndex(); // for (final FieldDefinition field : this.recordDefinition.getFields()) { // if (fieldIndex != idIndex) { // if (field.isRequired() || !isNull(nullFields, optionalFieldIndex++)) { // final FgdbField fgdbField = (FgdbField)field; // fgdbField.setValue(record, buffer); // } // } // fieldIndex++; // } // } // // final int rowLength = in.readLEInt(); // // final byte[] b = new byte[rowLength]; // // final int read = in.read(b); // // System.out.println(Arrays.toString(b)); // // } // // protected FgdbField readFieldDescription() throws IOException { // final String fieldName = readUtf16String(); // final String fieldAlias = readUtf16String(); // final int fieldType = this.in.read(); // int length = -1; // FgdbField field; // boolean required = false; // switch (fieldType) { // case 0: // this.in.read(); // length // required = readFlags(); // // ubyte: ldf = length of default value in byte if (flag&4) != 0 // // followed by ldf bytes // field = new ShortField(fieldName, required); // break; // case 1: // this.in.read(); // length // required = readFlags(); // // // ubyte: ldf = length of default value in byte if (flag&4) != 0 // // followed by ldf bytes // field = new IntField(fieldName, required); // break; // case 2: // this.in.read(); // length // required = readFlags(); // // ubyte: ldf = length of default value in byte if (flag&4) != 0 // // followed by ldf bytes // field = new FloatField(fieldName, required); // break; // case 3: // this.in.read(); // length // required = readFlags(); // // ubyte: ldf = length of default value in byte if (flag&4) != 0 // // followed by ldf bytes // field = new DoubleField(fieldName, required); // break; // case 4: // length = this.in.readLEInt(); // required = readFlags(); // field = new StringField(fieldName, length, required); // break; // case 5: // this.in.read(); // length // required = readFlags(); // // ubyte: ldf = length of default value in byte if (flag&4) != 0 // // followed by ldf bytes // field = new FgdbField(fieldName, DataTypes.DATE_TIME, required); // break; // case 6: // // OBJECTID // this.in.read(); // required = readFlags(); // field = new ObjectIdField(fieldName, true); // break; // case 7: // final int geometryFlag1 = this.in.read(); // final int geometryFlag2 = this.in.read(); // final String wkt = readUtf8String(); // final CoordinateSystem coordinateSystem = EsriCoordinateSystems.getCoordinateSystem(wkt); // final int geometryFlags = this.in.read(); // int axisCount = 2; // if (geometryFlags == 5) { // axisCount = 3; // } // if (geometryFlags == 7) { // axisCount = 4; // } // final double xOrigin = this.in.readLEDouble(); // final double yOrigin = this.in.readLEDouble(); // final double xyScale = this.in.readLEDouble(); // double zScale; // double mScale; // if (axisCount == 4) { // final double mOrigin = this.in.readLEDouble(); // mScale = this.in.readLEDouble(); // } else { // mScale = 0; // } // if (axisCount >= 3) { // final double zOrigin = this.in.readLEDouble(); // zScale = this.in.readLEDouble(); // } else { // zScale = 0; // } // final double xyTolerance = this.in.readLEDouble(); // if (axisCount == 4) { // final double mTolerance = this.in.readLEDouble(); // // } // if (axisCount >= 3) { // final double zTolerance = this.in.readLEDouble(); // } // final double minX = this.in.readLEDouble(); // final double minY = this.in.readLEDouble(); // final double maxX = this.in.readLEDouble(); // final double maxY = this.in.readLEDouble(); // final GeometryFactory geometryFactory = GeometryFactory.fixed(coordinateSystem, axisCount, // xyScale, zScale); // final BoundingBox boundingBox = geometryFactory.newBoundingBox(minX, minY, maxX, maxY); // boolean run = true; // while (run) { // final int v1 = this.in.read(); // final int v2 = this.in.read(); // final int v3 = this.in.read(); // final int v4 = this.in.read(); // final int v5 = this.in.read(); // if (v1 == 0 && v2 > 0 && v2 < 3 && v3 == 0 && v4 == 0 && v5 == 0) { // for (int i = 0; i < v2; i++) { // this.in.readLEDouble(); // } // run = required; // } else { // this.in.read(); // this.in.read(); // this.in.read(); // } // } // // Read 5 bytes // // If those bytes are 0x00 XXX 0x00 0x00 0x00 where XXX=0x01, 0x02 or // // 0x03, then read XXX * float64 values and go to 6. // // Otherwise, rewind those 5 bytes // // Read a float64 value // // Goto 1 // // End // field = new GeometryField(fieldName, this.geometryType, required, geometryFactory); // break; // case 8: // this.in.read(); // required = readFlags(); // field = new BinaryField(fieldName, length, required); // break; // case 9: // // Raster // field = new FgdbField(fieldName, DataTypes.BLOB, required); // break; // case 10: // // UUID // this.in.read(); // required = readFlags(); // field = new FgdbField(fieldName, DataTypes.STRING, required); // break; // case 11:// UUID // this.in.read(); // required = readFlags(); // field = new FgdbField(fieldName, DataTypes.STRING, required); // break; // case 12: // // XML // field = new XmlField(fieldName, length, required); // break; // default: // System.out.println("Unknown field type " + fieldName + " " + fieldType); // return null; // } // field.setProperty("ALIAS", fieldAlias); // return field; // } // // private void readFieldDescriptions() throws IOException { // final int headerSize = this.in.readLEInt(); // final int version = this.in.readLEInt(); // final int geometryType = this.in.read(); // switch (geometryType) { // case 0: // break; // case 1: // this.geometryType = DataTypes.POINT; // break; // case 2: // this.geometryType = DataTypes.MULTI_POINT; // break; // case 3: // this.geometryType = DataTypes.MULTI_LINE_STRING; // break; // case 4: // this.geometryType = DataTypes.MULTI_POLYGON; // break; // // default: // System.out.println("Unknown geometry type " + geometryType); // break; // } // final int unknown1 = this.in.read(); // final int unknown2 = this.in.read(); // final int unknown3 = this.in.read(); // final short numFields = this.in.readLEShort(); // this.optionalFieldCount = 0; // for (int i = 0; i < numFields; i++) { // final FgdbField field = readFieldDescription(); // if (field != null) { // this.recordDefinition.addField(field); // if (field instanceof ObjectIdField) { // final String fieldName = field.getName(); // this.recordDefinition.setIdFieldName(fieldName); // } // if (!field.isRequired()) { // this.optionalFieldCount++; // } // } // } // this.recordDefinition.setProperty("optionalFieldCount", this.optionalFieldCount); // System.out.println(MapObjectFactory.toString(this.recordDefinition)); // } // // protected boolean readFlags() throws IOException { // final int flag = this.in.read(); // if ((flag & 4) != 0) { // final int defaultBytes = this.in.read(); // for (int i = 0; i < defaultBytes; i++) { // this.in.read(); // } // } // final int i = flag & 1; // return i == 0; // } // // private void readHeader() throws IOException { // final int signature = this.in.readLEInt(); // this.numValidRows = this.in.readLEInt(); // final int unknown1 = this.in.readLEInt(); // final int unknown2 = this.in.readLEInt(); // final int unknown3 = this.in.readLEInt(); // final int unknown4 = this.in.readLEInt(); // final int fileSize = this.in.readLEInt(); // final int unknown6 = this.in.readLEInt(); // this.fieldDescriptionOffset = this.in.readLEInt(); // final int unknown8 = this.in.readLEInt(); // // } // // private String readUtf16String() throws IOException { // final int numCharacters = this.in.read(); // final char[] characters = new char[numCharacters]; // for (int i = 0; i < numCharacters; i++) { // final short c = this.in.readLEShort(); // characters[i] = (char)c; // } // return new String(characters); // } // // private String readUtf8String() throws IOException { // final short numBytes = this.in.readLEShort(); // final int numWords = numBytes / 2; // final char[] characters = new char[numWords]; // for (int i = 0; i < numWords; i++) { // final short c = this.in.readLEShort(); // characters[i] = (char)c; // } // return new String(characters); // } // // private void run() { // try { // readHeader(); // readFieldDescriptions(); // readData(); // } catch (final IOException e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } }