在入库和查询中需要自动的让geography的类型和实体类中的类型映射。

实体类中接收参数是String类型(geoJson)

PostGis中的geography类型是十六进制的扩展WKB类型(EWKB),

虽然Postgis数据库中提供类类型转换函数,能转换各种类型:postgis常用命令_yaoct的博客-CSDN博客

但是基于mybatis框架查询时,就需要用java代码来转换。初步方案时mybatis中的类型转换器。

先引入java处理GIS的库,这里用的是Geotools库。

1、geotools的maven引入

<properties><geotools.version>20.0</geotools.version></properties><dependencies><!-- geotools相关jar包 --><dependency><groupId>org.geotools</groupId><artifactId>gt-geojson</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-swing</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-jdbc</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools.jdbc</groupId><artifactId>gt-jdbc-postgis</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-epsg-hsql</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-shapefile</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-api</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-data</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>org.geotools</groupId><artifactId>gt-referencing</artifactId><version>${geotools.version}</version></dependency><dependency><groupId>net.postgis</groupId><artifactId>postgis-jdbc</artifactId><version>2.5.0</version></dependency></dependencies><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><repository><id>osgeo-snapshot</id><name>OSGeo Snapshot Repository</name><url>https://repo.osgeo.org/repository/snapshot/</url><snapshots><enabled>true</enabled></snapshots><releases><enabled>false</enabled></releases></repository></repositories>

2、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);

3、mybatis-plus类型转换器

package org.jeecg.oyz.modules.ost.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.oyz.common.config.MyGeographyTypeHandler;import java.io.Serializable;//一标三识_单体化表
@TableName(value = "oyz_ost_monomer",autoResultMap = true)
@Data
public class Monomer implements Serializable {@TableId(value = "id",type = IdType.AUTO)@ApiModelProperty(value = "主键ID")private Integer id;@ApiModelProperty(value = "名称")private String name;@ApiModelProperty(value = "酒店(OST_HOTEL)、住宅房屋(OST_HOME)、党政机关(OST_PARTY)、小区楼宇(OST_BUILDING)、店铺(OST_SHOP)")private String type;//楼层高@ApiModelProperty(value = "楼层高")private Double floorHeig;@ApiModelProperty(value = "基础高")private Double baseHeigh;@ApiModelProperty(value = "顶高")private Double topHeight;@ApiModelProperty(value = "地理数据")@TableField(exist = false)private String geometry;@ApiModelProperty(value = "地理数据")@TableField(typeHandler = MyGeographyTypeHandler.class)private String geog;@ApiModelProperty(value = "颜色")private String color;@ApiModelProperty(value = "小区名称")private String communityName;@ApiModelProperty(value = "楼号")private String buildingNo;@ApiModelProperty(value = "单元")private String unit;@ApiModelProperty(value = "小区名称")private String doorNo;@ApiModelProperty(value = "楼层")private String floorName;@ApiModelProperty(value = "相机坐标")private String viewingAngle;}

自定义GeoJson数据对象:
package org.jeecg.oyz.common.entity;import com.alibaba.fastjson.JSONObject;import java.util.List;/*** 自定义geojson对象*/
public class MyGeoJson {private String type;private List features;private JSONObject crs;public MyGeoJson() {this.type = "FeatureCollection";this.crs = new JSONObject();this.crs.put("type","name");JSONObject properties = new JSONObject();properties.put("name","EPSG:4326");this.crs.put("properties",properties);}public String getType() {return type;}public void setType(String type) {this.type = type;}public List getFeatures() {return features;}public void setFeatures(List features) {this.features = features;}public JSONObject getCrs() {return crs;}public void setCrs(JSONObject crs) {this.crs = crs;}//内部类:Feature对象public static class Feature{private String id;private String type;private JSONObject properties;private JSONObject geometry;public Feature() {this.type = "Feature";}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getType() {return type;}public void setType(String type) {this.type = type;}public JSONObject getProperties() {return properties;}public void setProperties(JSONObject properties) {this.properties = properties;}public JSONObject getGeometry() {return geometry;}public void setGeometry(JSONObject geometry) {this.geometry = geometry;}}}

自定义类型转换器代码:
package org.jeecg.oyz.common.config;

import org.apache.ibatis.type.BaseTypeHandler;import org.apache.ibatis.type.JdbcType;import org.apache.ibatis.type.MappedTypes;import org.geotools.data.postgis.WKBReader;import org.geotools.geojson.geom.GeometryJSON;import org.locationtech.jts.geom.Geometry;import org.locationtech.jts.io.ParseException;import org.postgis.PGgeography;

import java.sql.CallableStatement;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;

@MappedTypes({String.class})public class MyGeographyTypeHandler extends BaseTypeHandler<String> {

    //插入数据,转换,geoJson2EWKB    @Override    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {        PGgeography pGgeography = new PGgeography(parameter);        ps.setObject(i, pGgeography);    }

    @Override    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {        PGgeography pGgeography = new PGgeography(rs.getString(columnName));        if (pGgeography == null) {            return null;        }        return pGgeography.toString();    }

    @Override    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {        PGgeography pGgeography = new PGgeography(rs.getString(columnIndex));        if (pGgeography == null) {            return null;        }        return pGgeography.toString();    }

    @Override    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {        PGgeography pGgeography = new PGgeography(cs.getString(columnIndex));        if (pGgeography == null) {            return null;        }        return pGgeography.toString();    }

    //取出数据转换,WKB->Geojson    @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;        }        // 设置保留15位小数,否则GeometryJSON默认保留4位小数        GeometryJSON geometryJson = new GeometryJSON(16);        return geometryJson.toString(geometry);    }

}

4、GeoJson测试数据

{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.9738866671596,38.24802650187823],[101.97516074815859,38.24760957596093],[101.97525587066582,38.24777783863527],[101.97402119122222,38.248244352806516],[101.9738866671596,38.24802650187823]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21","base_height":"1959.71","top_height":"1980.71","address":"1","color":"#0099ff","id":1}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97516774566134,38.24756192366929],[101.97581658589463,38.24734488944303],[101.97586713946525,38.247495261468295],[101.97524052942822,38.24769933767308],[101.97516774566134,38.24756192366929]]]]},"geometry_name":"the_geom","properties":{"floor_height":"20","base_height":"1959.21","top_height":"1979.21","address":"2","color":"#0099ff","id":2}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97408539624891,38.24834258113536],[101.97521113714267,38.247963713081],[101.97528940606377,38.24810578159661],[101.97417503681662,38.248524362321845],[101.97408539624891,38.24834258113536]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21.7","base_height":"1959.01","top_height":"1980.71","address":"3","color":"#0099ff","id":3}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97539956572204,38.24794040388107],[101.97598913456741,38.24774703817632],[101.97605022583218,38.24787105919719],[101.97548750933808,38.248070046946246],[101.97539956572204,38.24794040388107]]]]},"geometry_name":"the_geom","properties":{"floor_height":"20.5","base_height":"1959.71","top_height":"1979.21","address":"4","color":"#0099ff","id":4}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97425025075555,38.24863509426437],[101.97535153527221,38.2482423711667],[101.97545665917151,38.24840732335468],[101.97433326065388,38.248782588524065],[101.97425025075555,38.24863509426437]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21.6","base_height":"1958.36","top_height":"1979.96","address":"5","color":"#0099ff","id":5}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97544662494822,38.24830645258619],[101.97616465300517,38.24805769780499],[101.97622897240959,38.248178394776055],[101.97548890345051,38.24842273026219],[101.97544662494822,38.24830645258619]]]]},"geometry_name":"the_geom","properties":{"floor_height":"20.4","base_height":"1958.22","top_height":"1978.62","address":"6","color":"#0099ff","id":6}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97441138941603,38.24895536097051],[101.97555609614969,38.2485602404651],[101.9756472596321,38.24873700704262],[101.97448111772378,38.249116048333235],[101.97441138941603,38.24895536097051]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21.3","base_height":"1958.1","top_height":"1979.4","address":"7","color":"#0099ff","id":7}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97572508249701,38.24862761373713],[101.9763547169892,38.24839146934206],[101.97644057061181,38.248555443150345],[101.97580343185976,38.24876455328588],[101.97572508249701,38.24862761373713]]]]},"geometry_name":"the_geom","properties":{"floor_height":"14.62","base_height":"1957.27","top_height":"1971.89","address":"8","color":"#0099ff","id":8}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97455020602396,38.249271551722785],[101.9752201501758,38.24906667800479],[101.97527212285912,38.24918518811116],[101.97462631248919,38.249403013582885],[101.97455020602396,38.249271551722785]]]]},"geometry_name":"the_geom","properties":{"floor_height":"18.70","base_height":"1956.80","top_height":"1975.5","address":"9","color":"#0099ff","id":9}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97560756178844,38.248907870439005],[101.9764727439547,38.24865343359926],[101.97658723270561,38.248871828833636],[101.97574405645503,38.24917948010292],[101.97560756178844,38.248907870439005]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21.99","base_height":"1957.11","top_height":"1979.1","address":"10","color":"#0099ff","id":10}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97473448369715,38.24953195068419],[101.9754729952202,38.249301055722896],[101.97556936660517,38.24945981465984],[101.97481863748091,38.249699636853514],[101.97473448369715,38.24953195068419]]]]},"geometry_name":"the_geom","properties":{"floor_height":"21.85","base_height":"1956.71","top_height":"1978.65","address":"11","color":"#0099ff","id":11}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.9755984423815,38.24930334091215],[101.97632040509546,38.249065853713354],[101.97640637757502,38.24921825795419],[101.97569336941301,38.249441080080416],[101.9755984423815,38.24930334091215]]]]},"geometry_name":"the_geom","properties":{"floor_height":"20.7","base_height":"1957.2","top_height":"1977.9","address":"12","color":"#0099ff","id":12}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97489010202722,38.24982900024954],[101.97567489909527,38.2495956955634],[101.97576412774175,38.24975163803929],[101.97495345974949,38.25002715229073],[101.97489010202722,38.24982900024954]]]]},"geometry_name":"the_geom","properties":{"floor_height":"22.80","base_height":"1955.11","top_height":"1979.61","address":"13","color":"#0099ff","id":13}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97580034565847,38.249586902965234],[101.97682340861867,38.2492490796096],[101.97693253298186,38.24943374227494],[101.9758976581547,38.249761603608505],[101.97580034565847,38.249586902965234]]]]},"geometry_name":"the_geom","properties":{"floor_height":"20.75","base_height":"1957","top_height":"1975.75","address":"14","color":"#0099ff","id":14}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97501744258008,38.2501171409867],[101.97592532481521,38.24982145008936],[101.97606024676887,38.25006283431469],[101.97514914788083,38.25034308087054],[101.97501744258008,38.2501171409867]]]]},"geometry_name":"the_geom","properties":{"floor_height":"23.4","base_height":"1955.83","top_height":"1979.23","address":"15","color":"#0099ff","id":15}},{"type":"Feature","geometry":{"type":"MultiPolygon","coordinates":[[[[101.97595220485555,38.24981832023942],[101.9769584425255,38.24950409057583],[101.977090638593,38.249708662267096],[101.97607942964663,38.25005079494555],[101.97595220485555,38.24981832023942]]]]},"geometry_name":"the_geom","properties":{"floor_height":"23.4","base_height":"1955.83","top_height":"1979.23","address":"16","color":"#0099ff","id":16}}],"totalFeatures":12,"numberMatched":12,"numberReturned":12,"timeStamp":"2021-07-06T01:51:52.710Z","crs":{"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::404000"}}
}

5、读取数据库数据,返回前端geojson数据

{"code": 200,"message": "请求成功","data": {"type": "FeatureCollection","features": [{"id": "1049","type": "Feature","properties": {"topHeight": 1979.1,"color": "#0099ff","geog": "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[101.97560756178844,38.248907870439005],[101.9764727439547,38.24865343359926],[101.97658723270561,38.248871828833636],[101.97574405645503,38.24917948010292],[101.97560756178844,38.248907870439005]]]]}","baseHeigh": 1957.11,"type": null,"floorHeig": 21.99,"unit": "3单元","buildingNo": "1号楼","name": null,"communityName": "清河小区","geometry": null,"viewingAngle": null,"doorNo": null,"floorName": null,"id": 1049},"geometry": {"coordinates": [[[[101.97560756178844,38.248907870439005],[101.9764727439547,38.24865343359926],[101.97658723270561,38.248871828833636],[101.97574405645503,38.24917948010292],[101.97560756178844,38.248907870439005]]]],"type": "MultiPolygon"}},{"id": "1048","type": "Feature","properties": {"topHeight": 1975.5,"color": "#0099ff","geog": "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[101.97455020602396,38.249271551722785],[101.9752201501758,38.24906667800479],[101.97527212285912,38.24918518811116],[101.97462631248919,38.249403013582885],[101.97455020602396,38.249271551722785]]]]}","baseHeigh": 1956.8,"type": null,"floorHeig": 18.7,"unit": "3单元","buildingNo": "1号楼","name": null,"communityName": "清河小区","geometry": null,"viewingAngle": null,"doorNo": null,"floorName": null,"id": 1048},"geometry": {"coordinates": [[[[101.97455020602396,38.249271551722785],[101.9752201501758,38.24906667800479],[101.97527212285912,38.24918518811116],[101.97462631248919,38.249403013582885],[101.97455020602396,38.249271551722785]]]],"type": "MultiPolygon"}},{"id": "1047","type": "Feature","properties": {"topHeight": 1971.89,"color": "#0099ff","geog": "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[101.97572508249701,38.24862761373713],[101.9763547169892,38.24839146934206],[101.97644057061181,38.248555443150345],[101.97580343185976,38.24876455328588],[101.97572508249701,38.24862761373713]]]]}","baseHeigh": 1957.27,"type": null,"floorHeig": 14.62,"unit": "3单元","buildingNo": "1号楼","name": null,"communityName": "清河小区","geometry": null,"viewingAngle": null,"doorNo": null,"floorName": null,"id": 1047},"geometry": {"coordinates": [[[[101.97572508249701,38.24862761373713],[101.9763547169892,38.24839146934206],[101.97644057061181,38.248555443150345],[101.97580343185976,38.24876455328588],[101.97572508249701,38.24862761373713]]]],"type": "MultiPolygon"}}],"crs": {"type": "name","properties": {"name": "EPSG:4326"}}},"success": true
}

参考:

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) - 灰信网(软件开发博客聚合)

Mybatis-plus读取(GeoJson)和保存Postgis geography数据相关推荐

  1. PostGISGeography支持功能PostGIS Geography Support Functions

    PostGIS地理支持功能 PostGIS Geography Support Functions 下面给出的函数和操作符是PostGIS函数/操作符,它们接受Geography数据类型对象作为输入或 ...

  2. 如何用matlab读取npz文件,Python Numpy中数据的常用的保存与读取方法

    在经常性读取大量的数值文件时(比如深度学习训练数据),可以考虑现将数据存储为Numpy格式,然后直接使用Numpy去读取,速度相比为转化前快很多. 下面就常用的保存数据到二进制文件和保存数据到文本文件 ...

  3. python读excel两列为字典_用python读取Excel并保存字典?一两行代码完成骚操作

    分享一个前几天晚上粉丝问的问题,觉得很实用的一个问题,用python读取Excel并保存字典,如何做? 下面是该同学问题截图和代码 代码截图是下面这样的 不知道大家第一眼看了这个代码,什么感受?我第一 ...

  4. 使用Vivado保存仿真波形数据并读取

    1.1 使用Vivado保存波形数据并读取 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)使用Vivado保存仿真波形数据并读取: 5)结束语. 1.1.2 本节引言 ...

  5. c#读取ini配置文件、将配置数据保存至ini文件

    全栈工程师开发手册 (作者:栾鹏) c#教程全解 c#读取ini配置文件.将配置数据保存至ini文件 测试代码 static void Main() {string value = readini(& ...

  6. pandas读取csv写入mysql_使用python的pandas库读取csv文件保存至mysql数据库

    第一:pandas.read_csv读取本地csv文件为数据框形式 data=pd.read_csv('G:\data_operation\python_book\chapter5\\sales.cs ...

  7. 【海康威视单个摄像头读取视频流并保存本地】

    [海康威视单个摄像头读取视频流并保存本地] 文前白话 代码 文前白话 本段代码作为之前一篇博客的补充: 链接: [OpenCV-python&实现多进程两个摄像头同时录入视频并保存]. 本段代 ...

  8. opencv2读取摄像头并保存为视频

    opencv2读取摄像头并保存为视频 #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui ...

  9. opencv-python读取摄像头视频流保存为视频

    opencv-python读取摄像头视频流保存为视频文件 opencv-python version:4.4.0.46 代码如下: import cv2# 通过cv2中的类获取视频流操作对象cap c ...

最新文章

  1. 西安交通大学计算机科学与技术学科评估,西安交通大学学科评估排名!附西安交大a类学科名单...
  2. Exchange 2007更改用户收发邮件大小限制
  3. MAVEN项目环境搭建
  4. SFB 项目经验-57-Skype for business-录音系统-你拥有吗(模拟线路)
  5. 【小米校招笔试】假如已知有n个人和m对好友关系(存于数字r)。如果两个人是直接或间接的好友(好友的好友的好友...),则认为他们属于同一个朋友圈,请写程序求出这n个人里一共有多少个朋友圈。
  6. sql语句换行_Spark随笔|关于Bucket Table与SQL语句转换
  7. three.js(五) 地形纹理混合
  8. 黑科技DeepFake检测方法:利用心跳做信号,还能「揪出」造假模型
  9. 语言中根号打法_知识的诅咒,数学老师在教学中不得不防的陷阱
  10. MediaWiki自动登陆和更新页面
  11. html怎么添加自动关机,按键精灵怎样设置自动关机
  12. 华硕服务器主板那个系列好,华硕主板型号性价比排行 华硕主板那个性价最好用...
  13. 计算机网络(一):网络层次划分及各层的网络协议
  14. 3.3Packet Tracer - 实施基本连接
  15. 迪尼斯神奇英语全32集含教材
  16. 一维码识别技术与二维码识别技术
  17. python访问陌生人qq空间_用Python登录好友QQ空间点赞的示例代码
  18. PS之立体台球制作步骤
  19. PHP入门需要多久?
  20. Echarts 当Y轴取值存在正负值的时候,x轴文字与x轴贴合(不在底部显示)

热门文章

  1. 漏洞分析丨HEVD-0x2.StackOverflowGS[win7x86]
  2. 使用Celery 容联云 异步发送验证码详解!!!
  3. 树莓派学习笔记(5):成功实现NAS家庭服务器(流媒体播放、文件共享及下载机)
  4. 传感器检测与转换技术QY-CG810B
  5. ASP.NET Core MVC中的viewmodel
  6. 四川大学c语言实验报告,四川大学-C语言程序设计精品课程申报网站
  7. 吉西他滨纳米载药细胞膜囊泡|红细胞囊泡包载的纳米药物(齐岳试剂)
  8. 测试人员都应该是好的产品人员
  9. 阿里p7程序员:生活压力大,有房贷不敢离职,离职股票就没了
  10. 阅文集团副总裁傅徐军:最佳技术架构选型方法论 1