GPS坐标系转换(标准坐标系WGS84转GCJ-02火星坐标系)

这篇博客介绍了不同地理坐标系之间的转换,包括WGS84(全球定位系统标准坐标系)到GCJ-02(中国国测局坐标,又称火星坐标系)以及GCJ-02到WGS84的转换算法。GCJ-02坐标系在中国大陆被广泛使用,而百度地图使用的是在此基础上再次加密的BD-09坐标系。文章提供了C语言实现的坐标转换代码,帮助开发者处理不同坐标系间的位置偏差问题。
摘要由CSDN通过智能技术生成

坐标系简介

通常用经纬度来表示一个地理位置,但是由于一些原因,我们从不同渠道得到的经纬度信息可能并不是在同一个坐标系下。

高德地图、腾讯地图以及谷歌中国区地图使用的是GCJ-02坐标系
百度地图使用的是BD-09坐标系
底层接口(HTML5 Geolocation或ios、安卓API)通过GPS设备获取的坐标使用的是WGS-84坐标系
不同的坐标系之间可能有几十到几百米的偏移,所以在开发基于地图的产品,或者做地理数据可视化时,我们需要修正不同坐标系之间的偏差。

WGS-84 标准坐标系

WGS-84(World Geodetic System, WGS)是使用最广泛的坐标系,也是世界通用的坐标系,GPS设备得到的经纬度就是在WGS84坐标系下的经纬度。通常通过底层接口得到的定位信息都是WGS84坐标系。

GCJ-02 - 国测局坐标

GCJ-02(G-Guojia国家,C-Cehui测绘,J-Ju局),又被称为火星坐标系,是一种基于WGS-84制定的大地测量系统,由中国国测局制定。此坐标系所采用的混淆算法会在经纬度中加入随机的偏移。

国家规定,中国大陆所有公开地理数据都需要至少用GCJ-02进行加密,也就是说我们从国内公司的产品中得到的数据,一定是经过了加密的。绝大部分国内互联网地图提供商都是使用GCJ-02坐标系,包括高德地图,谷歌地图中国区等。

BD-09 - 百度坐标系

BD-09(Baidu, BD)是百度地图使用的地理坐标系,其在GCJ-02上多增加了一次变换,用来保护用户隐私。从百度产品中得到的坐标都是BD-09坐标系。

干货前的说明

其实可以这么理解,火星坐标系是在标准坐标系的基础上进行了一次加密,加密也就是加了一次位置的偏移量,而百度坐标系是进行了两次加密

WGS84转GCJ-02代码

#include <stdio.h>
#include <math.h>

double lng_r,lat_r,tran_lng,tran_lat;
double dlat,dlng,radlat,magic,sqrtmagic;
double mglat,mglng,lngtitude,lattitude;

double lng_w = 120.13372381819;  //标准坐标系 
double lat_w = 30.181981289109;

double PI = 3.1415926535897932384626;
double ee = 0.00669342162296594323;
int a = 6378245;

//标准坐标系WGS84转GCJ-02火星坐标系
void WG_to_GCJ(float lng,float lat)
{
	lng_r = lng - 105.0;
	lat_r = lat - 35.0;
	//经度转换 
	tran_lng= 300.0 + lng_r + 2.0 * lat_r + 0.1 * lng_r * lng_r + 0.1 * lng_r * lat_r + 0.1 * sqrt(abs(lng_r));
	tran_lng = tran_lng + (20.0 * sin(6.0 * lng_r * PI) + 20.0 * sin(2.0 * lng_r * PI)) * 2.0 / 3.0;
	tran_lng = tran_lng + (20.0 * sin(lng_r * PI) + 40.0 * sin(lng_r / 3.0 * PI)) * 2.0 / 3.0;
	tran_lng = tran_lng + (150.0 * sin(lng_r / 12.0 * PI) + 300.0 * sin(lng_r / 30.0 * PI)) * 2.0 / 3.0;
	//转换纬度
	tran_lat = -100.0 + 2.0 * lng_r + 3.0 * lat_r + 0.2 * lat_r * lat_r + 0.1 * lng_r * lat_r + 0.2 * sqrt(abs(lng_r));
	tran_lat = tran_lat+(20.0 * sin(6.0 * lng_r * PI) + 20.0 * sin(2.0 * lng_r * PI)) * 2.0 / 3.0;
	tran_lat = tran_lat+(20.0 * sin(lat_r * PI) + 40.0 * sin(lat_r / 3.0 * PI)) * 2.0 / 3.0;
	tran_lat = tran_lat+(160.0 * sin(lat_r / 12.0 * PI) + 320 * sin(lat_r * PI / 30.0)) * 2.0 / 3.0;
	
	dlat = tran_lat;
	dlng = tran_lng;
	
	radlat = lat/180.0 * PI;
	magic = sin(radlat);
	magic = 1- ee * magic * magic;
	sqrtmagic = sqrt(magic);
	dlat = (dlat * 180.0)/((a * (1-ee))/(magic * sqrtmagic)*PI);
	dlng = (dlng * 180.0)/(a / sqrtmagic * cos(radlat) * PI);
	mglat = lat + dlat;
	mglng = lng + dlng;
	printf("%lf,%lf\r\n",mglat,mglng);
 } 
 int main(void)
 {
    WG_to_GCJ(lng_w,lat_w);
 	return 0;  
 }

GCJ-02转WGS84代码


double lng_r,lat_r,tran_lng,tran_lat;
double dlat,dlng,radlat,magic,sqrtmagic;
double mglat,mglng,lngtitude,lattitude;

double lng_G = 120.13845564;  //火星坐标系 
double lat_G = 30.17967337889;

double PI = 3.1415926535897932384626;
double ee = 0.00669342162296594323;
int a = 6378245;

void GCJ_to_WG(float lng,float lat)
{
	lng_r = lng - 105.0;
	lat_r = lat - 35.0;
	//转换经度 
	tran_lng= 300.0 + lng_r + 2.0 * lat_r + 0.1 * lng_r * lng_r + 0.1 * lng_r * lat_r + 0.1 * sqrt(abs(lng_r));
	tran_lng = tran_lng + (20.0 * sin(6.0 * lng_r * PI) + 20.0 * sin(2.0 * lng_r * PI)) * 2.0 / 3.0;
	tran_lng = tran_lng + (20.0 * sin(lng_r * PI) + 40.0 * sin(lng_r / 3.0 * PI)) * 2.0 / 3.0;
	tran_lng = tran_lng + (150.0 * sin(lng_r / 12.0 * PI) + 300.0 * sin(lng_r / 30.0 * PI)) * 2.0 / 3.0;
	//转换纬度
	tran_lat = -100.0 + 2.0 * lng_r + 3.0 * lat_r + 0.2 * lat_r * lat_r + 0.1 * lng_r * lat_r + 0.2 * sqrt(abs(lng_r));
	tran_lat = tran_lat+(20.0 * sin(6.0 * lng_r * PI) + 20.0 * sin(2.0 * lng_r * PI)) * 2.0 / 3.0;
	tran_lat = tran_lat+(20.0 * sin(lat_r * PI) + 40.0 * sin(lat_r / 3.0 * PI)) * 2.0 / 3.0;
	tran_lat = tran_lat+(160.0 * sin(lat_r / 12.0 * PI) + 320 * sin(lat_r * PI / 30.0)) * 2.0 / 3.0;
	
	dlat = tran_lat;
	dlng = tran_lng;
	
	radlat = lat/180.0 * PI;
	magic = sin(radlat);
	magic = 1- ee * magic * magic;
	sqrtmagic = sqrt(magic);
	dlat = (dlat * 180.0)/((a * (1-ee))/(magic * sqrtmagic)*PI);
	dlng = (dlng * 180.0)/(a / sqrtmagic * cos(radlat) * PI);
	mglat = lat + dlat;
	mglng = lng + dlng;

	lngtitude = lng * 2 - mglng;
	lattitude = lat * 2 - mglat;
	printf("%f,%f\r\n",lattitude,lngtitude);
}

 int main(void)
 {
   	GCJ_to_WG(lng_G,lat_G);
 	return 0;  
 }

结果

在这里插入图片描述

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
WGS84坐标系转换GCJ02坐标系是一个常见的需求,在Java开发中可以使用提供的Java代码来实现。该代码可以在的博客中找到,可以参考该博客进行使用。 具体的转换过程如下: 1. 首先,你需要获取要转换WGS84坐标系的经度和纬度。 2. 然后,使用提供的Java代码,将WGS84坐标系的经度和纬度作为参数传入转换函数。 3. 转换函数会返回对应的GCJ02坐标系的经度和纬度。 4. 最后,你可以使用返回的GCJ02坐标系的经度和纬度进行后续的操作。 通过这个过程,你就可以将WGS84坐标系转换GCJ02坐标系了。请参考中的Java代码和说明来实现具体的转换过程。<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换](https://download.csdn.net/download/junehappylove/11218182)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [java_adnroid_GPS坐标转换工具类的标准代码_百度坐标系 GCJ-02 WGS84 经纬度转换](https://download.csdn.net/download/qq_38334677/85377874)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值