package com.yb.postgis; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.io.WKTReader; import org.locationtech.jts.io.WKTWriter; import lombok.SneakyThrows; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.postgis.PGgeometry; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; /** * Geometry字段和MyBatis类型转换器 * * @param 具体的几何类型 * @author wangrubin * @date 2022-08-06 */ public abstract class AbstractGeometryTypeHandler extends BaseTypeHandler { /** * WKTReader非线程安全 */ private static final ThreadLocal READER_POOL = ThreadLocal.withInitial(WKTReader::new); /** * WKTWriter非线程安全 */ private static final ThreadLocal WRITER_POOL = ThreadLocal.withInitial(WKTWriter::new); /** * 与数据库中几何列的空间坐标系保持一致,要不然写入会报错 */ private static final int SRID_IN_DB = 4326; @Override public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { PGgeometry pGgeometry = new PGgeometry(WRITER_POOL.get().write(parameter)); org.postgis.Geometry geometry = pGgeometry.getGeometry(); geometry.setSrid(SRID_IN_DB); ps.setObject(i, pGgeometry); } @SneakyThrows @Override public T getNullableResult(ResultSet rs, String columnName) throws SQLException { PGgeometry pgGeometry = (PGgeometry) rs.getObject(columnName); return getResult(pgGeometry); } @SneakyThrows @Override public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException { PGgeometry pgGeometry = (PGgeometry) rs.getObject(columnIndex); return getResult(pgGeometry); } @SneakyThrows @Override public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { PGgeometry string = (PGgeometry) cs.getObject(columnIndex); return getResult(string); } private T getResult(PGgeometry pGgeometry) { if (pGgeometry == null) { return null; } String pgWkt = pGgeometry.toString(); String target = String.format("SRID=%s;", SRID_IN_DB); String wkt = pgWkt.replace(target, ""); try { return (T) READER_POOL.get().read(wkt); } catch (Exception e) { throw new RuntimeException("解析wkt失败:" + wkt, e); } } }