当前位置:  开发笔记 > 编程语言 > 正文

如何根据Java中的两个纬度+经度点测量距离并创建边界框?

如何解决《如何根据Java中的两个纬度+经度点测量距离并创建边界框?》经验,为你挑选了5个好方法。

我想找到两个不同点之间的距离.我知道这可以用很大的圆距来完成. http://www.meridianworlddata.com/Distance-calculation.asp

一旦完成,我想找到一个点和距离,我想找到距离北方的点,以及距离为东的点,以便在点周围创建一个方框.



1> Sean..:

这是Haversine公式的Java实现.我在项目中使用它来计算纬度/长度之间的英里距离.

public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
    double earthRadius = 3958.75; // miles (or 6371.0 kilometers)
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double sindLat = Math.sin(dLat / 2);
    double sindLng = Math.sin(dLng / 2);
    double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
            * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = earthRadius * c;

    return dist;
    }


只需注意一下,它将以英里为单位返回距离(因为earthRadius设置).对于其他单位,请更改earthRadius(有关更多信息,请参阅http://en.wikipedia.org/wiki/Earth_radius)
使用earthRadius作为**6371**以获得**公里**的结果.

2> JavadocMD..:

或者你可以使用SimpleLatLng.Apache 2.0在我所知道的一个生产系统中获得许可并使用:我的.

短篇故事:

我正在寻找一个简单的地理图书馆,找不到符合我需求的图书馆.谁想在每个应用程序中反复编写,测试和调试这些小地理工具?必须有更好的方法!

因此,SimpleLatLng作为一种存储纬度 - 经度数据,进行距离计算和创建形状边界的方法而诞生.

我知道我帮助原始海报的时间已经晚了两年,但我的目的是帮助像我一样在搜索中找到这个问题的人.我希望让一些人使用它,并为这个小型轻量级实用程序的测试和愿景做出贡献.



3> Brendan Cash..:

我们在使用OpenMap绘制大量位置数据方面取得了一些成功.有一个LatLonPoint类具有一些基本功能,包括距离.


警告可能的采用者:我刚刚遇到OpenMap的一个大问题; 他们在内部使用浮点数作为十进制纬度/经度,这取决于你是否接近赤道的准确度.他们计划从版本4.7开始支持OMGraphic类的双打选项,但目前的稳定版仅为4.6.5(截至2010年3月).资料来源:http://openmap.bbn.com/mailArchives/openmap-users/2006-01/4522.html
由于两个链接都处于脱机状态,因此该答案现已过时.

4> Victor P...:

要获得更精确的距离(0.5mm),您还可以使用Vincenty近似值:

/**
 * Calculates geodetic distance between two points specified by latitude/longitude using Vincenty inverse formula
 * for ellipsoids
 * 
 * @param lat1
 *            first point latitude in decimal degrees
 * @param lon1
 *            first point longitude in decimal degrees
 * @param lat2
 *            second point latitude in decimal degrees
 * @param lon2
 *            second point longitude in decimal degrees
 * @returns distance in meters between points with 5.10-4 precision
 * @see Originally posted here
 */
public static double distVincenty(double lat1, double lon1, double lat2, double lon2) {
    double a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params
    double L = Math.toRadians(lon2 - lon1);
    double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1)));
    double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2)));
    double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
    double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);

    double sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM;
    double lambda = L, lambdaP, iterLimit = 100;
    do {
        sinLambda = Math.sin(lambda);
        cosLambda = Math.cos(lambda);
        sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda)
                + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda));
        if (sinSigma == 0)
            return 0; // co-incident points
        cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda;
        sigma = Math.atan2(sinSigma, cosSigma);
        sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma;
        cosSqAlpha = 1 - sinAlpha * sinAlpha;
        cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha;
        if (Double.isNaN(cos2SigmaM))
            cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6)
        double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha));
        lambdaP = lambda;
        lambda = L + (1 - C) * f * sinAlpha
                * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)));
    } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0);

    if (iterLimit == 0)
        return Double.NaN; // formula failed to converge

    double uSq = cosSqAlpha * (a * a - b * b) / (b * b);
    double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
    double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
    double deltaSigma = B
            * sinSigma
            * (cos2SigmaM + B
                    / 4
                    * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM
                            * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM)));
    double dist = b * A * (sigma - deltaSigma);

    return dist;
}

此代码可从http://www.movable-type.co.uk/scripts/latlong-vincenty.html免费改编



5> 小智..:

修正了Haversine距离公式....

public static double HaverSineDistance(double lat1, double lng1, double lat2, double lng2) 
{
    // mHager 08-12-2012
    // http://en.wikipedia.org/wiki/Haversine_formula
    // Implementation

    // convert to radians
    lat1 = Math.toRadians(lat1);
    lng1 = Math.toRadians(lng1);
    lat2 = Math.toRadians(lat2);
    lng2 = Math.toRadians(lng2);

    double dlon = lng2 - lng1;
    double dlat = lat2 - lat1;

    double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2);

    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));

    return EARTH_RADIUS * c;
}   

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有