Example #1
0
  /**
   * Transfer (by bytes) the data at the current record to the ShapefileWriter.
   *
   * @param bounds double array of length four for transfering the bounds into
   * @return The length of the record transfered in bytes
   */
  public int transferTo(ShapefileWriter writer, int recordNum, double[] bounds) throws IOException {

    buffer.position(this.toBufferOffset(record.end));
    buffer.order(ByteOrder.BIG_ENDIAN);

    buffer.getInt(); // record number
    int rl = buffer.getInt();
    int mark = buffer.position();
    int len = rl * 2;

    buffer.order(ByteOrder.LITTLE_ENDIAN);
    ShapeType recordType = ShapeType.forID(buffer.getInt());

    if (recordType.isMultiPoint()) {
      for (int i = 0; i < 4; i++) {
        bounds[i] = buffer.getDouble();
      }
    } else if (recordType != ShapeType.NULL) {
      bounds[0] = bounds[1] = buffer.getDouble();
      bounds[2] = bounds[3] = buffer.getDouble();
    }

    // write header to shp and shx
    headerTransfer.position(0);
    headerTransfer.putInt(recordNum).putInt(rl).position(0);
    writer.shpChannel.write(headerTransfer);
    headerTransfer.putInt(0, writer.offset).position(0);
    writer.offset += rl + 4;
    writer.shxChannel.write(headerTransfer);

    // reset to mark and limit at end of record, then write
    int oldLimit = buffer.limit();
    buffer.position(mark).limit(mark + len);
    writer.shpChannel.write(buffer);
    buffer.limit(oldLimit);

    record.end = this.toFileOffset(buffer.position());
    record.number++;

    return len;
  }
Example #2
0
  /**
   * 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);
  }
Example #3
0
  /**
   * Fetch the next record information.
   *
   * @throws IOException
   * @return The record instance associated with this reader.
   */
  public Record nextRecord() throws IOException {

    // need to update position
    buffer.position(getNextOffset());
    if (currentShape != UNKNOWN) currentShape++;

    // record header is big endian
    buffer.order(ByteOrder.BIG_ENDIAN);

    // read shape record header
    int recordNumber = buffer.getInt();
    // silly ESRI say contentLength is in 2-byte words
    // and ByteByffer uses bytes.
    // track the record location
    int recordLength = buffer.getInt() * 2;

    if (!buffer.isReadOnly() && !useMemoryMappedBuffer) {
      // capacity is less than required for the record
      // copy the old into the newly allocated
      if (buffer.capacity() < recordLength + 8) {
        this.currentOffset += buffer.position();
        ByteBuffer old = buffer;
        // ensure enough capacity for one more record header
        buffer = ensureCapacity(buffer, recordLength + 8, useMemoryMappedBuffer);
        buffer.put(old);
        NIOUtilities.clean(old, useMemoryMappedBuffer);
        fill(buffer, channel);
        buffer.position(0);
      } else
      // remaining is less than record length
      // compact the remaining data and read again,
      // allowing enough room for one more record header
      if (buffer.remaining() < recordLength + 8) {
        this.currentOffset += buffer.position();
        buffer.compact();
        fill(buffer, channel);
        buffer.position(0);
      }
    }

    // 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);
    }

    // peek at bounds, then reset for handler
    // many handler's may ignore bounds reading, but we don't want to
    // second guess them...
    buffer.mark();
    if (recordType.isMultiPoint()) {
      record.minX = buffer.getDouble();
      record.minY = buffer.getDouble();
      record.maxX = buffer.getDouble();
      record.maxY = buffer.getDouble();
    } else if (recordType != ShapeType.NULL) {
      record.minX = record.maxX = buffer.getDouble();
      record.minY = record.maxY = buffer.getDouble();
    }
    buffer.reset();

    record.offset = record.end;
    // update all the record info.
    record.length = recordLength;
    record.type = recordType;
    record.number = recordNumber;
    // remember, we read one int already...
    record.end = this.toFileOffset(buffer.position()) + recordLength - 4;
    // mark this position for the reader
    record.start = buffer.position();
    // clear any cached shape
    record.shape = null;

    return record;
  }