Google Maps & JavaFX: Tampilkan penanda di peta setelah mengklik tombol JavaFX

359

Saya telah mencoba untuk menampilkan penanda di peta ketika saya mengklik Tombol aplikasi JavaFX saya. Jadi yang terjadi adalah ketika saya mengklik tombol itu, saya menulis posisi dalam file JSON, file ini akan dimuat dalam file html yang berisi peta. Masalahnya adalah ia berfungsi dengan baik ketika saya membuka halaman html di browser, tetapi tidak ada yang terjadi di tampilan web JavaFX, dan saya tidak tahu mengapa!

Ini adalah file 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>

Ketika saya mengklik tombol, saya mengisi file JSON (yang bekerja dengan sempurna) dan kemudian saya menjalankan ini untuk menyegarkan tampilan web:

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

Seperti yang saya katakan sebelumnya, ketika saya membuka file di browser saya melihat hasil yang diharapkan, tetapi saya tidak tahu apa masalahnya dengan JavaFX. Jika ada cara yang lebih baik untuk melakukan ini tolong beri tahu saya.

EDIT:

Saya menemukan solusi untuk masalah ini dengan mengirim langsung data (koordinat GPS) dari JavaFX ke Javascript menggunakan metode executeScript (), jadi saya tidak perlu file json sebagai jembatan antara kedua platform. Jadi ini adalah contoh bagaimana kode tersebut terlihat:

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

Dan di sini adalah 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);
  }

Terima kasih atas komentar dan jawaban Anda, dan adu penalti untuk reddit.

Chandler Bing
sumber
48
Untuk referensi: reddit.com/r/ProgrammerHumor/comments/6e6wu6/…
Mateen Ulhaq
1
Meskipun skrip tidak ditulis sebaik mungkin, tampaknya tidak ada yang salah dengan skrip itu. Ada beberapa kemungkinan yang dapat membuatnya tidak berfungsi. Pastikan penanda baru ditambahkan ke bagian atas file json. Lewati cache: falsepanggilan ajax jika itu di-cache, dan pastikan Anda menargetkan file yang tepat. Juga beberapa log di sana-sini akan membantu mengidentifikasi masalah.
Gökhan Kurt
1
Mungkinkah, hal JavaFX memiliki masalah menggunakan ajax untuk menerima panggilan / data dari titik akhir yang dilayani non-HTTP seperti test.json Anda?
Sebastian
@Sebastian Apa yang membuat saya gila adalah ketika saya membuka aplikasi file json dimuat dengan benar dan saya melihat hasil yang diharapkan. Masalahnya adalah ketika saya memperbarui file json dengan nilai lain (saat aplikasi terbuka), ia tidak mau menyegarkan untuk menampilkan penanda baru! Jadi tidak ada masalah dengan panggilan ajax. Tapi bisakah itu menjadi hal panggilan balik? karena initMap () dipanggil saat halaman dibuka
Chandler Bing
@ GökhanKurt maukah Anda membaca jawaban di atas
Chandler Bing

Jawaban:

70

Jika saya harus menebak - salah satu dari dua hal ini terjadi:

Baik A) javaFX Anda tidak mendukung panggilan ajax lintas situs atau B) itu tidak menunggu respons ajax asinkron / ada sesuatu yang salah.

Jadi mari kita lakukan pengujian bersama. Pertama bisakah kita membersihkan ini untuk membuat panggilan ajax? Lalu dapatkah Anda menambahkan beberapa pernyataan console.log untuk mengetahui apa yang masing-masing kirimkan kembali? Jika Anda melewatkan beberapa keluaran, kami tahu di mana kesalahannya dan itu akan membantu kami memperbaiki berbagai hal.

Catatan Saya telah mengubah kesuksesan menjadi penambahan 'selesai' karena kesuksesan agak ketinggalan zaman, dan semuanya bersarang untuk menghilangkan pertanyaan seputar apakah ada kekosongan yang dikirim ke panggilan berikutnya (masalah sinkronisitas):

$.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);
});

Berikut ini tautan untuk mendapatkan keluaran konsol.log ke System.out di Jawa jika ini merupakan masalah: JavaFX 8 WebEngine: Bagaimana cara mendapatkan console.log () dari javascript ke System.out di java?

... Juga halo dari reddit.

David G
sumber
Halo, jadi Anda pikir masalahnya ada pada panggilan ajax. Ok, saya akan mencoba mencari cara lain untuk mengirim posisi GPS ke javascript (menggunakan executescript).
Chandler Bing
Tidak, ini bukan panggilan ajax. Masalahnya adalah saya tidak bisa menyegarkan tampilan web untuk menunjukkan penanda baru. Ketika saya membuka aplikasi, peta ditampilkan yang berarti bahwa panggilan ajax berfungsi dengan baik.
Chandler Bing
18

Dalam barisan:

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

Saya akan mencoba mengecek path ke file yang benar. Membaca jawaban lain di StackOverflow, sepertinya ini seharusnya relatif terhadap paket root dan baik dengan atau tanpa tanda '/'. yaitu getResource("data/index.html"). Tapi, sekali lagi, mungkin Anda sudah melihat kesalahan terkait getResource()...

Tujuan saya berikutnya, untuk keperluan debugging, adalah untuk mengomentari bagian di mana Anda menulis JSON dan hanya secara manual menulis beberapa JSON yang baik dan hanya mencoba membuatnya muncul di webView. Semakin sedikit bagian yang bergerak, semakin baik. Jika Anda bisa membuatnya bekerja dengan JSON pra-tertulis Anda maka Anda dapat menganggap itu adalah masalah dengan JSON yang Anda tulis dengan Java dan kemudian dimuat ke HTML.

Sunting: Saya menggali sedikit lebih dalam. Ini bisa jadi benar-benar salah lagi, tetapi mungkin Anda dapat mencoba memanggil initMap()fungsi secara manual dari Java yang biasanya disebut browser web Anda onload. Bagaimana cara memanggil fungsi JavaScript dari JavaFX WebView pada tombol klik? memiliki lebih banyak detail. Coba this.webView.getEngine().executeScript("initMap()");setelah Anda mengedit JSON dengan tombol Anda.

Sunting 2 Sebagai tambahan, mungkin masuk akal untuk memecah initMapmenjadi initMapdan updateMapberfungsi untuk membuat peta untuk memulai dan kemudian mengatur penanda pada peta. Meskipun ini hampir tidak melanggar apa pun.

Mat
sumber
Bukan itu masalahnya, saya menampilkan peta ketika saya membuka aplikasi usign garis itu. Tetapi ketika saya mengklik tombol, saya ingin meletakkan penanda di peta. Tapi saya tidak bisa menyegarkan peta untuk menunjukkan penanda di atasnya.
Chandler Bing
1
Ah, mengerti. Saya salah paham. Apakah Anda mengatakan halaman dasar sedang dimuat tetapi tidak ada penanda yang dimuat? Apakah setidaknya peta muncul di webView Anda? Saya pikir Anda mungkin ke sesuatu seperti yang Anda sebutkan initMap di atas. Jika hanya memanggil fungsi itu pada memuat halaman maka itu mungkin tidak mendapatkan suntingan ke json. Anda harus me-refresh halaman dalam tampilan web atau memberitahu halaman untuk memanggil initMap lagi entah bagaimana - mungkin melalui ajax? Kecuali JavaFX bisa mendapatkan webView untuk memanggil fungsi javascript
Matt
Ketika aplikasi dibuka semua yang ada di file json dimuat. Tetapi ketika saya mengubah nilai saat aplikasi terbuka, saya ingin menyegarkan tampilan web untuk melihat perubahan. Tapi itu tidak berhasil! Ini masalahnya.
Chandler Bing
1
Lihat hasil edit saya - apakah menambahkan panggilan manual dari Jawa ke fungsi initMap membantu?
Matt
4

Jika roda mouse Anda digunakan untuk memperkecil atau memperkecil peta dan penanda muncul, maka Anda mengalami masalah yang sama dengan yang saya lakukan.

Coba perbesar tampilan peta secara manual untuk memulihkan marker. Saya juga harus menggunakan teknik ini ketika menampilkan rute dari Layanan Arahan, jika tidak, penanda waypoint tidak ditampilkan dengan benar.

Ini adalah kode di kelas kontroler Javafx saya untuk melakukannya:

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);

Ini menggunakan GMapsFX, yang hanya pembungkus Java tipis di sekitar panggilan mesin javascript pada JavaFX WebView. Semoga bermanfaat.

Fraser
sumber