2017-03-04 4 views
0

直線距離のための特別な勾配については、マップに格納されている他のすべての点に対して、指定された緯度/経度が10kmを超える新しい点を確認する必要があります。私は、マップ内のすべての点が順次比較されることを避けたいと思います。1つの値をすべてのリスト項目と1ステップで比較するにはどうすればよいですか?

私は、次のコードを試してみました:

private static Map<Long,String> getTop10DSEGs() throws IOException { 
    Map<Long,String> top10Dsegs = new HashMap<>(); 
    List<String> allDsegs = loadDsegRanking(rFiles); 
    //the list allDsegs is a csv with the following structure 
    //dsegID, Latitide, Longitude 
    //1167317891449551556,51.435550689697266,6.695819854736328 
    double LatFromList, LonFromList; 
    double LatFromMap, LonFromMap; 
    String[] listArray; 
    String[] mapArray; 
    Long firstDseg = Long.parseLong(allDsegs.get(0).substring(0, 19)); 
    top10Dsegs.put(firstDseg, allDsegs.get(0).substring(20)); 
    //Iterating through all dsegs 
    for(String line : allDsegs){ 
     Long nextID = null; 
     String nextCoordinates = "0.0000,0.0000"; 
     listArray = line.split(","); 
     LatFromList = Double.valueOf(listArray[1]); 
     LonFromList = Double.valueOf(listArray[2]); 
     //checking all coordinates of maped dsegs 
     for(Map.Entry<Long, String> entry : top10Dsegs.entrySet()){ 
      List<Double> distanceList = new ArrayList<>(); 
      mapArray = entry.getValue().split(","); 
      LatFromMap = Double.valueOf(mapArray[0]); 
      LonFromMap = Double.valueOf(mapArray[1]); 
      //calculating the distance between the next city from the list and the other dsegs from the map 
      //result of dist is a double and it's metric is Km. 
      Double dist = Implements.DistanceCalculator.distance(LatFromMap, LonFromMap, LatFromList, LonFromList, "K"); 
      distanceList.add(dist); 
      for(Double value : distanceList){ 
       if (dist>10){ 
        nextID = Long.parseLong(listArray[0]); 
        nextCoordinates = listArray[1] + "," + listArray[2]; 
       } 
      } 
     } 
     if(nextID != null && top10Dsegs.size() < 10){ 
      top10Dsegs.put(nextID, nextStartCoordinates); 
     } 
return top10Dsegs;  
} 
+0

本当にいいアルゴリズムです –

+0

(1)「1ステップで」とは何ですか? (2)ポイントのリストや*「新しいポイント」をチェックする必要がありますか?それがリストであれば、何とかソートされていますか? (3)どのマップがポイントを格納し、キーと値は何を表していますか? (4)なぜ「地図内のすべての点が順番に比較される」*を避けたいのですか? (4)そのマップはどのくらいの頻度で変更されますか? (5)ストリームを使用できますか? – user1803551

+0

最初のリストをソートすることで、ポイントをより早く削除するのに大いに役立ちます... –

答えて

1

はすべて、既に保存されたポイントと新しい間の距離を計算し、比較しないようにするにはJavaの8ストリームAPIに

boolean exists = allDsegs.stream().anyMatch(x -> x.equals(firstDseg /* or whetever you compare */)); 
+0

あなたのプログラムで反復が見られないだけでは、それが起こらないというわけではありません。 – Henry

+0

いいえ、値をリスト内の値と比較するには、リストを参照しないでください。彼は反復を実装したくないという疑問を理解しています –

+0

すべてを反復するよりも速く近くの点を見つけることを可能にする別のデータ構造を使うことができます。 geopoints間の直線距離を比較するための別の方法があります:全く別の質問 – Henry

2

anyMatchを見てください(マルチ)マップまたは配列で実装されている何らかの種類のグリッド(またはマトリックス)を使用することができます。グリッドの各セルは、sqrt(10km)のサイズを持ち、関連する座標を持つすべての点を含みます。点の適切なセルの座標をsqrt(10)で割ることで、その座標を簡単に計算できます。

したがって、次の点を追加するときには、9個のセル(自分自身+周囲)の点までの距離をチェックすることができます。私はそれが地図上のすべてのポイントよりずっと少ないと思う。

+0

あなたは私の問題を誤解しましたか? 私はすべて保存されたポイントで新しい値を比較する必要があります。あらかじめ定義されたリストと別のリスト(マップ)があります。別のリストには、距離が10 kmを超えるdsegしか格納されません。 –

+0

あなたはポイントを保存したり、入力リストを修正するために、他の狭窄を使用したくない場合は、私が思うに、すべての距離を比較するより他に方法はありません。 – Nolequen

0

大丈夫です。

今、私はStream-Apiを使用し、そこにallMatch() - メソッドを使用して解決しました。問題は、新しい要素を保存するためのマップを作成したこと、さらにはcheck = allDsegs.stream().anyMatch(x->dist>10);というテストが間違っていたことです。 解決策は、新しい要素にリスト(top10List)を使用し、top10Listに10km未満の要素があるかどうかをテストする必要があることです。

ここは、(残念ながら)美しくないコードです。私はちょうど7ヶ月以来初心者です:

private static List<Top10Dsegs> getTop10DSEGs() throws IOException { 
    List<File>rFiles = getRFiles(); 
    List<String> allDsegs = loadDsegRanking(rFiles); 
    List<Top10Dsegs> top10List = new ArrayList<>(); 
    double startLat_allDsegs, startLon_allDsegs; 
    double startLat_top10List, startLon_top10List; 
    String[] listArray; 
    //declaring the starting dseg and its coordinates 
    String startEntry = allDsegs.get(0); 
    Top10Dsegs firstEntry = new Top10Dsegs(startEntry); 
    top10List.add(firstEntry); 
    System.out.println("Iteration starts here!\n---------------------"); 
    //begin to iterate over all entries (just ranked) 
     for(String line : allDsegs){ 
      boolean check=true; 
      Top10Dsegs nextEntry=null; 
      //structure from allDsegs: 
      //DSEG,startLat,startLon 
      //1231231231231231231, 54.123, 8.456 
      listArray = line.split(","); 
      startLat_allDsegs = Double.valueOf(listArray[1]); 
      startLon_allDsegs = Double.valueOf(listArray[2]); 

      //start to check if line-entry of allDsegs has a distance > 10 km compared to given Dsegs 
      for(Top10Dsegs entry : top10List){ 
       startLat_top10List = entry.getStartLat(); 
       startLon_top10List = entry.getStartLon(); 
       //the DistanceCalculator calculates the distance between the dseg from allDsegs and the other dseg from top10Dsegs 
       DistanceCalculator distanceCalculator = new DistanceCalculator(); 
       Double dist = distanceCalculator.distance(startLat_top10List, startLon_top10List, startLat_allDsegs, startLon_allDsegs, "K"); 
       System.out.println("Checked Dseg: " + listArray[0]); 
       System.out.println("Distance between checked Dseg and " + entry.getSegmentID() + " = " + dist); 
       //check if there is a dseg from allDsegs distance > 10 km compared to ALL OTHER dsegs 
       if(top10List.stream().allMatch(x->dist<10)==true){ 
       check = false; 
       } 
       System.out.println("Are all distances > 10 ? \t" + check); 
      } 
      if(check==true && top10List.size()<10){ 
       nextEntry = new Top10Dsegs(listArray[0]+","+listArray[1]+","+listArray[2]); 
       top10List.add(nextEntry); 
      } 
      System.out.println("Progress: \n"+top10List.size()+" entries inside top 10 list. \n<---------------->\nNext Iteration:"); 
    } 
    return top10List; 
} 
関連する問題