2

Web ブラウザ コントロールを介して Google Earth プラグインを使用する ac# アプリケーションを構築しています。アプリケーションの一部として、地球上の特定の領域の周囲に複数選択ボックスを作成できるようにする必要があります (ファイル ブラウザーで複数のファイルをドラッグして選択するようなものを考えてください)。

私が現在セットアップしている方法では、c# コードは、選択モードになっているときを追跡します。もしそうなら、最初の左クリックで、Google Earth プラグインからそのポイントの緯度経度を取得します。その後、マウスの動きによって反対側の角の緯度経度が取得され、C# コードは次の 2 つの JavaScript 関数を呼び出します。

function clearHighlightBox(){
    var placemark = ge.getElementById('DARTselectBox');
    if(placemark)
    {
        ge.getFeatures().removeChild(placemark);
    }
}

function setHighlightBox(lat1, long1, lat2, long2){
    clearHighlightBox();
    var placemark = ge.createPlacemark('DARTselectBox');
    var lineString = ge.createLineString('');
    var coords = lineString.getCoordinates();
    coords.pushLatLngAlt(lat1, long1, 5000);
    coords.pushLatLngAlt(lat1, long2, 5000);
    coords.pushLatLngAlt(lat2, long2, 5000);
    coords.pushLatLngAlt(lat2, long1, 5000);
    coords.pushLatLngAlt(lat1, long1, 5000);
    placemark.setGeometry(lineString);
    ge.getFeatures().appendChild(placemark);
}

まず、目印の ID をこの方法で作成してもうまくいかないようです (ge.createPlacemark('DARTselectBox');)。これを切り替えてすべてをクリアし、Create Placemark 呼び出しから ID を削除すると、少なくともクラッシュしません。ただし、それを行っても、長方形の右の垂直脚しか表示されません。

4

2 に答える 2

1

これを切り替えてすべてをクリアし、Create Placemark 呼び出しから ID を削除すると、少なくともクラッシュしません。

問題は、削除してから同じ ID を持つオブジェクトをすぐに追加できないことです。簡単に言えば、IDがまだ内部で使用されているge.createPlacemark('DARTselectBox')ため、クラッシュの原因となっているのは への呼び出しです。DARTselectBox最終的には再び使用できますが、時間は WebBrowser コントロールのガベージ コレクションに依存します。

クラッシュを回避するには、プレースマークで release を呼び出して、ID がすぐに解放されるようにしてください。呼び出しreleaseが何をするかについては、このメモを参照してください (私の強調)

オブジェクトを完全に削除し、その ID を再利用できるようにします。解放されたオブジェクトにアクセスしようとすると、エラーが発生します。

毎回目印を追加したり削除したりするのではなく、単に目印の表示状態を切り替えることができない場合。

ID の再利用に関する実際の問題はバグとしてリストされており、問題に関する詳細情報がここにあります。

編集:

それを見ると、リリース方法にバグがある可能性があります。

私が投稿したリンクを読んだらcode.google.com/p/earth-api-samples/issues/detail?id=253、一番下のコメントのいくつかがこれを示唆しているようです。

とにかく、ハッシュは機能するので、増分カウンターも機能します。しかし、単に可視性を false に設定したり、ID なしで Placemark を作成したり、操作中に参照を保持したりしない理由がわかりません。

表示の問題は、テッセレーションと高度モードが原因である可能性があります。

setTessellate(true)Placemarks ジオメトリ オブジェクトを呼び出してみてください。また、高度モードが に設定されていることを確認clampToGroundしてください。これを行うsetAltitudeMode(ge.ALTITUDE_CLAMP_TO_GROUND)には、Placemarks ジオメトリ オブジェクトでもう一度呼び出します。

だからあなたは持っています

var lineString = ge.createLineString('');
lineString.getCoordinates().pushLatLngAlt( ... );
lineString.setTessellate(true);
lineString.setAltitudeMode(ge.ALTITUDE_CLAMP_TO_GROUND);

それでもうまくいかない場合は、地形レイヤーをオフにして、線があるかどうかを確認してみてください。

また、私は API で多くのことを行う無料のコントロール ライブラリを作成しました。これは GPL であるため、ほとんど好きなように使用できます。このように多くのことをカバーしています。 http://code.google.com/p/winforms-geplugin-control-library/

于 2013-07-16T05:33:26.360 に答える
-1

私は非常に似たようなことをするアプリケーションを持っています。残念ながら、コードは GPL ではないため、ここで公開することはできません。一般的に、あなたのアプローチは正しいですが、問題はボックスの構築に使用している構造にあると思います。

4 つの個別KmlLineStringのオブジェクト (ボックスのエッジに 1 つ)を使用するかKmlLinearRing、囲まれたボックスを作成する必要があります。が閉じた多角形を作成するように設計されたとは思いませんKmlLineString。それが線形リングの目的です。

ボックス ポイントを計算する方法は (私の作業ソリューションと比較して) 私には良さそうに見えるので、交換するだけcreateLineStringcreateLinearRingうまくいくと思います。

Google のサンプルは以下のリンクにあります。linearRing囲まれたポリゴンに使用されていることがわかります。(ページの半分くらい)

https://developers.google.com/earth/documentation/geometries

于 2013-07-16T01:18:30.853 に答える