2016-04-21 19 views
2

アンドロイドで図形の中心を取得しようとしています。図形は地図上に手で描かれています。私はすべてのコーディネイトを持っていますが、平均値は思ったよりも厄介なものになっています。私は平均緯度と経度にマーカーをプロットしたいと思います。Googleマップの緯度と経度の点の中心点

私は緯度と経度を別々に合計してから、ポイント数で除算しようとしました。これは正しい答えを出すものではありません。マーカーは、常に描画図の後ろにあるようです。私はまた、実装を使用して試してみましたが、それは同じ答え、前のSOの質問、私が使用しているCalculate the center point of multiple latitude/longitude coordinate pairs

コード提供します:

private void calculateFreeHandPolygonParameters(){ 

    double xValues = 0; 
    double yValues = 0; 
    double zValues = 0; 
    int count = 0; 

    // linesForPolygon a list of the lines in the polygon 
    for(Polyline line : linesForPolygon){ 
     for (LatLng point : line.getPoints()) { 
      xValues += Math.cos(Math.toRadians(point.latitude)) * Math.cos(Math.toRadians(point.longitude)); 
      yValues += Math.cos(Math.toRadians(point.latitude)) * Math.sin(Math.toRadians(point.longitude)); 
      zValues += Math.sin(Math.toRadians(point.latitude)); 
      count++; 
     } 
    } 

    double meanX = xValues/count; 
    double meanY = yValues/count; 
    double meanZ = zValues/count; 

    double centralLongitude = Math.atan2(meanY, meanX); 
    double centralSquareRoot = Math.sqrt(Math.pow(meanX, 2) + Math.pow(meanX, 2) + Math.pow(meanX, 2)); 
    double centralLatitude = Math.atan2(meanZ, centralSquareRoot); 

    double latitude = Math.toDegrees(centralLatitude); 
    double longitude = Math.toDegrees(centralLongitude); 

    Log.i("MAPS", "Freehand Parameters: x mean -> " + latitude + " y mean -> " + longitude); 

    testMarker = mMap.addMarker(new MarkerOptions() 
      .position(new LatLng(latitude, longitude)) 
      .title("Polygon center") 
      .snippet("lat: " + latitude + " long: " + longitude)); 
} 
+0

あなたが記述する方法は、経度が国際的なデータ線の近くにある場合や、場所が極の近くにある場合を除いて、機能するはずです。おそらくコードを共有する必要があります。 – JerryM

答えて

1

を試してみてください...あなたは、アルゴリズムの擬似コードを理解した後に、それは簡単なコーディング作業ですが、古典的なGISの質問である私の重心のコードは次のとおりです。

public class PolygonCentroid { 

    private List<GeoPoint> points; 
    private int pointsSize; 

    public PolygonCentroid(List<GeoPoint> points) { 
     this.points = points; 
     this.pointsSize = points.size(); 
    } 

    protected double polygonArea() { 
     double area = 0; 
     for (int i = 0, j; i < pointsSize; i++) { 
      j = (i + 1) % pointsSize; 
      area += points.get(i).getLongitude() * points.get(j).getLatitude(); 
      area -= points.get(i).getLatitude() * points.get(j).getLongitude(); 
     } 
     area /= 2.0; 
     return area; 
    } 

    public GeoPoint centroid() { 
     double cx = 0, cy = 0; 
     double factor; 
     for (int i = 0, j; i < pointsSize; i++) { 
      j = (i + 1) % pointsSize; 
      factor = (points.get(i).getLongitude() * points.get(j).getLatitude() - points.get(j).getLongitude() * points.get(i).getLatitude()); 
      cx += (points.get(i).getLongitude() + points.get(j).getLongitude()) * factor; 
      cy += (points.get(i).getLatitude() + points.get(j).getLatitude()) * factor; 
     } 
     double A = polygonArea(); 
     factor = 1.0/(6.0 * A); 
     cx *= factor; 
     cy *= factor; 
     return new GeoPoint(cy, cx); 
    } 

} 

enter image description here

また、重心が多角形の外であってもよいことに注意してください:

enter image description here

Full source codeおよびusage

+0

このメソッドは、最初の繰り返しに対してのみ機能します。別のポリゴンを描くとなぜ機能しないのか分かりません。マーカーは、前のバージョンのコードと同じように後ろにあります。 –

+0

私のように座標のリストをリセットすることを忘れないでください。 –

+0

> "マーカの後ろにある"私はあなたが[Z-ordering](https://stackoverflow.com/questions/14771569/google-maps-v2-marker-zordering-set-to-top)に注意する必要があります。オーバーレイの一部を常に上に表示したいとします。 –

1
  1. をあなたが実際にCENTROIDと呼ばれるものを計算する必要があります。それは些細なことではありません: http://www.spatialanalysisonline.com/HTML/index.html?centroids_and_centers.htm 飛行機マップ上のリコールフライトプランに注意してください。距離が比較的大きい場合は、この現象を念頭に置く必要があります。
  2. これは、ここでgis.stackexchange.com
+0

私が使っているコードはどうしてうまくいかないのですか?私がしたように平均を計算するのは完璧な意味がありますか?あなたが与えたリンクの最初の方法は、私が最初に試したものですが、後ろについてきました。領域を計算する必要があるメソッドは非常に複雑になるでしょう –

+0

はい、この種のアルゴリズムの低レベルコードは実際に複雑です...通常、この種のタスクのgisライブラリを使用します。ポストギスは、この種のクエリメソッドも持っています。 – michael

関連する問題