【问题标题】:Google Maps & JavaFX: Display marker on the map after clicking JavaFX buttonGoogle Maps & JavaFX:点击 JavaFX 按钮后在地图上显示标记
【发布时间】:2017-10-23 03:34:22
【问题描述】:

当我单击 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);
  }

感谢您的 cmets 和回答,以及对 reddit 的特别枪战。

【问题讨论】:

  • 虽然脚本不是以最好的方式编写的,但它似乎没有任何问题。有几种可能性可能使其不起作用。确保将新标记添加到 json 文件的顶部。将cache: false 传递给ajax 调用,以防它被缓存,并确保您定位正确的文件。此外,这里和那里的一些日志将有助于识别问题。
  • JavaFX 使用 ajax 接收来自非 HTTP 服务端点(如 test.json)的调用/数据是否存在问题?
  • @Sebastian 让我抓狂的是,当我打开应用程序时,json 文件已正确加载并且我看到了预期的结果。问题是当我用另一个值更新 json 文件时(当应用程序打开时)它只是不想刷新以显示新标记!所以ajax调用没有问题。但它可以是回调的东西吗?因为在页面加载时调用了 initMap()
  • @GökhanKurt 你会看上面的答案

标签: javascript google-maps javafx javafx-webengine


【解决方案1】:

如果我不得不猜测 - 两种情况之一正在发生:

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: How to get console.log() from javascript to System.out in java?

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

【讨论】:

  • 您好,您认为问题出在 ajax 调用上。好的,我会尝试寻找另一种方式将 GPS 位置发送到 javascript(使用 executescript)。
  • 不,它不是 ajax 调用。问题是我无法刷新 webview 以显示新标记。当我打开应用程序时,会显示地图,这意味着 ajax 调用工作正常。
【解决方案2】:

行内:

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

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

出于调试目的,我接下来要做的是注释掉您编写 JSON 的部分,然后手动编写一些好的 JSON,然后尝试让它显示在 webView 中。运动部件越少越好。如果您可以让它与您预先编写的 JSON 一起工作,那么您可以假设您使用 Java 编写的 JSON 存在问题,然后将其加载到 HTML。

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

编辑 2 顺便说一句,将 initMap 拆分为 initMapupdateMap 函数以制作地图开始然后设置标记可能是有意义的地图。虽然这几乎没有破坏任何东西。

【讨论】:

  • 不,这不是问题,当我打开应用程序时我会显示地图并使用该行。但是当我点击一个按钮时,我想在地图上放置一个标记。但我无法刷新地图以在其上显示标记。
  • 啊,明白了。我误解了。您是说正在加载基本页面,但没有加载任何标记?地图是否至少显示在您的 webView 中?我想你可能会像上面提到的 initMap 那样做一些事情。如果它只是在页面加载时调用该函数,那么它可能没有对 json 进行编辑。您将不得不在 webview 中刷新页面或告诉页面以某种方式再次调用 initMap ——也许通过 ajax?除非JavaFX可以让webView调用javascript函数
  • 当应用程序打开时,所有存在于 json 文件中的内容都会被加载。但是当我在应用程序打开时更改一个值时,我想刷新 webview 以查看更改。但这只是行不通!这就是问题所在。
  • 查看我的编辑 -- 将 Java 手动调用添加到 initMap 函数有帮助吗?
【解决方案3】:

如果您的鼠标滚轮用于缩小或缩小地图并出现标记,那么您遇到的问题与我相同。

尝试手动缩放地图视图以恢复标记。在显示来自 Directions Service 的路线时,我也必须使用这种技术,否则路点标记无法正确显示。

这是我的 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 包装器。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多