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


359

当我单击JavaFX应用程序的按钮时,我一直试图在地图上显示标记。因此,发生的事情是当我单击该按钮时,将位置写入JSON文件,该文件将被加载到包含地图的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的问题是什么。如果有更好的方法,请告诉我。

编辑:

我通过使用executeScript()方法将数据(GPS坐标)从JavaFX直接发送到Javascript找到了解决方案,所以我不需要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);
  }

感谢您的评论和回答,以及特别的点球大战。



1
尽管脚本并非以最佳方式编写,但似乎没有任何问题。有几种可能使其无法正常工作的可能性。确保将新标记添加到json文件的顶部。cache: false如果已缓存,请传递给ajax调用,并确保您定位正确的文件。此外,这里和那里的一些日志将有助于识别问题。
格克汗库尔特

1
难道JavaFX东西在使用ajax接收来自非HTTP服务的端点(如test.json)的调用/数据时遇到问题?
塞巴斯蒂安

@Sebastian让我发疯的是,当我打开应用程序时,json文件已正确加载,并且看到了预期的结果。问题是当我用另一个值更新json文件(在应用程序打开时)时,它只是不想刷新以显示新标记!因此,ajax调用没有问题。但这可以是回调吗?因为在页面加载时调用了initMap()
Chandler

@GökhanKurt你会读出上面的答案
钱德勒兵

Answers:


70

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

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

如果存在此问题,以下是在Java中将console.log输出输入到System.out的链接:JavaFX 8 WebEngine:如何在Java 中将console.log()从javascript获取到System.out?

...也来自reddit。


您好,所以您认为问题出在ajax调用上。好的,我将尝试寻找另一种将GPS位置发送到javascript(使用executescript)的方法。
钱德·宾

不,它不是ajax调用。问题是我无法刷新Web视图以显示新标记。当我打开应用程序时,将显示地图,这意味着ajax调用可以正常工作。
钱德·宾

18

在该行中:

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

我会尝试仔细检查文件的路径是否正确。阅读有关StackOverflow的其他答案,看起来这应该是相对于包根目录的,并且带有或不带有开头的“ /”。即getResource("data/index.html")。但是,话又说回来,也许您已经看到与getResource()... 相关的错误。

为了调试目的,我接下来要做的是注释掉编写JSON的部分,然后手动编写一些好的JSON,然后尝试使其显示在webView中。运动部件越少越好。如果您可以将其与预编写的JSON配合使用,则可以假定您正在使用Java编写的JSON出现问题,然后将其加载到HTML。

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

编辑2顺便说一句,也可以将and 分割initMapinitMapand updateMap函数,以使地图开始,然后在地图上设置标记。尽管这几乎没有破坏任何东西。


没错,这不是问题,我在使用该行打开应用程序时显示地图。但是,当我单击按钮时,我想在地图上放置一个标记。但是我无法刷新地图以在其上显示标记。
钱德·宾

1
啊,知道了 我误解了。您是说基本页面正在加载但没有标记正在加载吗?地图是否至少出现在您的webView中?我认为您可能会谈到上面提到的initMap。如果它仅在页面加载时调用该函数,则它可能未获得对json的编辑。您将不得不刷新Web视图中的页面,或者告诉页面以某种方式再次调用initMap -也许是通过Ajax吗?除非JavaFX可以获取webView来调用javascript函数
马特

打开应用程序后,将加载json文件中存在的所有内容。但是,当我在应用程序打开时更改值时,我想刷新Web视图以查看更改。但这是行不通的!这就是问题。
Chandler Bing

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.