在 Gluon 地图上显示工具提示 onclick MapPoint
Show tooltip on Gluon Maps onclick MapPoint
是否可以在地图点做onclick()
时显示popup window
,当你正确改变缩放位置时,有人成功了吗?
使用的库是gluon maps
.
我想在单击地图点时显示工具提示,当我更改缩放比例时,地图点会移动到正确的位置,在示例中缩放时它不会定位。
MapPoint point = candidate.getKey();
Node icon = candidate.getValue();
Point2D mapPoint = baseMap.getMapPoint(point.getLatitude(), point.getLongitude());
icon.setVisible(true);
icon.setTranslateX(mapPoint.getX());
icon.setTranslateY(mapPoint.getY());
final Tooltip tp=new Tooltip();
icon.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
tp.setText("Pruebas");
com.sun.glass.ui.Robot robot = com.sun.glass.ui.Application
.GetApplication().createRobot();
tp.show(icon, robot.getMouseX() + 10,
robot.getMouseY() + 10);
}
});
icon.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
//tp.hide();
}
});
像point一样改变position tooltip是否可行,缩放时位置point会改变?有人试过吗?
由于您在 Gluon Map 的演示 package 中引用了 PoiLayer
class,因此您可以轻松地将其修改为:
当您单击地图的一个位置时相应地更新图标位置,而不需要缩放更新。
在您的图标上显示工具提示。
只需将此方法添加到 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
class:
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());
});
}
这很好用,但是如果你有一个包含多个点的层,你需要一种方法来select你想移动哪个点。
编辑
基于 OP 要求使用永久弹出窗口而不是工具提示,这是一个非常简单的弹出窗口实现。为了更好的解决方案,推荐ControlsFXPopOver
控制
这个可以加到PoiLayer
class:
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();
}
无论何时单击该图标,都会出现一个模式弹出窗口(您需要在返回地图之前将其关闭)。当然,这可以更改为具有非模态和可自动关闭的弹出窗口。
是否可以在地图点做onclick()
时显示popup window
,当你正确改变缩放位置时,有人成功了吗?
使用的库是gluon maps
.
我想在单击地图点时显示工具提示,当我更改缩放比例时,地图点会移动到正确的位置,在示例中缩放时它不会定位。
MapPoint point = candidate.getKey();
Node icon = candidate.getValue();
Point2D mapPoint = baseMap.getMapPoint(point.getLatitude(), point.getLongitude());
icon.setVisible(true);
icon.setTranslateX(mapPoint.getX());
icon.setTranslateY(mapPoint.getY());
final Tooltip tp=new Tooltip();
icon.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
tp.setText("Pruebas");
com.sun.glass.ui.Robot robot = com.sun.glass.ui.Application
.GetApplication().createRobot();
tp.show(icon, robot.getMouseX() + 10,
robot.getMouseY() + 10);
}
});
icon.setOnMouseExited(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
//tp.hide();
}
});
像point一样改变position tooltip是否可行,缩放时位置point会改变?有人试过吗?
由于您在 Gluon Map 的演示 package 中引用了 PoiLayer
class,因此您可以轻松地将其修改为:
当您单击地图的一个位置时相应地更新图标位置,而不需要缩放更新。
在您的图标上显示工具提示。
只需将此方法添加到 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
class:
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());
});
}
这很好用,但是如果你有一个包含多个点的层,你需要一种方法来select你想移动哪个点。
编辑
基于 OP 要求使用永久弹出窗口而不是工具提示,这是一个非常简单的弹出窗口实现。为了更好的解决方案,推荐ControlsFXPopOver
控制
这个可以加到PoiLayer
class:
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();
}
无论何时单击该图标,都会出现一个模式弹出窗口(您需要在返回地图之前将其关闭)。当然,这可以更改为具有非模态和可自动关闭的弹出窗口。