我在mysql中有一个2d point列。我使用jdbc将其读入java对象。结果是一个字节[25]。我想知道这是什么格式,所以我可以把它转换成我的点(例如,双值)点设置如下:
UPDATE ... SET point=GeomFromText('POINT(18 63)')
数据库中的结果字节:
0x00000000010100000000000000000032400000000000804F40
5tmbdcev1#
通常一个好的做法是显式地列出表中要查询的所有列,但是如果要使用通配符( * )还有 ST_X/Y() 对于坐标的点属性函数,可以尝试使用表别名:
*
ST_X/Y()
SELECT ST_X(t.myPointColumn) as x_coordinate, ST_Y(t.myPointColumn) as y_coordinate, t.* FROM myTable t WHERE ...
SELECT ST_X(t.myPointColumn) as x_coordinate, ST_Y(t.myPointColumn) as y_coordinate, t.*
FROM myTable t WHERE ...
在java中,您可以使用
myResultSet.getDouble("x_coordinate");myResultSet.getDouble("y_coordinate");
myResultSet.getDouble("x_coordinate");
myResultSet.getDouble("y_coordinate");
gr8qqesn2#
因此,对于解决方案,我使用了wkb阅读器的代码:https://github.com/simplegeo/jts/tree/master/src/com/vividsolutions/jts/io因为我不想包含所有内容,所以我只使用代码从byteordervalues.java读取endian格式的double:
/** * 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; }
/**
* 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.
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
public static double readDoubleFromBytes(byte[] buf, boolean bigEndian) {
long longVal = bigEndian ? readLongFromBytesBigEndian(buf)
: readLongFromBytesLittleEndian(buf);
return Double.longBitsToDouble(longVal);
* @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;
注意:我的第一个字节,表示big/little endian,被设置为0,根据wkbreader应该是big endian。但是我发现littl-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是实际的格式。