1

这是我开始编写的一些代码,墨卡托投影基于此答案

using System;
using System.Drawing;

namespace CoordinatesTool
{
    public class GeoPoint
    {
        public double Longitude { get; set; }
        public double Latitude { get; set; }

        public string ToString()
        {
            return Latitude + "," + Longitude;
        }

        public PointF ToMercator(int width, int height)
        {
            var x = (float)((Longitude + 180) * width / 360);

            var latRadians = Latitude * Math.PI / 180;
            var yTransformed = Math.Log(Math.Tan((latRadians / 2) + (Math.PI / 4)));
            var yScaled = (float)((height / 2.0) - (width * yTransformed / (2 * Math.PI)));

            return new PointF(x, yScaled);
        }

        public static GeoPoint FromMercator(PointF point, int width, int height)
        {
            return FromMercator(point.X, point.Y, width, height);
        }

        public static GeoPoint FromMercator(double x, double y, int width, int height)
        {
            // No clue what to do here
        }
    }
}

我的目标是在 WinForms 应用程序中使用这个实用程序类。我在这张地图上使用它: http ://en.wikipedia.org/wiki/File:Mercator-projection.jpg (宽度:2048,高度:1588)。

墨卡托反演工作得很好(但是,我怀疑它在北极/南极地区不是很准确)。

但是墨卡托逆投影真的让我很困惑。我玩弄了另一个问题中提出的解决方案,但无处可去。特别是我不了解 Gudermannian(和逆)函数、DEGREES_PER_RADIAN 和 RADIANS_PER_DEGREE 常量,以及我应该如何将 y 值转换为纬度以调用 GudermannianInv() 函数。

编辑:这是我尝试如何进行逆投影的方法:

从 yScaled(FromMercator 函数中的参数 y)开始:

var yTransformed = 2 * Math.PI * (height / 2.0 - yScaled) / width;
var latRadians = Math.Arctan(Math.Pow(Math.E, yTransformed) - Math.PI / 4) / 2;
// ...
4

1 回答 1

1

以下是您寻求的一些内容:

  1. radians * degrees/radians == degrees:degrees_per_radian 只是用degrees/radians“英语”而不是“数学”表达的一种方式。radians_per_degree 留给读者作为练习。所以这两个常数表示在角度和弧度之间转换时使用的数字。

  2. 查看您发布的代码,您可以将这些行转换latRadians为 y。实现代码来反转这些操作看起来很简单。你需要'un'-scale 和'un'-transform 'yScaled'。例如,处理线(部分):

    yScaled = ((height / 2.0) - (width * yTransformed / (2 * Math.PI)))

    作为一个数学方程,您需要yTransformed根据yScaled.

  3. 至于Gudermannian,您提到的问题在一行代码中实现,而逆Gudermannian 在3 行中实现。Gudermannian 只是一种将圆形测量(例如以度或弧度为单位的测量)转换为线性测量(例如要在纸上发表的图表上以厘米为单位的测量)的一种方法。特别是,与此相关的是,古德曼算子会将纬度转换为从 0 开始的线性距离。

编辑

好的,所以看起来更近一点,在您的原始代码中,您将纬度从角度测量转换为线性测量:

yTransformed = Math.Log(Math.Tan((latRadians / 2) + (Math.PI / 4)))

我认为您可能应该将其替换为对反向 Gudermannian 的调用,如您链接到的问题的答案所示。我怀疑您自制的转换在 tan/arctan 函数中遇到了极值点。然后,您当然会在非转换中使用直接的古德曼式。

于 2012-05-14T09:17:15.243 回答