1、修改数据库字段类型为geometry
ALTER TABLE t_test
ALTER COLUMN lnglat_geom TYPE geometry(Point,4326);
2、添加postgis依赖
<!-- postgis -->
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.5.0</version>
</dependency>
3、自定义抽象TypeHandler,子类可以是点,线,多点,多边形,看自己使用场景用哪个都行。
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgis.Geometry;
import org.postgis.PGgeometry;
/**
* @author kevin
*
*/
public abstract class AbstractGeometryTypeHandler<T extends Geometry> extends BaseTypeHandler<T> {
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
PGgeometry geometry = new PGgeometry();
geometry.setGeometry(parameter);
ps.setObject(i, geometry);
}
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
PGgeometry pGgeometry = (PGgeometry) rs.getObject(columnName);
if (pGgeometry == null) {
return null;
}
return (T) pGgeometry.getGeometry();
}
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
PGgeometry pGgeometry = (PGgeometry) rs.getObject(columnIndex);
if (pGgeometry == null) {
return null;
}
return (T) pGgeometry.getGeometry();
}
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
PGgeometry pGgeometry = (PGgeometry) cs.getObject(columnIndex);
if (pGgeometry == null) {
return null;
}
return (T) pGgeometry.getGeometry();
}
}
4、定义“坐标点”子类,继承上面的抽象类
import org.apache.ibatis.type.MappedTypes;
import org.postgis.Point;
/**
* 点,子类
* @author kevin
*
*/
@MappedTypes(Point.class)
public class PointTypeHandler extends AbstractGeometryTypeHandler<Point> {
}
5、定义“多坐标点”子类,继承上面的抽象类
import org.apache.ibatis.type.MappedTypes;
import org.postgis.MultiPoint;
/**
* 多点,子类
* @author kevin
*
*/
@MappedTypes(MultiPoint.class)
public class MultiPointTypeHandler extends AbstractGeometryTypeHandler<MultiPoint> {
}
6、定义“线”子类,继承上面的抽象类
import org.apache.ibatis.type.MappedTypes;
import org.postgis.LineString;
/**
* 线,子类
* @author kevin
*
*/
@MappedTypes(LineString.class)
public class LineStringTypeHandler extends AbstractGeometryTypeHandler<LineString> {
}
7、定义“多边形”子类,继承上面的抽象类
import org.apache.ibatis.type.MappedTypes;
import org.postgis.Polygon;
/**
* 多边形,子类
* @author kevin
*
*/
@MappedTypes(Polygon.class)
public class PolygonTypeHandler extends AbstractGeometryTypeHandler<Polygon> {
}
8、定义坐标点格式化工具类
import org.apache.commons.lang3.ArrayUtils;
import org.postgis.LineString;
import org.postgis.LinearRing;
import org.postgis.Point;
import org.postgis.Polygon;
/**
* 坐标点格式化工具类
*/
public class CorrdinateUtil {
/**
* 格式化Polygon类型:
* 将Vertexts字符串转换成Polygon类型
* @param vertexes 多边形围栏形状点(顺时针或逆时针): "double,double; double,double; ...;double,double"
* @return Polygon
*/
public static Polygon formatPolygon(String vertexes) throws Exception{
vertexes = CorrdinateUtil.stringUtils(vertexes);
String[] points = vertexes.split(";");
int length = points.length;
Point[] pointArray = new Point[length + 1];
for (int i = 0;i<length;i++){
String[] xy = points[i].split(",");
pointArray[i] = new Point(Double.parseDouble(xy[0]),Double.parseDouble(xy[1]));
}
//首尾两点一致,封闭形成多边形
String[] firstPoint = points[0].split(",");
pointArray[length] = new Point(Double.parseDouble(firstPoint[0]),Double.parseDouble(firstPoint[1]));
LinearRing linearRing = new LinearRing(pointArray);
Polygon polygon = new Polygon(new LinearRing[]{linearRing});
return polygon;
}
/**
* 格式化Point类型:
* 将Vertexts字符串转换成Point类型
* @param vertexes 点坐标:"double,double"
* @return Point
*/
public static Point formatPoint(String vertexes) throws Exception{
vertexes = CorrdinateUtil.stringUtils(vertexes);
String[] split = vertexes.split(",");
Point point = new Point(Double.parseDouble(split[0]), Double.parseDouble(split[1]));
point.dimension = 2;
//WGS84坐标系,也就是GPS使用的坐标
point.srid = 4326;
return point;
}
/**
* 经纬度转为Point对象
*
* @param lnglat
* @return
*/
public static Point lnglatToPoint(Double[] lnglat) {
if(ArrayUtils.isNotEmpty(lnglat)) {
String vertexes = String.valueOf(lnglat[0])+","+String.valueOf(lnglat[1]);
try {
return CorrdinateUtil.formatPoint(vertexes);
} catch (Exception e) {
}
}
return null;
}
/**
* 格式化LineString类型:
* 将Vertexts字符串转换成LineString类型
* @param vertexes 折线点: "double,double; double,double; ...;double,double"
* @return LineString
*/
public static LineString formatLineString(String vertexes) throws Exception{
vertexes = CorrdinateUtil.stringUtils(vertexes);
String[] points = vertexes.split(";");
int length = points.length;
Point[] pointArray = new Point[length];
for (int i = 0;i<length;i++){
String[] xys = points[i].split(",");
pointArray[i] = new Point(Double.parseDouble(xys[0]),Double.parseDouble(xys[1]));
}
LineString lineString = new LineString(pointArray);
return lineString;
}
//过滤""号
public static String stringUtils(String str){
return str.replace("\"","");
}
}
9、定义数据库实体PO对象
import java.io.Serializable;
import org.postgis.Point;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
//此处改为自己的TypeHandler包路径
import *.*.*.*.ArrayTypeHandler;
import *.*.*.*.PointTypeHandler;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
/**
* Entity
*
* @author kevin
*/
@Data
@TableName(autoResultMap = true)
public class Test implements Serializable{
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
/**
* 经纬度
*/
@TableField(value = "lnglat", typeHandler = ArrayTypeHandler.class)
private Double[] lnglat;
/**
* 地图聚合点
*/
@TableField(value = "lnglat_geom", typeHandler = PointTypeHandler.class)
private Point lnglatGeom;
/**
* 位置
*/
@TableField("location")
private String location;
/**
* 是否删除
*/
@TableField(value = "is_deleted", fill = FieldFill.INSERT)
@TableLogic //逻辑删除
private Integer isDeleted;
/**
* 版本变更号
*/
@Version //乐观锁
@TableField("revision")
private Integer revision;
}
10、使用
//地图经纬度
Double[] lnglat = new Double[];
lnglat[0] = 104.345666;
lnglat[1] = 39.99999;
Test entity = new Test();
//用工具类转换为地图坐标点
entity.setLnglatGeom(CorrdinateUtil.lnglatToPoint(lnglat));
//调用mybatisplus的保存
this.baseMapper.insert(entiry);