6

我现在搜索了大约一天,但在 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());

有人可以帮我吗?代码示例或提示。

谢谢并恭祝安康

4

2 回答 2

4

维基百科有你需要的大部分信息:

在此处输入图像描述

像往常一样,这些公式假设了一些事情。它们以投影尺寸说话,该尺寸小于组件。[0,0] 位于中心,而不是左上角。Y 坐标上升而不是下降。结果是半径而不是度数。解决这些问题,它们将为您工作。

由于您没有提供链接,我假设您使用的是GitHub 上的 Java 地图投影库。没有文档且时间有限,我无法 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 应该会报告 map 的两个方法是私有的,您需要先将它们更改为 public(或使用反射)。然后启动它,选择 Mollweide,单击地球并观察控制台。随意调整窗口大小。

于 2017-03-12T04:35:30.263 回答
1

此答案使用来自英语维基百科关于Mollweide 投影的条目的信息。我已经从那里逐字转录了这个公式。

简短的答案,因此您可以编写自己的代码:

获取地图的半径,r:
projectionWidth /(2 * √2)

得到theta,点在地图上的角度:
反正弦(y / (r * √2))

注意:反正弦是正弦的倒数。在 java 中使用 Math.asin(a)

获取纬度:
反正弦((2 * theta + sine(2 * theta)) / PI)

获取经度:
PI * x / (2 * R * √2 * cosine(theta)) + 中央经线。

或者你可以copyPasta这个。
它不是很有效;x 和 y 是双精度型,因为懒得写 typecast 避免缩小
no-setters no-getters all-vars public
all-world-one-love Dr. 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。此外,可能必须根据中央经线在投影上的位置调整经度。

于 2017-03-12T03:35:32.223 回答