首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java根据经纬度获取两点之间的距离

Java根据经纬度获取两点之间的距离

作者头像
SmileNicky
发布2024-12-23 11:00:39
发布2024-12-23 11:00:39
57700
代码可运行
举报
文章被收录于专栏:Nicky's blogNicky's blog
运行总次数:0
代码可运行

Java根据经纬度获取两点之间的距离,最近在实现类似于钉钉打卡签到的需求,因为对精度要求不是很高,所以可以通过一个球面距离的公式来求两点距离,这里将地球当成一个球体,实际上地球是一个不规则的球体,所以这个实现方法只能适用一些精度要求不高的需求,如果要高精度,可以用第三方的api去实现。

实现思路

  • 先新增一个配置页面,调用百度地图,保存好经纬度数据到数据库表,同时也保存距离
  • 手机打卡获取当前位置的经纬度数据,通过接口对比,计算两点距离是否在配置的打卡范围内

代码实现

写一个实体类,传入经纬度信息

代码语言:javascript
代码运行次数:0
运行
复制
package cn.nzp.ems.ecb.server.common;

import lombok.Data;

@Data
public class PositionParam {
    private String positionlng;  //坐标经度
    private String positionlat;  //坐标纬度

}

写一个工具类,EARTH_RADII为地球半径的估值

代码语言:javascript
代码运行次数:0
运行
复制
package cn.server.common;


public class GPSUtil {


    // 圆周率
    private static final Double PI = Math.PI;
    private static final Double PK = 180 / PI;
    private static final Double EARTH_RADII = 6370996.81;


    /**
     * 计算两个百度地图坐标实际距离:米
     *
     * @param sourcePosition
     * @param targetPosition
     * @return
     */
    public static double getDistanceByCoordinate(PositionParam sourcePosition, PositionParam targetPosition) {
        double o_lat = Double.valueOf(sourcePosition.getPositionlat());
        double o_lng = Double.valueOf(sourcePosition.getPositionlng());

        double d_lat = Double.valueOf(targetPosition.getPositionlat());
        double d_lng = Double.valueOf(targetPosition.getPositionlng());

        double t1 = Math.cos(o_lat / PK) * Math.cos(o_lng / PK) * Math.cos(d_lat / PK) * Math.cos(d_lng / PK);

        double t2 = Math.cos(o_lat / PK) * Math.sin(o_lng / PK) * Math.cos(d_lat / PK) * Math.sin(d_lng / PK);

        double t3 = Math.sin(o_lat / PK) * Math.sin(d_lat / PK);

        double tt = Math.acos(t1 + t2 + t3);

        return EARTH_RADII * tt;
    }

}

接口判断是否在签到范围内

代码语言:javascript
代码运行次数:0
运行
复制
public ResultResponse<Integer> checkInGpsRange(QueryDto queryDto) {
        ResultResponse<Integer> resultResponse = ResultResponse.getSuccessfulResultResponse(AppConsts.NO_IN_GPS_RANGE);

		// 获取配置gps签到范围数据
        List<GpsAddress> gpsAddressList = Optional.ofNullable(gpsAddressMapper.listGpsAddressByConfigId(queryDto.getId())).orElse(Lists.newArrayList());
        for (GpsAddress gpsAddress : gpsAddressList) {
            if (Objects.isNull(gpsAddress.getRangeNum())) {
                continue;
            }
            // 主要复制经纬度信息,sourceParam是手机打卡时候,前端传过来的
            PositionParam sourceParam = BeanUtil.copyProperties(queryDto, PositionParam.class);
            // 这个是数据库保存的打卡范围,经纬度信息
            PositionParam targetParam = BeanUtil.copyProperties(gpsAddress, PositionParam.class);
            // 判断是否在签到范围内
            double difference = GPSUtil.getDistanceByCoordinate(sourceParam, targetParam);
            // 在签到范围内
            if (difference < gpsAddress.getRangeNum()) {
                resultResponse.setData(AppConsts.IN_GPS_RANGE);
                return resultResponse;
            }
        }

        return resultResponse;
    }

ps,这个是通过Java实现的简单例子,只能适用于不是特别精准的情况,要特别精准,请用第三方api,比如百度的,https://lbsyun.baidu.com/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实现思路
  • 代码实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档