jdbc:如何读取mysql点格式

ijxebb2r  于 2021-06-23  发布在  Mysql
关注(0)|答案(2)|浏览(491)

我在mysql中有一个2d point列。我使用jdbc将其读入java对象。结果是一个字节[25]。我想知道这是什么格式,所以我可以把它转换成我的点(例如,双值)
点设置如下:

  1. UPDATE ... SET point=GeomFromText('POINT(18 63)')

数据库中的结果字节:

  1. 0x00000000010100000000000000000032400000000000804F40
5tmbdcev

5tmbdcev1#

通常一个好的做法是显式地列出表中要查询的所有列,但是如果要使用通配符( * )还有 ST_X/Y() 对于坐标的点属性函数,可以尝试使用表别名:

  1. SELECT ST_X(t.myPointColumn) as x_coordinate, ST_Y(t.myPointColumn) as y_coordinate, t.*
  2. FROM myTable t WHERE ...

在java中,您可以使用

  1. myResultSet.getDouble("x_coordinate");
  2. myResultSet.getDouble("y_coordinate");
gr8qqesn

gr8qqesn2#

因此,对于解决方案,我使用了wkb阅读器的代码:https://github.com/simplegeo/jts/tree/master/src/com/vividsolutions/jts/io
因为我不想包含所有内容,所以我只使用代码从byteordervalues.java读取endian格式的double:

  1. /**
  2. * Read a long from a byte buffer in big endian format.
  3. * @param buf must be 8 bytes
  4. */
  5. public static long readLongFromBytesBigEndian(byte[] buf) {
  6. return (long) (buf[0] & 0xff) << 56
  7. | (long) (buf[1] & 0xff) << 48
  8. | (long) (buf[2] & 0xff) << 40
  9. | (long) (buf[3] & 0xff) << 32
  10. | (long) (buf[4] & 0xff) << 24
  11. | (long) (buf[5] & 0xff) << 16
  12. | (long) (buf[6] & 0xff) << 8
  13. | (long) (buf[7] & 0xff);
  14. }
  15. /**
  16. * Read a long from a byte buffer in little endian format.
  17. * @param buf must be 8 bytes
  18. */
  19. public static long readLongFromBytesLittleEndian(byte[] buf) {
  20. return (long) (buf[7] & 0xff) << 56
  21. | (long) (buf[6] & 0xff) << 48
  22. | (long) (buf[5] & 0xff) << 40
  23. | (long) (buf[4] & 0xff) << 32
  24. | (long) (buf[3] & 0xff) << 24
  25. | (long) (buf[2] & 0xff) << 16
  26. | (long) (buf[1] & 0xff) << 8
  27. | (long) (buf[0] & 0xff);
  28. }
  29. /**
  30. * Read a long from a byte buffer in big or little endian format.
  31. * @param bigEndian true for big endian, false for little endian
  32. * @param buf must be 8 bytes
  33. */
  34. public static double readDoubleFromBytes(byte[] buf, boolean bigEndian) {
  35. long longVal = bigEndian ? readLongFromBytesBigEndian(buf)
  36. : readLongFromBytesLittleEndian(buf);
  37. return Double.longBitsToDouble(longVal);
  38. }
  39. /**
  40. * Read a long from a byte buffer in big or little endian format.
  41. * @param bigEndian true for big endian, false for little endian
  42. * @param buf must be 8 bytes length after offset
  43. */
  44. public static double readDoubleFromBytes(byte[] buf, int offset, boolean bigEndian) {
  45. byte[] bufOf8Bytes = Arrays.copyOfRange(buf, offset, offset + 8);
  46. return readDoubleFromBytes(bufOf8Bytes, bigEndian);
  47. }
  48. /**
  49. * Read a coordinate from a byte array in WKB format.
  50. * @param wkbBytes must be 25 bytes long
  51. */
  52. public static Coordinate readCoordinateFromWkbBytes(byte[] wkbBytes) {
  53. // Points are stored in MySQL marked as big endian, but in reality is little endian. Not good
  54. boolean isBigEndian = false; // readIsWkbBigEndianByteOrder(wkbBytes[0]);
  55. double x = readDoubleFromBytes(wkbBytes, 9, isBigEndian);
  56. double y = readDoubleFromBytes(wkbBytes, 17, isBigEndian);
  57. Coordinate coordinate = new Coordinate();
  58. coordinate.setX(x);
  59. coordinate.setY(y);
  60. return coordinate;
  61. }
  62. public static boolean readIsWkbBigEndianByteOrder(byte b) {
  63. final byte BIG_ENDIAN = 0;
  64. final byte LITTLE_ENDIAN = 1;
  65. return b == BIG_ENDIAN;
  66. }

注意:我的第一个字节,表示big/little endian,被设置为0,根据wkbreader应该是big endian。但是我发现littl-endian是实际的格式。

展开查看全部

相关问题