geomtry string 转换_mybatis几何geometry类型转换

示例:github地址

利用mybatis从postgresql中读取geometry类型字段到实体类中,可以多种接受方式:

1. 直接利用String去接受wkt

2. 利用mybatis在写入实体类时将wkt转换为geometry类型

第一种方式:非常简单粗暴,不过在代码中需要用到geometry类型时,都会写上如下代码:

try {

......

JtsUtils.createLineStringByWKT(wkt)

......

} catch (ParseException) {

e.printStackTrace();

}

如果代码中存在较多的地方用到几何运算相关的内容,这个在出现很多次。个人认为没有太大必要如此繁琐。当然几何运用的地方较少就当我没有说,直接跳过本文余下内容。

第二种方式:利用mybatis的自定义类型转换的功能,在写入实体时进行统一转换,同时在实体转换为数据库类型是将geometry类型转换为wkt字符串。

废话不多说,直接上代码:

AbstractGeometryTypeHandler.java 几何转换的父类

package com.threestone.common.mybatisTypeHandler;

import com.threestone.utils.JtsUtils;

import com.vividsolutions.jts.geom.Geometry;

import com.vividsolutions.jts.io.WKTReader;

import org.apache.ibatis.type.BaseTypeHandler;

import org.apache.ibatis.type.JdbcType;

import org.apache.ibatis.type.MappedJdbcTypes;

import java.sql.CallableStatement;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

/**

* 字符串转为JTS对应的几何类型

* Created by Friday on 2019/6/19.

*/

@MappedJdbcTypes({JdbcType.OTHER})

public abstract class AbstractGeometryTypeHandler extends BaseTypeHandler {

/**

* 把Java类型参数转换为对应的数据库类型

*

* @param ps 当前的PreparedStatement对象

* @param i 当前参数位置

* @param parameter 当前参数的Java对象

* @param jdbcType 当前参数的数据库类型

* @throws SQLException

*/

public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {

String wkt = JtsUtils.toEwkt(parameter);

ps.setObject(i, wkt);

}

/**

* 获取数据结果集时把数据库类型转换为对应的Java类型

*

* @param rs 当前的结果集

* @param columnName 当前的字段名称

* @return 转换后的Java对象

* @throws SQLException

*/

public T getNullableResult(ResultSet rs, String columnName) throws SQLException {

String wkt = (String) rs.getObject(columnName);

return (T) getGeometryFromWkt(wkt);

}

/**

* 通过字段位置获取字段数据时把数据库类型转换为对应的Java类型

*

* @param rs 当前的结果集

* @param columnIndex 当前字段的位置

* @return 转换后的Java对象

* @throws SQLException

*/

public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {

String wkt = (String) rs.getObject(columnIndex);

return (T) getGeometryFromWkt(wkt);

}

/**

* 调用存储过程后把数据库类型的数据转换为对应的Java类型

*

* @param cs 当前的CallableStatement执行后的CallableStatement

* @param columnIndex 当前输出参数的位置

* @return

* @throws SQLException

*/

public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {

String wkt = (String) cs.getObject(columnIndex);

return (T) getGeometryFromWkt(wkt);

}

// 从WKT中获取几何

private Geometry getGeometryFromWkt(String wkt) {

WKTReader reader = new WKTReader();

Geometry geometry = null;

try {

geometry = reader.read(wkt);

} catch (Exception e) {

e.printStackTrace();

}

if (geometry == null) {

return null;

}

return geometry;

}

}

LineStringTypeHandler.java 几何转换的直线类

package com.threestone.common.mybatisTypeHandler;

import com.vividsolutions.jts.geom.LineString;

import org.apache.ibatis.type.MappedTypes;

/**

* WKT转为LineString

* Created by Friday on 2019/6/19.

*/

@MappedTypes(LineString.class)

public class LineStringTypeHandler extends AbstractGeometryTypeHandler{

}

PointTypeHandler.java 几何转换的点类

package com.threestone.common.mybatisTypeHandler;

import com.vividsolutions.jts.geom.Point;

import org.apache.ibatis.type.MappedTypes;

/**

* WKT转为Point

* Created by Friday on 2019/6/19.

*/

@MappedTypes(Point.class)

public class PointTypeHandler extends AbstractGeometryTypeHandler {

}

其他几何类型polygon等也是如此继承即可。

JtsUtils.java 工具类

// 将几何类型转换为wkt字符串

public static String toEwkt(Geometry geom) {

if (geom == null) {

return null;

}

String type = geom.getGeometryType().toUpperCase();

switch (type) {

case "POINT": {

Coordinate coor = geom.getCoordinate();

return "POINT(" + formatCoordinate(coor) + ")";

}

case "MULTIPOINT": {

return coordinateToEwkt("MULTIPOINT(", geom.getCoordinates(), ")");

}

case "LINESTRING": {

return coordinateToEwkt("LINESTRING(", geom.getCoordinates(), ")");

}

case "POLYGON": {

return coordinateToEwkt("POLYGON((", geom.getCoordinates(), "))");

}

case "MULTILINESTRING": {

StringBuffer sb = new StringBuffer();

sb.append("MULTILINESTRING(");

sb.append(multiGeometryFormat(geom));

sb.append(")");

return sb.toString();

}

case "MULTIPOLYGON": {

StringBuffer sb = new StringBuffer();

sb.append("MULTIPOLYGON(");

sb.append(multiGeometryFormat(geom));

sb.append(")");

return sb.toString();

}

case "GEOMETRYCOLLECTION": {

StringBuffer sb = new StringBuffer();

int num = geom.getNumGeometries();

sb.append("GEOMETRYCOLLECTION(");

for (int j = 0; j < num; j++) {

Geometry element = geom.getGeometryN(j);

String subType = element.getGeometryType().toUpperCase();

if ("POINT".equals(subType)) {

sb.append("POINT(" + formatCoordinate(element.getCoordinate()) + ")");

} else if ("LINESTRING".equals(subType)) {

sb.append(coordinateToEwkt("LINESTRING(", element.getCoordinates(), ")"));

} else if ("POLYGON".equals(subType)) {

sb.append(coordinateToEwkt("POLYGON((", element.getCoordinates(), "))"));

}

if (j < num - 1) {

sb.append(",");

}

}

sb.append(")");

return sb.toString();

}

}

return null;

}

private static String formatCoordinate(Coordinate coordinate) {

if (Double.isNaN(coordinate.z)) {

coordinate.z = 0;

}

return df.format(coordinate.x) + " " + df.format(coordinate.y) + " " + (coordinate.z != 0 ? df.format(coordinate.z) : "0");

}

public static String coordinateToEwkt(String prefix, Coordinate[] coordinates, String suffix) {

StringBuffer sb = new StringBuffer();

sb.append(prefix);

boolean append = false;

for (Coordinate coordinate : coordinates) {

if (append) {

sb.append(",");

}

sb.append(formatCoordinate(coordinate));

append = true;

}

sb.append(suffix);

return sb.toString();

}

接下来就需要对xml进行改写

......

st_asewkt("geom") as "geom"

insert into link(

)

values

(

ST_GEOMFROMTEXT(#{item.geom, typeHandler=com.threestone.common.mybatisTypeHandler.LineStringTypeHandler})

NULL

)

xml中需要注意我们的数据读取还是读取的wkt字符串,只是在mybatis写入实体时进行了转换。

同时需要注意数据写入数据库时,此时实体类中的geom字段为几何类型,但是mybatis它不认识,这样也需要对其进行标注,告诉mybatis这个字段是geometry类型需要用到我们定义的转换器进行转换。

ST_GEOMFROMTEXT(#{item.geom, typeHandler=com.threestone.common.mybatisTypeHandler.LineStringTypeHandler})

到此大功告成,如有什么不对的地方欢迎指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java 中,PostgreSQL 中的 `geometry` 类型通常被映射为 `PGgeometry` 类型。`PGgeometry` 是由 `org.postgis` 包提供的一个类,它表示 PostGIS 中的几何对象。 要使用 `PGgeometry` 类型,需要在项目中包含 PostGIS 的相关依赖。如果使用 Maven 管理项目,可以在 pom.xml 文件中添加以下依赖: ``` <dependency> <groupId>org.postgis</groupId> <artifactId>postgis-jdbc</artifactId> <version>2.5.1</version> </dependency> ``` 使用 `PGgeometry` 类型可以很方便地将 PostgreSQL 中的 `geometry` 类型与 Java 中的数据类型相互转换。例如,假设有一个 `mytable` 表,其中包含一个名为 `geom` 的 `geometry` 列,可以使用以下代码从数据库中检索该列的值: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import org.postgis.PGgeometry; public class GeometryExample { public static void main(String[] args) throws Exception { // Connect to the database String url = "jdbc:postgresql://localhost/mydatabase"; String user = "myusername"; String password = "mypassword"; Connection conn = DriverManager.getConnection(url, user, password); // Prepare and execute a SELECT statement String sql = "SELECT geom FROM mytable"; PreparedStatement stmt = conn.prepareStatement(sql); ResultSet rs = stmt.executeQuery(); // Process the results while (rs.next()) { PGgeometry geom = (PGgeometry) rs.getObject("geom"); // Do something with the geometry object // ... } // Clean up rs.close(); stmt.close(); conn.close(); } } ``` 在这个例子中,`rs.getObject("geom")` 方法返回一个 `Object` 类型的对象,需要将其转换为 `PGgeometry` 类型的对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值