Mysql gis空间数据查询,将结果在Controller层转换成GeoJson输出 ---保姆级全流程

***java后台技术栈***

SpringBoot+MyBatisPlus+Mysql8.0

(空间数据处理最专业的还是postGis,比较大型、复杂的地理数据处理和储存推荐使用pg,当然mysql的spatial比较方便,不需要进行额外的模块安装,在高版本的mysql可以直接使用)

***数据准备***

首先需要先对mysql spatial或postGis的空间数据类型作一个基本了解。

共有这八种类型:

  • GEOMETRY

  • POINT

  • LINESTRING

  • POLYGON

  • MULTIPOINT

  • MULTILINESTRING

  • MULTIPOLYGON

  • GEOMETRYCOLLECTION

可以在mysql或者postGis的官方文档进行查看。

这里介绍mysql的官方文档:

在mysql5.6版本以上开始支持对空间数据类型的操作,mysql8.0的spatial文档地址如下:

https://dev.mysql.com/doc/refman/8.0/en/spatial-geojson-functions.html

在数据库中创建一个包含空间基本类型列的表,如图:

其中point是点类型。

 

建完表后插入一些数据

INSERT into geom VALUES(1000001,ST_GeomFromText('POINT(121.474103 31.232862)'),'危险点1',1)

INSERT into geom VALUES(1000002,ST_GeomFromText('POINT(161.474101 41.232862)'),'危险点2',1)

SELECT * FROM `geom`

 

查询结果如下图:

可以看到数据已经成功以空间类型存储,但是查询后的格式是有问题的,java是无法接收point类型的数据的(除非自定义一个Point类,当然,如果这样做那么所有的空间类型都需要自己定义对应的类,不是很方便)。

所以我们需要在mysql进行查询操作的时候将查询出来的数据格式进行转换,然后放到java中去处理,接下来看第二步。

 

 

***数据处理***

GeoJSON是用json的语法表达和存储地理数据,可以说是json的子集。我们的数据最终传给前端时需要转换成GeoJSON格式。

 

在mysql对数据进行查询时将空间类型的数据直接利用GeoJSON格式转换函数进行查询,示例如下:

select id, ST_AsGeoJSON(point) point ,name,type from geom

 

可以看到查询出来的是个GeoJSON格式的字符串,在Java中我们可以用String类接收。

以下是用MyBatisPlus插件一键生成的实体类和Mapper文件,我们需要把实体类中的Point属性改为String类。

实体类entity

@TableName(value ="geom")
@Data
public class Geom implements Serializable {
    /**
     * 
     */
    @TableId
    private Long id;

    /**
     * 坐标点
     */
    private String point;

    /**
     * 坐标名
     */
    private String name;

    /**
     * 类型
     */
    private Integer type;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

mapper

@Repository
public interface GeomMapper extends BaseMapper<Geom> {
    List<Geom> getGeomList();

    List<Geom> getGeoJSONGeomList();
}

mapper.xml

<select id="getGeoJSONGeomList" resultType="com.cyl.geo.entity.Geom">
    select id, ST_AsGeoJSON(point) point ,name,type from geom
</select>

controller

@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private GeomMapper geomMapper;

    @GetMapping("getGeoJSONGeom")
    public R getGeoJSONGeom(){
        List<Geom> geoms=geomMapper.getGeoJSONGeomList();
        List<Map<String, Object>> geomlist = new ArrayList<>();
        for (Geom geom:geoms) {
            Map<String, Object> map=new HashMap<>();
            map.put("id",geom.getId());
            map.put("name",geom.getName());
            map.put("point", JSONObject.parse(geom.getPoint()));  //JSONObject引用的是fastJson包,导入对应依赖即可
            map.put("type",geom.getType());
            geomlist.add(map);
        }
        return R.ok().data("geomlist",geomlist);  //R 是自定义的一个统一响应格式类,可以改成Map<String,Object>将geomlist放进去即可
    }
}

 

***PostMan测试***

启动服务后在PostMan访问接口 localhost:8080/test/getGeoJSONGeom 

结果如下:

成功将空间数据转换成GeoJSON在接口返回!

 

posted @ 2021-09-01 16:24  onecyl  阅读(1186)  评论(0编辑  收藏  举报