Java计算两个经纬度间的距离最简单的方式

开发中经常会遇到计算两个点(经纬度)之间的距离或者计算最近门店的场景,下面简单实现一下如何计算两个经纬度之间相隔的距离。

1、导入geodesy的maven依赖 或者到阿里云maven仓库下载jar包

<dependency>
  <groupId>org.gavaghan</groupId>
  <artifactId>geodesy</artifactId>
  <version>1.1.3</version>
</dependency>

2、实现计算

package com.test.gps;

import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;

public class CaculateDistanceTest
{
    public static void main(String[] args)
    {
        GlobalCoordinates source = new GlobalCoordinates(29.490295, 106.486654);
        GlobalCoordinates target = new GlobalCoordinates(29.615467, 106.581515);

        double meter = getDistanceMeter(source, target);
        System.out.println(meter + "米");
    }

    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo)
    {
        //选择合适坐标系,欧洲之外选择WGS84坐标系
        Ellipsoid ellipsoid;
        if (!isPointInEurope(gpsFrom) && !isPointInEurope(gpsTo))
        {
            ellipsoid = Ellipsoid.WGS84;
        }
        else
        {
            ellipsoid = Ellipsoid.GRS80;
        }
        //创建GeodeticCalculator,传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);

        return geoCurve.getEllipsoidalDistance();
    }

    public static boolean isPointInEurope(GlobalCoordinates point)
    {
        try
        {
            double northernmostPoint = dms2Decimal(new int[]{ 81, 48, 24 });
            double southernmostPoint = dms2Decimal(new int[]{ 34, 48, 2 });
            double westernmostPoint = dms2Decimal(new int[]{ -24, 32, 3 });
            double easternmostPoint = dms2Decimal(new int[]{ 69, 2, 0 });
            return northernmostPoint > point.getLatitude() && southernmostPoint < point.getLatitude() && westernmostPoint < point
                    .getLongitude() && easternmostPoint > point.getLongitude();
        }
        catch (RuntimeException e)
        {
            throw new RuntimeException(e);
        }
    }

    public static double dms2Decimal(int[] dms) throws RuntimeException
    {
        if (dms != null && dms.length == 3)
        {
            int sign = dms[0] > 0 ? 1 : -1;
            double decimal = 0.0D;
            decimal += (double) Math.abs(dms[0]);
            double secondsTotal = (double) (dms[1] * 60 + dms[2]);
            decimal += secondsTotal / 3600.0D;
            return truncateDecimal(decimal) * (double) sign;
        }
        else
        {
            throw new RuntimeException();
        }
    }

    public static double truncateDecimal(double decimal)
    {
        double factor = Math.pow(10.0D, 6.0D);
        return Math.rint(decimal * factor) / factor;
    }
}

3、输出结果:

对比百度地图的结果,存在几十米的误差,对于一般应用场景可以满足。

猜你喜欢

转载自www.cnblogs.com/xuzhw/p/10143626.html
今日推荐