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在接口返回!