有段时间为了追求效率,把用es相关的地理位置功能都去掉了,使用mysql已有的geometry的功能做地理位置,mybatis这块
@TableName(value = "t_event_info",autoResultMap = true) 如果使用复杂的数据结构,json,有两个方式 1、使用xml的是要 resultMap 2、没有使用xml的 必须配置autoResultMap=true 地理相关的函数https://dev.mysql.com/doc/refman/8.0/en/spatial-function-reference.html
geometry的类型
MySQL 具有对应于 OpenGIS 类的空间数据类型。
一些空间数据类型包含单个几何值:
GEOMETRY
POINT
LINESTRING
POLYGON
GEOMETRY
可以存储任何类型的几何值。其他单值类型(POINT
、 LINESTRING
和POLYGON
)将它们的值限制为特定的几何类型。
其他空间数据类型包含值的集合:
MULTIPOINT
MULTILINESTRING
MULTIPOLYGON
GEOMETRYCOLLECTION
GEOMETRYCOLLECTION
可以存储任何类型的对象的集合。其他集合类型(MULTIPOINT
、 MULTILINESTRING
和 MULTIPOLYGON
)将集合成员限制为具有特定几何类型的成员。
Well-Known Text (WKT) format 文本
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) 从低端写入 (不大确定)