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

本文翻译自:Google Maps & JavaFX: Display marker on the map after clicking JavaFX button

I have been trying to display a marker on the map when I click on a Button of my JavaFX application. 当我点击我的JavaFX应用程序的Button时,我一直在尝试在地图上显示标记。 So what happens is when I click on that button, I write the position in a JSON file, this file will be loaded in the html file that contains the map. 所以当我点击该按钮时,我在JSON文件中写入该位置,该文​​件将被加载到包含该地图的html文件中。 The problem is that it works perfectly when I open the html page in the browser, but nothing happens in the JavaFX's web view, and I don't know why ! 问题是当我在浏览器中打开html页面时,它工作得很好,但在JavaFX的Web视图中没有任何反应,我不知道为什么!

This is the html 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>

When I click the button, I fill the JSON file (which works perfectly) and then I execute this to refresh the webview: 当我单击按钮时,我填写JSON文件(完美地工作),然后执行此操作以刷新webview:

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

As I said before, when I open the file on the browser I see the expected result, but I don't know what is the problem with the JavaFX. 正如我之前所说,当我在浏览器上打开文件时,我看到了预期的结果,但我不知道JavaFX有什么问题。 If there is a better way to do this please tell me. 如果有更好的方法,请告诉我。

EDIT: 编辑:

I found a solution to the problem by sending directly the data (the GPS coordinates) from JavaFX to Javascript using the executeScript() method, so I don't need a json file as bridge between the two platforms. 我通过使用executeScript()方法直接从JavaFX向Javascript发送数据(GPS坐标)找到了解决问题的方法,因此我不需要json文件作为两个平台之间的桥梁。 So this is an example of how the code looks like: 所以这是代码如何的示例:

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

And here is the Javascript: 这是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);
  }

Thank you for your comments and answers, and a special shootout to reddit. 感谢您的评论和回答,以及对reddit的特别枪战。


#1楼

参考:https://stackoom.com/question/2zALK/Google-Maps-JavaFX-单击JavaFX按钮后在地图上显示标记


#2楼

If I had to guess - one of two things is happening: 如果我不得不猜测 - 发生了两件事之一:

Either A) your javaFX is not supporting cross site ajax calls or B) it is not waiting for the asynchronous ajax response/something else is going wrong. 要么A)你的javaFX不支持跨站点ajax调用,要么B)它不等待异步ajax响应/其他东西出错。

So let's do some testing together. 所以让我们一起做一些测试。 Firstly can we clean this up to nest the ajax calls? 首先,我们可以清理它以嵌套ajax调用吗? Then can you add in some console.log statements to find out what each is sending back? 那么你可以添加一些console.log语句来找出每个发送回来的内容吗? If you miss some output we know where it's going wrong and that'll help us fix things. 如果你错过了一些输出,我们知道哪里出了问题,这将有助于我们解决问题。

Note I've changed success to the 'done' additions because success is a bit out of date, and everything is nested to eliminate the question around whether any blanks are being sent in to the next calls (synchronicity issues): 注意我已经将成功更改为“完成”添加,因为成功有点过时,并且所有内容都嵌套以消除围绕是否有任何空白被发送到下一个调用(同步问题)的问题:

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

Here is a link on getting the console.log output in to System.out in Java if this is an issue: JavaFX 8 WebEngine: How to get console.log() from javascript to System.out in java? 如果这是一个问题,这里有一个关于将console.log输出到Java中的System.out的链接: JavaFX 8 WebEngine:如何在java中将console.log()从javascript导入System.out?

...Also hello from reddit. ...还有来自reddit的问候。


#3楼

In the line: 在线:

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

I would try double-checking the path to the file is correct. 我会尝试仔细检查文件的路径是否正确。 Reading other answers on StackOverflow, it looks like this is supposed to be relative to the package root and either with or without the leading '/'. 在StackOverflow上阅读其他答案,看起来这应该是相对于包根,并且有或没有前导'/'。 ie getResource("data/index.html") . getResource("data/index.html") But, then again, maybe you would already be seeing errors related to getResource() ... 但是,再说一遍,也许你会看到与getResource()相关的错误......

My next go to, for debugging purposes, would be to comment out the part where you write the JSON and just manually write some good JSON and just try to get it to show up in the webView. 我的下一步是,为了调试目的,将注释掉你编写JSON的部分,只需手动编写一些好的JSON,然后尝试让它显示在webView中。 The fewer moving parts, the better. 移动部件越少越好。 If you can get it to work with your pre-written JSON then you can assume it is some problem with the JSON you are writing with Java and then it being loaded to the HTML. 如果您可以使用预先编写的JSON,那么您可以假设使用Java编写的JSON存在问题,然后将其加载到HTML中。

Edit: I dug a bit deeper. 编辑:我挖得更深了一点。 This could be totally wrong again but maybe you can try manually calling the initMap() function from Java that your web browser normally calls onload. 这可能是完全错误的,但也许您可以尝试从Web浏览器通常调用onload手动调用Java的initMap()函数。 How to call a JavaScript function from a JavaFX WebView on Button click? 如何在Button上单击JavaFX WebView调用JavaScript函数? has some more details. 有更多细节。 Try this.webView.getEngine().executeScript("initMap()"); 试试this.webView.getEngine().executeScript("initMap()"); after you edit the JSON with your button. 使用按钮编辑JSON后。

Edit 2 As an aside, too, it might make sense to split initMap into an initMap and updateMap function for making the map to begin with and then setting the markers on the map. 编辑2另外,将initMap拆分为initMapupdateMap函数以使地图开始然后在地图上设置标记可能是有意义的。 Though this is hardly breaking anything. 虽然这几乎没有破坏任何东西。


#4楼

If your mouse-wheel is used to zoom the map out or in and the marker appears, then you are experiencing the same issue that I did. 如果使用鼠标滚轮将地图缩小或放大并显示标记,则表示您遇到了与我相同的问题。

Try manually zooming the mapview to restore the markers. 尝试手动缩放mapview以恢复标记。 I also had to employ this technique when displaying a route from the Directions Service, otherwise the waypoint markers were not displaying correctly. 我还必须在从路线服务显示路线时使用此技术,否则航路点标记无法正确显示。

This is the code in my Javafx controller class to do so: 这是我的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);

This was using GMapsFX, which is just a thin Java wrapper around javascript engine calls on a JavaFX WebView. 这是使用GMapsFX,它只是围绕JavaFX WebView上的javascript引擎调用的瘦Java包装器。 Hopefully it helps. 希望它有所帮助。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值