Created
January 9, 2015 09:57
-
-
Save liulunet/4cb49272c9db078d7b15 to your computer and use it in GitHub Desktop.
Geodetic System WGS-84==>GCJ-02<==>BD-09
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// derived from https://on4wp7.codeplex.com/SourceControl/changeset/view/21483#353936 | |
#ifndef coordinate_convert_h | |
#define coordinate_convert_h | |
#include <math.h> | |
const double pi = 3.14159265358979324; | |
// | |
// Krasovsky 1940 | |
// | |
// a = 6378245.0, 1/f = 298.3 | |
// b = a * (1 - f) | |
// ee = (a^2 - b^2) / a^2; | |
const double a = 6378245.0; | |
const double ee = 0.00669342162296594323; | |
bool outOfChina(double lat, double lon); | |
static double transformLat(double x, double y); | |
static double transformLon(double x, double y); | |
// | |
// World Geodetic System ==> Mars Geodetic System | |
CLLocationCoordinate2D transform(CLLocationCoordinate2D wgsCoordinate) | |
{ | |
double wgLat = wgsCoordinate.latitude; | |
double wgLon = wgsCoordinate.longitude; | |
if (outOfChina(wgLat, wgLon)) | |
{ | |
return wgsCoordinate; | |
} | |
double dLat = transformLat(wgLon - 105.0, wgLat - 35.0); | |
double dLon = transformLon(wgLon - 105.0, wgLat - 35.0); | |
double radLat = wgLat / 180.0 * pi; | |
double magic = sin(radLat); | |
magic = 1 - ee * magic * magic; | |
double sqrtMagic = sqrt(magic); | |
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); | |
dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * pi); | |
CLLocationCoordinate2D marsCoordinate = {wgLat + dLat, wgLon + dLon}; | |
return marsCoordinate; | |
} | |
bool outOfChina(double lat, double lon) | |
{ | |
if (lon < 72.004 || lon > 137.8347) | |
return true; | |
if (lat < 0.8293 || lat > 55.8271) | |
return true; | |
return false; | |
} | |
double transformLat(double x, double y) | |
{ | |
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x)); | |
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0; | |
ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0; | |
ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0; | |
return ret; | |
} | |
double transformLon(double x, double y) | |
{ | |
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x)); | |
ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0; | |
ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0; | |
ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0; | |
return ret; | |
} | |
const double x_pi = 3.14159265358979324 * 3000.0 / 180.0; | |
CLLocationCoordinate2D bd_encrypt(CLLocationCoordinate2D ggCoordinate) | |
{ | |
double x = ggCoordinate.longitude, y = ggCoordinate.latitude; | |
double z = sqrt(x * x + y * y) + 0.00002 * sin(y * x_pi); | |
double theta = atan2(y, x) + 0.000003 * cos(x * x_pi); | |
double bd_lon = z * cos(theta) + 0.0065; | |
double bd_lat = z * sin(theta) + 0.006; | |
CLLocationCoordinate2D bdCoordinate = {bd_lat, bd_lon}; | |
return bdCoordinate; | |
} | |
CLLocationCoordinate2D bd_decrypt(CLLocationCoordinate2D bdCoordinate) | |
{ | |
double x = bdCoordinate.longitude - 0.0065, y = bdCoordinate.latitude - 0.006; | |
double z = sqrt(x * x + y * y) - 0.00002 * sin(y * x_pi); | |
double theta = atan2(y, x) - 0.000003 * cos(x * x_pi); | |
double gg_lon = z * cos(theta); | |
double gg_lat = z * sin(theta); | |
CLLocationCoordinate2D ggCoordinate = {gg_lat, gg_lon}; | |
return ggCoordinate; | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment