2012-05-14 52 views
1

下面是我開始寫的一些代碼,墨卡託投影基於this answer如何做逆墨卡託投影

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)。

墨卡託反演工作得很好(但是,我懷疑它在北極/南極地區不是很準確)。

但逆墨卡託投影真的讓我感到困惑。我玩弄了another question中提出的解決方案,但無法獲得任何地方。尤其是我不明白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; 
// ... 

回答

0

這裏是你尋求一些位:

  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)))

    的數學公式,你需要在yScaled方面解決yTransformed

  3. 至於Gudermannian,你提到的問題實現了在一行代碼和逆Gudermannian在3行。 Gudermannian只是一種將圓形度量(例如以度或弧度表示的度量)轉換爲線性度量(例如在紙上發佈的圖表上的釐米)的方法。特別是,與此相關的古德曼將改變一個緯度成直線距離0.1

編輯

好了,找一個近一點,在原始代碼,你變換緯度從一個角度測量成線性一個與線:

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

我認爲你或許應該逆古德曼的呼叫替換此,作爲回答您鏈接到的問題表示。我懷疑你的自釀變革在tan/arctan函數的極端點磕磕絆絆。然後,您將使用直接Gudermannian進行未轉換。

+0

所以DEGREES_PER_RADIAN是360 /(2 * Math.PI)和RADIANS_PER_DEGREE是(2 * Math.PI)/ 360? – DavWEB

+0

嗯,我總是用'180/pi'和'pi/180'去,但是,是的,你的價值觀是正確的。 –

+0

你的第二點正是我第一次嘗試的。 '非'規模的部分並不困難。但是,我想,因爲它沒有像預期的那樣工作,所以我在努力處理'不'轉換部分。我會用我得到的東西更新我的問題。 – DavWEB