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在介面返回!