几种地图经纬度坐标系转换

C/C++代码 blackfeather


wgs84:GPS使用的坐标系

gcj02:中国国家测绘局制订的地理信息系统的坐标系统,是在WGS84经纬度的基础上执行加密算法而成。因为GPS得到的经纬度直接在 GCJ-02 坐标系下会定位到错误的地点,有种到了火星的感觉,因此在坊间也将 GCJ-02 戏称为火星坐标系。高德地图、腾讯地图均使用的此坐标系。

bd09:百度地图使用的,在gcj02基础上又做了一次转换。


地图大陆/港/澳台湾省海外

高德

腾讯

GCJ-02WGS84WGS84
GoogleGCJ-02WGS84WGS84
百度BD-09 / GCJ-02BD-09 / GCJ-02WGS84



//由于坐标系名词比较拗口,注释写的就通俗易懂了

//百度转高德坐标系
void bd09togcj02(double bd_lat, double bd_lon, double& out_lat, double& out_lon);
//高德转百度坐标系
void gcj02tobd09(double gcj_lat, double gcj_lon, double& out_lat, double& out_lon);
//高德转wgs84
void gcj02towgs84(double gcj_lat, double gcj_lon, double& out_lat, double& out_lon);
//wgs84转高德
void wgs84togcj02(double wgs_lat, double wgs_lon, double& out_lat, double& out_lon);


double x_PI = 3.14159265358979323846 * 3000.0 / 180.0;
double PI = 3.1415926535897932384626;
double a = 6378245.0;
double ee = 0.00669342162296594323;

bool outof_China(double lon, double lat)
{
	return(lon < 72.004 || lon>137.8374 || lat < 0.8293 || lat >55.8271 || false);
}
double translate_lon(double lon, double lat)
{
	double ret = 300.0 + lon + 2.0 * lat + 0.1 * lon * lon + 0.1 * lon * lat + 0.1 * sqrt(abs(lon));
	ret += (20.0 * sin(6.0 * lon * PI) + 20.0 * sin(2.0 * lon * PI)) * 2.0 / 3.0;
	ret += (20.0 * sin(lon * PI) + 40.0 * sin(lon / 3.0 * PI)) * 2.0 / 3.0;
	ret += (150 * sin(lon / 12.0 * PI) + 300.0 * sin(lon / 30.0 * PI)) * 2.0 / 3.0;
	return ret;
}
double translate_lat(double lon, double lat)
{
	double ret = -100 + 2.0 * lon + 3.0 * lat + 0.2 * lat * lat + 0.1 * lon * lat + 0.2 * sqrt((abs(lon)));
	ret += (20.0 * sin(6.0 * lon * PI) + 20 * sin(2.0 * lon * PI)) * 2.0 / 3.0;
	ret += (20.0 * sin(lat * PI) + 40.0 * sin(lat / 3.0 * PI)) * 2.0 / 3.0;
	ret += (160.0 * sin(lat / 12.0 * PI) + 320.0 * sin(lat / 30.0 * PI)) * 2.0 / 3.0;
	return ret;
}
void bd09togcj02(double bd_lat, double bd_lon, double& out_lat, double& out_lon)
{
	double x = bd_lon - 0.0065;
	double y = bd_lat - 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);
	out_lon = z * cos(theta);
	out_lat = z * sin(theta);
}
void gcj02tobd09(double gcj_lat, double gcj_lon, double& out_lat, double& out_lon)
{
	double z = sqrt(gcj_lon * gcj_lon + gcj_lat * gcj_lat) + 0.00002 * sin(gcj_lat * x_PI);
	double theta = atan2(gcj_lat, gcj_lon) + 0.000003 * cos(gcj_lon * x_PI);
	out_lon = z * cos(theta) + 0.0065;
	out_lat = z * sin(theta) + 0.006;
}
void gcj02towgs84(double gcj_lat, double gcj_lon, double& out_lat, double& out_lon)
{
	if (outof_China(gcj_lon, gcj_lat))
	{
		out_lon = gcj_lon;
		out_lat = gcj_lat;
		return;
	}
	
	double dlat = translate_lat(gcj_lon - 105.0, gcj_lat - 35.0);
	double dlon = translate_lon(gcj_lon - 105.0, gcj_lat - 35.0);
	double radlat = gcj_lat / 180.0 * PI;
	double magic = sin(radlat);
	magic = 1 - ee * magic * magic;
	double squrtmagic = sqrt(magic);
	dlon = (dlon * 180.0) / (a / squrtmagic * cos(radlat) * PI);
	dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * squrtmagic) * PI);
	out_lon = gcj_lon - dlon;
	out_lat = gcj_lat - dlat;
}
void wgs84togcj02(double wgs_lat, double wgs_lon, double& out_lat, double& out_lon)
{
	if (outof_China(wgs_lon, wgs_lat))
	{
		out_lon = wgs_lon;
		out_lat = wgs_lat;
		return;
	}
	
	double dlat = translate_lat(wgs_lon - 105.0, wgs_lat - 35.0);
	double dlon = translate_lon(wgs_lon - 105.0, wgs_lat - 35.0);
	double radlat = wgs_lat / 180.0 * PI;
	double magic = sin(radlat);
	magic = 1 - ee * magic * magic;
	double squrtmagic = sqrt(magic);
	dlon = (dlon * 180.0) / (a / squrtmagic * cos(radlat) * PI);
	dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * squrtmagic) * PI);
	out_lon = wgs_lon + dlon;
	out_lat = wgs_lat + dlat;
}


评论列表:

发表评论: