网上以讹传讹的说法比较多,大多说称Spatialite Geometry为标准WKB格式,实际上按照官方文档解释并非如此
SpatiaLite internally stores geometry values using ordinary SQLite's BLOB columns in a format that is very closely related to WKB format, but not exactly identical.
举例不同的存储格式
WKT格式
LINESTRING Z (113.530643603811 34.7597662611779 106.213826217689,113.530643271043 34.7597058782661 106.250836674124,113.530642964671 34.7596706162388 106.272155821154)
WKB格式
1,-22,3,0,0,3,0,0,0,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64,27,0,41,84,-81,-115,90,64,56,-66,49,15,-10,97,92,64,-83,-35,-50,10,62,97,65,64,0,0,68,-75,13,-112,90,64,83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,112,-47,63,0,107,-111,90,64
SQlite Geometry格式
0,1,-26,16,0,0,83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64,124,-22,3,0,0,3,0,0,0,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64,27,0,41,84,-81,-115,90,64,56,-66,49,15,-10,97,92,64,-83,-35,-50,10,62,97,65,64,0,0,68,-75,13,-112,90,64,83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,112,-47,63,0,107,-111,90,64,-2
对比二进制
- 分析WKB二进制
- 1 byteOrder XDR/NDR (1)
- -22,3,0,0 类型(2,5)
- 3,0,0,0,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64,27,0,41,84,-81,-115,90,64,56,-66,49,15,-10,97,92,64,-83,-35,-50,10,62,97,65,64,0,0,68,-75,13,-112,90,64,83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,112,-47,63,0,107,-111,90,64 坐标值
2. 分析Geometry二进制
- 0 START=0
- 1 ENDIAN=1
- -26,16,0,0 SRID=(2,5位)
- 83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64 BBOX(6,37位)
- 124 END(38固定值)
- —–缺省byteOrder的WKB—
-22,3,0,0 类型(39,42)
3,0,0,0,-54,12,-105,16,-10,97,92,64,-128,46,86,5,64,97,65,64,27,0,41,84,-81,-115,90,64,56,-66,49,15,-10,97,92,64,-83,-35,-50,10,62,97,65,64,0,0,68,-75,13,-112,90,64,83,-57,-24,13,-10,97,92,64,41,61,2,-29,60,97,65,64,112,-47,63,0,107,-111,90,64 坐标值
- -2 LAST(最后一位固定值)
结论
如果不想或者无法使用spatialite插件,直接截取sql3 Blob字节数组的[39- 倒数第二位],首位增加byteOrder=1,即为标准WKB
示例代码:
byte[] bytes = new byte[geom.length - 39];
bytes[0] = geom[1];
System.arraycopy(geom, 39, bytes, 1, bytes.length - 1);
Geometry geometry = new WKBReader().read(bytes);