2017-05-29 22 views
2

GMapsFxを使用してJavaFxアプリケーションを構築し、Google Mapsを埋め込むようにしています。JavaFX:地図を追加して上に描画する

私は、このAPIを使用してマップの一番上に楕円を描こうとしていますが、APIはアークのみを提供しています。
これを回避するために、私は楕円の4分の3を描画しようとしましたが、円の4分の3しか描画できなかったので、GMapsFxは半径の1つを無視して円弧を描くようでした。

次のコードの結果:

double centerLat = 31.166724; 
double centerLong = 34.793119; 
double latDelta = 0.5; 
double longDelta = 0.01; 
LatLong centreP = new LatLong(centerLat, centerLong); 
LatLong start = new LatLong(centerLat, centerLong + longDelta); 
LatLong end= new LatLong(centerLat + latDelta, centerLong); 
MVCArray p= ArcBuilder.buildArcPoints(centreP, end, start); 

com.lynden.gmapsfx.shapes.Polyline pp = new com.lynden.gmapsfx.shapes.Polyline(); 
pp.setPath(p); 
map.addMapShape(pp); 

は、次の画像に表示されます。

Result of the code

番号を消化:
センター:31.166724、34.793119
スタート:31.166724、34.803119
終了:31.666724、34.793119

あなたがendcenterはそれぞれに非常に接近していることがわかります他の(私たちは非常に高く狭い弧を得ていたはずです)、弧は実際に東方で非常に遠くから円の四分の一を始めます。

  1. この問題の原因は何ですか?
  2. 地図の上に楕円を描画するためのより良い方法がありますか?JavaFx

答えて

1

ArcBuilderは1つの半径しか使用しません。始点と終点は、円弧の始点と終点のベアリングを得るために使用されます(LatLong)。したがって、楕円を描くには使用できません。この画像では、次のコード

double centerLat = 31.166724; 
double centerLong = 34.793119; 
double latDelta = 0.5; 
double longDelta = 0.01; 
LatLong centreP = new LatLong(centerLat, centerLong); 
LatLong start = new LatLong(centerLat, centerLong + longDelta); 
LatLong end = new LatLong(centerLat + latDelta, centerLong); 

double longRadius = centreP.distanceFrom(start); 
double latRadius = centreP.distanceFrom(end); 

MVCArray p = EllipseBuilder.buildEllipsePoints(centreP, longRadius, latRadius); 

com.lynden.gmapsfx.shapes.Polyline pp = new com.lynden.gmapsfx.shapes.Polyline(); 
pp.setPath(p); 
map.addMapShape(pp); 

// Add markers to the map 
MarkerOptions markerOptionsStart = new MarkerOptions(); 
markerOptionsStart.position(start).visible(Boolean.TRUE).title("Start").label("S"); 
Marker markerStart = new Marker(markerOptionsStart); 
map.addMarker(markerStart); 

MarkerOptions markerOptionsEnd = new MarkerOptions(); 
markerOptionsEnd.position(end).visible(Boolean.TRUE).title("End").label("E"); 
Marker markerEnd = new Marker(markerOptionsEnd); 
map.addMarker(markerEnd); 

結果を使用してそれを呼び出す

import com.lynden.gmapsfx.javascript.object.LatLong; 
import com.lynden.gmapsfx.javascript.object.MVCArray; 

public class EllipseBuilder { 

    private static final int DEFAULT_ELLIPSE_POINTS = 10000; 

    /** 
    * Generates the points for an ellipse based on two radii from a center point. 
    * 
    * @param center 
    *   The LatLong point of the center. 
    * @param longRadius 
    *   longitude radius in meters 
    * @param latRadius 
    *   latitude radius in meters 
    * @return An array of LatLong points in an MVC array representing the ellipse. 
    */ 
    public static final MVCArray buildEllipsePoints(LatLong center, double longRadius, double latRadius) { 
    return buildEllipsePoints(center, longRadius, latRadius, 0.); 
    } 

    /** 
    * Generates the points for an ellipse based on two radii from a center point and a counter clockwise rotation angle. 
    * 
    * @param center 
    *   The LatLong point of the center. 
    * @param longRadius 
    *   longitude radius in meters 
    * @param latRadius 
    *   latitude radius in meters 
    * @param rotAngle 
    *   rotation angle in degree, counter clockwise 
    * @return An array of LatLong points in an MVC array representing the ellipse. 
    */ 
    public static final MVCArray buildEllipsePoints(LatLong center, double longRadius, double latRadius, double rotAngle) { 
    int points = DEFAULT_ELLIPSE_POINTS; 

    MVCArray res = new MVCArray(); 

    double longRadiusSquared = longRadius * longRadius; 
    double latRadiusSquared = latRadius * latRadius; 

    double radiiProduct = longRadius * latRadius; 

    double theta = 0d; 
    double angleIncrement = 360.0/points; 
    for (int i = 0; (i < points + 1); i++) { 
     theta = i * angleIncrement; 
     double r = radiiProduct/(Math.sqrt(latRadiusSquared * Math.pow(Math.sin(Math.toRadians(theta)), 2) 
       + longRadiusSquared * Math.pow(Math.cos(Math.toRadians(theta)), 2))); 
     res.push(center.getDestinationPoint(theta - rotAngle, r)); 
    } 

    return res; 
    } 
} 

:ライブラリは、楕円形状を提供していないので

は、私が代わりに EllipseBuilderクラスを書いた

GMapFX Ellipse Example

回転楕円を描くには、角度を度で追加します。楕円は、反時計方向に回転する。

double longRadius = centreP.distanceFrom(start); 
double latRadius = centreP.distanceFrom(end); 
double rotAngle = 20.; 

MVCArray p = EllipseBuilder.buildEllipsePoints(centreP, longRadius, latRadius, rotAngle); 

楕円が20度回転し、反時計回り:

GMapFX Rotated Ellipse Example

Iは、開始と終了点をマークするためのマーカーを使用しました。

あなたのケースでは楕円が非常に狭いので、私はDEFAULT_ELLIPSE_POINTSに非常に高い値を使用しました。ユースケースに応じて、この値は小さくする必要があるため、静的変数の代わりにパラメータとして設定すると便利です。

+0

ありがとうございました!非常に役立ちます。 –

+0

ところで、与えられた角度に対してこの楕円の回転をいかに簡単に実装するかについての一般的な考え方はありますか? –

+0

@StasRodovコードにローテーションを追加しました。うれしかったよ! –

関連する問題