1. 程式人生 > >利用米勒投影法實現經緯度和平面座標的相互轉換

利用米勒投影法實現經緯度和平面座標的相互轉換

      常用的地球經緯度與平面座標的轉換方法有米勒投影、墨卡託投影、橫軸墨卡託投影(也叫UTM投影,百度地圖api就用的是這個)、高斯-克呂格投影、Lambert等角正割圓錐投影等

       因為我這裡需求是地球經緯度座標轉平面笛卡爾座標,所以選和墨卡託投影方式類似的米勒投影。這種投影簡單是說,就是假設有一個和赤道垂直的圓柱套在地球上,然後在地心點亮一盞燈,燈光將地球各個點投影在圓柱上,在把圓柱展開,就得到地球的平面投影了,示意圖如下:

        使用這種方式得到的投影地圖在兩極會拉長,如圖所示:

       米勒投影和墨卡託投影類似,只是在幾點區域面積變形不如後者。使用米勒投影法實現地球經緯度座標與笛卡爾平面座標互相轉換的C++原始碼如下:

#include <math.h>
#include <iostream>
using namespace std;
#define M_PI       3.14159265358979323846

double* MillierConvertion(double lat, double lon)
{
	double L = 6381372 * M_PI * 2;//地球周長  
	double W = L;// 平面展開後,x軸等於周長  
	double H = L / 2;// y軸約等於周長一半  
	double mill = 2.3;// 米勒投影中的一個常數,範圍大約在正負2.3之間  
	double x = lon * M_PI / 180;// 將經度從度數轉換為弧度  
	double y = lat * M_PI / 180;// 將緯度從度數轉換為弧度  
	y = 1.25 * log(tan(0.25 * M_PI + 0.4 * y));// 米勒投影的轉換  
	// 弧度轉為實際距離  
	x = (W / 2) + (W / (2 * M_PI)) * x;
	y = (H / 2) - (H / (2 * mill)) * y;
	double* result = new double[2];
	result[0] = (int)x;
	result[1] = (int)y;
	return result;
}

double* MillierConvertion1(double x, double y)
{
        double L = 6381372 * M_PI * 2;//地球周長  
	double W = L;// 平面展開後,x軸等於周長  
	double H = L / 2;// y軸約等於周長一半  
	double mill = 2.3;// 米勒投影中的一個常數,範圍大約在正負2.3之間  
	double lat;
	lat = ((H / 2 - y) * 2 * mill) / (1.25 * H);
	lat = ((atan(exp(lat)) - 0.25 * M_PI) * 180) / (0.4 * M_PI);
	double lon;
	lon = (x - W / 2) * 360 / W;
	double* result = new double[2];
	result[0] = lon;
	result[1] = lat;
	return result;
}


void main()
{
	double a, b;
	double *test;
	double *tet;
	a = 0;
	b = 0;
	tet = MillierConvertion(a, b);
	cout << tet[0] << endl << tet[1];
	cout << endl;
	test = MillierConvertion1(tet[0], tet[1]);
	cout << test[0] << endl << test[1];
}