簡體   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