赞
踩
在入库和查询中需要自动的让geometry的类型和实体类中的类型映射。
实体类中接收参数是String类型(geoJson)
PostGis中的geometry类型是十六进制的扩展WKB类型(EWKB),
说明输入格式是EWKB二进制格式,或者EWKB和EWKT文本格式。输出格式为二进制EWKB或文本格式HEXEWKB
以下接收到文本格式HEXEWKB处理
虽然Postgis数据库中提供类类型转换函数,能转换各种类型postgis常用命令_yaoct的博客-CSDN博客
但是基于mybatis框架查询时,就需要用java代码来转换。初步方案时mybatis中的类型转换器。
先引入java处理GIS的库,这里用的是Geotools库。
geotools的maven引入:
- <!-- geotools的远程库 -->
- <properties>
- <geotools.version>27.0</geotools.version>
- </properties>
- <repositories>
- <repository>
- <id>osgeo</id>
- <name>OSGeo Release Repository</name>
- <url>https://repo.osgeo.org/repository/release/</url>
- <snapshots>
- <enabled>false</enabled>
- </snapshots>
- <releases>
- <enabled>true</enabled>
- </releases>
- </repository>
- </repositories>
- <dependencies>
- <!--geotool https://docs.geotools.org/latest/userguide/tutorial/quickstart/maven.html-->
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-geojson</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-main</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-opengis</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-referencing</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-metadata</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- <dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-epsg-hsql</artifactId>
- <version>${geotools.version}</version>
- </dependency>
- </dependencies>

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);
这里框架用的是mybatis-plus,所有使用转换时,mybatis-plus中的实体类也要配置一些转换注解,其他和mybaitis中的xml配置属性相同。参考
-
- @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)
- @JsonRawValue
- 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
因为缺少JDBC映射,数据库开始报错:‘类型为 geometry, 但表达式的类型为 character varying’
参考:Mybatis-plus读取和保存Postgis geometry数据 - 简书
应该是缺少JDBC-type类型。引入响应的postGIS驱动
添加maven包:
- <!-- 这里会补充mybatis缺少的JDBC-Type如postGis中的geometry类型 -->
- <dependency>
- <groupId>net.postgis</groupId>
- <artifactId>postgis-jdbc</artifactId>
- <version>2.5.0</version>
- </dependency>
类型转换器代码:
- 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;
-
- /**
- * @version 2.0
- * @description
- * @Author yaoct
- * @create 2021/12/22 16:19
- */
- @Slf4j
- public class WKB2GeoJsonTypeHandler implements TypeHandler<String> {
-
- /**
- * 插入数据,转换,geoJson2EWKB
- * @param ps
- * @param i
- * @param parameter
- * @param jdbcType
- * @throws SQLException
- */
- @Override
- public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
- //EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担
- // CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class);
- // String EWKB = mapper.geo2EWKB(parameter);
- // PGgeometry ewkb = new PGgeometry(EWKB);
- // ps.setObject(i,ewkb);
-
- //通过geoTool转换WKB
- GeometryJSON geometryJson = new GeometryJSON(7);
- Geometry read = null;
- try {
- read = geometryJson.read(parameter);
- } catch (IOException e) {
- e.printStackTrace();
- }
- // System.out.println(read.toString());
- read.setSRID(4326);
- // GeometryJSON geometryJson = new GeometryJSON(7);
- WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);
- byte[] write = wkbWriter.write(read);
- String s1 = WKBWriter.toHex(write);
- PGgeometry ewkb = new PGgeometry(s1);
- ps.setObject(i,ewkb);
- }
-
- /**
- * 取出数据转换,WKB->Geojson
- * @param rs
- * @param columnName
- * @return
- * @throws SQLException
- */
- @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;
- }
- //转换成4326
- try {
- int srid = geometry.getSRID();
- CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);
- CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326",true);
- MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS,true);
- geometry = JTS.transform(geometry, transform);
- } catch (Exception e) {
- e.printStackTrace();
- }
- // 设置保留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;
- }
- }

- @Component
- public class SpringContextUtil implements ApplicationContextAware {
-
- private static ApplicationContext applicationContext;
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- SpringContextUtil.applicationContext = applicationContext;
- }
-
- //获取applicationContext
- public static ApplicationContext getApplicationContext() {
- return applicationContext;
- }
-
- //通过name获取 Bean.
- public static Object getBean(String name) {
- return getApplicationContext().getBean(name);
- }
-
- //通过class获取Bean.
- public static <T> T getBean(Class<T> clazz) {
- return getApplicationContext().getBean(clazz);
- }
-
- //通过name,以及Clazz返回指定的Bean
- public static <T> T getBean(String name, Class<T> clazz) {
- return getApplicationContext().getBean(name, clazz);
- }
-
- //关闭springboot
- public static void close(){
- ((ConfigurableApplicationContext)(getApplicationContext())).close();
- }
-
- //得到当前线程的HttpServletResponse,可在静态方法中得到
- public static HttpServletResponse getHttpServletResponse(){
- return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
- }
-
- //得到当前线程的HttpServletRequest,可在静态方法中得到
- public static HttpServletRequest getHttpServletRequest(){
- return ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
- }
-
- }

- @Repository
- public interface CommonCodeMapper extends BaseMapper<CommonCode> {
-
- /**
- * EWKB是pg数据库自定义的类型,所以需要用数据库函数
- * @param geoJson
- * @return
- */
- @Select("select ST_GeomFromGeoJSON(#{geoJson})")
- String geo2EWKB(String geoJson);
-
-
- }
=============================mybatis中使用================================
在mapper类中使用示例:https://www.jianshu.com/p/6465189984b0
- /**
- * 使用ResultMap
- */
- @Results(id = "userMap", value = {
- //可以使用这种方式来处理字段名和数据库表字段名不一致的情况
- @Result(column = "username", property = "username", jdbcType=JdbcType.VARCHAR,typeHandler = WKB2GeoJsonTypeHandler.class),
- @Result(column = "passwd", property = "passwd", jdbcType=JdbcType.VARCHAR),
- @Result(column = "birth_day", property = "birthDay", jdbcType=JdbcType.VARCHAR)
- })
- @Select("SELECT * FROM t_user WHERE id=#{id}")
- User loadByIdResultMap(Long id);
-
- /**
- * 引用其他的Result
- */
- @ResultMap("userMap")
- @Select("SELECT * FROM t_user WHERE id=#{id}")
- User loadByIdResultMapReference(Long id);

在xml中使用示例示例:
- <resultMap id="locationResultMap" type="com.zjzy.model.po.ExaminationApplication">
- <result typeHandler="com.zjzy.mapper.typehandler.WKB2GeoJsonTypeHandler" column="dig_position" javaType="String"
- property="digPosition"/>
- </resultMap>
-
- <select id="selectExaminationApplicationByPage" resultMap="locationResultMap">
- </select>
注意:
1.postgresql的JDBC实现中(驱动),数据自定义的类型对应java类型一般都通过实现
org.postgresql.util.PGobject。
2.对应数据库geometry类型的java类不在PG的JDBC驱动的实现类中,因为geometry类型在PG的扩展postgis中,所以响应的要引入postGIS这部分的驱动,
3. PG的JDBC驱动底层也是通过SOCKET连接org.postgresql.core.PGStream#createSocket
4.原生jdbc接口在java.sql包中。
5.一定要实现org.postgresql.util.PGobject#getValue方法因为,org.postgresql.jdbc.PgPreparedStatement#setPGobject底层调用org.postgresql.jdbc.PgPreparedStatement#setString(int, java.lang.String, int)时
要用到org.postgresql.util.PGobject#getValue方法
以下方式不用导入 net.postgis包
- package com.zjzy.mapper.typehandler;
-
- import com.alibaba.fastjson.JSONObject;
- import com.zjzy.util.GisUtil;
- import com.zjzy.util.SpringContextUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.ibatis.type.JdbcType;
- import org.apache.ibatis.type.TypeHandler;
- import org.geotools.geojson.geom.GeometryJSON;
- import org.geotools.geometry.jts.JTS;
- import org.geotools.geometry.jts.WKBReader;
- import org.geotools.referencing.CRS;
- import org.locationtech.jts.geom.Geometry;
- import org.locationtech.jts.io.ByteOrderValues;
- import org.locationtech.jts.io.ParseException;
- import org.locationtech.jts.io.WKBWriter;
- import org.locationtech.jts.io.WKTWriter;
- import org.opengis.referencing.crs.CoordinateReferenceSystem;
- import org.opengis.referencing.operation.MathTransform;
- import org.postgis.PGbox2d;
- import org.postgis.PGgeometry;
- import org.postgresql.util.PGobject;
- import org.springframework.core.env.Environment;
-
- import java.io.IOException;
- import java.sql.CallableStatement;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
-
- /**
- * @version 1.0
- * @description
- * @Author yaoct
- * @create 2021/12/22 16:19
- */
- @Slf4j
- public class WKB2GeoJsonTypeHandler implements TypeHandler<String> {
-
- /**
- * 插入数据,转换,geoJson2EWKB
- * @param ps
- * @param i
- * @param parameter
- * @param jdbcType
- * @throws SQLException
- */
- @Override
- public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
- //EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担
- // CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class);
- // String EWKB = mapper.geo2EWKB(parameter);
- // PGgeometry ewkb = new PGgeometry(EWKB);
- // ps.setObject(i,ewkb);
-
- //通过geoTool转换WKB
- GeometryJSON geometryJson = new GeometryJSON(7);
- Geometry geometry = null;
- try {
- geometry = geometryJson.read(parameter);
- } catch (IOException e) {
- e.printStackTrace();
- }
- // System.out.println(read.toString());
- geometry.setSRID(4326);
- // GeometryJSON geometryJson = new GeometryJSON(7);
-
- //方式1.基于net.postgis
- // WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);
- // byte[] write = wkbWriter.write(geometry);
- // String s1 = WKBWriter.toHex(write);
- // PGgeometry ewkb = new PGgeometry(s1);//EWKB比WKB多了SRID头字符串,PGgeometry.toString()会自动添加SRID
- // ps.setObject(i,ewkb);
-
- //方式2.设置ewkb,Postgresql驱动会先去数据库 pg_catalog.pg_type 查出geometry的类型id,这里的geometry字符串对应数据库pg_catalog.pg_type表中的geometry
- //以下方式不用导入net.postgis包
- // PGobject pGobject = new PGobject();
- // pGobject.setType("geometry");
- // pGobject.setValue(s1);
- // ps.setObject(i,pGobject);
-
- //方式3.设置拼接ewkt
- //以下方式不用导入net.postgis包,ewkb太长会超出sql限制,以下转换为ewkt
- PGobject pGobject = new PGobject();
- pGobject.setType("geometry");
- String pre="SRID="+4326+";";
- pGobject.setValue(pre+GisUtil.Geometry2WKT(geometry));
- ps.setObject(i,pGobject);
- }
-
-
- /**
- * 取出数据转换,WKB->Geojson
- * @param rs
- * @param columnName
- * @return
- * @throws SQLException
- */
- @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;
- }
- //转换成4326
- try {
- int srid = geometry.getSRID();
- if(srid==0)srid=4549;//默认4549
- int targetSrid=4326;//默认4326
- Environment environment = SpringContextUtil.getBean(Environment.class);
- if(environment!=null){
- String sridTarget = environment.getProperty("sridTarget");
- if(sridTarget!=null){
- try {
- targetSrid=Integer.valueOf(sridTarget);
- } catch (Exception e){
- //转换失败
- }
- }
- }
-
- CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);
- CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:"+targetSrid,true);
- MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS,true);
- geometry = JTS.transform(geometry, transform);
- } catch (Exception e) {
- e.printStackTrace();
- }
- // 设置保留6位小数,否则GeometryJSON默认保留4位小数
- GeometryJSON geometryJson = new GeometryJSON(7);
- String json = geometryJson.toString(geometry);
- JSONObject jsonObject = JSONObject.parseObject(json);
- jsonObject.put("srid",geometry.getSRID());
- return jsonObject.toJSONString();
- }
-
- @Override
- public String getResult(ResultSet rs, int columnIndex) throws SQLException {
- return null;
- }
-
- @Override
- public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
- return null;
- }
-
- }

- package com.zjzy.util;
-
- import org.geotools.geojson.geom.GeometryJSON;
- import org.geotools.geometry.jts.JTS;
- import org.geotools.geometry.jts.WKBReader;
- import org.geotools.referencing.CRS;
- import org.geotools.referencing.GeodeticCalculator;
- import org.geotools.referencing.crs.DefaultGeographicCRS;
- import org.locationtech.jts.geom.Geometry;
- import org.locationtech.jts.io.*;
- import org.opengis.referencing.FactoryException;
- import org.opengis.referencing.crs.CoordinateReferenceSystem;
- import org.opengis.referencing.operation.MathTransform;
- import org.opengis.referencing.operation.TransformException;
-
- import java.io.IOException;
-
- /**
- * @Author yaoct
- * @Date 2022/9/16 10:55
- * @Version 1.0
- * @description
- */
- public class GisUtil {
-
- /**
- * WKB字符串转Geometry格式
- * @param WKB
- * @return
- */
- public static Geometry WKB2Geometry(String WKB){
- WKBReader reader = new WKBReader();
- Geometry geometry = null;
- try {
- geometry = reader.read(WKBReader.hexToBytes(WKB));
- } catch (ParseException e) {
- //转换失败
- throw new RuntimeException("转换失败",e);
- }
- return geometry;
- }
-
- /**
- * Geometry格式转WKB字符串
- * @param geometry
- * @return
- */
- public static String Geometry2WKB(Geometry geometry){
- WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);
- byte[] write = wkbWriter.write(geometry);
- String ret = WKBWriter.toHex(write);
- return ret;
- }
-
- /**
- * WKT字符串转Geometry格式
- * @param WKT
- * @return
- */
- public static Geometry WKT2Geometry(String WKT){
- WKTReader reader = new WKTReader();
- Geometry geometry = null;
- try {
- geometry = reader.read(WKT);
- } catch (ParseException e) {
- //转换失败
- throw new RuntimeException("转换失败",e);
- }
- return geometry;
- }
-
- /**
- * Geometry格式转WKT字符串
- * @param geometry
- * @return
- */
- public static String Geometry2WKT(Geometry geometry){
- WKTWriter wktWriter = new WKTWriter();
- String wkt= wktWriter.write(geometry);
- return wkt;
- }
-
- /**
- * 转换Geometry坐标
- * @param geometry
- * @param targetSrid 新坐标
- * @return
- */
- public static Geometry coordinateTransfer(Geometry geometry, int targetSrid){
- int originSrid = geometry.getSRID();
- CoordinateReferenceSystem sourceCRS = null;
- CoordinateReferenceSystem targetCRS = null;
- MathTransform transform=null;
- try {
- sourceCRS = CRS.decode("EPSG:"+originSrid,true);
- targetCRS = CRS.decode("EPSG:"+targetSrid,true);
- transform = CRS.findMathTransform(sourceCRS, targetCRS,true);
- } catch (FactoryException e) {
- throw new RuntimeException("坐标错误",e);
- }
- Geometry ret = null;
- try {
- ret = JTS.transform(geometry, transform);
- } catch (TransformException e) {
- throw new RuntimeException("坐标转换错误",e);
- }
- return ret;
- }
-
- /**
- * Geometry->geoJson
- * @param geometry
- * @return
- */
- public static String geometry2GeoJson(Geometry geometry){
- // 设置保留6位小数,否则GeometryJSON默认保留4位小数
- GeometryJSON geometryJson = new GeometryJSON(7);
- String json = geometryJson.toString(geometry);
- // JSONObject jsonObject = JSONObject.parseObject(json);
- // jsonObject.put("srid",geometry.getSRID());
- // return jsonObject.toJSONString();
- return json;
- }
-
- /**
- * geoJson->Geometry
- * @param geoJson
- * @return
- */
- public static Geometry geoJson2Geometry(String geoJson){
- GeometryJSON geometryJson = new GeometryJSON(7);
- Geometry ret=null;
- try {
- Geometry read = geometryJson.read(geoJson);
- } catch (IOException e) {
- throw new RuntimeException("转换失败",e);
- }
- return ret;
- }
-
- /**
- * 计算两点间的距离
- * @param lon1
- * @param lat1
- * @param lon2
- * @param lat2
- * @return
- */
- public static double calculateDistance(double lon1,double lat1,double lon2,double lat2){
- //CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);
- GeodeticCalculator geodeticCalculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
- // 起点经纬度
- geodeticCalculator.setStartingGeographicPoint(lon1,lat1);
- // 末点经纬度
- geodeticCalculator.setDestinationGeographicPoint(lon2,lat2);
- // 计算距离,单位:米
- double distance = geodeticCalculator.getOrthodromicDistance();
- return distance;
- }
- }

转换成map类型,实体类接受前端传入json兼容性更好
- package com.wisdomcity.laian.monitor.mapper.typehandler;
-
- import com.alibaba.fastjson.JSONObject;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fhs.common.spring.SpringContextUtil;
- import com.kingbase8.util.KBobject;
- import com.wisdomcity.laian.monitor.utils.GisUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.ibatis.type.JdbcType;
- import org.apache.ibatis.type.TypeHandler;
- import org.geotools.geojson.geom.GeometryJSON;
- import org.geotools.geometry.jts.JTS;
- import org.geotools.geometry.jts.WKBReader;
- import org.geotools.referencing.CRS;
- import org.locationtech.jts.geom.Geometry;
- import org.locationtech.jts.io.ByteOrderValues;
- import org.locationtech.jts.io.ParseException;
- import org.locationtech.jts.io.WKBWriter;
- import org.opengis.referencing.crs.CoordinateReferenceSystem;
- import org.opengis.referencing.operation.MathTransform;
-
- import java.io.IOException;
- import java.sql.CallableStatement;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.Map;
-
- /**
- * @version 1.0
- * @description
- * @Author yaoct
- * @create 2021/12/22 16:19
- */
- @Slf4j
- public class WKB2GeoJsonTypeHandler implements TypeHandler<Map> {
-
- /**
- * 插入数据,转换,geoJson2EWKB
- * @param ps
- * @param i
- * @param parameter
- * @param jdbcType
- * @throws SQLException
- */
- @Override
- public void setParameter(PreparedStatement ps, int i, Map parameter, JdbcType jdbcType) throws SQLException {
- //EWKB是pg数据库自定义的类型,所以需要用数据库函数,插入数据库一般次数较少,这样并不会对数据库造成过大负担
- // CommonCodeMapper mapper = SpringContextUtil.getBean(CommonCodeMapper.class);
- // String EWKB = mapper.geo2EWKB(parameter);
- // PGgeometry ewkb = new PGgeometry(EWKB);
- // ps.setObject(i,ewkb);
-
- //通过geoTool转换WKB
- GeometryJSON geometryJson = new GeometryJSON(7);
- Geometry geometry = null;
- try {
- geometry = geometryJson.read(JSONObject.toJSONString(parameter));
- } catch (IOException e) {
- e.printStackTrace();
- }
- // System.out.println(read.toString());
- geometry.setSRID(4326);
- // GeometryJSON geometryJson = new GeometryJSON(7);
-
- //方式1.基于net.postgis
- WKBWriter wkbWriter = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN,true);
- byte[] write = wkbWriter.write(geometry);
- String s1 = WKBWriter.toHex(write);
- // PGgeometry ewkb = new PGgeometry(s1);//EWKB比WKB多了SRID头字符串,PGgeometry.toString()会自动添加SRID
- // ps.setObject(i,ewkb);
-
- //方式2.设置ewkb,Postgresql驱动会先去数据库 pg_catalog.pg_type 查出geometry的类型id,这里的geometry字符串对应数据库pg_catalog.pg_type表中的geometry
- // 以下方式不用导入net.postgis包
- // PGobject pGobject = new PGobject();
- // pGobject.setType("geometry");
- // pGobject.setValue(s1);
- // ps.setObject(i,pGobject);
-
- //方式3.设置拼接ewkt
- //以下方式不用导入net.postgis包,ewkb太长会超出sql限制,以下转换为ewkt
- // PGobject pGobject = new PGobject();
- // pGobject.setType("geometry");
- // String pre="SRID="+4326+";";
- // pGobject.setValue(pre+GisUtil.Geometry2WKT(geometry));
- // ps.setObject(i,pGobject);
- KBobject pGobject = new KBobject();
- pGobject.setType("geometry");
- String pre="SRID="+4326+";";
- pGobject.setValue(pre+ GisUtil.Geometry2WKT(geometry));
- ps.setObject(i,pGobject);
- }
-
-
- /**
- * 取出数据转换,WKB->Geojson
- * @param rs
- * @param columnName
- * @return
- * @throws SQLException
- */
- @Override
- public Map 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;
- }
- //转换成4326
- try {
- int srid = geometry.getSRID();
- // if(srid==0)srid=4549;//默认4549
- int targetSrid=4326;//默认4326
- // Environment environment = SpringContextUtil.getBean(Environment.class);
- // if(environment!=null){
- // String sridTarget = environment.getProperty("sridTarget");
- // if(sridTarget!=null){
- // try {
- // targetSrid=Integer.valueOf(sridTarget);
- // } catch (Exception e){
- // //转换失败
- // }
- // }
- // }
- if(srid!=targetSrid&&srid!=0){
- CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:"+srid,true);
- CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:"+targetSrid,true);
- MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS,true);
- geometry = JTS.transform(geometry, transform);
- geometry.setSRID(targetSrid);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- // 设置保留6位小数,否则GeometryJSON默认保留4位小数
- GeometryJSON geometryJson = new GeometryJSON(7);
- String json = geometryJson.toString(geometry);
- // JSONObject jsonObject = JSONObject.parseObject(json);
- // jsonObject.put("srid",geometry.getSRID());
- // return jsonObject.toJSONString();
- return JSONObject.parseObject(json);
- }
-
- @Override
- public Map getResult(ResultSet rs, int columnIndex) throws SQLException {
- return null;
- }
-
- @Override
- public Map getResult(CallableStatement cs, int columnIndex) throws SQLException {
- return null;
- }
-
- }

实体类字段改为 :
- @ApiModelProperty(value = "二进制WKB数据")
- @TableField(value = "location",typeHandler = WKB2GeoJsonTypeHandler.class)
- private Map location;
xml中使用
- <resultMap id="locationResultMap" type="com.wisdomcity.laian.monitor.model.supply.po.SupplyPipePoint">
- <result typeHandler="com.wisdomcity.laian.monitor.mapper.typehandler.WKB2GeoJsonTypeHandler" column="geom" javaType="Map"
- property="geom"/>
- </resultMap>
===================================================================
参考:
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) - 灰信网(软件开发博客聚合)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。