Google Maps & JavaFX : JavaFX 버튼을 클릭 한 후지도에 마커 표시


359

JavaFX 애플리케이션의 버튼을 클릭 할 때 맵에 마커를 표시하려고했습니다. 그래서 그 버튼을 클릭하면 JSON 파일에 위치를 씁니다.이 파일은 맵을 포함하는 html 파일에로드됩니다. 문제는 브라우저에서 html 페이지를 열 때 완벽하게 작동하지만 JavaFX의 웹보기에서는 아무 일도 일어나지 않으며 왜 그런지 모르겠다는 것입니다!

이것은 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 파일 (완벽하게 작동 함)을 채우고 이것을 실행하여 웹보기를 새로 고칩니다.

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

앞에서 말했듯이 브라우저에서 파일을 열면 예상 결과가 표시되지만 JavaFX의 문제점이 무엇인지 모르겠습니다. 더 좋은 방법이 있다면 알려주십시오.

편집하다:

executeScript () 메소드를 사용하여 JavaFX에서 Javascript로 데이터 (GPS 좌표)를 직접 전송하여 문제에 대한 해결책을 찾았으므로 두 플랫폼 간의 브릿지로 json 파일이 필요하지 않습니다. 이것이 코드의 모습에 대한 예입니다.

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

그리고 여기 자바 스크립트가 있습니다 :

/*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);
  }

귀하의 의견과 답변, 특별한 레딧 아웃에 감사드립니다.



1
스크립트가 최선의 방법으로 작성되지는 않았지만 아무런 문제가 없습니다. 작동하지 않을 수있는 몇 가지 가능성이 있습니다. 새 마커가 json 파일의 맨 위에 추가되었는지 확인하십시오. 패스 cache: false가 캐시되는 경우에 아약스 호출에, 그리고 당신이 올바른 파일을 대상으로합니다. 또한 여기에 일부 로그가 있으며 문제를 식별하는 데 도움이 될 것입니다.
Gökhan Kurt

1
JavaFX에 ajax를 사용하여 test.json과 같은 HTTP가 아닌 엔드 포인트에서 호출 / 데이터를 수신하는 데 문제가 있습니까?
Sebastian

@Sebastian 나를 미치게 만드는 것은 앱을 열 때 json 파일이 올바르게로드되고 예상 결과가 표시된다는 것입니다. 문제는 json 파일을 다른 값으로 업데이트 할 때 (앱이 열려있는 동안) 새 마커를 표시하기 위해 새로 고침하고 싶지 않습니다! 따라서 아약스 호출에는 문제가 없습니다. 그러나 콜백 일 수 있습니까? 페이지를로드하는 동안 initMap ()이 호출되기 때문에
Chandler Bing

@ GökhanKurt 위의 답변을 읽으시겠습니까
Chandler Bing

답변:


70

내가 추측해야한다면-두 가지 중 하나가 일어나고 있습니다.

A) 귀하의 javaFX가 크로스 사이트 아약스 호출을 지원하지 않거나 B) 비동기 아약스 응답을 기다리는 중이 아니거나 다른 것이 잘못되었습니다.

테스트를 함께하겠습니다. 먼저 이것을 정리하여 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);
});

문제가있는 경우 console.log 출력을 Java의 System.out으로 가져 오는 링크는 다음과 같습니다. JavaFX 8 WebEngine : java의 console.log ()를 java의 System.out으로 가져 오는 방법은 무엇입니까?

... 또한 레딧에서 안녕하세요.


안녕하세요, 아약스 호출에 문제가 있다고 생각합니다. 좋아, GPS 위치를 자바 스크립트 (exescript 실행)로 보내는 다른 방법을 찾으려고 노력할 것이다.
챈들러 빙

아약스 호출이 아닙니다. 문제는 새 마커를 표시하기 위해 웹보기를 새로 고칠 수 없다는 것입니다. 앱을 열면 맵이 표시되어 ajax 호출이 제대로 작동한다는 것을 의미합니다.
챈들러 빙

18

라인에서 :

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

파일 경로를 다시 확인하려고합니다. StackOverflow에서 다른 답변을 읽으면 이것이 패키지 루트와 관련이 있으며 앞의 '/'가 있거나없는 것으로 보입니다. 즉 getResource("data/index.html"). 그러나 다시 말하지만, 아마도 관련 오류가 이미있을 수 있습니다 getResource()...

다음으로 디버깅 목적으로 JSON을 작성하는 부분을 주석 처리하고 수동으로 좋은 JSON을 작성하고 webView에 표시하도록하십시오. 움직이는 부품이 적을수록 좋습니다. 미리 작성된 JSON에서 작동하도록 할 수 있다면 Java로 작성하고 HTML로로드하는 JSON에 문제가 있다고 가정 할 수 있습니다.

편집 : 나는 조금 더 깊이 파고 들었다. 이것은 다시 완전히 잘못 될 수 있지만 initMap()웹 브라우저가 일반적으로 onload를 호출하는 Java에서 수동으로 함수를 호출 할 수 있습니다 . 버튼 클릭시 JavaFX WebView에서 JavaScript 함수를 호출하는 방법은 무엇입니까? 더 자세한 내용이 있습니다. this.webView.getEngine().executeScript("initMap()");버튼으로 JSON을 편집 한 후 시도하십시오 .

편집 2 따로, 지도를 시작한 다음지도에 마커를 설정하기위한 및 기능 으로 분할 initMap하는 것이 좋습니다. 이것은 거의 아무것도 깨뜨리지 않지만.initMapupdateMap


문제는 아닙니다. 해당 라인을 사용하는 앱을 열면지도가 표시됩니다. 그러나 버튼을 클릭하면지도에 마커를 배치하고 싶습니다. 하지만지도를 표시하기 위해지도를 새로 고침 할 수 없습니다.
챈들러 빙

1
아. 나는 오해했다. 기본 페이지가로드 중이지만 마커가로드되지 않았다고 말씀하십니까? 최소한 WebView에지도가 표시됩니까? 위의 initMap을 언급 한 것처럼 뭔가있을 수 있다고 생각합니다. 페이지로드시 해당 함수를 호출하는 경우 json을 편집하지 못할 수 있습니다. webview 내에서 페이지를 새로 고치거나 페이지에 initMap을 다시 호출하도록 지시해야합니다. 아약스를 통해? JavaFX가 webView가 자바 스크립트 함수를 호출 할 수 없다면
Matt

앱이 열리면 json 파일에 존재하는 모든 것이로드됩니다. 그러나 앱이 열려있는 동안 값을 변경하면 변경 사항을 확인하기 위해 웹보기를 새로 고치고 싶습니다. 그러나 그것은 작동하지 않습니다! 이게 문제 야.
챈들러 빙

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

이것은 GFXsFX를 사용하고 있었는데 JavaFX WebView에서 Javascript 엔진 호출을 둘러싼 얇은 Java 래퍼입니다. 잘하면 도움이됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.