对 lon\lat 点列表进行排序,从最近的开始

发布于 2024-10-25 21:29:49 字数 194 浏览 3 评论 0原文

我有 GPS 位置(lon_base、lat_base)。 我有一个位置列表(lon1、lat1|lon2、lat2|lon3、lat3...) 这个名单很长,遍布世界各地。

我的问题是: 1. 如何从该列表中仅获取距离我的 lon_base\lat_base 1 英里的 lon\lat? 2. 如何从最近到最远对它们进行排序?

提前致谢!

I have location from GPS (lon_base, lat_base).
I have a list of locations (lon1, lat1|lon2, lat2|lon3, lat3...)
This list is very long and is around the world.

My questions are:
1. How do I get from that list only the lon\lat that are 1 mile from my lon_base\lat_base?
2. How do I sort them from closest to farthest?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

歌入人心 2024-11-01 21:29:49
public static List<Location> sortLocations(List<Location> locations, final double myLatitude,final double myLongitude) {
    Comparator comp = new Comparator<Location>() {
        @Override
        public int compare(Location o, Location o2) {
            float[] result1 = new float[3];
            android.location.Location.distanceBetween(myLatitude, myLongitude, o.Lat, o.Long, result1);
            Float distance1 = result1[0];

            float[] result2 = new float[3];
            android.location.Location.distanceBetween(myLatitude, myLongitude, o2.Lat, o2.Long, result2);
            Float distance2 = result2[0];

            return distance1.compareTo(distance2);
        }
    };


    Collections.sort(locations, comp);
    return locations;
}

其中位置列表是包含您自己的位置类的列表,而不是 android.location.Location。

public static List<Location> sortLocations(List<Location> locations, final double myLatitude,final double myLongitude) {
    Comparator comp = new Comparator<Location>() {
        @Override
        public int compare(Location o, Location o2) {
            float[] result1 = new float[3];
            android.location.Location.distanceBetween(myLatitude, myLongitude, o.Lat, o.Long, result1);
            Float distance1 = result1[0];

            float[] result2 = new float[3];
            android.location.Location.distanceBetween(myLatitude, myLongitude, o2.Lat, o2.Long, result2);
            Float distance2 = result2[0];

            return distance1.compareTo(distance2);
        }
    };


    Collections.sort(locations, comp);
    return locations;
}

Where the List of Locations is a list containing your own Location class, not the android.location.Location.

清旖 2024-11-01 21:29:49

您可以使用大圆距离来计算已知纬度的两点之间的距离- 经度坐标。 公式非常容易编码:

static double distance(double fromLat, double fromLon, double toLat, double toLon) {
    double radius = 6378137;   // approximate Earth radius, *in meters*
    double deltaLat = toLat - fromLat;
    double deltaLon = toLon - fromLon;
    double angle = 2 * Math.asin( Math.sqrt(
        Math.pow(Math.sin(deltaLat/2), 2) + 
        Math.cos(fromLat) * Math.cos(toLat) * 
        Math.pow(Math.sin(deltaLon/2), 2) ) );
    return radius * angle;
}

You may use the great circle distance to calculate the distance between two points whose you know the latitude-longitude coordinates. The formulae are quite easy to code:

static double distance(double fromLat, double fromLon, double toLat, double toLon) {
    double radius = 6378137;   // approximate Earth radius, *in meters*
    double deltaLat = toLat - fromLat;
    double deltaLon = toLon - fromLon;
    double angle = 2 * Math.asin( Math.sqrt(
        Math.pow(Math.sin(deltaLat/2), 2) + 
        Math.cos(fromLat) * Math.cos(toLat) * 
        Math.pow(Math.sin(deltaLon/2), 2) ) );
    return radius * angle;
}
错々过的事 2024-11-01 21:29:49

您想要定义自己的 Comparator,一般来说,它看起来像这样:

LonLat myHouse = /* whatever */ ;
Comparable comp = new Comparable () {
    LonLat a;
    int compareTo (Object b) {
        int aDist = calcDistance(a, myHouse) ;
        int bDist = calcDistance(b, myHouse) ;
        return aDist - bDist;
    }
};
myLonLatList.sort(lonLatList, comp);

其中 calcDistance() 只是计算两点之间的距离。如果您使用的是 Android,我认为 Google 地图在其 API 中的某处有一个函数可以为您执行此操作。

编辑:您希望您的 calcDistance() 函数看起来像 ChrisJ 的 distance 函数。

-tjw

You want to define your own Comparator that, in general, looks something like this:

LonLat myHouse = /* whatever */ ;
Comparable comp = new Comparable () {
    LonLat a;
    int compareTo (Object b) {
        int aDist = calcDistance(a, myHouse) ;
        int bDist = calcDistance(b, myHouse) ;
        return aDist - bDist;
    }
};
myLonLatList.sort(lonLatList, comp);

where calcDistance() simply calculates the distance between the two points. If you're on Android, I think Google Maps has a function somewhere in their API that will do this for you.

EDIT : You'll want your calcDistance() function to look like ChrisJ's distance function.

-tjw

我ぃ本無心為│何有愛 2024-11-01 21:29:49

您可以使用以下近似值(因为 1 英里远小于地球半径)来计算距基地的距离:

dx = cos(phi_base) * (theta - theta_base)
dy = phi - phi_base

dist = sqrt(dx*dx+dy*dy) 

其中:phi = 纬度,theta = 经度

如果 thetaphi 以度为单位,则结果以 60 海里为单位。
对于纬度与基准纬度相差​​很大的点,结果将非常错误,但如果您只想知道哪些点距基准纬度大约 1 英里,则这并不重要。

对于大多数编程语言,您必须将 phi_base 转换为弧度(乘以 pi/180)才能将其用于 cos()

(注意:如果您的基本经度非常接近 180° 或 -180°,则必须特别小心,但情况可能并非如此:-)

使用计算出的距离作为排序键对点进行排序。

如果您必须更精确(例如,如果您想知道距您家 2000 英里左右的所有点),则必须使用 大圆距离 用于计算球体上两点的精确距离。

You can use followig approximation (since 1 mile is much smaller than the radius of the earth) to calculate the distances from your base:

dx = cos(phi_base) * (theta - theta_base)
dy = phi - phi_base

dist = sqrt(dx*dx+dy*dy) 

with: phi = latitude and theta = longitude

The result is in units of 60 nautical miles if theta and phi are given in degrees.
The results will be quite wrong for points that have a latitude that is much different from your base latitude, but this doesn't matter if you just want to know wich points are about 1 mile from your base.

For most programming languages you have to convert phi_base to radians (multiply by pi/180) in order to use it for cos().

(Attention: You have to take special care if your base longitude is very close to 180° or -180°, but probably that is not the case :-)

Use the calculated distances as sorting key to sort your points.

If you have to be more exact (e.g. if you want to know all points that are about 2000 miles from your home), than you must use the formula for Great Circle Distance to calculate the exact distance of two points on a sphere.

口干舌燥 2024-11-01 21:29:49

根据这个链接
我制定了工作方法。上面的答案是错误的,因为它不会将纬度/经度转换为弧度。

    private double getDistance(double fromLat, double fromLon, double toLat, double toLon){
        double radius = 6371;   // Earth radius in km
        double deltaLat = Math.toRadians(toLat - fromLat);
        double deltaLon = Math.toRadians(toLon - fromLon);
        double lat1 = Math.toRadians(fromLat);
        double lat2 = Math.toRadians(toLat);
        double aVal = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
            Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2);
        double cVal = 2*Math.atan2(Math.sqrt(aVal), Math.sqrt(1-aVal));  

        double distance = radius*cVal;
        Log.d("distance","radius * angle = " +distance);
        return distance;
    }

According to this link
i made working method. The answer above was wrong, because it doesn't convert lat/lng degrees to radians.

    private double getDistance(double fromLat, double fromLon, double toLat, double toLon){
        double radius = 6371;   // Earth radius in km
        double deltaLat = Math.toRadians(toLat - fromLat);
        double deltaLon = Math.toRadians(toLon - fromLon);
        double lat1 = Math.toRadians(fromLat);
        double lat2 = Math.toRadians(toLat);
        double aVal = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) +
            Math.sin(deltaLon/2) * Math.sin(deltaLon/2) * Math.cos(lat1) * Math.cos(lat2);
        double cVal = 2*Math.atan2(Math.sqrt(aVal), Math.sqrt(1-aVal));  

        double distance = radius*cVal;
        Log.d("distance","radius * angle = " +distance);
        return distance;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文