一、背景
将Mysql数据同步到ES,采用canal采集binlog日志,发现point/polygon字段写入到kafka为乱码,跟踪canal源码发现并未对该类型进行处理,记录一下方便有需要的朋友少走弯路,加班狗时间紧 忽略排版。
二、数据示例
1. 直接上示例代码
public static void main(String[] args) throws ParseException {
// 定义byte数组
byte[] byteArray = new byte[]{0, 0, 0, 0, 1, 1, 0, 0, 0, -40, 68, 102, 46, 112, 24, 93, 64, 96, 60, -125, -122, -2, -5, 67, 64};
// 解析byte数组 坐标参考系为little endian格式
ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
ByteBuffer.wrap(byteArray, 0, 4).order(byteOrder).getInt();
byte[] wkbData = new byte[byteArray.length - 4];
System.arraycopy(byteArray, 4, wkbData, 0, wkbData.length);
// 将byte数组转换为WKB格式
WKBReader wkbReader = new WKBReader();
Geometry geometry = wkbReader.read(wkbData);
System.out.println(geometry.toString());
}
2. 如果需要修改canal-server源码:
canal版本:1.6.0
修改parse工程下>LogEventConvert类,第832行
case Types.BINARY:
if(columnBuilder.getMysqlType().equals("point")||columnBuilder.getMysqlType().equals("polygon")){
try {
// 将Serializable类型转换为byte[]
byte[] bytes = (byte[]) value;
ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
ByteBuffer.wrap(bytes, 0, 4).order(byteOrder).getInt();
byte[] wkbData = new byte[bytes.length - 4];
System.arraycopy(bytes, 4, wkbData, 0, wkbData.length);
// 将byte数组转换为WKB格式
WKBReader wkbReader = new WKBReader();
Geometry geometry = wkbReader.read(wkbData);
columnBuilder.setValue(geometry.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
break;
3. 还需要引入jts包:
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts-core</artifactId>
<version>1.14.0</version>
</dependency>