Поскольку вы имеете в виду класс PoiLayer
в демоверсии Gluon Map пакет, вы можете легко изменить его на:
обновите положение значка соответствующим образом, когда вы нажимаете на одно место на карте, не требуя обновления масштаба.
показать всплывающую подсказку на вашем значке.
Просто добавьте этот метод в PoiLayer
, чтобы обновить данную точку до новых координат lat
и lon
:
public void updatePoint(MapPoint p, double lat, double lon) {
for (Pair<MapPoint, Node> candidate : points) {
MapPoint point = candidate.getKey();
if (point.equals(p)) {
p.update(lat, lon);
markDirty();
break;
}
}
}
Обратите внимание на вызов markDirty()
, который заставит пройти макет и обновит положение значка.
Если вы добавите Tooltip
к значку, вам не нужно будет заботиться об обновлении его положения:
private MapPoint mapPointIcon;
private PoiLayer createDemoLayer() {
PoiLayer answer = new PoiLayer();
Node icon = new Circle(7, Color.BLUE);
Tooltip.install(icon, new Tooltip("Pruebas"));
mapPointIcon = new MapPoint(40.4, -3.7);
answer.addPoint(mapPointIcon, icon);
return answer;
}
Единственная недостающая часть — это получение координат широты и долготы со сцены. Это вопрос охватывает это.
Итак, на его основе вы можете добавить этот метод в класс PoiLayer
:
public MapPoint getMapPosition(double x, double y) {
double z = baseMap.zoom().get();
double latrad = Math.PI - (2 * Math.PI * (y - baseMap.getTranslateY())) / (Math.pow(2, z) * 256.0);
double mlat = Math.toDegrees(Math.atan(Math.sinh(latrad)));
double mlon = (x - this.baseMap.getTranslateX()) / (256.0 * Math.pow(2, z)) * 360.0 - 180.0;
return new MapPoint(mlat, mlon);
}
Наконец, добавьте слушателя к вашему представлению:
@Override
public void start(Stage stage) throws Exception {
MapView view = new MapView();
PoiLayer myDemoLayer = createDemoLayer();
view.setZoom(4);
view.addLayer(myDemoLayer);
Scene scene = new Scene(view, 600, 700);
stage.setScene(scene);
stage.show();
view.flyTo(0, mapPointIcon, 1.);
view.setOnMouseClicked(e -> {
MapPoint position = myDemoLayer.getMapPosition(e.getX(), e.getY());
myDemoLayer.updatePoint(mapPointIcon, position.getLatitude(), position.getLongitude());
});
}
Это прекрасно работает, но если у вас есть слой с несколькими точками, вам понадобится способ выбрать, какую точку вы хотите переместить.
ИЗМЕНИТЬ
Основываясь на запросе OP на наличие постоянного всплывающего окна вместо всплывающей подсказки, это очень простая реализация всплывающего окна. Для лучшего решения, ControlsFX рекомендуется PopOver
элемент управления.
Это можно добавить в класс PoiLayer
:
public void addPoint(MapPoint p, Node icon) {
final Pair<MapPoint, Node> pair = new Pair(p, icon);
icon.setOnMouseClicked(e -> {
e.consume();
showPopup(pair);
});
points.add(pair);
this.getChildren().add(icon);
this.markDirty();
}
private void showPopup(Pair<MapPoint, Node> pair) {
Node icon = pair.getValue();
MapPoint point = pair.getKey();
final Stage primaryStage = (Stage) icon.getScene().getWindow();
final Stage popupStage = new Stage();
popupStage.initStyle(StageStyle.UNDECORATED);
popupStage.initModality(Modality.APPLICATION_MODAL);
popupStage.initOwner(primaryStage);
VBox box = new VBox(5);
box.setPadding(new Insets(5));
box.getChildren().addAll(new Label("Popup"),
new Label("Lat: " + String.format("%2.6fº", point.getLatitude())),
new Label("Lon: " + String.format("%2.6fº", point.getLongitude())));
Label close = new Label("X");
close.setOnMouseClicked(a -> popupStage.close());
StackPane.setAlignment(close, Pos.TOP_RIGHT);
final StackPane stackPane = new StackPane(box, close);
stackPane.setPadding(new Insets(5));
stackPane.setStyle("-fx-background-color: lightgreen;");
Scene scene = new Scene(stackPane, 150, 100);
Bounds iconBounds = icon.localToScene(icon.getBoundsInLocal());
popupStage.setX(primaryStage.getX() + primaryStage.getScene().getX() + iconBounds.getMaxX() );
popupStage.setY(primaryStage.getY() + primaryStage.getScene().getY() + iconBounds.getMaxY());
popupStage.setScene(scene);
popupStage.show();
}
Всякий раз, когда вы нажимаете на значок, появляется модальное всплывающее окно (вам нужно закрыть его, прежде чем вернуться к карте). Это, конечно, можно изменить, чтобы иметь немодальное и автоматически закрывающееся всплывающее окно.
![Пользовательское всплывающее окно](https://i.stack.imgur.com/qUDeK.jpg)
person
José Pereda
schedule
13.12.2017