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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44130442/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 02:21:30  来源:igfitidea点击:

Google Maps & JavaFX: Display marker on the map after clicking JavaFX button

javascriptgoogle-mapsjavafxjavafx-webengine

提问by Chandler Bing

I have been trying to display a marker on the map when I click on a Button of my JavaFX application. 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. 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 !

当我单击 JavaFX 应用程序的按钮时,我一直试图在地图上显示一个标记。所以当我点击那个按钮时会发生什么,我在一个 JSON 文件中写入位置,这个文件将被加载到包含地图的 html 文件中。问题是当我在浏览器中打开 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 文件(完美运行),然后执行此操作以刷新 web 视图:

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. If there is a better way to do this please tell me.

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

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. So this is an example of how the code looks like:

我通过使用 executeScript() 方法将数据(GPS 坐标)从 JavaFX 直接发送到 Javascript 找到了解决问题的方法,因此我不需要 json 文件作为两个平台之间的桥梁。因此,这是代码外观的示例:

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 的特别枪战。

回答by David G

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? Then can you add in some console.log statements to find out what each is sending back? If you miss some output we know where it's going wrong and that'll help us fix things.

所以让我们一起做一些测试。首先,我们可以清理它以嵌套 ajax 调用吗?然后你可以添加一些 console.log 语句来找出每个返回的内容吗?如果您错过了某些输出,我们就会知道哪里出了问题,这将帮助我们解决问题。

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?

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

...Also hello from reddit.

......还有来自reddit的你好。

回答by Matt

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 '/'. i.e. getResource("data/index.html"). But, then again, maybe you would already be seeing errors related to getResource()...

我会尝试仔细检查文件的路径是否正确。在 StackOverflow 上阅读其他答案,看起来这应该是相对于包根目录的,并且有或没有前导的“/”。即getResource("data/index.html")。但是,话又说回来,也许您已经看到了与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. 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 的部分,然后手动编写一些好的 JSON,然后尝试让它显示在 webView 中。运动部件越少越好。如果你可以让它与你预先编写的 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. How to call a JavaScript function from a JavaFX WebView on Button click?has some more details. Try this.webView.getEngine().executeScript("initMap()");after you edit the JSON with your button.

编辑:我挖得更深一些。这可能又是完全错误的,但也许您可以尝试initMap()从 Web 浏览器通常调用 onload 的 Java手动调用函数。如何在单击按钮时从 JavaFX WebView 调用 JavaScript 函数?有更多细节。this.webView.getEngine().executeScript("initMap()");使用按钮编辑 JSON 后尝试。

Edit 2As an aside, too, it might make sense to split initMapinto an initMapand updateMapfunction for making the map to begin with and then setting the markers on the map. Though this is hardly breaking anything.

编辑 2顺便说一句,也可以将其拆分initMapinitMapupdateMap函数以开始制作地图,然后在地图上设置标记。虽然这几乎没有破坏任何东西。

回答by Fraser

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. 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. Hopefully it helps.

这是使用 GMapsFX,它只是一个围绕 JavaFX WebView 上的 javascript 引擎调用的瘦 Java 包装器。希望它有帮助。