1. 程式人生 > 其它 >Mysql gis空間資料查詢,將結果在Controller層轉換成GeoJson輸出 ---保姆級全流程

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