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