MySQL Geometry的使用 —— 任意多邊形范圍搜索


地圖相關服務選擇的是四維圖新
本文記錄的是,地圖上任意多邊形搜索,后端邏輯和SQL(后端),前端相關接口服務可看 MineMap for 2D

一、搜索效果

自定義選擇多邊形,搜索出范圍內的數據

二、搜索處理邏輯

  • 前端調用地圖服務接口,獲得多邊形的點坐標數據,數據例如:[1 1,2 2,3 3,4 4,1 1]
  • 后端獲得范圍坐標數據,同時取得范圍坐標的2個極點(坐標最大最小,可先通過Double類型的經緯度大小判斷,將搜索范圍縮小),使用Geometry包含函數 ST_CONTAINS(),獲得符合函數坐標的數據
  • 將搜索結果返給前端

三、SQL

假設點坐標 (103,35)、(104,36)為多邊形點坐標極點,即所有符合要求范圍內的數據,必定在極點之內

select m.name, ST_AsGeoJSON(m.geometry) as geometry
FROM mapdata m
WHERE jd < 104 and jd > 103 and wd < 36 and wd > 35
	and ST_CONTAINS(ST_POLYGONFROMTEXT('POLYGON(103 35,104 35,104 36,103 36,103 35)'),m.geometry)

四、Java代碼中部分工具類

String ssfwStr= net.sf.json.getJSONArray("搜索范圍坐標,json格式");
List<List<Double>> maxPolygon = new getMaxPolygonDate().getMaxPolygonByJsonObject(ssfwStr);
/**
     * 多邊形數據格式轉換
     * "[[1,1][1,2][2,2]]" ——> "POLYGON(1 1,1 2,2 2)"
     * 
     * @param ssfwstr 搜索范圍坐標字符串
     * @return java.lang.String
     * @Author: changge
     * @date 2021/6/13 20:29
     **/
    public String polygonFormat(String ssfwStr) {
        //截取
        String str1 = StringUtils.substringBeforeLast(str, "]");
        String str2 = StringUtils.substringAfter(str1, "[");
        // "[]" ——> "()"
        String str3 = "POLYGON" + str2.replace("[", "(").replace("]", ")");
        String str4 = str3.replace(",", " ");
        String polygonString = str4.replace(") (", ",");
        return polygonString;
    }
/**
     * 地圖數據分類統計
     *
     * @param map 地圖數據集合
     * @return cn.hutool.json.JSONObject
     */
    @Override
    public cn.hutool.json.JSONObject mapCount(List<Mapdata> map) {

        // 統計
        cn.hutool.json.JSONArray data = new cn.hutool.json.JSONArray();
        HashMap<String, Integer> hashMap = new HashMap<>();
        HashMap<String, String> hashMap2 = new HashMap<>();

        HashMap<String, String> hashMap3 = new HashMap<>();
        // 循環遍歷,獲得數據有多少種地圖數據類別,並統計
        for (Mapdata m : map) {
        	// codeName 為地圖數據分類名稱,例如:建築物、實有單位、水域、橋梁、隧道等
            Integer codeNames = hashMap.get(m.getCodename());
            hashMap.put(m.getCodename(), codeNames == null ? 1 : codeNames + 1);
            // iconCode 為地圖圖標分類名稱,例如:醫院、學校、派出所等
            hashMap2.put(m.getCodename(), m.getIconCode());
            // code 為分類編碼,例如:醫院(00010)、學校(00007)、派出所(00015)
            hashMap3.put(m.getCodename(), m.getCode());
        }

        Set<String> codeNames = hashMap.keySet();
        // 處理數據,返回符合前端上圖要求的數據
        for (String codeName : codeNames) {
            cn.hutool.json.JSONObject datas = new cn.hutool.json.JSONObject();
            datas.putOpt("name", codeName);
            datas.putOpt("icon", hashMap2.get(codeName));
            datas.putOpt("code", hashMap3.get(codeName));
            datas.putOpt("count", hashMap.get(codeName));
            data.put(datas);
        }

        GeoJson geoJson = new GeoJson();
        cn.hutool.json.JSONObject mapdata = geoJson.SplicingGeoJSON(map);

        cn.hutool.json.JSONObject result = new cn.hutool.json.JSONObject();
        result.putOpt("data", data);
        result.putOpt("mapdata", mapdata);

        return result;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM