首页 文章

Google Maps&JavaFX:单击JavaFX按钮后在 Map 上显示标记

提问于
浏览
353

当我点击我的JavaFX应用程序的Button时,我一直在尝试在 Map 上显示标记 . 那么当我点击该按钮时,我在JSON文件中写入该位置,该文件将被加载到包含该 Map 的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文件(完美地工作),然后执行此操作以刷新webview:

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

正如我之前所说,当我在浏览器上打开文件时,我看到了预期的结果,但我不知道JavaFX有什么问题 . 如果有更好的方法,请告诉我 .

EDIT:

我通过使用executeScript()方法直接从JavaFX向Javascript发送数据(GPS坐标)找到了解决问题的方法,因此我不需要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的特别枪战 .

3 回答

  • 68

    如果我不得不猜测 - 发生了两件事之一:

    要么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);
    });
    

    如果这是一个问题,这里有一个关于将console.log输出到Java中的System.out的链接:JavaFX 8 WebEngine: How to get console.log() from javascript to System.out in java?

    ...还有来自reddit的问候 .

  • 3

    如果使用鼠标滚轮将 Map 缩小或放大并显示标记,那么您遇到的问题与我所遇到的相同 .

    尝试手动缩放mapview以恢复标记 . 我还必须在从路线服务显示路线时使用此技术,否则航路点标记无法正确显示 .

    这是我的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,它只是围绕JavaFX WebView上的javascript引擎调用的瘦Java包装器 . 希望它有所帮助 .

  • 17

    在线:

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

    我会尝试仔细检查文件的路径是否正确 . 在StackOverflow上阅读其他答案,看起来这应该是相对于包根,并且有或没有前导'/' . 即 getResource("data/index.html") . 但是,再说一遍,也许你会看到与 getResource() 相关的错误......

    我的下一步是,为了调试目的,将注释掉你编写JSON的部分,只需手动编写一些好的JSON,然后尝试让它显示在webView中 . 移动部件越少越好 . 如果您可以使用预先编写的JSON,那么您可以假设使用Java编写的JSON存在问题,然后将其加载到HTML .

    Edit: 我挖得更深了一点 . 这可能是完全错误的,但也许您可以尝试从Web浏览器通常调用onload手动调用Java的 initMap() 函数 . How to call a JavaScript function from a JavaFX WebView on Button click?有更多细节 . 使用按钮编辑JSON后尝试 this.webView.getEngine().executeScript("initMap()"); .

    Edit 2 顺便一提,将 initMap 拆分为 initMapupdateMap 函数可以将 Map 开始,然后在 Map 上设置标记 . 虽然这几乎没有破坏任何东西 .

相关问题