jdbc:如何读取mysql点格式

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

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

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

数据库中的结果字节:

0x00000000010100000000000000000032400000000000804F40
5tmbdcev

5tmbdcev1#

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

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");
gr8qqesn

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;
    }

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

相关问题