WGS84坐标地图怎样转火星坐标系转wgs84地图

利用纠偏数据来处理地球坐标(WGS-84)与火星坐标 (GCJ-02)转换 - 推酷
利用纠偏数据来处理地球坐标(WGS-84)与火星坐标 (GCJ-02)转换
关键代码:
using System.C
using System.Collections.G
using System.IO;
using YanZhiwei.DotNet2.Utilities.M
namespace YanZhiwei.mon
/// &summary&
/// 地图纠偏数据帮助类
/// &/summary&
public class MapOffsetDataHelper
#region 构造函数以及变量
private string offsetFullPath = string.E
/// &summary&
/// 构造函数
/// &/summary&
/// ¶m name=&path&&纠偏数据文件路径&/param&
public MapOffsetDataHelper(string path)
offsetFullPath =
#endregion
#region 私有方法
private void GetOffsetData(Action&MapCoord& mapCoordHanlder)
using (FileStream stream = new FileStream(offsetFullPath, FileMode.OpenOrCreate, FileAccess.Read))
using (BinaryReader reader = new BinaryReader(stream))
int _size = (int)stream.Length / 8;
for (int i = 0; i & _ i++)
byte[] _source = reader.ReadBytes(8);
MapCoord _coord = ToCoord(_source);
mapCoordHanlder(_coord);
/// &summary&
/// 将字节转化为具体的数据对象
/// &/summary&
/// ¶m name=&bytes&&bytes&/param&
/// &returns&MapCoord&/returns&
private MapCoord ToCoord(byte[] bytes)
//经度,纬度,x偏移量,y偏移量 【均两个字节】
MapCoord _coord = new MapCoord();
byte[] _b1 = new byte[2], _b2 = new byte[2], _b3 = new byte[2], _b4 = new byte[2];
Array.Copy(bytes, 0, _b1, 0, 2);
Array.Copy(bytes, 2, _b2, 0, 2);
Array.Copy(bytes, 4, _b3, 0, 2);
Array.Copy(bytes, 6, _b4, 0, 2);
_coord.Lon = BitConverter.ToInt16(_b1, 0);
_coord.Lat = BitConverter.ToInt16(_b2, 0);
_coord.X_off = BitConverter.ToInt16(_b3, 0);
_coord.Y_off = BitConverter.ToInt16(_b4, 0);
#endregion
#region 获取纠偏数据集合
/// &summary&
/// 获取纠偏数据集合
/// &/summary&
/// &returns&纠偏数据集合&/returns&
public List&MapCoord& GetMapCoordList()
List&MapCoord& _mapCoordList = new List&MapCoord&();
GetOffsetData(c =& _mapCoordList.Add(c));
return _mapCoordL
/// &summary&
/// 获取纠偏数据集合
/// &/summary&
/// &returns&纠偏数据集合&/returns&
public ArrayList GetMapCoordArrayList()
ArrayList _mapCoordArrayList = new ArrayList();
GetOffsetData(c =& _mapCoordArrayList.Add(c));
return _mapCoordArrayL
#endregion
---------------------------------------------------------------
using System.C
using YanZhiwei.DotNet2.Utilities.M
using YanZhiwei.DotNet2.Utilities.T
namespace YanZhiwei.mon
/// &summary&
/// 地图纠偏 帮助类
/// &/summary&
public class MapOffsetHelper
*1./forum.php?mod=viewthread&tid=137621&extra=page%3D1&page=1
*2.http://yanue.net/post-122.html
*3.//%E4%B8%AD%E5%9B%BD%E5%9C%B0%E5%9B%BE%E5%81%8F%E7%A7%BB%E6%A0%A1%E6%AD%A3php%E7%AE%97%E6%B3%95/
*4./ios_gps_google_-blog-.html
#region 构造函数以及变量
private ArrayList mapCoordArrayL
/// &summary&
/// 构造函数
/// &/summary&
/// ¶m name=&offsetData&&纠偏数据&/param&
public MapOffsetHelper(ArrayList offsetData)
mapCoordArrayList = offsetD
#endregion
#region 私有方法
private MapCoord QueryOffSetData(LatLngPoint point)
MapCoord _search = new MapCoord();
_search.Lat = (int)(point.LatY * 100);
_search.Lon = (int)(point.LonX * 100);
MapOffsetComparer rc = new MapOffsetComparer();
int _findedIndex = mapCoordArrayList.BinarySearch(0, mapCoordArrayList.Count, _search, rc);
MapCoord _findedCoord = (MapCoord)mapCoordArrayList[_findedIndex];
return _findedC
#endregion
#region 地球坐标(WGS-84)转火星坐标 (GCJ-02)
/// &summary&
/// 地球坐标(WGS-84)转火星坐标 (GCJ-02)
/// &/summary&
/// ¶m name=&wgsPoint&&地球坐标(WGS-84)&/param&
/// &returns&火星坐标 (GCJ-02)&/returns&
public LatLngPoint WGS84ToGCJ02(LatLngPoint wgsPoint)
MapCoord _findedCoord = QueryOffSetData(wgsPoint);
double _pixY = MapHelper.LatToPixel(wgsPoint.LatY, 18);
double _pixX = MapHelper.LonToPixel(wgsPoint.LonX, 18);
_pixY += _findedCoord.Y_
_pixX += _findedCoord.X_
double _lat = MapHelper.PixelToLat(_pixY, 18);
double _lng = MapHelper.PixelToLon(_pixX, 18);
return new LatLngPoint(_lat, _lng);
#endregion
#region 火星坐标转 (GCJ-02)地球坐标(WGS-84)
/// &summary&
/// 火星坐标转 (GCJ-02)地球坐标(WGS-84)
/// &/summary&
/// ¶m name=&gcjPoint&&火星坐标转 (GCJ-02)&/param&
/// &returns&地球坐标(WGS-84)&/returns&
public LatLngPoint GCJ02ToWGS84(LatLngPoint gcjPoint)
MapCoord _findedCoord = QueryOffSetData(gcjPoint);
double _pixY = MapHelper.LatToPixel(gcjPoint.LatY, 18);
double _pixX = MapHelper.LonToPixel(gcjPoint.LonX, 18);
_pixY -= _findedCoord.Y_
_pixX -= _findedCoord.X_
double _lat = MapHelper.PixelToLat(_pixY, 18);
double _lng = MapHelper.PixelToLon(_pixX, 18);
return new LatLngPoint(_lat, _lng);
#endregion
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致class Gps {
private double wgL
private double wgL
public Gps(double wgLat, double wgLon) {
setWgLat(wgLat);
setWgLon(wgLon);
public double getWgLat() {
return wgL
public void setWgLat(double wgLat) {
this.wgLat = wgL
public double getWgLon() {
return wgL
public void setWgLon(double wgLon) {
this.wgLon = wgL
public String toString() {
return wgLat + "," + wgL
* 各种坐标系转换工具类
* @author chenfangbo
* @return double
public class PositionUtil {
public static final String BAIDU_LBS_TYPE = "bd09ll";
public static double pi = 3. * 3000.0 / 180.0;
//此处注意 pi = 派 * 3000 / 180 ;
public static double a = ;
public static double ee = 0.;
* 84 to 火星坐标系 (GCJ-02) World Geodetic System ==& Mars Geodetic System
* 地球转谷歌
* @param lat
* @param lon
public static Gps gps84_To_Gcj02(double lat, double lon) {
if (outOfChina(lat, lon)) {
return null;
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 *
double magic = Math.sin(radLat);
magic = 1 - ee * magic *
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dL
double mgLon = lon + dL
return new Gps(mgLat, mgLon);
* 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
* 谷歌转地球
public static Gps gcj_To_Gps84(double lat, double lon) {
Gps gps = transform(lat, lon);
double lontitude = lon * 2 - gps.getWgLon();
double latitude = lat * 2 - gps.getWgLat();
return new Gps(latitude, lontitude);
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
* 谷歌转百度
* @param gg_lat
* @param gg_lon
public static Gps gcj02_To_Bd09(double gg_lat, double gg_lon) {
double x = gg_lon, y = gg_
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * pi);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * pi);
double bd_lon = z * Math.cos(theta) + 0.0065;
double bd_lat = z * Math.sin(theta) + 0.006;
return new Gps(bd_lat, bd_lon);
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
* 百度转谷歌
public static Gps bd09_To_Gcj02(double bd_lat, double bd_lon) {
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * pi);
double gg_lon = z * Math.cos(theta);
double gg_lat = z * Math.sin(theta);
return new Gps(gg_lat, gg_lon);
* (BD-09)--&84
* 百度转地球
* @param bd_lat
* @param bd_lon
public static Gps bd09_To_Gps84(double bd_lat, double bd_lon) {
Gps gcj02 = PositionUtil.bd09_To_Gcj02(bd_lat, bd_lon);
Gps map84 = PositionUtil.gcj_To_Gps84(gcj02.getWgLat(),
gcj02.getWgLon());
return map84;
public static boolean 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;
public static Gps transform(double lat, double lon) {
if (outOfChina(lat, lon)) {
return new Gps(lat, lon);
double dLat = transformLat(lon - 105.0, lat - 35.0);
double dLon = transformLon(lon - 105.0, lat - 35.0);
double radLat = lat / 180.0 *
double magic = Math.sin(radLat);
magic = 1 - ee * magic *
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
double mgLat = lat + dL
double mgLon = lon + dL
return new Gps(mgLat, mgLon);
public static 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 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
public static double transformLon(double x, double y) {
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1
* Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0
* pi)) * 2.0 / 3.0;
public static void main(String[] args) {
// 北斗芯片获取的经纬度为WGS84地理坐标 31..496145
Gps gps = new Gps(30.1568);
// System.out.println("gps :" + gps);
Gps gcj = gps84_To_Gcj02(gps.getWgLat(), gps.getWgLon());
System.out.println("地球转谷歌 :" + gcj);
Gps bd = gcj02_To_Bd09(gcj.getWgLat(), gcj.getWgLon());
System.out.println("谷歌转百度
Gps gcj2 = bd09_To_Gcj02(bd.getWgLat(), bd.getWgLon());
System.out.println("百度转谷歌 :" + gcj2);
Gps star = gcj_To_Gps84(gcj.getWgLat(), gcj.getWgLon());
System.out.println("谷歌转地球:" + star);
Gps gcj3 = bd09_To_Gps84(gps.getWgLat(), gps.getWgLon());
System.out.println("百度转地球 :" + gcj3);
阅读(...) 评论()GPS各种地图坐标系转换
地图供应商比较多,产生了许多地图坐标。地图坐标正确转换是个问题。在之前开发地图应用的时候发现从WGS84坐标系(GPS)转换成某个地图坐标系都比较困难。然后只能使用地图供应商提供的webservice接口转换。百度也提供了免费的webservice接口(限制并发量)。对于少数点的转换性能还可以,但是对于非常多点的转换压力比较大(使用多线程并行计算).个人感觉比较繁琐,而且很难保证转换的稳定性。
时间飞逝,百度地图更新了新版本,给我们带来了福音,map API中自带了相关坐标的转换,这就省事多了。但是其它的地图貌似没有提供转换API.怎么办呢?真是高手在民间呀,哪个牛人透露转换的算法呢?估计是和百度相关的牛人吧。下面是对算法的收集和整理。
这下使用地图转换就比较准确了。
java版本:
* 坐标转换程序
WGS84坐标系:即地球坐标系,国际上通用的坐标系。Earth
GCJ02坐标系:即火星坐标系,WGS84坐标系经加密后的坐标系。Mars
BD09坐标系:即百度坐标系,GCJ02坐标系经加密后的坐标系。
搜狗坐标系、图吧坐标系等,估计也是在GCJ02基础上加密而成的。
* 百度地图API
腾讯搜搜地图API
搜狐搜狗地图API
阿里云地图API
图吧MapBar地图API
高德MapABC地图API
灵图51ditu地图API
* @author fankun
public class CoordinateConvert {
private static
= Math.PI;
private static
double AXIS
private static
double OFFSET
//(a^2 - b^2) / a^2
private static
double X_PI
= PI * 3000.0 / 180.0;
//GCJ-02=&BD09 火星坐标系=&百度坐标系
public static double[] gcj2BD09(double glat, double glon){
double x =
double y =
double[] latlon = new double[2];
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
latlon[0] = z * Math.sin(theta) + 0.006;
latlon[1] = z * Math.cos(theta) + 0.0065;
//BD09=&GCJ-02 百度坐标系=&火星坐标系
public static double[] bd092GCJ(double glat, double glon){
double x = glon - 0.0065;
double y = glat - 0.006;
double[] latlon = new double[2];
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
latlon[0] = z * Math.sin(theta);
latlon[1] = z * Math.cos(theta);
//BD09=&WGS84 百度坐标系=&地球坐标系
public static double[] bd092WGS(double glat, double glon){
double[] latlon = bd092GCJ(glat,glon);
return gcj2WGS(latlon[0],latlon[1]);
// WGS84=》BD09
地球坐标系=&百度坐标系
public static double[] wgs2BD09(double wgLat, double wgLon) {
double[] latlon = wgs2GCJ(wgLat,wgLon);
return gcj2BD09(latlon[0],latlon[1]);
// WGS84=》GCJ02
地球坐标系=&火星坐标系
public static double[] wgs2GCJ(double wgLat, double wgLon) {
double[] latlon
= new double[2];
if (outOfChina(wgLat, wgLon)){
latlon[0] = wgL
latlon[1] = wgL
double[] deltaD =
delta(wgLat,wgLon);
latlon[0] = wgLat + deltaD[0];
latlon[1] = wgLon + deltaD[1];
//GCJ02=&WGS84
火星坐标系=&地球坐标系(粗略)
public static double[] gcj2WGS(double glat,double glon){
double[] latlon
= new double[2];
if (outOfChina(glat, glon)){
latlon[0] =
latlon[1] =
double[] deltaD =
delta(glat,glon);
latlon[0] = glat - deltaD[0];
latlon[1] = glon - deltaD[1];
//GCJ02=&WGS84
火星坐标系=&地球坐标系(精确)
public static double[] gcj2WGSExactly(double gcjLat,double gcjLon){
double initDelta = 0.01;
double threshold = 0.;
double dLat = initDelta, dLon = initD
double mLat = gcjLat - dLat, mLon = gcjLon - dL
double pLat = gcjLat + dLat, pLon = gcjLon + dL
double wgsLat, wgsLon, i = 0;
while (true) {
wgsLat = (mLat + pLat) / 2;
wgsLon = (mLon + pLon) / 2;
double[] tmp = wgs2GCJ(wgsLat, wgsLon);
dLat = tmp[0] - gcjL
dLon = tmp[1] - gcjL
if ((Math.abs(dLat) & threshold) && (Math.abs(dLon) & threshold))
if (dLat & 0) pLat = wgsL else mLat = wgsL
if (dLon & 0) pLon = wgsL else mLon = wgsL
if (++i & 10000)
double[] latlon = new double[2];
latlon[0] = wgsL
latlon[1] = wgsL
//两点距离
public static double distance(double latA, double logA, double latB,double
int earthR = 6371000;
double x = Math.cos(latA*Math.PI/180) * Math.cos(latB*Math.PI/180) * Math.cos((logA-logB)*Math.PI/180);
double y = Math.sin(latA*Math.PI/180) * Math.sin(latB*Math.PI/180);
double s = x +
if (s & 1)
if (s & -1)
double alpha = Math.acos(s);
double distance = alpha * earthR;
public static double[] delta(double wgLat, double wgLon){
double[] latlng
= new double[2];
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 = Math.sin(radLat);
magic = 1 - OFFSET * magic *
double sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtMagic) * PI);
dLon = (dLon * 180.0) / (AXIS / sqrtMagic * Math.cos(radLat) * PI);
latlng[0] =dL
latlng[1] =dL
public static boolean outOfChina(double lat, double lon){
if (lon & 72.004 || lon & 137.8347)
if (lat & 0.8293 || lat & 55.8271)
public static 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 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * PI) + 40.0 * Math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * PI) + 320 * Math.sin(y * PI / 30.0)) * 2.0 / 3.0;
public static double transformLon(double x, double y){
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
ret += (20.0 * Math.sin(6.0 * x * PI) + 20.0 * Math.sin(2.0 * x * PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * PI) + 40.0 * Math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * PI) + 300.0 * Math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

参考资料

 

随机推荐