繁体   English   中英

快速比较地理位置之间的距离

[英]Comparing distances between geopoints fast

我在地图上显示了一个(很长的)点列表。 我需要计算每个点到用户输入点的距离,并从最近到最远对列表进行排序。

现在,我正在这样做:

private List<Point> sortedPointList(LatLng ll, List<Point> pointList)
    SparseArray<Double> distances = new SparseArray<Double>();
    for (Point ll : pointList){
        double distance = calcDistance(ll.getLatLng(), point);
        distances.put(ll.getId(), distance);
    }
    Collections.sort(pointList, new Comparator<Point>(){

        @Override
        public int compare(final Tramo lhs, final Tramo rhs) {
            return distances.get(lhs.getId()).compareTo(distances.get(rhs.getId()));
        }
    });
    return pointList
}


private double calcDistance(LatLng ll1, LatLng ll2){
    final double lat1 = ll1.latitude;
    final double lon1 = ll1.longitude;
    final double lat2 = ll2.latitude;
    final double lon2 = ll2.longitude;
    final double lat = lat2-lat1;
    final double lon = lon2-lon1;
    final double squareLat = lat*lat;
    final double squareLon = lon*lon;
    final double squareDistance = squareLat+squareLon;
    return squareDistance;
}

calcDistance实际上返回两点之间的实际距离的平方,因为我认为比较平方将得到与比较实际值相同的结果,并且由于不需要创建平方根,因此速度更快。

但是,它仍然很慢(列表很长),我真的很感谢一些想法来加快这一过程。 我会在排序之前预先计算距离,因此我不会多次计算每个距离,但是我想不出任何其他改进。 有什么我想念的吗?

您可以在多个胎面之间进行划分,例如使用四个线程,并使用线程1计算前1/4个点的距离,使用线程2计算第二个1/4点的距离,等等。只需确保SparseArray#put是线程安全的(我不知道您要为此使用哪个库)-如果需要在put方法周围加一个锁,那么如果您在多个线程之间拆分它,则该程序实际上可能运行得较慢。

使用单精度而不是双精度浮点计算也可以加快速度。 如果只关心固定精度(例如,两个小数点精度),则可以改用定点算术 ,该算术实际上使用整数算术。

根据程序的工作情况,您可能可以延迟计算到其他点的距离-例如,如果您一次向用户显示25个点,则可以确定最接近的100左右点,然后等待计算下一个100点左右,直到用户滚动到75-100点为止; 无论如何,用户可能只关心前25个点,在这种情况下,您不必计算其他点的距离。 为此,您需要使用范围树kd树为点建立索引,以便您可以快速确定最接近查询点的点,而不必遍历整个列表。 如果您的点在数据库中,则可以执行范围查询。 请注意,无论哪种情况,树/查询都是根据其曼哈顿距离(delta-lat + delta-lon,而不是delta-lat ^ 2 + delta-lon * 2)来查找最接近的点,因此您仍然需要计算他们的笛卡尔距离。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM