/**
* Read a long from a byte buffer in big endian format.
* @param buf must be 8 bytes
*/
public static long readLongFromBytesBigEndian(byte[] buf) {
return (long) (buf[0] & 0xff) << 56
| (long) (buf[1] & 0xff) << 48
| (long) (buf[2] & 0xff) << 40
| (long) (buf[3] & 0xff) << 32
| (long) (buf[4] & 0xff) << 24
| (long) (buf[5] & 0xff) << 16
| (long) (buf[6] & 0xff) << 8
| (long) (buf[7] & 0xff);
}
/**
* Read a long from a byte buffer in little endian format.
* @param buf must be 8 bytes
*/
public static long readLongFromBytesLittleEndian(byte[] buf) {
return (long) (buf[7] & 0xff) << 56
| (long) (buf[6] & 0xff) << 48
| (long) (buf[5] & 0xff) << 40
| (long) (buf[4] & 0xff) << 32
| (long) (buf[3] & 0xff) << 24
| (long) (buf[2] & 0xff) << 16
| (long) (buf[1] & 0xff) << 8
| (long) (buf[0] & 0xff);
}
/**
* Read a long from a byte buffer in big or little endian format.
* @param bigEndian true for big endian, false for little endian
* @param buf must be 8 bytes
*/
public static double readDoubleFromBytes(byte[] buf, boolean bigEndian) {
long longVal = bigEndian ? readLongFromBytesBigEndian(buf)
: readLongFromBytesLittleEndian(buf);
return Double.longBitsToDouble(longVal);
}
/**
* Read a long from a byte buffer in big or little endian format.
* @param bigEndian true for big endian, false for little endian
* @param buf must be 8 bytes length after offset
*/
public static double readDoubleFromBytes(byte[] buf, int offset, boolean bigEndian) {
byte[] bufOf8Bytes = Arrays.copyOfRange(buf, offset, offset + 8);
return readDoubleFromBytes(bufOf8Bytes, bigEndian);
}
/**
* Read a coordinate from a byte array in WKB format.
* @param wkbBytes must be 25 bytes long
*/
public static Coordinate readCoordinateFromWkbBytes(byte[] wkbBytes) {
// Points are stored in MySQL marked as big endian, but in reality is little endian. Not good
boolean isBigEndian = false; // readIsWkbBigEndianByteOrder(wkbBytes[0]);
double x = readDoubleFromBytes(wkbBytes, 9, isBigEndian);
double y = readDoubleFromBytes(wkbBytes, 17, isBigEndian);
Coordinate coordinate = new Coordinate();
coordinate.setX(x);
coordinate.setY(y);
return coordinate;
}
public static boolean readIsWkbBigEndianByteOrder(byte b) {
final byte BIG_ENDIAN = 0;
final byte LITTLE_ENDIAN = 1;
return b == BIG_ENDIAN;
}
2条答案
按热度按时间5tmbdcev1#
通常一个好的做法是显式地列出表中要查询的所有列,但是如果要使用通配符(
*
)还有ST_X/Y()
对于坐标的点属性函数,可以尝试使用表别名:在java中,您可以使用
gr8qqesn2#
因此,对于解决方案,我使用了wkb阅读器的代码:https://github.com/simplegeo/jts/tree/master/src/com/vividsolutions/jts/io
因为我不想包含所有内容,所以我只使用代码从byteordervalues.java读取endian格式的double:
注意:我的第一个字节,表示big/little endian,被设置为0,根据wkbreader应该是big endian。但是我发现littl-endian是实际的格式。