将图像的X,Y坐标转换为经度和纬度?

9

我已经设置了一个特定静态地图图像的最小经度和纬度值。该地图图像是某个国家的一个部分。

/**
 * Maximum longitude value of the map
 */
private float mapLongitudeMax;

/**
 * Minimum longitude value of the map
 */
private float mapLongitudeMin;

/**
 * Maximum latitude value of the map
 */
private float mapLatitudeMax;

/**
 * Minimum latitude value of the map
 */
private float mapLatitudeMin;

我有一个名为mapImageBufferedImage

我和我的朋友编写了一个方法,它接收longitudelatitude,并给出大致在地图上的XY位置,以便您可以在地图上绘制一些东西。

现在,如果我想在地图上移动我的鼠标,我希望它显示我鼠标位置的longitude/latitude,这意味着我需要创建一个方法,将鼠标位置的X和Y转换为longitudelatitude,该方法应该与我的另一个方法相反。

这是我用于将地球坐标转换为图像XY的方法:

protected Location getCoordinatesByGlobe(float latitude, float longitude) {

    /**
     * Work out minimum and maximums, clamp inside map bounds
     */
    latitude = Math.max(mapLatitudeMin, Math.min(mapLatitudeMax, latitude));
    longitude = Math.max(mapLongitudeMin, Math.min(mapLongitudeMax, longitude));

    /**
     * We need the distance from 0 or minimum long/lat
     */
    float adjLon = longitude - mapLongitudeMin;
    float adjLat = latitude - mapLatitudeMin;

    float mapLongWidth = mapLongitudeMax - mapLongitudeMin;
    float mapLatHeight = mapLatitudeMax - mapLatitudeMin;

    float mapWidth = mapImage.getWidth();
    float mapHeight = mapImage.getHeight();

    float longPixelRatio = mapWidth / mapLongWidth;
    float latPixelRatio = mapHeight / mapLatHeight;

    int x = Math.round(adjLon * longPixelRatio) - 3;// these are offsets for the target icon that shows.. eedit laterrr @oz
    int y = Math.round(adjLat * latPixelRatio) + 3; //

    // turn it up
    y = (int) (mapHeight - y);

    return new Location(x, y);
}

现在我想了一下,首先想到的是反过来做...所以我开始做了,但是遇到了问题,比如我不能在没有longitudelatitude的情况下获取adjLonadjLat的值,因此这不能简单地通过反转来完成。我对坐标系统完全不熟悉,所以有点困惑,但我正在努力理解。
你有什么提示吗?
编辑(不可能吗?)
根据这个答案,你不能真正得到实际结果,因为地球不是平的,它无法用经度和纬度转换为平面地图,除非实现一个真正的数学算法来使其适应变化。
我的代码中有几个原因导致答案不可能精确:
1.由于上述原因 2.因为我的X、Y值是整数而不是浮点数。
那么我的问题是,如果用我的方法真的不可能吗?

可能是重复的问题,参见在地图上实现鼠标单击事件 - trashgod
你的应用程序是用来做什么的?如果你想用它来进行估算,一些四舍五入等处理是可以接受的。 - Hash
您可以使用精度足够的模型来获得对于您的应用程序而言“足够好”的结果。一般来说,这将由您鼠标悬停在其上的图像的像素:度数比确定。有许多不同的方法可以“展开”球体。我提到的是其中最受欢迎的之一,但还有其他方法。这应该可以帮助您入门: https://en.wikipedia.org/wiki/List_of_map_projections - Benjamin
3个回答

5
很遗憾,这个问题没有简单的答案。虽然您可以自己编写投影例程,但最简单的方法可能是获取GIS库,但由于我最终在C#而不是Java中完成了此操作,因此我不知道有哪些可用。
您需要的最重要的信息是地图图像使用的确切投影方式。 墨卡托投影非常流行,但并不是唯一的投影方式。您还需要确保您选择的投影方式适用于您想要的纬度和经度范围。如果您在极地进行大量位置定位,则墨卡托投影可能会出现问题,因为它在开始超过+-70 N时会出现问题。

1
根据您的代码,我了解到您的图像以经/纬坐标形式存在,并在画布上绘制以在屏幕上显示。然后,您在此图像上添加侦听器,是这样吗?如果是这样的话,答案很简单,您可以通过Canvas上的MouseListener方法检索图像中的X/Y位置,并基于鼠标事件中的位置(使用getX/getY方法)和画布的当前尺寸进行转换,然后将此位置在经/纬度范围内进行平移。
longitude = minLongitude + (MouseEvent.getX/Canvas.Width)*maxLongitude
lalitude = minLaltitude + (MouseEvent.getY/Canvas.Height)*maxLatitude

如果不这样做,你就需要知道 @ginkner 所说的投影技术,用于从经纬度转换为X/Y,并且在进行反向转换时会丢失一些信息。

0

地理坐标和几何坐标之间存在差异,就像三维地球表面和画布一样。Web Mercator投影或其他流行的投影坐标系统用于抽象化地球表面的可视化。因此,在不同位置的像素偏移会导致不同的距离。

如果您正在寻找一些基本的GIS Java库来处理这种类型的问题,Java中的Geotools可能是一个选项。GeoTools


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接