/** * Fetch the next record information. * * @param offset * @throws IOException * @return The record instance associated with this reader. */ public Geometry geomAt(int offset) throws IOException { // need to update position buffer.position(offset); // record header buffer.skip(8); // shape record is all little endian buffer.order(ByteOrder.LITTLE_ENDIAN); // read the type, handlers don't need it ShapeType recordType = ShapeType.forID(buffer.getInt()); // this usually happens if the handler logic is bunk, // but bad files could exist as well... if (recordType != ShapeType.NULL && recordType != fileShapeType) { throw new IllegalStateException( "ShapeType changed illegally from " + fileShapeType + " to " + recordType); } return handler.read(buffer, recordType); }
public Geometry read(ReadBufferManager buffer, ShapeType type) throws IOException { if (type == ShapeType.NULL) { return null; } int dimensions = (shapeType == ShapeType.ARCZ) ? 3 : 2; // read bounding box (not needed) buffer.skip(4 * 8); int numParts = buffer.getInt(); int numPoints = buffer.getInt(); // total number of points int[] partOffsets = new int[numParts]; // points = new Coordinate[numPoints]; for (int i = 0; i < numParts; i++) { partOffsets[i] = buffer.getInt(); } // read the first two coordinates and start building the coordinate // sequences PackedCoordinateSequence[] lines = new PackedCoordinateSequence[numParts]; int finish, start = 0; int length = 0; boolean clonePoint = false; for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == (numParts - 1)) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; if (length == 1) { length = 2; clonePoint = true; } else { clonePoint = false; } // TODO With next version of JTS uncomment this line // PackedCoordinateSequence builder = new // PackedCoordinateSequence.Double( // length, dimension); PackedCoordinateSequence builder = new PackedCoordinateSequence.Double(length, 3); for (int i = 0; i < length; i++) { builder.setOrdinate(i, 0, buffer.getDouble()); builder.setOrdinate(i, 1, buffer.getDouble()); // TODO With next version of JTS remove this line builder.setOrdinate(i, 2, Double.NaN); } if (clonePoint) { builder.setOrdinate(1, 0, builder.getOrdinate(0, 0)); builder.setOrdinate(1, 1, builder.getOrdinate(1, 0)); // TODO With next version of JTS remove this line builder.setOrdinate(1, 2, Double.NaN); } lines[part] = builder; } // if we have another coordinate, read and add to the coordinate // sequences if (dimensions == 3) { // z min, max buffer.skip(2 * 8); for (int part = 0; part < numParts; part++) { start = partOffsets[part]; if (part == (numParts - 1)) { finish = numPoints; } else { finish = partOffsets[part + 1]; } length = finish - start; if (length == 1) { length = 2; clonePoint = true; } else { clonePoint = false; } for (int i = 0; i < length; i++) { lines[part].setOrdinate(i, 2, buffer.getDouble()); } } } // Prepare line strings and return the multilinestring LineString[] lineStrings = new LineString[numParts]; for (int part = 0; part < numParts; part++) { lineStrings[part] = geometryFactory.createLineString(lines[part]); } return geometryFactory.createMultiLineString(lineStrings); }