MySQL的Geometry数据处理之WKT方案

news2024/7/5 0:44:11

WKT全称是Well-Known Text。它是一种表达几何信息的字符串内容。

比如:点可以用WKT表示为POINT (3 3);线可以用WKT表示为LINESTRING (1 1, 2 2)。

Mysql数据库可以存储一些几何类型数据,比如点、线、多边形等。这在一些基于地理信息的服务上比较有用,比如在地图上的商店地理坐标(点),或者路径规划中的行进路线(线)等。

目前Mysql 8.版本,它也是支持几何类型数据结构。

一、Geometry使用

一般我们会使用 org.locationtech.jts的 Geometry类来表达几何信息。

引入依赖:

        <!--Geometry工具库依赖-->
        <dependency>
            <groupId>org.locationtech.jts</groupId>
            <artifactId>jts-core</artifactId>
            <version>1.19.0</version>
        </dependency>

1、Geometry使用

使用Geometry进行几何结构构建。

GeometryFactory geometryFactory = new GeometryFactory();
Geometry geometry = geometryFactory.createPoint(new Coordinate(3, 3));

点集合

GeometryFactory geometryFactory = new GeometryFactory();
LineString lineString = geometryFactory
        .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) });

线

GeometryFactory geometryFactory = new GeometryFactory();
LineString lineString = geometryFactory
        .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) });

线集合

GeometryFactory geometryFactory = new GeometryFactory();
MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[] {
        geometryFactory
                .createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
        geometryFactory
                .createLineString(new Coordinate[] { new Coordinate(3, 3), new Coordinate(4, 4) })
});

GeometryFactory geometryFactory = new GeometryFactory();
Polygon polygon = geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1),
 					new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });

面集合

GeometryFactory geometryFactory = new GeometryFactory();
MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[] {
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                new Coordinate(3, 3), new Coordinate(1, 1) }),
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(4, 4), new Coordinate(5, 5),
                new Coordinate(6, 6), new Coordinate(4, 4) })
});

几何信息集合

GeometryFactory geometryFactory = new GeometryFactory();
GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[] {
        geometryFactory.createPoint(new Coordinate(1, 1)),
        geometryFactory.createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
        geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                new Coordinate(3, 3), new Coordinate(1, 1) })
});

下面我们需要将这些结构保存到Mysql数据库中。

由于org.locationtech.jts.geom.Geometry和Mysql内部存储的Geometry不匹配,需要转换操作。

项目中使用 MyBatis-Plus,自定义字段类型处理器来实现MySQL的Geometry数据处理之WKT方案。

二、自定义类型处理器

项目中使用 MyBatis-Plus,自定义字段类型处理器来实现MySQL的Geometry数据处理之WKB方案。
MyBatis-Plus字段类型处理器:https://baomidou.com/guides/type-handler/

1、完整TypeHandler类

public class GeometryTypeWKTHandler extends BaseTypeHandler<Geometry> {
    private static GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326);

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Geometry parameter, JdbcType jdbcType) throws SQLException {
        String str = serializeGeometry(parameter);
        ps.setString(i, str);
        ;
    }

    @Override
    public Geometry getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String str = rs.getString(columnName);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    @Override
    public Geometry getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String str = rs.getString(columnIndex);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    @Override
    public Geometry getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String str = cs.getString(columnIndex);
        try {
            return deserializeGeometry(str);
        } catch (ParseException e) {
            throw new SQLException(e);
        }
    }

    /**
     * 序列化
     *
     * @param geometry
     * @return
     */
    private static String serializeGeometry(Geometry geometry) {
        WKTWriter writer = new WKTWriter(2);
        return writer.write(geometry);
    }

    /**
     * 反序列化
     *
     * @param wkt
     * @return
     * @throws ParseException
     */
    private static Geometry deserializeGeometry(String wkt) throws ParseException {
        return new WKTReader(factory).read(wkt);
    }

}

WKTWriter会将org.locationtech.jts.geom.Geometry转换为String,然后交由SQL语句处理;

WKTReader会将SQL语句读取出来的String转换为org.locationtech.jts.geom.Geometry对象。

在这里插入图片描述

三、使用自定义类型处理器

自定义类型处理器主要使用String类型作为媒介来和SQL语句联系。那么SQL语句是如何把String转成
Mysql的Geometry内部结构的呢?这就需要借助ST_GeomFromText和ST_AsText常用函数。

  • ST_GeomFromText则可以将WKT(字符串)格式的几何信息转换为Mysql内部的Geometry结构。比如:ST_GeomFromText(‘MULTIPOINT (1 1, 2 2, 3 3)’)
ST_GeomFromText('MULTIPOINT (1 1, 2 2, 3 3)')
  • ST_AsText则可以将Mysql内部的Geometry结构转换为WKT(字符串)格式的几何信息。

在这里插入图片描述
所以,在Mybatis的Mapper XML中,需要我们手动借助上面函数处理几何信息字段或者使用 Mybatis-plus的 Mapper接口方法操作。

创建表SQL语句:

CREATE TABLE `t_geo_wkt` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `del_flag` char(1) DEFAULT '0' COMMENT '删除标记,0未删除,1已删除',
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `geo_type` varchar(255) DEFAULT NULL COMMENT 'geo_type',
  `geo` geometry NOT NULL COMMENT 'geo几何数据-GCJ02',
  PRIMARY KEY (`id`),
  SPATIAL KEY `idx_geo` (`geo`) COMMENT '空间数据索引'
) ENGINE=InnoDB COMMENT='几何数据wkt表';

1、DO类

@Getter
@Setter
@TableName("t_geo_wkt")
public class GeoWktDO implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 创建时间
     */
    @TableField("create_time")
    private LocalDateTime createTime;

    /**
     * 修改时间
     */
    @TableField("update_time")
    private LocalDateTime updateTime;

    /**
     * 删除标记,0未删除,1已删除
     */
    @TableField("del_flag")
    private String delFlag;

    /**
     * 名称
     */
    @TableField("name")
    private String name;

    /**
     * geo_type
     */
    @TableField("geo_type")
    private String geoType;

    @TableField("geo")
    private Geometry geo;

}

2、完整Mapper 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.charge.ws.core.mapper.GeoWktMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.charge.ws.core.entity.GeoWktDO">
        <id column="id" property="id"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="del_flag" property="delFlag"/>
        <result column="name" property="name"/>
        <result column="geo_type" property="geoType"/>
        <result column="geo" property="geo" typeHandler="com.charge.ws.handler.jts.GeometryTypeWKTHandler"
                jdbcType="BLOB"/>
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id
        , create_time, update_time, del_flag, name, geo_type, ST_AsText(geo) AS geo
    </sql>

    <select id="findAll" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List"/>
        FROM t_geo_wkt
    </select>

    <select id="findById" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_List"/>
        FROM t_geo_wkt
        WHERE id = #{id}
    </select>

    <insert id="insertOne">
        INSERT INTO t_geo_wkt(create_time, update_time, del_flag, name, geo_type, geo)
        VALUES (now(), now(), #{geoWktDO.delFlag}, #{geoWktDO.name}, #{geoWktDO.geoType},
                ST_GeomFromText(#{geoWktDO.geo, typeHandler=com.charge.ws.handler.jts.GeometryTypeWKTHandler, jdbcType=BLOB}))
    </insert>

    <insert id="insertList">
        INSERT INTO t_geo_wkt(id, create_time, update_time, del_flag, name, geo_type, geo) values
        <foreach item="item" collection="geoWktDOList" separator=",">
            (#{item.id}, now(), now(), #{item.delFlag}, #{item.name}, #{item.geoType},
            ST_GeomFromText(#{item.geo, typeHandler=com.charge.ws.handler.jts.GeometryTypeWKTHandler, jdbcType=BLOB}))
        </foreach>
    </insert>

    <insert id="insertGeometryCollection">
        insert into t_geo_wkt(id, create_time, update_time, del_flag, name, geo_type, geo)
        VALUES (#{geoWktDO.id}, now(), now(), #{geoWktDO.delFlag}, #{geoWktDO.name}, #{geoWktDO.geoType},
                ST_GeomCollFromText(#{geoWktDO.geo, typeHandler=com.charge.ws.handler.jts.GeometryTypeWKTHandler, jdbcType=BLOB}))
    </insert>

    <update id="updateOne">
        update t_geo_wkt
        set geo         = ST_GeomFromText(#{geoWktDO.geo, typeHandler=com.charge.ws.handler.jts.GeometryTypeWKTHandler, jdbcType=BLOB}),
            update_time = now()
        where id = #{geoWktDO.id}
    </update>


</mapper>

3、Mapper类

public interface GeoWktMapper extends BaseMapper<GeoWktDO> {

    List<GeoWktDO> findAll();

    GeoWktDO findById(@Param("id") Long id);

    int insertOne(@Param("geoWktDO") GeoWktDO geoWktDO);

    int insertList(@Param("geoWktDOList") List<GeoWktDO> geoWktDOList);

    int insertGeometryCollection(@Param("geoWktDO") GeoWktDO geoWktDO);

    int updateOne(@Param("geoWktDO") GeoWktDO geoWktDO);

}

四、示例测试

1、单元测试

    @Autowired
    private GeoWktMapper geoWktMapper;

    @Test
    public void testFindAll() {
        List<GeoWktDO> doList = geoWktMapper.findAll();
        System.out.println(doList);
    }

    @Test
    public void testGetById() {
        GeoWktDO geoWktDO = geoWktMapper.findById(1L);
        System.out.println(geoWktDO);
    }

    @Test
    public void testInsert1() {
        // 点
        GeometryFactory geometryFactory = new GeometryFactory();
        Geometry point = geometryFactory.createPoint(new Coordinate(108.939645, 34.343205));

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("点");
        saveDO.setGeoType("1");
        saveDO.setGeo(point);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert2() {
        // 点集合
        GeometryFactory geometryFactory = new GeometryFactory();
        LineString lineString = geometryFactory
                .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207),
                        new Coordinate(1, 1)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("点集合");
        saveDO.setGeoType("2");
        saveDO.setGeo(lineString);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert3() {
        // 线
        GeometryFactory geometryFactory = new GeometryFactory();
        LineString lineString = geometryFactory
                .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207),
                        new Coordinate(2, 2), new Coordinate(3, 3)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("线");
        saveDO.setGeoType("3");
        saveDO.setGeo(lineString);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert4() {
        // 线集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[]{
                geometryFactory
                        .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207)}),
                geometryFactory
                        .createLineString(new Coordinate[]{new Coordinate(108.939648, 34.343208), new Coordinate(108.939649, 34.343209)})
        });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("线集合");
        saveDO.setGeoType("4");
        saveDO.setGeo(multiLineString);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert5() {
        // 面
        GeometryFactory geometryFactory = new GeometryFactory();
        Polygon polygon = geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1),
                new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面");
        saveDO.setGeoType("5");
        saveDO.setGeo(polygon);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert6() {
        // 面集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2),
                        new Coordinate(3, 3), new Coordinate(1, 1)}),
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(4, 4), new Coordinate(5, 5),
                        new Coordinate(6, 6), new Coordinate(4, 4)})
        });


        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面集合");
        saveDO.setGeoType("6");
        saveDO.setGeo(multiPolygon);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert7() {
        // 几何信息集合
        GeometryFactory geometryFactory = new GeometryFactory();
        GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[]{
                geometryFactory.createPoint(new Coordinate(1, 1)),
                geometryFactory.createLineString(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2)}),
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2),
                        new Coordinate(3, 3), new Coordinate(1, 1)})
        });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("几何信息集合");
        saveDO.setGeoType("7");
        saveDO.setGeo(geometryCollection);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert8() {
        // 面-点集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiPoint multiPoint = geometryFactory.createMultiPointFromCoords(
                new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面-点集合");
        saveDO.setGeoType("8");
        saveDO.setGeo(multiPoint);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testInsert9() {
        // linearRing
        // geoWktMapper.insert(saveDO) 支持 LinearRing
        /**
         *  ==>  Preparing: INSERT INTO t_geo_wkt ( del_flag, name, geo_type, geo ) VALUES ( ?, ?, ?, ? )
         *  ==> Parameters: 0(String), linearRing(String), 8(String), [B@1cd853ee(byte[])
         *  <==    Updates: 1
         */
        GeometryFactory geometryFactory = new GeometryFactory();
        LinearRing linearRing = geometryFactory.createLinearRing(new Coordinate[] { new Coordinate(1, 1),
                new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("linearRing");
        saveDO.setGeoType("8");
        saveDO.setGeo(linearRing);
        geoWktMapper.insert(saveDO);
    }

    @Test
    public void testUpdateById() {
        GeometryFactory geometryFactory = new GeometryFactory();
        Coordinate coordinate = new Coordinate(2, 2);
        Geometry point = geometryFactory.createPoint(coordinate);
        GeoWktDO updateDO = new GeoWktDO();
        updateDO.setId(1L);
        updateDO.setGeo(point);
        geoWktMapper.updateById(updateDO);
    }

    /**
     * geoWktMapper.insert(saveDO);都支持。
     * 自定义 xml,使用函数也支持。
     */
    @Test
    public void testInsertOne1() {
        // 点
        GeometryFactory geometryFactory = new GeometryFactory();
        Geometry point = geometryFactory.createPoint(new Coordinate(108.939645, 34.343205));

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("点-InsertOne");
        saveDO.setGeoType("1");
        saveDO.setGeo(point);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne2() {
        // 点
        // 点集合
        GeometryFactory geometryFactory = new GeometryFactory();
        LineString lineString = geometryFactory
                .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207),
                        new Coordinate(1, 1)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("点-InsertOne");
        saveDO.setGeoType("1");
        saveDO.setGeo(lineString);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne3() {
        // 线
        GeometryFactory geometryFactory = new GeometryFactory();
        LineString lineString = geometryFactory
                .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207),
                        new Coordinate(2, 2), new Coordinate(3, 3)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("线-InsertOne");
        saveDO.setGeoType("3");
        saveDO.setGeo(lineString);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne4() {
        // 线集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[]{
                geometryFactory
                        .createLineString(new Coordinate[]{new Coordinate(108.939645, 34.343205), new Coordinate(108.939647, 34.343207)}),
                geometryFactory
                        .createLineString(new Coordinate[]{new Coordinate(108.939648, 34.343208), new Coordinate(108.939649, 34.343209)})
        });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("线集合-InsertOne");
        saveDO.setGeoType("4");
        saveDO.setGeo(multiLineString);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne5() {
        // 面
        GeometryFactory geometryFactory = new GeometryFactory();
        Polygon polygon = geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1),
                new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面-InsertOne");
        saveDO.setGeoType("5");
        saveDO.setGeo(polygon);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne6() {
        // 面集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2),
                        new Coordinate(3, 3), new Coordinate(1, 1)}),
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(4, 4), new Coordinate(5, 5),
                        new Coordinate(6, 6), new Coordinate(4, 4)})
        });


        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面集合-InsertOne");
        saveDO.setGeoType("6");
        saveDO.setGeo(multiPolygon);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne7() {
        // 几何信息集合
        GeometryFactory geometryFactory = new GeometryFactory();
        GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[]{
                geometryFactory.createPoint(new Coordinate(1, 1)),
                geometryFactory.createLineString(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2)}),
                geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2),
                        new Coordinate(3, 3), new Coordinate(1, 1)})
        });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("几何信息集合-InsertOne");
        saveDO.setGeoType("7");
        saveDO.setGeo(geometryCollection);
        // 两个都可以
        geoWktMapper.insertOne(saveDO);
        //geoWktMapper.insertGeometryCollection(saveDO);
    }

    @Test
    public void testInsertOne8() {
        // 面-点集合
        GeometryFactory geometryFactory = new GeometryFactory();
        MultiPoint multiPoint = geometryFactory.createMultiPointFromCoords(
                new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3)});

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("面-点集合-InsertOne");
        saveDO.setGeoType("8");
        saveDO.setGeo(multiPoint);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testInsertOne9() {
        // linearRing
        // st_geomfromtext 不支持 LinearRing
        /**
         *  ==>  Preparing: INSERT INTO t_geo_wkt ( del_flag, name, geo_type, geo ) VALUES ( ?, ?, ?, ? )
         *  ==> Parameters: 0(String), linearRing(String), 8(String), [B@1cd853ee(byte[])
         *  <==    Updates: 1
         */
        GeometryFactory geometryFactory = new GeometryFactory();
        LinearRing linearRing = geometryFactory.createLinearRing(new Coordinate[] { new Coordinate(1, 1),
                new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });

        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setDelFlag(CommonConstants.DELETE_FLAG_NORMAL);
        saveDO.setName("linearRing");
        saveDO.setGeoType("8");
        saveDO.setGeo(linearRing);
        geoWktMapper.insertOne(saveDO);
    }

    @Test
    public void testUpdateOne() {
        GeometryFactory geometryFactory = new GeometryFactory();
        Coordinate coordinate = new Coordinate(22, 22);
        Geometry point = geometryFactory.createPoint(coordinate);
        GeoWktDO saveDO = new GeoWktDO();
        saveDO.setId(10L);
        saveDO.setGeo(point);
        geoWktMapper.updateOne(saveDO);
    }

    @Test
    public void testInsertList() {
        List<GeoWktDO> doList = new ArrayList<>();
        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            Coordinate coordinate = new Coordinate(3, 3);
            Geometry point = geometryFactory.createPoint(coordinate);
            saveDO.setGeo(point);
            doList.add(saveDO);
        }

        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            LineString lineString = geometryFactory
                    .createLineString(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2)});
            saveDO.setGeo(lineString);
            doList.add(saveDO);
        }

        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            MultiLineString multiLineString = geometryFactory.createMultiLineString(new LineString[]{
                    geometryFactory
                            .createLineString(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2)}),
                    geometryFactory
                            .createLineString(new Coordinate[]{new Coordinate(3, 3), new Coordinate(4, 4)})
            });
            saveDO.setGeo(multiLineString);
            doList.add(saveDO);
        }

        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            MultiPolygon multiPolygon = geometryFactory.createMultiPolygon(new Polygon[]{
                    geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2),
                            new Coordinate(3, 3), new Coordinate(1, 1)}),
                    geometryFactory.createPolygon(new Coordinate[]{new Coordinate(4, 4), new Coordinate(5, 5),
                            new Coordinate(6, 6), new Coordinate(4, 4)})
            });
            saveDO.setGeo(multiPolygon);
            doList.add(saveDO);
        }

        // st_geomfromtext 不支持 LinearRing
         //{
         //    GeoWktDO saveDO = new GeoWktDO();
         //    GeometryFactory geometryFactory = new GeometryFactory();
         //    LinearRing linearRing = geometryFactory.createLinearRing(new Coordinate[] { new Coordinate(1, 1),
         //            new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1) });
         //    saveDO.setGeo(linearRing);
         //    doList.add(saveDO);
         //}

        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            MultiPoint multiPoint = geometryFactory.createMultiPointFromCoords(
                    new Coordinate[]{new Coordinate(1, 1), new Coordinate(2, 2), new Coordinate(3, 3)});
            saveDO.setGeo(multiPoint);
            doList.add(saveDO);
        }

        {
            GeoWktDO saveDO = new GeoWktDO();
            GeometryFactory geometryFactory = new GeometryFactory();
            Polygon polygon = geometryFactory.createPolygon(new Coordinate[]{new Coordinate(1, 1),
                    new Coordinate(2, 2), new Coordinate(3, 3), new Coordinate(1, 1)});
            saveDO.setGeo(polygon);
            doList.add(saveDO);
        }

         {
             GeoWktDO saveDO = new GeoWktDO();
             GeometryFactory geometryFactory = new GeometryFactory();
             GeometryCollection geometryCollection = geometryFactory.createGeometryCollection(new Geometry[] {
                     geometryFactory.createPoint(new Coordinate(1, 1)),
                     geometryFactory.createLineString(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2) }),
                     geometryFactory.createPolygon(new Coordinate[] { new Coordinate(1, 1), new Coordinate(2, 2),
                             new Coordinate(3, 3), new Coordinate(1, 1) })
             });
             saveDO.setGeo(geometryCollection);
             doList.add(saveDO);
         }

        int count = geoWktMapper.insertList(doList);
        System.out.println(count);
    }

通过单元测试结论:

  • 使用 Mubatis-plus的 封装的 Mapper接口操作方法,都支持,注意:字段上必须指定 @TableField(“geo”)。推荐使用。
  • 使用 函数在 Mapper XML中操作方法,发现 st_geomfromtext 不支持 LinearRing。

在这里插入图片描述

参考文章:

  • Mysql的Geometry数据处理之WKT方案:https://blog.csdn.net/breaksoftware/article/details/139094495

– 求知若饥,虚心若愚。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1886680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【unity实战】使用旧输入系统Input Manager 写一个 2D 平台游戏玩家控制器——包括移动、跳跃、滑墙、蹬墙跳

最终效果 文章目录 最终效果素材下载人物环境 简单绘制环境角色移动跳跃视差和摄像机跟随效果奔跑动画切换跳跃动画&#xff0c;跳跃次数限制角色添加2d物理材质&#xff0c;防止角色粘在墙上如果角色移动时背景出现黑线条方法一方法二 墙壁滑行实现角色滑墙不可以通过移动离开…

opencascade AIS_InteractiveContext源码学习7 debug visualization

AIS_InteractiveContext 前言 交互上下文&#xff08;Interactive Context&#xff09;允许您在一个或多个视图器中管理交互对象的图形行为和选择。类方法使这一操作非常透明。需要记住的是&#xff0c;对于已经被交互上下文识别的交互对象&#xff0c;必须使用上下文方法进行…

PIRANA: Faster Multi-query PIR via Constant-weight Codes(论文解析)

一、介绍 匿踪查询&#xff1a;一个客户从服务器查询数据&#xff0c;并且服务器无法知晓查询内容。注意这里是保护查询安全&#xff0c;并不保护服务器数据安全。 主要贡献&#xff1a; 1.设计了一款更高速度的匿踪查询方案。 2.设计一款支持批量查询的匿踪查询方案。 3.匿踪…

分享一款Type C接口USB转2路485模块【带完整原理图】

大家好&#xff0c;我是『芯知识学堂』的SingleYork&#xff0c;今天给大家分享一款很实用的工具–基于Type C接口的USB转2路485模块。 这款模块主芯片采用南京沁恒的CH342F这款芯片&#xff0c;芯片特性如下&#xff1a; 该系列芯片有QFN24和ESSOP10 这2种封装&#xff0c;…

快速申请IP地址SSL证书指南

在当今数字化时代&#xff0c;网络安全已成为每个互联网用户和企业的首要关注点。为了保护在线数据传输的安全和隐私&#xff0c;使用SSL证书对网站进行加密变得至关重要。 IP地址SSL证书是一种用于专门保护IP地址的SSL证书。与域名SSL证书不同&#xff0c;IP地址SSL证书可以直…

TensorRT学习(二)TensorRT使用教程(Python版)

本文适合快速了解TensorRT使用的整体流程,具体细节还是建议参考TensorRT的官方文档。 加速原理: 加速原理比较复杂,它将会根据显卡来优化算子,以起到加速作用(如下图所示)。简单的来说,就是类似于你出一个公式1+1+1,而你的显卡支持乘法,直接给你把这个公式优化成了1*…

免费可视化工具如何提升智慧物流管理效率

在现代智慧物流中&#xff0c;免费可视化工具正扮演着越来越重要的角色。这些工具通过数据的可视化展示&#xff0c;使物流管理更加高效、透明和智能化。免费可视化工具可以将复杂的物流数据转换为直观的图表和图形&#xff0c;帮助管理者实时监控和分析物流运作情况&#xff0…

文件销毁是一件非常重要的事情分享一下我是如何安全、环保地处理

如何安全有效地销毁文件&#xff1a;一份详尽指南 在信息爆炸的时代&#xff0c;文件的生成、存储与处理已成为日常生活和工作中不可或缺的一部分。然而&#xff0c;随着数据量的激增&#xff0c;如何妥善管理并最终安全销毁不再需要的文件&#xff0c;成为了一个日益重要的议…

sql拉链表

1、定义&#xff1a;维护历史状态以及最新数据的一种表 2、使用场景 1、有一些表的数据量很大&#xff0c;比如一张用户表&#xff0c;大约1亿条记录&#xff0c;50个字段&#xff0c;这种表 2.表中的部分字段会被update更新操作&#xff0c;如用户联系方式&#xff0c;产品的…

图文识别0难度上手~基于飞浆对pdf简易ocr并转txt

前言 本篇pdf适用windows对视觉识别0基础的的纯小白用户。大佬请绕道~~ 注意&#xff1a; 本项目pdf的ocr对于表格、画图文字&#xff0c;水印等干扰没做任何处理&#xff0c;因此希望各位使用该功能的pdf尽量不要含有这些干扰项&#xff0c;以免影响翻译效果。 流程 1.构建…

vue2项目的打包以及部署

打包 当我们写好vue2的项目后&#xff0c;可以通过npm build来对项目进行打包 npm build 打包完成后我们可以看到在当面目录下生成了dis目录,src下的文件都会被打包进这个目录里&#xff0c;当然打包后的文件我们不能直接在浏览器打开&#xff0c;需要进行部署 部署 1.新建一个…

Ubuntu开通5005端口 记录

Ubuntu版本&#xff1a;20.04 使用systemctl status firewalld查看防火墙状态&#xff0c;报错Unit firewalld.service could not be found 报错的原因是没有安装firewall&#xff0c;安装命令为sudo apt install firewalld&#xff0c;然后进行安装 安装完成后输入systemctl…

大数据可视化实验(八):大数据可视化综合实训

目录 一、实验目的... 1 二、实验环境... 1 三、实验内容... 1 1&#xff09;Python纵向柱状图实训... 1 2&#xff09;Python水平柱状图实训... 3 3&#xff09;Python多数据并列柱状图实训.. 3 4&#xff09;Python折线图实训... 4 5&#xff09;Python直方图实训...…

vscode jupyter选择Python环境时找不到我安装的Python

在一些情况下&#xff0c;我们需要自己安装一个Python&#xff0c;在选择内核是可能找不到指定的Python版本&#xff0c; 再次打开内核选择页面就能看到Python环境了 注意先到指定环境下安装依赖包&#xff1a; ./python3 pip install ipykernel notebook jupyter

高考失利咨询复读,银河补习班客服开挂回复

补习班的客服在高考成绩出来后&#xff0c;需要用专业的知识和足够的耐心来回复各种咨询&#xff0c;聊天宝快捷回复软件&#xff0c;帮助客服开挂回复。 ​ 前言 高考成绩出来&#xff0c;几家欢喜几家愁&#xff0c;对于高考失利的学生和家长&#xff0c;找一个靠谱的复读补…

爬虫笔记18——selenium自动加载并存储vip(唯品会)网页数据

爬取唯品会的商品数据信息 整体的流程就是在唯品会首页搜索栏搜索对应的商品&#xff0c;然后跳转到对应商品页面进行数据的爬取、筛选和存储。 其实也有另外一个爬取方案&#xff0c;不用selenium也是可以爬取到相应的数据&#xff0c;通过分析&#xff0c;搜索结果的页面是…

【机器学习】语音转文字 - FunASR 的应用与实践(speech to text)

本文将介绍 FunASR&#xff0c;一个多功能语音识别模型&#xff0c;包括其特点、使用方法以及在实际应用中的表现。我们将通过一个简单的示例来展示如何使用 FunASR 将语音转换为文字&#xff0c;并探讨其在语音识别领域的应用前景。 一、引言 随着人工智能技术的不断发展&am…

如何理解MySql的MVCC机制

MVCC是什么 MySQL的MVCC机制&#xff0c;全称为多版本并发控制&#xff08;Multi-VersionConcurrency Control&#xff09;&#xff0c;是一种提高数据库并发性能的技术。MVCC的主要目的是在保证数据一致性的同时&#xff0c;提高数据库的并发性能。 它通过为每个读操作创建数…

基于若依(ruoyi-vue)的周报管理系统

喂wangyinlon 填报人页面 审批人 审批不通过,填报人需要重新填写.

【漏洞复现】D-Link NAS 未授权RCE漏洞(CVE-2024-3273)

0x01 产品简介 D-Link 网络存储 (NAS)是中国友讯&#xff08;D-link&#xff09;公司的一款统一服务路由器。 0x02 漏洞概述 D-Link NAS nas_sharing.cgi接口存在命令执行漏洞&#xff0c;该漏洞存在于“/cgi-bin/nas_sharing.cgi”脚本中&#xff0c;影响其 HTTP GET 请求处…