Java 兼容 百度 && 腾讯 && 高德 经纬度校验距离

import java.util.HashMap;
import java.util.Map;

/**
 * Created by IntelliJ IDEA.
 * 百度 && 腾讯 && 高德 根据经纬度效验距离
 */
public class MapsTools {

    private static final double X_PI = 3.14159265358979324 * 3000.0 / 180.0;

    public static void main(String[] args) {

        // 百度 && 腾讯
        System.out.println(isWithinTheScopeOf("109.135072", "21.459071", "109.128571", "21.452749", 23));

        // 百度 && 高德
        System.out.println(isWithinTheScopeOf("109.135072", "21.459071", "109.128401", "21.452989", 20));

        // 百度 && 百度
        System.out.println(isWithinTheScopeOf("109.128401", "21.452989", "109.128401", "21.452989", 0));

        // 腾讯 && 腾讯
        System.out.println(isWithinTheScopeOf("109.135072", "21.459071", "109.135072", "21.459071", 0));

        // 腾讯 && 高德
        System.out.println(isWithinTheScopeOf("109.128571", "21.452749", "109.128401", "21.452989", 25));
    }


    /**
     * 判断是否在范围内
     *
     * @param lon      1点的纬度
     * @param lan      1点的经度
     * @param lon2     2点的纬度
     * @param lan2     2点的经度
     * @param distance 半径  单位米
     * @return true or false
     */
    private static boolean isWithinTheScopeOf(String lon, String lan, String lon2, String lan2, int radius) {

        Map<String, Double> baidu = bdEncrypt(lon2, lan2);

        Map<String, Double> tencent = bdDecrypt(lon2, lan2);

        double distance1 = getDistance(Double.valueOf(lon), Double.valueOf(lan), baidu.get("lon"), baidu.get("lat"));

        double distance2 = getDistance(Double.valueOf(lon), Double.valueOf(lan), tencent.get("lon"), tencent.get("lat"));

        double distance3 = getDistance(Double.valueOf(lon), Double.valueOf(lan), Double.valueOf(lon2), Double.valueOf(lan2));

        return distance1 <= radius || distance2 <= radius || distance3 <= radius;
    }


    /**
     * 腾讯转百度经纬度
     *
     * @param lon 经度
     * @param lan 纬度
     * @return
     */
    private static Map<String, Double> bdEncrypt(String lon, String lan) {
        double x = Double.valueOf(lon), y = Double.valueOf(lan);
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
        double bdLon = z * Math.cos(theta) + 0.0065;
        double bdLat = z * Math.sin(theta) + 0.006;
        Map<String, Double> baiduMap = new HashMap<>();
        baiduMap.put("lon", bdLon);
        baiduMap.put("lat", bdLat);
        return baiduMap;
    }

    /**
     * 百度转腾讯经纬度
     *
     * @param lon 经度
     * @param lan 纬度
     * @return
     */
    private static Map<String, Double> bdDecrypt(String lon, String lan) {
        double x = Double.valueOf(lon) - 0.0065, y = Double.valueOf(lan) - 0.006;
        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
        double ggLon = z * Math.cos(theta);
        double ggLat = z * Math.sin(theta);
        Map<String, Double> bdMap = new HashMap<>();
        bdMap.put("lon", ggLon);
        bdMap.put("lat", ggLat);
        return bdMap;
    }


    /**
     * 通过经纬度获取距离(单位:米)
     *
     * @param lat1 1点的纬度
     * @param lng1 1点的经度
     * @param lat2 2点的纬度
     * @param lng2 2点的经度
     * @return
     */
    private static double getDistance(double lat1, double lng1, double lat2,
                                      double lng2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * 6378.137;
        s = Math.round(s * 10000d) / 10000d;
        s = s * 1000;
        return s;
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值