我已经设置了特定静态地图图像的最小经度和纬度值。该地图图像是某个国家的切割。
/**
* 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;
我有一个名为mapImage
的BufferedImage
。
我有一个方法,我和一个朋友一起写的,它接收经度
和纬度
,并在地图上大致给你一个X
和一个Y
位置,这样你就可以在地图上画些东西。
现在,如果我想在地图上移动鼠标,我希望它显示我的鼠标位置的< code >经度/纬度,这意味着我需要创建一个方法,将鼠标位置的X和Y转换为< code >经度和< code >纬度,这应该与我的另一个方法相反。
这是我将地球仪坐标转换为图像X
和Y
的方法:
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);
}
现在我试着思考,我脑海中的第一个想法就是反过来做同样的事情……所以我开始这样做,我遇到了一些问题,比如,如果没有经度
或纬度
,我就无法得到的值,所以这不能简单地通过反转来完成。我对坐标系统很陌生,所以这对我来说有点困惑,但我开始赶上了。
有什么提示给我吗?
根据这个答案,你不可能得到真正的结果,因为地球不是平的,如果不实现真正的数学算法,使其能够适应变化,就无法将其转换为具有经度和纬度的平面地图。
在我的代码中,有几个原因导致答案不准确:
所以我现在的问题是,如果用我的方法真的不可能?
可悲的是,这个问题没有一个简单的答案。虽然您可以自己编写投影例程,但最简单的方法可能是获取 GIS 库,但由于我最终使用 C# 而不是 Java 执行此操作,因此我不知道有什么可用。
您需要的最大信息是您的地图图像使用哪种投影。墨卡托投影非常受欢迎,但不是唯一的一种。您还需要确保您选择的投影适用于您想要的纬度和经度范围。如果您开始超过-70 N,墨卡托投影就会中断,所以如果您在两极做了很多位置,那可能不适合您。
根据我在你代码中读到的,你的图像是在经度/纬度坐标中,你把它画在画布上以显示在屏幕上。然后你在这张图片上加上你的听众,对吗?
如果这是正确的,则响应是微不足道的,因为您可以通过Canvas上的Mouse Listener方法检索图像中的X/Y位置,并根据鼠标在画布内的位置(来自mouse Event的方法getX/getY)和画布的当前维度进行转换,然后在经度/纬度范围内转换此位置。
longitude = minLongitude + (MouseEvent.getX/Canvas.Width)*maxLongitude
lalitude = minLaltitude + (MouseEvent.getY/Canvas.Height)*maxLatitude
如果没有,那么你就必须知道,正如@ginkner所说,投影技术用于从long/lat转换到X/Y,并且在知道你会丢失一些信息的情况下进行逆变换。
地理坐标和几何坐标是有区别的,它就像一个三维的地球表面和一个画布。web墨卡托投影或其他流行的投影坐标系用于地球表面可视化的抽象。因此不同位置像素偏移将导致不同的距离。
如果您正在寻找一些基本的GIS java库来处理这类问题,java中的Geotools可能是一个选择。地理工具