读取shp文件,生成专用数据文件的类(J2SE程序)
public class readBin {
private static int iHeadBlockSize;
private static int iDataSize;
private static ArrayList dPs=new ArrayList();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// OutputStream opS = null;
try {
readShape("c:/宾馆_point.shp");
writeData("c:/hotal.bin");
//readData("c:/hotal.bin");
} catch (Exception exp) {
}
}
/**
* 写入文件
* @param f
*/
private static void writeData(String f) {
try {
DataOutputStream myDataStream;
FileOutputStream myFileStream;
BufferedOutputStream myBufferStream;
// get a file handle
myFileStream = new FileOutputStream(f);
// chain a buffered output stream (for efficiency);
myBufferStream = new BufferedOutputStream(myFileStream);
// chain a data output file
myDataStream = new DataOutputStream(myBufferStream);
//写入文件头
/*文件头格式
Lh.<空格> 头长度标示 4字节
头长度 int 4字节
Ver. 版本标示 4字节
版本号 int
Rn.<空格> 文件特征标示 4字节
特征码 int
Typ. 记录空间类型标示 4字节
空间类型 int 1-点 3-线 5-面
Sz.<空格> 空间记录数标示 4字节
空间记录数 int
共128字节 不足部分补int(0)
*/
myDataStream.write(new String("Lh. ").getBytes());
myDataStream.writeInt(128);
myDataStream.write(new String("Ver.").getBytes());
myDataStream.writeInt(1);
myDataStream.write(new String("Rn. ").getBytes());
myDataStream.writeInt(3102);
myDataStream.write(new String("Typ.").getBytes());
myDataStream.writeInt(1);
myDataStream.write(new String("Sz. ").getBytes());
myDataStream.writeInt(dPs.size());
int iLength = myDataStream.size();
for (int i = 0; i < (128 - iLength) / 4; i++)
myDataStream.writeInt(0);
//写入坐标数据
for (int j=0;j<dPs.size();j++)
{
Object o= dPs.get(j);
if (o instanceof Point)
{
Point p=(Point)o;
myDataStream.writeInt((int)p.getX());
myDataStream.writeInt((int)p.getY());
}
}
myDataStream.flush();
// close the data file explicitly
// Always colse the "topmost" file stream
myDataStream.close();
myBufferStream.close();
myFileStream.close();
} catch (Exception exception) {
}
}
/**
* 读取文件,测试写入数据是否正确
* @param f
*/
private static void readData(String f) {
try {
DataInputStream myDataStream;
FileInputStream myFileStream;
BufferedInputStream myBufferStream;
// get a file handle
myFileStream = new FileInputStream(f);
// chain a buffered output stream (for efficiency);
myBufferStream = new BufferedInputStream(myFileStream);
// chain a data output file
myDataStream = new DataInputStream(myBufferStream);
// Now we can use both input streams to access our file
// (If we want to ...)
byte[] bs1 = new byte[4];
int iReadLength = 0;
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
iHeadBlockSize = makeIntBigEndian(bs1, 0);
System.out.println(iHeadBlockSize);
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
iDataSize = makeIntBigEndian(bs1, 0);
System.out.println(iDataSize);
byte[] bs2 = new byte[8];
myDataStream.skip(iHeadBlockSize - iReadLength);
for (int i = 0; i < iDataSize; i++) {
myDataStream.read(bs2, 0, 8);
System.out.println(makeIntBigEndian(bs2, 0));
System.out.println(makeIntBigEndian(bs2, 4));
}
// close the data file explicitly
// Always colse the "topmost" file stream
myDataStream.close();
myBufferStream.close();
myFileStream.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
protected static int makeIntBigEndian(byte[] b, int off) {
return (int) (((((int) b[off + 0]) << 24) & 0xff000000)
| ((((int) b[off + 1]) << 16) & 0x00ff0000)
| ((((int) b[off + 2]) << 8) & 0x0000ff00) | (((int) b[off + 3]) & 0x000000ff));
}
protected static int makeIntLittleEndian(byte[] b, int off) {
return (int) (((((int) b[off + 3]) << 24) & 0xff000000)
| ((((int) b[off + 2]) << 16) & 0x00ff0000)
| ((((int) b[off + 1]) << 8) & 0x0000ff00) | (((int) b[off + 0]) & 0x000000ff));
}
protected static double makeDoubleBigEndian(byte[] b, int off) {
long tmp = (((((long) b[off + 0]) << 56) & 0xff00000000000000L)
| ((((long) b[off + 1]) << 48) & 0x00ff000000000000L)
| ((((long) b[off + 2]) << 40) & 0x0000ff0000000000L)
| ((((long) b[off + 3]) << 32) & 0x000000ff00000000L)
| ((((long) b[off + 4]) << 24) & 0x00000000ff000000L)
| ((((long) b[off + 5]) << 16) & 0x0000000000ff0000L)
| ((((long) b[off + 6]) << 8) & 0x000000000000ff00L) | (((long) b[off + 7]) & 0x00000000000000ffL));
return Double.longBitsToDouble(tmp);
}
protected static double makeDoubleLittleEndian(byte[] b, int off) {
long tmp = (((((long) b[off + 7]) << 56) & 0xff00000000000000L)
| ((((long) b[off + 6]) << 48) & 0x00ff000000000000L)
| ((((long) b[off + 5]) << 40) & 0x0000ff0000000000L)
| ((((long) b[off + 4]) << 32) & 0x000000ff00000000L)
| ((((long) b[off + 3]) << 24) & 0x00000000ff000000L)
| ((((long) b[off + 2]) << 16) & 0x0000000000ff0000L)
| ((((long) b[off + 1]) << 8) & 0x000000000000ff00L) | (((long) b[off + 0]) & 0x00000000000000ffL));
return Double.longBitsToDouble(tmp);
}
/**
* 读取ESRI Shape文件
* 该部分调用了Oracle9i SDOAPI,需要SDOAPI.Jar支持
* 测试原因只处理点Geometry
* @param sn
*/
private static void readShape(String sn) {
try {
if (!OraSpatialManager
.registerGeometryAdapter(new AdapterShapefile(
OraSpatialManager.getGeometryFactory()))) {
System.out
.println("The Shapefile adapter could not be registered.");
return;
}
// Get adapters
GeometryAdapter sfAdapter = OraSpatialManager.getGeometryAdapter(
"Shapefile", "1.0", byte[].class, null, null);
if (sfAdapter == null)
throw new Exception("Requested Shapefile adapter is null.");
// Open input file
ShapefileReader sfh = new ShapefileReader(sn);
byte bA[];
for (int i = 0; i < sfh.numRecords(); i++) {
System.out.println("Converting geometry #" + (i + 1));
// read Shapefile geometry
bA = sfh.getGeometryBytes(i);
Geometry g1 = sfAdapter.importGeometry(bA);
// write it to File
//处理点Geometry
if (g1 instanceof oracle.sdoapi.geom.Point) {
dPs.add(getPoint(g1));
}
//处理复合点Geometry
if (g1 instanceof oracle.sdoapi.geom.MultiPoint) {
MultiPoint mp = (MultiPoint) g1;
Geometry[] ps = mp.getGeometryArray();
for(int j=0;j<ps.length;j++)
dPs.add(getPoint(ps[j]));
}
}
sfh.closeShapefile();
} catch (Exception exp) {
exp.printStackTrace();
}
}
/**
* 转换点Geometry
* @param g
* @return
*/
private static Point getPoint(Geometry g)
{
Point p = (Point) g;
//System.out.println("X:" + p.getX());
//System.out.println("Y:" + p.getY());
return p;
}
}
public class readBin {
private static int iHeadBlockSize;
private static int iDataSize;
private static ArrayList dPs=new ArrayList();
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
// OutputStream opS = null;
try {
readShape("c:/宾馆_point.shp");
writeData("c:/hotal.bin");
//readData("c:/hotal.bin");
} catch (Exception exp) {
}
}
/**
* 写入文件
* @param f
*/
private static void writeData(String f) {
try {
DataOutputStream myDataStream;
FileOutputStream myFileStream;
BufferedOutputStream myBufferStream;
// get a file handle
myFileStream = new FileOutputStream(f);
// chain a buffered output stream (for efficiency);
myBufferStream = new BufferedOutputStream(myFileStream);
// chain a data output file
myDataStream = new DataOutputStream(myBufferStream);
//写入文件头
/*文件头格式
Lh.<空格> 头长度标示 4字节
头长度 int 4字节
Ver. 版本标示 4字节
版本号 int
Rn.<空格> 文件特征标示 4字节
特征码 int
Typ. 记录空间类型标示 4字节
空间类型 int 1-点 3-线 5-面
Sz.<空格> 空间记录数标示 4字节
空间记录数 int
共128字节 不足部分补int(0)
*/
myDataStream.write(new String("Lh. ").getBytes());
myDataStream.writeInt(128);
myDataStream.write(new String("Ver.").getBytes());
myDataStream.writeInt(1);
myDataStream.write(new String("Rn. ").getBytes());
myDataStream.writeInt(3102);
myDataStream.write(new String("Typ.").getBytes());
myDataStream.writeInt(1);
myDataStream.write(new String("Sz. ").getBytes());
myDataStream.writeInt(dPs.size());
int iLength = myDataStream.size();
for (int i = 0; i < (128 - iLength) / 4; i++)
myDataStream.writeInt(0);
//写入坐标数据
for (int j=0;j<dPs.size();j++)
{
Object o= dPs.get(j);
if (o instanceof Point)
{
Point p=(Point)o;
myDataStream.writeInt((int)p.getX());
myDataStream.writeInt((int)p.getY());
}
}
myDataStream.flush();
// close the data file explicitly
// Always colse the "topmost" file stream
myDataStream.close();
myBufferStream.close();
myFileStream.close();
} catch (Exception exception) {
}
}
/**
* 读取文件,测试写入数据是否正确
* @param f
*/
private static void readData(String f) {
try {
DataInputStream myDataStream;
FileInputStream myFileStream;
BufferedInputStream myBufferStream;
// get a file handle
myFileStream = new FileInputStream(f);
// chain a buffered output stream (for efficiency);
myBufferStream = new BufferedInputStream(myFileStream);
// chain a data output file
myDataStream = new DataInputStream(myBufferStream);
// Now we can use both input streams to access our file
// (If we want to ...)
byte[] bs1 = new byte[4];
int iReadLength = 0;
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
iHeadBlockSize = makeIntBigEndian(bs1, 0);
System.out.println(iHeadBlockSize);
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(makeIntBigEndian(bs1, 0));
iReadLength += myDataStream.read(bs1, 0, 4);
System.out.println(new String(bs1));
iReadLength += myDataStream.read(bs1, 0, 4);
iDataSize = makeIntBigEndian(bs1, 0);
System.out.println(iDataSize);
byte[] bs2 = new byte[8];
myDataStream.skip(iHeadBlockSize - iReadLength);
for (int i = 0; i < iDataSize; i++) {
myDataStream.read(bs2, 0, 8);
System.out.println(makeIntBigEndian(bs2, 0));
System.out.println(makeIntBigEndian(bs2, 4));
}
// close the data file explicitly
// Always colse the "topmost" file stream
myDataStream.close();
myBufferStream.close();
myFileStream.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
protected static int makeIntBigEndian(byte[] b, int off) {
return (int) (((((int) b[off + 0]) << 24) & 0xff000000)
| ((((int) b[off + 1]) << 16) & 0x00ff0000)
| ((((int) b[off + 2]) << 8) & 0x0000ff00) | (((int) b[off + 3]) & 0x000000ff));
}
protected static int makeIntLittleEndian(byte[] b, int off) {
return (int) (((((int) b[off + 3]) << 24) & 0xff000000)
| ((((int) b[off + 2]) << 16) & 0x00ff0000)
| ((((int) b[off + 1]) << 8) & 0x0000ff00) | (((int) b[off + 0]) & 0x000000ff));
}
protected static double makeDoubleBigEndian(byte[] b, int off) {
long tmp = (((((long) b[off + 0]) << 56) & 0xff00000000000000L)
| ((((long) b[off + 1]) << 48) & 0x00ff000000000000L)
| ((((long) b[off + 2]) << 40) & 0x0000ff0000000000L)
| ((((long) b[off + 3]) << 32) & 0x000000ff00000000L)
| ((((long) b[off + 4]) << 24) & 0x00000000ff000000L)
| ((((long) b[off + 5]) << 16) & 0x0000000000ff0000L)
| ((((long) b[off + 6]) << 8) & 0x000000000000ff00L) | (((long) b[off + 7]) & 0x00000000000000ffL));
return Double.longBitsToDouble(tmp);
}
protected static double makeDoubleLittleEndian(byte[] b, int off) {
long tmp = (((((long) b[off + 7]) << 56) & 0xff00000000000000L)
| ((((long) b[off + 6]) << 48) & 0x00ff000000000000L)
| ((((long) b[off + 5]) << 40) & 0x0000ff0000000000L)
| ((((long) b[off + 4]) << 32) & 0x000000ff00000000L)
| ((((long) b[off + 3]) << 24) & 0x00000000ff000000L)
| ((((long) b[off + 2]) << 16) & 0x0000000000ff0000L)
| ((((long) b[off + 1]) << 8) & 0x000000000000ff00L) | (((long) b[off + 0]) & 0x00000000000000ffL));
return Double.longBitsToDouble(tmp);
}
/**
* 读取ESRI Shape文件
* 该部分调用了Oracle9i SDOAPI,需要SDOAPI.Jar支持
* 测试原因只处理点Geometry
* @param sn
*/
private static void readShape(String sn) {
try {
if (!OraSpatialManager
.registerGeometryAdapter(new AdapterShapefile(
OraSpatialManager.getGeometryFactory()))) {
System.out
.println("The Shapefile adapter could not be registered.");
return;
}
// Get adapters
GeometryAdapter sfAdapter = OraSpatialManager.getGeometryAdapter(
"Shapefile", "1.0", byte[].class, null, null);
if (sfAdapter == null)
throw new Exception("Requested Shapefile adapter is null.");
// Open input file
ShapefileReader sfh = new ShapefileReader(sn);
byte bA[];
for (int i = 0; i < sfh.numRecords(); i++) {
System.out.println("Converting geometry #" + (i + 1));
// read Shapefile geometry
bA = sfh.getGeometryBytes(i);
Geometry g1 = sfAdapter.importGeometry(bA);
// write it to File
//处理点Geometry
if (g1 instanceof oracle.sdoapi.geom.Point) {
dPs.add(getPoint(g1));
}
//处理复合点Geometry
if (g1 instanceof oracle.sdoapi.geom.MultiPoint) {
MultiPoint mp = (MultiPoint) g1;
Geometry[] ps = mp.getGeometryArray();
for(int j=0;j<ps.length;j++)
dPs.add(getPoint(ps[j]));
}
}
sfh.closeShapefile();
} catch (Exception exp) {
exp.printStackTrace();
}
}
/**
* 转换点Geometry
* @param g
* @return
*/
private static Point getPoint(Geometry g)
{
Point p = (Point) g;
//System.out.println("X:" + p.getX());
//System.out.println("Y:" + p.getY());
return p;
}
}