在入库和查询中需要自动的让geometry的类型和实体类中的类型映射。
实体类中接收参数是String类型(geoJson)
PostGis中的geometry类型是十六进制的扩展WKB类型(EWKB),
虽然Postgis数据库中提供类类型转换函数,能转换各种类型postgis常用命令_yaoct的博客-CSDN博客
但是基于mybatis框架查询时,就需要用java代码来转换。初步方案时mybatis中的类型转换器。
先引入java处理GIS的库,这里用的是Geotools库。
1.java代码中数据类型的转换geotools的maven引入:
osgeo
OSGeo Release Repository
https://repo.osgeo.org/repository/release/
false
true
osgeo-snapshot
OSGeo Snapshot Repository
https://repo.osgeo.org/repository/snapshot/
true
false
org.geotools
gt-geojson
${geotools.version}
org.geotools
gt-main
${geotools.version}
org.geotools
gt-opengis
${geotools.version}
org.geotools
gt-referencing
${geotools.version}
org.geotools
gt-metadata
${geotools.version}
Geotools工具类转换WKB和Geojson
WKBReader reader = new WKBReader( );
Geometry geometry = reader.read(WKBReader.hexToBytes("0101000020E61000002C39382229FD5D4085716007088C3E40"));
// 设置保留6位小数,否则GeometryJSON默认保留4位小数
GeometryJSON geometryJson = new GeometryJSON(7);
String s = geometryJson.toString(geometry);
System.out.println(s);
//{"type":"Point","coordinates":[119.9556356,30.5469975]}
//EWKB->转geojson丢失信息
Geometry read = geometryJson.read("{"type":"Point","coordinates":[119.9556356,30.5469975]}");
System.out.println(read.toString());
WKBWriter wkbWriter = new WKBWriter();
byte[] write = wkbWriter.write(geometry);
String s1 = WKBWriter.toHex(write);
System.out.println(s1);
2.mybatis-plus类型转换器
这里框架用的是mybatis-plus,所有使用转换时,mybatis-plus中的实体类也要配置一些转换注解,其他和mybaitis中的xml配置属性相同。参考
MyBatis Plus 自动类型转换之TypeHandler
@Data
@ToString
@TableName (value = "test_table",autoResultMap = true)
@ApiModel ("test")
public class TestTable implements Serializable {
private static final long serialVersionUID = 8881418345724766899L;
@TableId(value = "id")
private Integer id;
@ApiModelProperty(value = "二进制WKB数据")
@TableField(value = "position",typeHandler = WKB2GeoJsonTypeHandler.class)
private String position;
@TableField("name")
private String name;
}
mybatis-plus配置添加转换器包路径,类似mybatis,之后用于写xml中sql
mybatis-plus:
type-handlers-package: com.zjzy.mapper.typehandler
configuration:
map-underscore-to-camel-case: true
auto-mapping-behavior: full
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:mapper*Mapper.xml
3.mybatis类型转换器转换geometry格式
因为缺少JDBC映射,开始报错:‘类型为 geometry, 但表达式的类型为 character varying’
参考:Mybatis-plus读取和保存Postgis geometry数据 - 简书
应该是缺少JDBC-type类型。
添加maven包:
net.postgis
postgis-jdbc
2.5.0
类型转换器代码:
package com.zjzy.mapper.typehandler; import com.zjzy.mapper.CommonCodeMapper; import com.zjzy.util.SpringContextUtil; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedJdbcTypes; import org.apache.ibatis.type.MappedTypes; import org.apache.ibatis.type.TypeHandler; import org.geotools.geojson.geom.GeometryJSON; import org.geotools.geometry.jts.WKBReader; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.ParseException; import org.postgis.PGgeometry; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Set; @Slf4j public class WKB2GeoJsonTypeHandler implements TypeHandler{ @Override public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { //TODO //EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担 CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class); String EWKB = mapper.geo2EWKB(parameter); PGgeometry ewkb = new PGgeometry(EWKB); ps.setObject(i,ewkb); } @Override public String getResult(ResultSet rs, String columnName) throws SQLException { String WKB = rs.getString(columnName); if(WKB==null){ return null; } WKBReader reader = new WKBReader( ); Geometry geometry = null; try { geometry = reader.read(WKBReader.hexToBytes(WKB)); } catch (ParseException e) { //转换失败 return null; } // 设置保留6位小数,否则GeometryJSON默认保留4位小数 GeometryJSON geometryJson = new GeometryJSON(7); return geometryJson.toString(geometry); } @Override public String getResult(ResultSet rs, int columnIndex) throws SQLException { return null; } @Override public String getResult(CallableStatement cs, int columnIndex) throws SQLException { return null; } }
参考:
Mybatis-plus读取和保存Postgis geometry数据 - 简书
MyBatis Plus 自动类型转换之TypeHandler - 周世元ISO8859-1 - 博客园
GeoTools The Open Source Java GIS Toolkit — GeoTools
Geotools中Geometry对象与GeoJson的相互转换_mathyrs的博客-CSDN博客_geojson转geometry
mybatis 自定义TypeHandler映射Geometry空间几何数据 PGPoint (java +mybatis+ pgsql) - 灰信网(软件开发博客聚合)



