java程序解析jts的geometry类型并入PG数据库

news/2024/9/22 8:27:10/

场景

GIS开发,会有需要将jts包中的geometry类型数据存入pg(postgis扩展后)数据库的需求。

工程是springboot,mybatis作为持久层框架。

解决方案

1. pg的geometry字段对应的类型为geometry类型,比如:

2. 定义geometry的typeHandler,在mapper.xml中声明使用

背景知识

postgis的geometry字段存储的数据在内部是二进制数据(即PostgreSQL的bytea数据类型),WKB/EWKB也是二进制数据类型。字符集为ascii。

但是通常我们查询数据库时,geometry数据会表示为HEXEWKB数据类型(EWKB对应的十六进制形式)。例如执行以下查询:

SELECT ST_GeomFromEWKT('POINT (1 1)'); 
-- 或者直接从一个有geometry的表里查询出来一个geometry
select geom from i_table limit 1; -- geom就是geometry类型的字段

得到的结果为:

这和执行以下两个查询得到的结果是一样的:

SELECT ST_AsHEXEWKB(ST_GeomFromEWKT('POINT (1 1)')); 
SELECT encode(ST_AsEWKB(ST_GeomFromEWKT('POINT (1 1)')), 'hex'); 

 详情可以查看这篇文章:

PostGIS空间数据类型的组织与表达(一):Geometry - 知乎

所以存储时需要将jts的geometry对象转换为ewkb的二进制格式即可存入pg的geometry字段。

查询时也只需要将二进制转换为geometry即可。

实现

typehandler

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKBReader;
import org.locationtech.jts.io.WKBWriter;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class GeometryTypeHandler implements TypeHandler<Geometry> {@Overridepublic void setParameter(PreparedStatement preparedStatement, int i, Geometry geometry, JdbcType jdbcType) throws SQLException {int dimension = geometry.getDimension();dimension = (dimension == 2 || dimension == 3) ? dimension : 2;WKBWriter wkbWriter = new WKBWriter(dimension, true);final byte[] write = wkbWriter.write(geometry);preparedStatement.setBytes(i, write);}@Overridepublic Geometry getResult(ResultSet resultSet, String s) throws SQLException {final byte[] bytes = resultSet.getBytes(s);return bytes2Geometry(bytes);}@Overridepublic Geometry getResult(ResultSet resultSet, int i) throws SQLException {final byte[] bytes = resultSet.getBytes(i);return bytes2Geometry(bytes);}@Overridepublic Geometry getResult(CallableStatement callableStatement, int i) throws SQLException {final byte[] bytes = callableStatement.getBytes(i);return bytes2Geometry(bytes);}private Geometry bytes2Geometry(byte[] bytes) {WKBReader wkbReader = new WKBReader();try {return wkbReader.read(bytes);} catch (Exception e) {e.printStackTrace();}return null;}
}

xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jfqqq.vector.mapper.IGeomMapper"><resultMap id="resultMap" type="com.jfqqq.vector.entity.MyGeom"><result property="gid" column="gid"/><result property="version" column="version"/><result property="geom" column="geom"typeHandler="com.jfqqq.vector.typeHandler.GeometryTypeHandler"/><result property="createTime" column="create_time"/></resultMap><sql id="SELECT_BASE_COLUMN">gid, version, st_asewkb(geom) as geom, create_time</sql><insert id="insert" parameterType="com.jfqqq.vector.entity.MyGeom" useGeneratedKeys="true" keyProperty="gid">insert into i_geometry(version, geom, create_time)values (#{version},#{geom,typeHandler=com.jfqqq.vector.typeHandler.GeometryTypeHandler},now())</insert><select id="queryByBoxAndVersion"  resultMap="resultMap">select <include refid="SELECT_BASE_COLUMN" /> from i_geometrywhere version = #{version} and st_intersects(geom, st_makeenvelope(${bbox.minX}, ${bbox.minY}, ${bbox.maxX}, ${bbox.maxY}, 4326)) = true;</select>
</mapper>

http://www.ppmy.cn/news/40403.html

相关文章

面向对象三大基本特征

面向对象三大基本特征封装继承多态封装 把客观事物封装成抽象的一个类&#xff0c;并且类可以把自己的数据和方法只让可信的类或者对象来操作。 一个类就是一个封装的数据&#xff0c;以及操作这些数据的代码的逻辑实体。 在一个对象的内部&#xff0c;某些代码或者是某些数…

NTP8835(30W内置DSP双通道D类音频功放芯片)

数字功放是一种具有失真小、噪音低、动态范围大等特点的音频功率放大器&#xff1b;由工采网代理的韩国耐福旗下NTP系列专业功率放大器是ClassD功放的一个新里程碑。 NTP8835是一款高性能、高保真功率驱动集成全数字音频放大器&#xff0c;工作电压范围&#xff1a;7V&#xf…

linux上的无线网卡灯不亮

linux上的无线网卡灯不亮&#xff0c;查看了型号后&#xff0c;RTL8811CU 这个方法&#xff0c;可以说是一步到位 先克隆 git 仓库 git clone https://github.com/morrownr/8821cu-20210916.git cd 8821cu-20210916 直接运行安装脚本 ./install-driver.sh 安装完会问两个…

c语言获取天气信息示例(通过心知天气api获取)

关于curl/curl.h库的使用&#xff0c;参考下述内容&#xff1a; VS2010编译libcurl库并简单使用(c语言)_西晋的no1的博客-CSDN博客 1.先在心知天气注册&#xff0c;获取私钥&#xff1a; https://www.seniverse.com/dashboard 2.将私钥放入下述url中【私钥” 直接请求方式】 将…

Spark IPmapping方案

使用数据中的uid imei imsi mac androidid uuid 等标识字段&#xff0c;按优先级取一个标识&#xff0c;作为这条数据的用户唯一标识。有严重的漏洞。第一天登陆了&#xff0c;取uid&#xff0c;第二天没登录&#xff0c;取imei 是一个人吗。 在现实的日志数据中&#xff0c…

高性能网络SIG月度动态:virtio-net 支持动态中断调节,SMC v2 协议增加新扩展

高性能网络 SIG&#xff08;Special Interest Group&#xff09; &#xff1a;在云计算时代&#xff0c;软硬件高速发展&#xff0c;云原生、微服务等新的应用形态兴起&#xff0c;让更多的数据在进程之间流动&#xff0c;而网络则成为了这些数据流的载体&#xff0c;在整个云时…

Msray-Plus采集工具帮您快速获取数据,让您的市场营销更加精细

随着互联网的不断发展&#xff0c;数据已经成为企业竞争的重要资产之一。市场营销人员需要通过数据来了解客户需求、市场趋势和竞争对手情况&#xff0c;从而制定更加精细的市场营销策略。然而&#xff0c;采集数据并不是一件容易的事情&#xff0c;需要耗费大量的时间和精力。…

Microsoft Viva Connections部署方案

目录 前言 一、Microsoft Viva Connections介绍 二、部署方案的步骤 2.1 对企业现有门户进行分析和整理