将图像X,Y坐标转换为经度和纬度?
我设置了特定静态地图图像的最小经度和纬度值。 那张地图图片是某个国家的剪影。
/** * 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
。
我有一个与朋友一起写的方法,它接收longitude
和latitude
并在地图上大约给你一个X
和Y
位置,这样你就可以在地图上画出一些东西。
现在,如果我想在地图上移动鼠标,我希望它显示我的鼠标位置的longitude/latitude
,这意味着我需要创建一个方法,将鼠标位置的X和Y转换为longitude
和latitude
,这应该做与我的另一种方法相反。
这是我将地球坐标转换为图像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); }
现在我试着思考,第一个进入脑海中的想法就是反过来做同样的事情…所以我开始这样做了,我遇到了类似的问题,我不能得到adjLon
或adjLat
的值而没有longitude
或latitude
,所以这不能简单地通过反转来完成。 我对坐标系统都很陌生,所以对我来说有点混乱,但我开始追上它。
有什么提示吗?
编辑(不可能?)
根据这个答案 ,你不可能真正得到真正的结果,因为地球不是平坦的,它不能真正转换成具有经度和纬度的平面地图而不实施真正的数学算法以使其适应变化。
我的代码中有几个原因导致答案不准确:
- 由于上述原因
- 因为我的X,Y值是整数而不是浮点数。
所以现在我的问题是,如果我的方法真的不可能吗?
可悲的是,这并不是一个简单的答案。 虽然您可以自己编写投影例程,但最简单的方法可能是获取GIS库,但由于我最终在C#而不是Java中执行此操作,因此我不知道可用的内容。
您需要的最大信息就是地图图像使用的投影。 墨卡托投影很受欢迎,但它不是唯一的。 您还需要确保所选投影适用于您想要的纬度和经度范围。 如果你开始超过+ -70 N,那么墨卡托投影就会中断,所以如果你在极点上做了很多可能不适合投射的位置。
从我在你的代码中读到的,你的图像是经度/纬度坐标,你在canvas上绘制它以显示在屏幕上。 然后你在这个图像上添加你的监听器是正确的吗?
如果这是正确的,则响应是微不足道的,因为您可以通过Canvas上的MouseListener方法检索图像中的X / Y位置,并根据canvas内鼠标的位置(来自mouseEvent的方法getX / getY)和当前位置对其进行转换canvas的尺寸,然后在经度/纬度的范围内平移此位置。
longitude = minLongitude + (MouseEvent.getX/Canvas.Width)*maxLongitude lalitude = minLaltitude + (MouseEvent.getY/Canvas.Height)*maxLatitude
如果没有,那么你将不得不知道@ginkner说投影技术用于从long / lat传递到X / Y并进行逆变换,因为知道你会丢失一些信息。
地理坐标和几何坐标之间存在差异,它非常像3D earch表面和要绘制的canvas。 网络墨卡托投影或其他流行的投影坐标系用于抽象地球表面的可视化。 因此,不同位置的像素移位将导致不同的距离。
如果您正在寻找一些基本的GIS java库来处理这类问题,那么Java中的Geotools可能是一种选择。 GeoTools