赞
踩
你还在使用xml中写st_geomfromewkt(#{geom})进行坐标点导入么?
你还在使用xml中写st_astext(geom)进行二进制查询坐标点?
如果觉得复杂了,请看下放。
首先直接说方法,后面有说明用到的类
1.1 maven导入pgsql驱动与postgis
<!-- Postgresql驱动包 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.5.0</version>
</dependency>
1.2 继承BaseTypeHandler,创建MyGeometryTypeHandler类
因为用到了srid,如果没有用到可以删除,用到了但不是4326,可以自行替换
@MappedTypes({String.class}) public class MyGeometryTypeHandler extends BaseTypeHandler<String> { @Override public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { PGgeometry pGgeometry = new PGgeometry(parameter); Geometry geometry = pGgeometry.getGeometry(); geometry.setSrid(4326); ps.setObject(i, pGgeometry); } @Override public String getNullableResult(ResultSet rs, String columnName) throws SQLException { String string = rs.getString(columnName); return getResult(string); } @Override public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { String string = rs.getString(columnIndex); return getResult(string); } @Override public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { String string = cs.getString(columnIndex); return getResult(string); } private String getResult(String string) throws SQLException { PGgeometry pGgeometry = new PGgeometry(string); if (pGgeometry == null) { return null; } String s = pGgeometry.toString(); return s.replace("SRID=4326;", ""); } }
1.3 实体类添加标签
@Data @TableName(value = "tland", autoResultMap = true) public class Tland extends BaseEntity { private static final long serialVersionUID = 1L; /** * 自增id */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 空间坐标 */ @TableField(typeHandler = MyGeometryTypeHandler.class) private String geom; /** * 地块编号 */ private String landcode; }
核心在于
1、@TableField(typeHandler = MyGeometryTypeHandler.class)
通过拦截的方法拦截转换字段
2、@TableName(value = “tland”, autoResultMap = true)
如果不加autoResultMap =rue,
进不去MyGeometryTypeHandler中getNullableResult()这个方法,就会导致无法将二进制转回到坐标点。
1.4 保存与查询数据
通过Mybatis-plus,insert(),或updateById()等方法导入。会将坐标点转换成二进制入库。
通过Mybatis-plus,selectOne()等查询方法,可以将二进制数据转换为坐标点。
保存时请求入参为
{
"id": 75446,
"geom": "POLYGON((77.97868543333607 39.43378804933673,77.978492314287 39.4337826849187,77.97842794127064 39.434056270238216,77.9780417031725 39.43412064325457,77.97858887381153 39.43414746534472,77.97868543333607 39.43378804933673))",
"landcode": "653130204000008069"
}
保存后数据为
2.1 BaseTypeHandler说明
BaseTypeHandler 是个抽象类,需要子类去实现其定义的 4 个抽象方法,而它本身实现了 typeHandler 接口的 4
个方法。可以对数据保存与查询时做出相应处理,类似操作数据库之间的一个拦截器
可以通过该类做密码加密解密操作
上文中坐标点与二进制转换可以看成是一个操作
首先自定义handler 继承BaseTypeHandler重写他里边的四个方法
public abstract void setNonNullParameter(PreparedStatement var1, int var2, T var3, JdbcType var4) throws SQLException;
public abstract T getNullableResult(ResultSet var1, String var2) throws SQLException;
public abstract T getNullableResult(ResultSet var1, int var2) throws SQLException;
public abstract T getNullableResult(CallableStatement var1, int var2) throws SQLException;
setNonNullParameter()
可以理解为加密操作,将带有标签的字段,在inster,update操作时进行拦截,执行实现setNonNullParameter()方法体中的逻辑。
getNullableResult()
可以理解为解密操作,将带有标签的字段,在select操作时进行拦截,执行实现getNullableResult()方法体中的逻辑。
2.1 postgis说明
上文中用到的是postgis-jdbc,这样可以通过工具类,将坐标点与二进制进行转换。
坐标点转二进制
PGgeometry pGgeometry = new PGgeometry(parameter);
Geometry geometry = pGgeometry.getGeometry();
geometry.setSrid(4326);
ps.setObject(i, pGgeometry);
通过新建PGgeometry对象,传入坐标点或者二进制字符串都可以。具体可以查看PGgeometry的构造函数。点到最下面会发现有这段代码。判断你的入参是什么,就执行什么方法。
public static Geometry geomFromString(String value, BinaryParser bp, boolean haveM) throws SQLException { value = value.trim(); int srid = Geometry.UNKNOWN_SRID; if (value.startsWith(SRIDPREFIX)) { // break up geometry into srid and wkt String[] parts = splitSRID(value); value = parts[1].trim(); srid = Geometry.parseSRID(Integer.parseInt(parts[0].substring(5))); } //这里是核心,自己理解逻辑 Geometry result; if (value.startsWith("00") || value.startsWith("01")) { result = bp.parse(value); } else if (value.endsWith("EMPTY")) { // We have a standard conforming representation for an empty // geometry which is to be parsed as an empty GeometryCollection. result = new GeometryCollection(); } else if (value.startsWith("MULTIPOLYGON")) { result = new MultiPolygon(value, haveM); } else if (value.startsWith("MULTILINESTRING")) { result = new MultiLineString(value, haveM); } else if (value.startsWith("MULTIPOINT")) { result = new MultiPoint(value, haveM); } else if (value.startsWith("POLYGON")) { result = new Polygon(value, haveM); } else if (value.startsWith("LINESTRING")) { result = new LineString(value, haveM); } else if (value.startsWith("POINT")) { result = new Point(value, haveM); } else if (value.startsWith("GEOMETRYCOLLECTION")) { result = new GeometryCollection(value, haveM); } else { throw new SQLException("Unknown type: " + value); } if (srid != Geometry.UNKNOWN_SRID) { result.srid = srid; } return result; }
二进制转坐标点
PGgeometry pGgeometry = new PGgeometry(string);
if (pGgeometry == null) {
return null;
}
String s = pGgeometry.toString();
return s.replace("SRID=4326;", "");
核心与坐标点转二进制一致,就不说明了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。