1

Is it possible to show a popup window when doing onclick() in a map point and that when you change the zoom position correctly, has someone succeeded? The used library is gluon maps.

I want to show a tooltip when I click on a mappoint and when I change the zoom the mappoint moves to its correct position, in the example it does not position when zooming.

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

Would it be viable to change the position tooltip like the point, where the position point is changed when zooming? Someone has tried?

1 Answers1

2

Since you are referring to the PoiLayer class in the Gluon Map's demo package, you can modify it easily to:

  • update the icon position accordingly when you click on one location of the map, without requiring zoom updates.

  • show a tooltip on your icon.

Just add this method to PoiLayer to update a given point to a new lat and lon coordinates:

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

Note the call to markDirty(), that will force a layout pass and will update the icon position.

If you add a Tooltip to the icon, you won't need to take care of updating its position:

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

The only part missing is getting the latitude and longitude coordinates from the scene. This question covers that.

So based on it, you can add this method to the 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);
}

Finally, add a listener to your view:

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

This works fine, but if you have a layer with several points, you'll need a way to select which point you want to move.

EDIT

Based in the OP request of having a permanent popup instead of a tooltip, this is a very simple popup implementation. For a better solution, ControlsFX PopOver control is recommended.

This can be added to the 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();
}

Whenever you click in the icon, a modal popup will show up (you need to close it before going back to the map). This can be changed, of course, to have a non modal and auto closable popup.

Custom Popup

José Pereda
  • 44,311
  • 7
  • 104
  • 132
  • Thank you very much. This code moves the point of the position map but the tooltip does not move next to the point when there is zoom in the map. – Marian López Dec 13 '17 at 15:41
  • I explained myself wrong, sorry. What I want is for a window like the Google map with info to appear when I click on a point on the map. The tooltip appears with the mouse over after having the mouse over too long. – Marian López Dec 13 '17 at 15:54
  • Ok, so you mean a popup, not a tooltip :) – José Pereda Dec 13 '17 at 16:30
  • Have you tried with a popup? Do you think it may be feasible to implement a pop-up window? Thank you very much for your help! – Marian López Dec 13 '17 at 16:54
  • Yes, it can be done easily, I'll post it now. If you want a really good popup control, you need to use ControlsFX, which is open source as well (but you will be adding a large dependency to your mobile application). – José Pereda Dec 13 '17 at 16:56
  • I have used the ControlFX library for a leader in a desktop application. It's a pretty useful library. At the moment I will not use it. Thanks a lot! – Marian López Dec 13 '17 at 17:04
  • I've edited my answer with a very simple popup implementation. – José Pereda Dec 13 '17 at 17:43