我现在搜索了一天,但没有在Javacode找到我的问题的任何例子。
我的世界地图大小为2000 * 1400像素,带有“Mollweide”投影。 如何找出地图中点(500,300)的经度和纬度? 我想用Java编写代码。
我尝试使用'Java Map Projection Library':
Point2D.Double pointonmap = null;
Point2D.Double latlon = null;
MolleweideProjection molproj=new MolleweideProjection();
pointonmap = new Point2D.Double (1400,1000);
latlon=molproj.inverseTransform(pointonmap,new Point2D.Double ());
System.out.println("latlon: " + latlon.getX() + ", " + latlon.getY());
有人可以帮我吗? Codeexample或提示。
感谢和问候
答案 0 :(得分:4)
维基百科需要most of the information:
这些公式像往常一样假设一些事情。 它们以投影尺寸说话,尺寸小于组件。 [0,0]位于中心,而不是左上角。 Y坐标上升而不是下降。 结果是半径而不是度。 修复这些并且它们将为您工作。
由于您没有提供链接,我假设您使用的是Java Map Projection Library on GitHub。
如果没有文档并且时间有限,我无法理解inverseTransform
以便修复您的代码;但捆绑的MapComponent更容易编码:
map.addMouseListener( new MouseAdapter() { @Override public void mouseClicked( MouseEvent e ) {
double x = e.getX() - map.getWidth() / 2, // Mouse X with [0,0] at centre.
y = e.getY() - map.getHeight() / 2, // Mouse Y with [0,0] at centre.
// Max Y of projected map, in pixel with [0,0] at centre.
maxY = map.getMapExtension().getMaxY() * map.getScaleToShowAll(),
sqrt2 = Math.sqrt( 2 ), // Can be optimised away, but let's be faithful.
R = maxY / sqrt2, // Radius of projection, in pixel.
theta = Math.asin( y / ( R * sqrt2 ) );
int delta_long = -lon0Slider.getValue(); // Longtitude shift from -180 to 180.
// Find lat long in radius and converts to degree.
double latInRad = Math.asin( -( 2 * theta + Math.sin( 2 * theta ) ) / Math.PI ),
latitude = Math.toDegrees( latInRad ),
longInRad = Math.PI * x / ( 2 * R * sqrt2 * Math.cos( theta ) ),
longitude = Math.toDegrees( longInRad ) + delta_long;
System.out.println( "Lat: " + latitude + ", Long: " + longitude );
}
您可以将此代码粘贴到ch.ethz.karto.gui.ProjectionSelectionPanel
的构造函数中。
IDE应报告地图的两个方法是私有的,您需要先将它们更改为公共(或使用反射)。
然后启动它,选择Mollweide,点击地球仪并观看控制台。随意调整窗口大小。
答案 1 :(得分:1)
此答案使用来自Mollweide projection的英语维基百科条目的信息。我从那里逐字地转录了这个公式。
简短的回答,所以你可以编写自己的代码:
获取地图的半径,r:
projectionWidth /(2 *√2)
获取theta,沿地图的点角度:
反正弦(y /(r *√2))
注意:Arcsine是正弦的倒数。在java中使用Math.asin(a)
获得自由:
反正弦((2 * theta + sine(2 * theta))/ PI)
获得经度:
PI * x /(2 * R *√2*余弦(θ))+中央子午线。
或者你可以复制帕斯塔
效率不高; x和y是双倍的规格因为懒得写类型避免缩小
没有特许的禁忌公共场所
全世界的爱人Bronner博士的电视晚餐为您解决问题
和东西
enoj
public class MolleweidePoint
{
public double x, y, latitude, longitude;
public MolleweidePoint(double projectionWidth, double x, double y)
{
double rootTwo = Math.sqrt(2);
double r = projectionWidth / 2 / rootTwo;
double theta = Math.asin(y / r / rootTwo);
this.x = x;
this.y = y;
longitude = Math.PI * x / 2 / r / rootTwo / Math.cos(theta);
latitude = Math.asin(2 * theta + Math.sin(2 * theta) / Math.PI);
}
}
在调用构造函数之后
MolleweidePoint ted = new MolleweidePoint(projection.width, 300, 500)
您可以从ted.longitude
和ted.latitude
获取经度和纬度。此外,可能必须根据中央子午线放置在投影上的位置来调整经度。