如何使用 Gluon Maps 1.0.1 将鼠标指针坐标转换为 MapPoint?

How can I convert mouse pointer coordinates to a MapPoint using Gluon Maps 1.0.1?

使用 Gluon Mobile 4 和 Gluon Maps 1.0.1,我正在显示一个地图,其中一个图层显示足迹。当用户双击鼠标按钮时,会显示一个新的脚步。这很好用,但我目前需要一种解决方法来将指针坐标(用户单击的位置)转换为 MapPoints(图层需要)。

鼠标点击的获取方式如下:

public MainView(String name) {
    super(name);
    MapView mapView = new MapView();
    mapView.setZoom(18f);
    mapView.setCenter(NUREMBERG);
    layer = new FootStepsLayer();
    mapView.addLayer(layer);
    setCenter(mapView);

    layer.addPoint(NUREMBERG);

    setOnMouseClicked(event -> {
        if ((event.getButton() == MouseButton.PRIMARY)
                && (event.getClickCount() == 2)) {
            double x = event.getX();
            double y = event.getY();
            layer.addPoint(x, y);
        }
    });
}

目前我的图层实现如下所示:

public class FootStepsLayer extends MapLayer {

    private static final Image FOOTSTEPS
            = new Image(FootStepsLayer.class.getResourceAsStream("/footsteps.png"),
                    32, 32, true, true);

    private final ObservableList<Pair<MapPoint, Node>> points
            = FXCollections.observableArrayList();

    public void addPoint(MapPoint mapPoint) {
        Node node = new ImageView(FOOTSTEPS);
        Pair<MapPoint, Node> pair = new Pair<>(mapPoint, node);
        points.add(pair);
        getChildren().add(node);
        markDirty();
    }

    public void addPoint(double x, double y) {
        Bounds bounds = baseMap.getParent().getLayoutBounds();
       baseMap.moveX(x - bounds.getWidth() / 2);
        baseMap.moveY(y - bounds.getHeight() / 2);
        addPoint(new MapPoint(baseMap.centerLat().get(),
                baseMap.centerLon().get()));
    }

    @Override
    protected void layoutLayer() {
        // Warning: suggested conversion to functional style crashed app on BlueStacks
        for (Pair<MapPoint, Node> element : points) {
            MapPoint mapPoint = element.getKey();
            Node node = element.getValue();
            Point2D point = baseMap.getMapPoint(mapPoint.getLatitude(), mapPoint.getLongitude());
            node.setVisible(true);
            node.setTranslateX(point.getX());
            node.setTranslateY(point.getY());
        }
    }
}

我的解决方法是public void addPoint(double x, double y):我正在调用moveX()moveY(),因为之后我可以查询centerLat()centerLong()。这并不理想,因为地图移动并且新的脚步成为地图的中心。我想要的是地图位置保持不变。

如果我没有忽略的话,似乎没有 API 可以将鼠标坐标转换为地理位置。正如问题 中的回答,BaseMap class 有两个 getMapPoint 方法,但我发现 none 相反。但必须有办法做到这一点。 ;-)

如果您查看 BaseMap,已经有一种方法可以准确地满足您的需求,但仅适用于地图的中心:calculateCenterCoords.

在此基础上,您可以将自己的方法添加到 BaseMap,其中 sceneXsceneY 坐标被考虑在内:

public MapPoint getMapPosition(double sceneX, double sceneY) {
    double x = sceneX - this.getTranslateX();
    double y = sceneY - this.getTranslateY();
    double z = zoom.get();
    double latrad = Math.PI - (2 * Math.PI * y) / (Math.pow(2, z) * 256);
    double mlat = Math.toDegrees(Math.atan(Math.sinh(latrad)));
    double mlon = x / (256 * Math.pow(2, z)) * 360 - 180;
    return new MapPoint(mlat, mlon);
}

那你可以在MapView中暴露这个方法:

public MapPoint getMapPosition(double sceneX, double sceneY) {
    return baseMap.getMapPosition(sceneX, sceneY);
}

所以你可以在你的地图上使用它:

mapView.setOnMouseClicked(e -> {
        MapPoint mapPosition = mapView.getMapPosition(e.getSceneX(), e.getSceneY());
        System.out.println("mapPosition: " + mapPosition.getLatitude()+ ", " + mapPosition.getLongitude());
    });

此方法应该是地图的一部分,因此请随时创建功能请求甚至拉取请求。