web-dev-qa-db-ja.com

GoogleマップでARCポリラインを描く

Googleマップで円弧ポリラインを描画するにはどうすればよいですか?

私はすでに this コードを使用してcurvedポリラインを作成しました。

曲線のポリラインを描画するためのメソッドは次のとおりです。

private void showCurvedPolyline (LatLng p1, LatLng p2, double k) {
    //Calculate distance and heading between two points
    double d = SphericalUtil.computeDistanceBetween(p1,p2);
    double h = SphericalUtil.computeHeading(p1, p2);

    //Midpoint position
    LatLng p = SphericalUtil.computeOffset(p1, d*0.5, h);

    //Apply some mathematics to calculate position of the circle center
    double x = (1-k*k)*d*0.5/(2*k);
    double r = (1+k*k)*d*0.5/(2*k);

    LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0);

    //Polyline options
    PolylineOptions options = new PolylineOptions();
    List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dash(30), new Gap(20));

    //Calculate heading between circle center and two points
    double h1 = SphericalUtil.computeHeading(c, p1);
    double h2 = SphericalUtil.computeHeading(c, p2);

    //Calculate positions of points on circle border and add them to polyline options
    int numpoints = 100;
    double step = (h2 -h1) / numpoints;

    for (int i=0; i < numpoints; i++) {
        LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step);
        options.add(pi);
    }

    //Draw polyline
    mMap.addPolyline(options.width(10).color(Color.Magenta).geodesic(false).pattern(pattern));
}

出力

1. this.showCurvedPolyline(latLng1、latLng2、0.1);を使用している場合次に取得:

enter image description here

上の画像でわかるように、私たちは目標を達成するのに非常に近いですが、なぜそれが別のエンドポイントに接続していないのかわかりません

2. this.showCurvedPolyline(latLng1、latLng2、1);を使用している場合次に取得:

enter image description here

3.LatLngを使用している場合c = SphericalUtil.computeOffset(p、x、h-90.0);次に取得:

enter image description here

注:これほどは欲しくない大きな円の形、本当にそんなに高さは欲しくない

これが下の画像に示すようにARCシェイプが欲しいものです

enter image description here

これが[〜#〜] code [〜#〜]私が使用している曲線ポリラインの追加2つの間geo-locatios

private void addCurvedPolyLine() {

        LatLng latLng1 = new LatLng(40.7128, 74.0059); // New York
        LatLng latLng2 = new LatLng(51.5074, 0.1278); // London

        Marker marker1 = mMap.addMarker(new MarkerOptions().position(latLng1).title("Start"));
        Marker marker2 = mMap.addMarker(new MarkerOptions().position(latLng2).title("End"));

        LatLngBounds.Builder builder = new LatLngBounds.Builder();

        builder.include(marker1.getPosition());
        builder.include(marker2.getPosition());

        LatLngBounds bounds = builder.build();
        int padding = 0; // offset from edges of the map in pixels
        CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
        mMap.moveCamera(cu);
        mMap.animateCamera(cu);

        this.showCurvedPolyline(latLng1, latLng2, 0.1);

    }
12
Sonali

別の質問 で提案した解決策は、非常に短い距離の曲線ポリラインに焦点を当てていました。たとえば、始点と終点が道路にスナップされるDirections APIルートがあるが、元のリクエストの実際の始点と終点が建物の位置であった場合、この曲線の破線のポリラインで道路と建物を接続できます。 。

あなたの例のように長距離の場合、APIで利用可能な測地線ポリラインを使用できると思います。ポリラインオプションの測地線プロパティをtrueに設定できます。

public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    mMap.getUiSettings().setZoomControlsEnabled(true);

    LatLng latLng1 = new LatLng(40.7128, 74.0059); // New York
    LatLng latLng2 = new LatLng(51.5074, 0.1278); // London

    Marker marker1 = mMap.addMarker(new MarkerOptions().position(latLng1).title("Start"));
    Marker marker2 = mMap.addMarker(new MarkerOptions().position(latLng2).title("End"));

    List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dash(30), new Gap(20));
    PolylineOptions popt = new PolylineOptions().add(latLng1).add(latLng2)
       .width(10).color(Color.Magenta).pattern(pattern)
       .geodesic(true);
    mMap.addPolyline(popt);

    LatLngBounds.Builder builder = new LatLngBounds.Builder();

    builder.include(marker1.getPosition());
    builder.include(marker2.getPosition());

    LatLngBounds bounds = builder.build();
    int padding = 150; // offset from edges of the map in pixels
    CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
    mMap.moveCamera(cu);
    mMap.animateCamera(cu);
}  

結果のポリラインは私のスクリーンショットに表示されます

enter image description here

これがお役に立てば幸いです。

5
xomena

円弧を描く別の方法があります。グーグルマップ投影APIを使用してオーバーレイビューにポリラインを描画すると、多くのことが可能になります。これを確認してください repo 例があります。

enter image description here

1
amalBit

これは、 @ xomena からいくつかの改善を行った後に使用しているRouteオブジェクトです。

Route.Java

私の変更:

  • heading - 90.0の代わりにheading + 90.0を使用してください
  • 変数の名前を変更し、定数を作成します(コードの一部が何をしているのかをまだ理解しています...)
  • 新しいロジックで書き直します

基本的には、起点と終点の距離が1000km未満の場合にのみカーブルートを描きます。長距離の場合、 ここ で述べたように、ループ内のh1 + i * stepの部分が、すべてのイテレータのdouble calculation errorのために小さなエラーを起こし、最終ルートを作成しないことがわかりました。正しく配置されています。

私の安全な選択は、代わりにカラスの飛行ルートを描くことですが、これにk = 1を使用しないことをお勧めします。これは、パフォーマンス効率ではありません。ルートに起点と終点を追加するだけで、他のすべての複雑な計算をスキップする別のメソッドを作成しました。

私は将来、この長いカーブのルートの問題に立ち返ろうとしますが、今のところ、この解決策はまだ私の問題に適しています。

編集:

これまでの2番目の問題に対する私の解決策は次のとおりです。

  • heading + 90またはheading - 90を変更しても問題は解決しなかったため、修正しないでください。
  • 代わりに、step変数の計算を次のように変更します。

    ダブルステップ= Math.toDegrees(Math.atan(distance/2/midPerpendicularLength))* 2/DEFAULT_CURVE_POINTS;

1
Tam Huynh

こんにちは、このメソッドでshowCurvePolylineメソッドを変更する必要があります。

    private void showCurvedPolyline (LatLng p1, LatLng p2, double k) {
    //Calculate distance and heading between two points
    double d = 0;


if (d == 0)
        d= SphericalUtil.computeDistanceBetween(Origin, dest);



double h = SphericalUtil.computeHeading(p1, p2);

    // Calculate midpoint position
    LatLng midPoint = SphericalUtil.computeOffset(p1, d / 2, h);




    //Apply some mathematics to calculate position of the circle center
    double x = (1-k*k)*d*0.5/(2*k);
    double r = (1+k*k)*d*0.5/(2*k);

    LatLng c = SphericalUtil.computeOffset(p, x, h + 90.0);

    //Polyline options
    PolylineOptions options = new PolylineOptions();
    List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dash(30), new Gap(20));

    //Calculate heading between circle center and two points
    double h1 = SphericalUtil.computeHeading(c, p1);
    double h2 = SphericalUtil.computeHeading(c, p2);

// Calculate position of the curve center point
    double sqrCurvature = DEFAULT_CURVE_ROUTE_CURVATURE * DEFAULT_CURVE_ROUTE_CURVATURE;
    double extraParam = distance / (4 * DEFAULT_CURVE_ROUTE_CURVATURE);
    double midPerpendicularLength = (1 - sqrCurvature) * extraParam;
    double r = (1 + sqrCurvature) * extraParam;

    LatLng midCurvePoint = SphericalUtil.computeOffset(midPoint, midPerpendicularLength, heading - 90.0);

    // Calculate heading between circle center and two points
    double headingToOrigin = SphericalUtil.computeHeading(midCurvePoint, Origin);
    double headingToDest = SphericalUtil.computeHeading(midCurvePoint, dest);
    // Calculate positions of points on the curve
    double step = (headingToDest - headingToOrigin) / DEFAULT_CURVE_POINTS;

    List<LatLng> points = new ArrayList<>();
    for (int i = 0; i < DEFAULT_CURVE_POINTS; ++i) {
        points.add(SphericalUtil.computeOffset(midCurvePoint, r, headingToOrigin + i * step));
    }


    for (int i=0; i <points; i++) {
        LatLng pi = SphericalUtil.computeOffset(c, r, h1 + i * step);
        options.add(pi);
    }

    //Draw polyline
    mMap.addPolyline(options.width(10).color(Color.Magenta).geodesic(false).pattern(pattern));
}

次に、arcPolyLineを描画できます。これは、前の回答で提供されたファイルで提供されていました。

1
Sardar Khan