Package chunmap.data.provider.shp

Source Code of chunmap.data.provider.shp.ShapefileReader

/**
* Copyright (c) 2009-2011, chunquedong(YangJiandong)
*
* This file is part of ChunMap project
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
*
* History:
*     2010-05-05  Jed Young  Creation
*/
package chunmap.data.provider.shp;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

import chunmap.model.elem.Envelope;
import chunmap.model.geom.GeoPoint;
import chunmap.model.geom.Geometry;
import chunmap.model.geom.GeometryType;

/**
* @author chunquedong
*
*/
public class ShapefileReader {
  private String path;
  private String name;
  private RandomAccessFile shaperf;
  private RandomAccessFile indexrf;
  private GeometryType geometryType;
  private int shapefileType;
  private long shapeCount;
  private int version;
  private Envelope envelop;
  private final ShapefileReaderHelper helper = new ShapefileReaderHelper();

  public ShapefileReader(String path) {
    setPath(path);
    open();
    readHeader();
  }

  private void setPath(String apath) {

    File file = new File(apath);
    this.name = file.getName();

    this.path = apath.substring(0, apath.lastIndexOf("."));
  }

  private void open() {
    try {
      shaperf = new RandomAccessFile(path + ".shp", "r");
      indexrf = new RandomAccessFile(path + ".shx", "r");
    } catch (FileNotFoundException e) {
      throw new RuntimeException(e);
    }
  }

  public void close() {
    try {
      indexrf.close();
      shaperf.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private void readHeader() {
    try {
      // 文件编号
      indexrf.seek(0);
      int ii = indexrf.readInt();
      if (ii != 9994)
        throw new IOException("bad file");
      // 文件长度
      indexrf.seek(24);
      int fileLength = 2 * indexrf.readInt();// 16位算一个
      // 图形个数
      shapeCount = (fileLength - 100) / 8;// 100bytes头文件。偏移4bytes,长度4bytes,没条记录共占8bytes。
      // 格式版本
      version = Integer.reverseBytes(indexrf.readInt());
      // 图类型
      shapefileType = Integer.reverseBytes(indexrf.readInt());
      // 边框盒子
      geometryType = ShapefileType.getShapeType(shapefileType);

      envelop = helper.readEnvelop(indexrf);

    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    // _envelop.MinPoint.Z = _binaryReader_Index.ReadDouble();
    // _envelop.MaxPoint.Z = _binaryReader_Index.ReadDouble();
    // _envelop.MinPoint.Coordinate.M = _binaryReader_Index.ReadDouble();
    // _envelop.MaxPoint.Coordinate.M = _binaryReader_Index.ReadDouble();
  }

  public Geometry getGeometry(long id) throws IOException {
    int index = getIndex(id) + 8;// 加8表示跳过记录头信息,包括记录号和记录长度。
    shaperf.seek(index);
    int type = Integer.reverseBytes(shaperf.readInt());
    Geometry geometry;

    switch (type) {
    case ShapefileType.Null:
      return null;

    case ShapefileType.Point:
      geometry = new GeoPoint(helper.readPoint(shaperf));
      break;

    case ShapefileType.Multipoint:
      geometry = helper.readMultiPoint(shaperf);
      break;

    case ShapefileType.PolyLine:
      geometry = helper.readMultiLine(shaperf);
      break;

    case ShapefileType.Polygon:
      geometry = helper.readMultiPolygon(shaperf);
      break;

    // case ShapefileType.PointM:
    // geometry = helper.readPointM(shaperf);
    // break;

    // case ShapefileType.MultiPointM:
    // geometry = helper.readMultiPointM(shaperf);
    // break;

    // case ShapefileType.PolyLineM:
    // geometry = helper.readMultiLineM(shaperf);
    // break;

    // case ShapefileType.PolygonM:
    // geometry = helper.readMultiPolygonM(shaperf);
    // break;

    // case ShapefileType.PointZ:
    // geometry = helper.readPointZ(shaperf);
    // break;

    // case ShapefileType.MultiPointZ:
    // geometry = helper.readMultiPointZ(shaperf);
    // break;

    // case ShapefileType.PolyLineZ:
    // geometry = helper.readMultiPolygonZ(shaperf);
    // break;
    //
    // case ShapefileType.PolygonZ:
    // geometry = helper.readMultiLineZ(shaperf);
    // break;

    default:
      throw new UnsupportedOperationException(
          "this ShapefileType is unsupported");
    }
    //geometry.setId(id + "");
    return geometry;
  }

  // 从索引文件查到偏移量
  public int getIndex(long id) throws IOException {
    indexrf.seek(id * 8 + 100);
    return 2 * indexrf.readInt();// 16位算一个

  }

  public Envelope getShapeEnvelop(long id) throws IOException {
    int index = getIndex(id) + 8;// 加8表示跳过记录头信息,包括记录号和记录长度。
    shaperf.seek(index);
    int type = Integer.reverseBytes(shaperf.readInt());

    Envelope elp;
    if (type == ShapefileType.Null)
      return new Envelope();
    else if (type == ShapefileType.Point || type == ShapefileType.PointM
        || type == ShapefileType.PointZ) {
      elp = new GeoPoint(helper.readPoint(shaperf)).getEnvelop();
    } else {
      elp = helper.readEnvelop(shaperf);
    }

    return elp;
  }

  public String getPath() {
    return path;
  }

  public String getName() {
    return name;
  }

  public GeometryType getGeometryType() {
    return geometryType;
  }

  public int getShapefileType() {
    return shapefileType;
  }

  public long getShapeCount() {
    return shapeCount;
  }

  public int getVersion() {
    return version;
  }

  public Envelope getEnvelop() {
    return envelop;
  }
}
TOP

Related Classes of chunmap.data.provider.shp.ShapefileReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.