Google Maps&JavaFX:JavaFXボタンをクリックした後に地図上にマーカーを表示


359

JavaFXアプリケーションのボタンをクリックすると、マップにマーカーを表示しようとしています。ボタンをクリックすると、JSONファイルに位置が書き込まれ、このファイルはマップを含むhtmlファイルに読み込まれます。問題は、ブラウザーでHTMLページを開いたときに完全に機能することですが、JavaFXのWebビューでは何も起こらず、理由がわかりません。

これはhtmlファイルです:

<!DOCTYPE html>
<html>
  <head>
  <title>Simple Map</title>
  <meta name="viewport" content="initial-scale=1.0">
  <meta charset="utf-8">
  <style>
  /* Always set the map height explicitly to define the size of the div
   * element that contains the map. */
  /*#map {
    height: 100%;
  }*/
  #map{width:100%;height:100%;margin:auto;}
  /* Optional: Makes the sample page fill the window. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>
</head>
<body>
<div id="map"></div>
<script>
  var map;
  var marker;
  // Multiple Markers
  var markers = [];
  var pos = {lat: 46.662388, lng: 0.3599617};
  var itinerary_markers = [];

  function initMap() {

    var currentLat, currentLng;//Latitude et longtitude courante

    $.ajax({
      url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
      async: false,
      dataType: 'json',
      success: function (data) {
        currentLat = data.results[0].geometry.location.lat;
        currentLng = data.results[0].geometry.location.lng;
      }
    });

    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: currentLat, lng: currentLng},
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });


    /*MARQUEUR*/ 
    $.ajax({
        async: false,
        url: 'test.json',
        data: "",
        accepts:'application/json',
        dataType: 'json',
        success: function (data) {
            for (var i = 0; i < data.hydrants.length; i++) {
                markers.push( data.hydrants[i]);
            }
        }
    });

      var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
      marker = new google.maps.Marker({
          position: posi,
          map: map,
          //title: markers[i][0]
          title: markers[0].Name
        });

  }
</script>

<script
    src="https://code.jquery.com/jquery-3.2.1.min.js"
    integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
    crossorigin="anonymous">
</script>


<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap&language=fr"
async defer></script>

</body>
</html>

ボタンをクリックすると、JSONファイル(完全に機能します)に入力してから、これを実行してWebビューを更新します。

this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());

前に言ったように、ブラウザーでファイルを開くと、期待どおりの結果が表示されますが、JavaFXの何が問題なのかわかりません。これを行うより良い方法がある場合は教えてください。

編集:

executeScript()メソッドを使用してJavaFXからJavaScriptにデータ(GPS座標)を直接送信することで問題の解決策を見つけたので、2つのプラットフォーム間のブリッジとしてjsonファイルは必要ありません。したがって、これはコードがどのように見えるかの例です:

eng.executeScript("updateMarker(" + lat + ", " + lng + ")");//eng is a WebEngine instance

そしてここにJavascriptがあります:

/*The initial latitude and longtitude*/
var currentLat = the latitude;
var currentLng = the longtitude;

function initMap() {

    map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: currentLat, lng: currentLng},
      zoom: 15,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    var posi = new google.maps.LatLng(currentLat, currentLng);
    marker = new google.maps.Marker({
        position: posi,
        map: map,
        visible: false
    });
  }

/*The method that is I call from JavaFX*/
function updateMarker(_lat, _lng){
    marker.setPosition({lat: _lat, lng: _lng});
    map.setCenter(new google.maps.LatLng(_lat, _lng));
    marker.setVisible(true);
  }

コメントと回答、そしてredditへの特別な銃撃戦をありがとう。



1
スクリプトは可能な限り最善の方法で記述されていませんが、問題はないようです。それが機能しない可能性があるいくつかの可能性があります。新しいマーカーがjsonファイルの先頭に追加されていることを確認します。cache: falseキャッシュされている場合はajax呼び出しに渡して、正しいファイルをターゲットにしていることを確認してください。また、いくつかのログが問題の特定に役立ちます。
グーカンクルト

1
JavaFXでajaxを使用してtest.jsonなどの非HTTPサービスのエンドポイントから呼び出し/データを受信するのに問題があるのでしょうか?
セバスチャン

@Sebastian Whatsが私を狂わせているのは、アプリを開くとjsonファイルが正しく読み込まれ、期待どおりの結果が表示されることです。問題は、jsonファイルを別の値で更新するとき(アプリが開いているときに)、更新して新しいマーカーを表示したくないだけです。したがって、ajax呼び出しに問題はありません。しかし、それはコールバックのことでしょうか?ページの読み込み中にinitMap()が呼び出されるため
Chandler Bing

@GökhanKurtあなたは上の答えを読んでいただけます
チャンドラービン

回答:


70

私が推測しなければならなかった場合-2つのことの1つが起こっています:

A)javaFXがクロスサイトのajax呼び出しをサポートしていないか、B)非同期のajax応答を待っていないか、何かがうまくいかない。

一緒にいくつかのテストをしてみましょう。最初に、これをクリーンアップしてajax呼び出しをネストできますか?次に、いくつかのconsole.logステートメントを追加して、それぞれが何を送り返しているかを確認できますか?一部の出力を見逃した場合は、どこで問題が発生しているかがわかります。これは問題の修正に役立ちます。

成功は少し古いので、成功を「完了」の追加に変更しました。空白が次の呼び出しに送信されているかどうかに関する質問を排除するためにすべてがネストされています(同期の問題)。

$.ajax({
    url: 'https://maps.googleapis.com/maps/api/geocode/json?address=My+ADDRESS&key=MY_KEY',
    async: false,
    dataType: 'json'
}).done(function(data) {
    currentLat = data.results[0].geometry.location.lat;
    currentLng = data.results[0].geometry.location.lng;
    console.log(currentLat);
    console.log(currentLng);
    // Multiple Markers
    var markers = [];
    var pos = {lat: 46.662388, lng: 0.3599617};
    var itinerary_markers = [];
    var map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: currentLat, lng: currentLng},
        zoom: 15,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    console.log(map);
    /*MARQUEUR*/ 
    $.ajax({
        async: false,
        url: 'test.json',
        data: "",
        accepts:'application/json',
        dataType: 'json'
    }).done(function(data) {
        for (var i = 0; i < data.hydrants.length; i++) {
            markers.push( data.hydrants[i]);
        }
        console.log(markers);
        var posi = new google.maps.LatLng(markers[0].Lat, markers[0].Lng);
        console.log(posi);
        var marker = new google.maps.Marker({
            position: posi,
            map: map,
            //title: markers[i][0]
            title: markers[0].Name
        });
        console.log(marker);
    }).fail(function(jqXHR, testStatus){
        console.log(textStatus);
    });
}).fail(function(jqXHR, testStatus){
    console.log(textStatus);
});

これが問題である場合、Javaでのsystem.outへのconsole.log出力の取得に関するリンクは次のとおりです。 とおりです。JavaFX 8 WebEngine:javascriptからjava。

...また、redditからこんにちは。


こんにちは。問題はajax呼び出しにあると思います。OK、GPSの位置をJavaScriptに送信する別の方法を探します(executescriptを使用)。
チャンドラービン2017年

いいえ、ajaxの呼び出しではありません。問題は、新しいマーカーを表示するためにWebビューを更新できないことです。アプリを開くと、マップが表示されます。つまり、ajax呼び出しは正常に機能します。
チャンドラービン

18

行:

this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());

ファイルへのパスが正しいことを再確認してみます。StackOverflowで他の回答を読むと、これはパッケージのルートに関連しており、先頭に「/」があるかどうかに関係なく想定されているようです。すなわちgetResource("data/index.html")。しかし、もう一度、おそらくあなたはすでに関連するエラーを見ているでしょうgetResource()...

次にデバッグを行うために、JSONを記述している部分をコメント化し、手動で適切なJSONを記述して、それをwebViewに表示してみます。可動部分が少ないほど良いです。事前に記述されたJSONで動作させることができれば、Javaで記述しているJSONに問題があり、HTMLにロードされていると想定できます。

編集:私は少し深く掘りました。これは完全に間違っている可能性がありますがinitMap()、Webブラウザが通常onloadを呼び出すJavaから関数を手動で呼び出すことができる場合があります。ボタンのクリックでJavaFX WebViewからJavaScript関数を呼び出す方法 詳細がいくつかあります。this.webView.getEngine().executeScript("initMap()");ボタンを使用してJSONを編集した後で試してください。

編集2余談としては、あまりにも、それを分割しても意味がありますinitMapinitMapしてupdateMapで開始するマップを作成して、地図上のマーカーを設定する機能。これはほとんど何も壊していませんが。


いいえ、問題ありません。その行を使用してアプリを開くと、マップが表示されます。しかし、ボタンをクリックすると、マーカーを地図上に配置したいと思います。しかし、マップを更新してマーカーを表示することはできません。
チャンドラービン

1
ああ、落とし穴。誤解しました。基本ページはロードされているが、マーカーがロードされていないと言っていますか?マップは少なくともwebViewに表示されていますか?上記のinitMapについて述べたように、あなたは何かに夢中かもしれません。ページの読み込み時にその関数を呼び出すだけの場合は、おそらくjsonへの編集が行われていません。Webビュー内のページを更新するか、何らかの方法で再度initMapを呼び出すようにページに指示する必要があります-多分ajaxを介して?JavaFXがwebViewにJavaScript関数を呼び出せない限り
Matt

アプリを開くと、jsonファイルに存在するすべてのものが読み込まれます。しかし、アプリが開いている間に値を変更した場合、Webビューを更新して変更を確認します。しかし、それはうまくいきません!これが問題です。
チャンドラービング2017年

1
私の編集を参照してください-JavaからinitMap関数への手動呼び出しの追加は役立ちますか?
Matt

4

マウスホイールを使用して地図を拡大または縮小し、マーカーが表示される場合は、私と同じ問題が発生しています。

手動でマップビューをズームして、マーカーを復元してみてください。ルートサービスからのルートを表示するときにもこの手法を使用する必要がありました。そうしないと、ウェイポイントマーカーが正しく表示されませんでした。

これは、Javafxコントローラークラスのコードです。

KeyFrame kf1 = new KeyFrame(Duration.seconds(0.75), e -> map.setZoom(map.getZoom() - 1));
KeyFrame kf2 = new KeyFrame(Duration.seconds(1.5), e -> map.setZoom(map.getZoom() + 1));
Timeline timeline = new Timeline(kf1, kf2);
Platform.runLater(timeline::play);

これはGMapsFXを使用していました。GMapsFXは、JavaFX WebViewでのJavaScriptエンジン呼び出しの薄いJavaラッパーです。うまくいけば、それが役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.