Well-Known Binary (WKB) format 二进制
domain
@TableField(value = "main_geo",typeHandler = GeometryTypeHandler.class)
private String mainGeo;
handler
@Slf4j
@MappedTypes(value = {String.class})
public class GeometryTypeHandler extends BaseTypeHandler {
@Override
public void setNonNullParameter(PreparedStatement preparedStatement, int i, Object o, JdbcType jdbcType) throws SQLException {
WKTReader wktReader= SpringUtil.getBean(WKTReader.class);
try {
Geometry pointGeo = wktReader.read(o.toString());
WKBWriter wkbWriter= SpringUtil.getBean(WKBWriter.class);
byte[] writer = wkbWriter.write(pointGeo);
byte[] wkb=new byte[writer.length+4];
ByteOrderValues.putInt(4326, wkb, ByteOrderValues.LITTLE_ENDIAN);
System.arraycopy(writer,0,wkb,4,writer.length);
preparedStatement.setBytes(i, wkb);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 获取jts包对象的wkt文本,再转换成sqlserver的Geometry对象
* 调用ps的setBytes()方法,以二进制持久化该geometry对象
*/
@Override
public String getNullableResult(ResultSet resultSet, String s) {
try {
/**
* 从ResultSet中读取二进制转换为SqlServer的Geometry对象
* 使用jts的WKTReader将wkt文本转成jts的Geometryd对象
*/
WKBReader wkbReader= SpringUtil.getBean(WKBReader.class);
byte[] bytes = resultSet.getBytes(s);
byte[] bytesN = new byte[bytes.length-4];
System.arraycopy(bytes,4,bytesN,0,bytes.length-4);
Geometry geometry = wkbReader.read(bytesN);
return geometry.toText();
} catch (Exception e) {
log.error(e.getMessage());
}
return null;
}
@Override
public String getNullableResult(ResultSet resultSet, int i) throws SQLException {
return null;
}
@Override
public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
return null;
}
工具类申明
@Component
@ComponentScan(value = {"cn.hutool.extra.spring"})
@Import(SpringUtil.class)
public class JTSBean {
private GeometryFactory geometryFactory;
public JTSBean() {
geometryFactory = new GeometryFactory(new PrecisionModel(), 4326);
}
@Bean
public WKBWriter wkbWriter() {
return new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN);
}
@Bean
public WKBReader wkbReader() {
return new WKBReader(geometryFactory);
}
@Bean
public WKTReader wktReader() {
return new WKTReader(geometryFactory);
}
}
有两点注意,
1、整数 SRID (0) 的 4 个字节的值 必须与GeometryFactory声明的一致
2、WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN) 从低端写入 (不大确定)