/**
* 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.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
import chunmap.model.coord.Coordinate2D;
import chunmap.model.coord.CPoint;
import chunmap.model.elem.Envelope;
import chunmap.model.geom.*;
/**
* @author chunquedong
*
*/
public class ShapefileReaderHelper {
public Envelope readEnvelop(RandomAccessFile br) throws IOException {
double xMin = reverseBytes(br.readDouble());
double yMin = reverseBytes(br.readDouble());
double xMax = reverseBytes(br.readDouble());
double yMax = reverseBytes(br.readDouble());
return new Envelope(xMin, yMin, xMax, yMax);
}
public double reverseBytes(double d) {
long lon = Long.reverseBytes(Double.doubleToRawLongBits(d));
return Double.longBitsToDouble(lon);
}
public CPoint readPoint(RandomAccessFile br) throws IOException {
double x = reverseBytes(br.readDouble());
double y = reverseBytes(br.readDouble());
return new Coordinate2D(x, y);
}
public MultiPoint readMultiPoint(RandomAccessFile br) throws IOException {
Envelope env = readEnvelop(br);
int numPoints = Integer.reverseBytes(br.readInt());
List<CPoint> points = readPointList(br, numPoints);
List<GeoPoint> geoPointList=new ArrayList<GeoPoint>();
for(CPoint p:points){
geoPointList.add(new GeoPoint(p));
}
MultiPoint mPoint = new MultiPoint(geoPointList);
mPoint._setEnvelop(env);
return mPoint;
}
private List<CPoint> readPointList(RandomAccessFile br, int num)
throws IOException {
List<CPoint> points = new ArrayList<CPoint>();
for (int i = 0; i < num; i++) {
points.add(readPoint(br));
}
return points;
}
private LineString readLineString(RandomAccessFile br, int num)
throws IOException {
List<CPoint> points = readPointList(br, num);
LineString ls = new LineString(points);
return ls;
}
public MultiLineString readMultiLine(RandomAccessFile br)
throws IOException {
List<LineString> multiPath = new ArrayList<LineString>();
Envelope env = readEnvelop(br);
int numParts = Integer.reverseBytes(br.readInt());
int numPoints = Integer.reverseBytes(br.readInt());
// 几何体中第一个点在点集里面的索引,从零开始。
int[] parts = new int[numParts];
for (int i = 0; i < numParts; i++) {
parts[i] = Integer.reverseBytes(br.readInt());
}
// 读取线串
for (int i = 0; i < numParts; i++) {
LineString ls;
if (i == (numParts - 1)) {
// 表示读最后一个几何体
int last = numPoints;
ls = readLineString(br, last - parts[i]);
} else {
ls = readLineString(br, parts[i + 1] - parts[i]);
}
multiPath.add(ls);
}
MultiLineString mls = new MultiLineString(multiPath);
mls._setEnvelop(env);
return mls;
}
// public MultiLineString readMultiLineZ(RandomAccessFile br)
// throws IOException {
// return readMultiLine(br);
// }
//
// public MultiLineString readMultiLineM(RandomAccessFile br)
// throws IOException {
// return readMultiLine(br);
// }
// 读取多边形
public MultiPolygon readMultiPolygon(RandomAccessFile br)
throws IOException {
List<Polygon> polygons = new ArrayList<Polygon>();
Envelope env = readEnvelop(br);
int numParts = Integer.reverseBytes(br.readInt());
int numPoints = Integer.reverseBytes(br.readInt());
// 几何体中第一个点在点集里面的索引,从零开始。
int[] parts = new int[numParts];
for (int i = 0; i < numParts; i++) {
parts[i] = Integer.reverseBytes(br.readInt());
}
// 读取环
for (int i = 0; i < numParts; i++) {
Ring r;
if (i == (numParts - 1)) {
// 表示读最后一个几何体
int last = numPoints;
r = readLineString(br, last - parts[i]).toLinearRing();
} else {
r = readLineString(br, parts[i + 1] - parts[i]).toLinearRing();
}
Polygon pg = new Polygon(r);
polygons.add(pg);
}
MultiPolygon mpolygon = new MultiPolygon(polygons);
mpolygon._setEnvelop(env);
return mpolygon;
}
}