Карты Google и JavaFX: отображение маркера на карте после нажатия кнопки JavaFX
Я пытаюсь отобразить маркер на карте, когда я нажимаю кнопку Button моего приложения JavaFX. Так что происходит, когда я нажимаю на эту кнопку, я пишу позицию в файле JSON, этот файл будет загружен в html файл, содержащий карту. Проблема в том, что он отлично работает, когда я открываю html-страницу в браузере, но ничего не происходит в веб-представлении JavaFX, и я не знаю почему!
Это 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:
Я нашел решение проблемы, отправив непосредственно данные (координаты GPS) из JavaFX в Javascript с помощью метода executeScript(), поэтому мне не нужен 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.
Ответы
Ответ 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);
});
Вот ссылка на получение вывода console.log в System.out в Java, если это проблема:
JavaFX 8 WebEngine: как получить console.log() от javascript до System.out в java?
... Также привет от reddit.
Ответ 2
В строке:
this.webView.getEngine().load(getClass().getResource("/data/index.html").toString());
Я бы попытался дважды проверить путь к файлу правильно. Читая другие ответы на StackOverflow, похоже, что это должно относиться к корню пакета и с или без ведущего "/". т.е. getResource("data/index.html")
. Но, опять же, возможно, вы уже будете видеть ошибки, связанные с getResource()
...
В следующий раз для целей отладки следует прокомментировать часть, в которой вы пишете JSON, и просто вручную напишите хороший JSON и просто попробуйте показать его в webView. Чем меньше движущихся частей, тем лучше. Если вы можете заставить его работать с вашим предварительно написанным JSON, вы можете предположить, что это некоторая проблема с JSON, который вы пишете с Java, а затем загружаете в HTML.
Изменить: Я углубился глубже. Это может быть совершенно неправильно, но, возможно, вы можете попробовать вручную вызвать функцию initMap()
из Java, которую обычно вызывает ваш веб-браузер. Как вызывать функцию JavaScript из JavaFX WebView на кнопке click? содержит более подробную информацию. Попробуйте this.webView.getEngine().executeScript("initMap()");
после редактирования JSON с помощью кнопки.
Изменить 2. В стороне также может иметь смысл разделить initMap
на функцию initMap
и updateMap
для начала создания карты, а затем установить маркеры на карта. Хотя это почти ничего не сломает.
Ответ 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, который представляет собой просто тонкую оболочку Java вокруг движков javascript, вызываемых JavaFX WebView. Надеюсь, это поможет.