判断某个经纬度,是否在一个封闭区域内(通过mysql提供的GEOMETRY类型)

本文介绍了如何在Java开发中利用MySQL的GEOMETRY类型处理封闭区域信息,包括经纬度对象的创建、范围的获取和转换,以及服务层中如何将经纬度转换为MySQL所需的格式并进行范围判断。
摘要由CSDN通过智能技术生成

下面通过一个在开发中的真是应用描述一下

需求就像标题所说, 现在需要处理这个封闭区域信息, 这里选用的是mysql提供的GEOMETRY类型

注: 代码存在部分省略

工具类:
经纬度对象
@Data
@NoArgsConstructor
public class GeoPoint {

    private double latitude;
    private double longitude;

    public GeoPoint(double latitude, double longitude) {
        this.latitude = latitude;
        this.longitude = longitude;
    }

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

public class Geo {
	/**
     * 获取地块首位经纬度
     * 
     * @param plotRange 地块范围
     * @param flag      ture 第一个, false 最后一个
     * @return
     */
    public static GeoPoint getGeoPoint(String plotRange, boolean flag) {
        JSONArray jsonArray = JSON.parseArray(plotRange);
        if (flag) {
            JSONArray geo = jsonArray.getJSONArray(0);
            return new GeoPoint(Double.parseDouble(geo.get(1).toString()), Double.parseDouble(geo.get(0).toString()));
        }
        JSONArray geo = jsonArray.getJSONArray(jsonArray.size() - 1);
        return new GeoPoint(Double.parseDouble(geo.get(1).toString()), Double.parseDouble(geo.get(0).toString()));
    }

    /**
     * 获取最终mysql地理类型的的地块范围
     * 封闭范围
     *
     * @param range
     * @return
     */
    public static String getFinalGeo(String range) {
        GeoPoint geoPoint = getGeoPoint(range, true);
        return "{\"type\":\"MultiPolygon\",\"coordinates\":[[" + range.substring(0, range.length() - 1) + ",[" + geoPoint.getLongitude() + "," + geoPoint.getLatitude() + "]]]]}".trim();
    }

    /**
     * 获取Point格式
     *
     * @param geoPoint 经纬度
     * @return 格式化后的Point
     */
    public static String getPointGeoForMysqlGEOMETRY(GeoPoint geoPoint) {
        return String.format("POINT(%s %s)", geoPoint.getLatitude(), geoPoint.getLongitude());
    }
}
表结构:

在这里插入图片描述

对于判断一个经纬度是否在一个封闭区域内的的示例:

实体类:
/**
 * 公司管理地块范围实体
 *
 * @author : cookie
 * date : 2024-01-26
 */
public class ScreenCompanyRange {

    @Id
    private String id;

    @ApiModelProperty("一个完整封闭区域范围")
    private String range;

    @ApiModelProperty("公司id")
    @Column(name = "company_id")
    private String companyId;

    @ApiModelProperty("范围名称")
    @Column(name = "range_name")
    private String rangeName;

    private String geo;

}
service层方法
@Override
public int save(ScreenCompanyRange screenCompanyRange) {
    // 手动设置id
    screenCompanyRange.setId(Sid.nextShort());
    // 调用工具类中的方法获取mysql GEOMETRY 类型需要的格式
    screenCompanyRange.setGeo(Geo.getFinalGeo(screenCompanyRange.getRange()));
    return screenCompanyRangeMapper.insertMessage(screenCompanyRange);
}
*Mapper.xml

这里使用了 ST_GeomFromGeoJSON 方法 将我们格式化好的数据转换为 mysql中 GEOMETRY 类型

    <insert id="insertMessage">
        insert into screen_company_range(id, `range`, company_id, geo, range_name)
        values (#{id}, #{range}, #{companyId}, ST_GeomFromGeoJSON(#{geo}), #{rangeName})
    </insert>
插入数据格式:

下面数据是一个示例, 经纬度列表就按照 , 顺序即可

我提供的经纬度不一定对, 做了混淆

{
  "companyId": "240565BX5H7TRNMW",
  "range": "[[116.269186,32.159889],[126.261416,32.147559],[116.275658,32.156151],[116.268110,32.149781]]",
  "rangeName": "xxxx"
}
数据展示

插入成功后数据库中的数据如下:

在这里插入图片描述

现在就还差最后一步, 就是判断点是否在一个范围内, 通过下面的示例SQL

SELECT ST_INTERSECTS(ST_GEOMFROMTEXT('POINT(31.149781 106.268110)', 4326), geo) exist FROM screen_company_range 

在这里插入图片描述

存在 返回1 不存在结果是 0

POINT(31.149781 106.268110) 这一块封装的有 方法 getPointGeoForMysqlGEOMETRY

注意这里的经纬度,是反过来的

高德js判断点是否在一个面里
https://lbs.amap.com/demo/javascript-api-v2/example/relationship-judgment/point-surface-relation
在这里插入图片描述
在这里插入图片描述

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yfs1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值