一、各大坐标系
目前地图开发离不开定位,定位又离不开坐标系的选取和转换,所以有必要简单说一下啦。
世界大地坐标(WGS84)
1.国际上采用的标准,是为GPS全球定位系统使用而建立的坐标系统,可从专业GPS设备中获取数据。
2.国际地图使用的坐标系。
3.谷歌国外地图、osm地图
火星坐标(GCJ-02)
1.中国采用的标准,准确是叫国测局坐标系,可从国行移动设备定位获得数据
2.国内出版的各类地图都至少采用GCJ-02对地理位置进行加密偏移
3.高德地图、天地图、搜搜地图等
百度坐标(BD-09)
1.百度地图自己采用的坐标标准。
2.百度坐标是在GCJ-02的基础上再次加密
3.百度地图
二、各大坐标系间的转换
通用实体
1 /// <summary> 2 /// 经度和纬度 3 /// </summary> 4 public class StationGps 5 { 6 /// <summary> 7 /// 经度 8 /// </summary> 9 public double longitude { get; set; } 10 /// <summary> 11 /// 纬度 12 /// </summary> 13 public double latitude { get; set; } 14 }
1、火星坐标转百度
1 private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; 2 3 public static StationGps HxToBd(double lon, double lat) 4 { 5 var result = new StationGps(); 6 double x = lon, y = lat; 7 var z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi); 8 var theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi); 9 result.longitude = z * Math.Cos(theta) + 0.0065; 10 result.latitude = z * Math.Sin(theta) + 0.006; 11 return result; 12 }
2、百度转火星坐标
1 private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; 2 3 public static StationGps BdToHx(double lon, double lat) 4 { 5 var result = new StationGps(); 6 double x = lon - 0.0065, y = lat - 0.006; 7 var z = Math.Sqrt(x * x + y * y) - 0.00002 * Math.Sin(y * x_pi); 8 var theta = Math.Atan2(y, x) - 0.000003 * Math.Cos(x * x_pi); 9 result.longitude = z * Math.Cos(theta); 10 result.latitude = z * Math.Sin(theta); 11 return result; 12 }
3、世界大地坐标转火星坐标
1 private static double pi = 3.14159265358979324; 2 private static double a = 6378245.0; 3 private static double ee = 0.00669342162296594323; 4 5 public static StationGps WgsToHx(double lon, double lat) 6 { 7 var result = new StationGps(); 8 double dLat = TransformLat(lat - 35.0, lon - 105.0); 9 double dLon = TransformLon(lat - 35.0, lon - 105.0); 10 double radLat = lat / 180.0 * pi; 11 double magic = Math.Sin(radLat); 12 magic = 1 - ee * magic * magic; 13 var sqrtMagic = Math.Sqrt(magic); 14 dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); 15 dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi); 16 result.latitude = lat + dLat; 17 result.longitude = lon + dLon; 18 return result; 19 } 20 21 private static double TransformLat(double lon, double lat) 22 { 23 var ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.Sqrt(Math.Abs(lat)); 24 ret += (20.0 * Math.Sin(6.0 * lat * pi) + 20.0 * Math.Sin(2.0 * lat * pi)) * 2.0 / 3.0; 25 ret += (20.0 * Math.Sin(lon * pi) + 40.0 * Math.Sin(lon / 3.0 * pi)) * 2.0 / 3.0; 26 ret += (160.0 * Math.Sin(lon / 12.0 * pi) + 320 * Math.Sin(lon * pi / 30.0)) * 2.0 / 3.0; 27 return ret; 28 } 29 private static double TransformLon(double lon, double lat) 30 { 31 var ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.Sqrt(Math.Abs(lat)); 32 ret += (20.0 * Math.Sin(6.0 * lat * pi) + 20.0 * Math.Sin(2.0 * lat * pi)) * 2.0 / 3.0; 33 ret += (20.0 * Math.Sin(lat * pi) + 40.0 * Math.Sin(lat / 3.0 * pi)) * 2.0 / 3.0; 34 ret += (150.0 * Math.Sin(lat / 12.0 * pi) + 300.0 * Math.Sin(lat / 30.0 * pi)) * 2.0 / 3.0; 35 return ret; 36 }
4、世界大地坐标转为百度坐标
1 private static double pi = 3.14159265358979324; 2 private static double a = 6378245.0; 3 private static double ee = 0.00669342162296594323; 4 private static double x_pi = 3.14159265358979324 * 3000.0 / 180.0; 5 6 public static StationGps WgsToBd(double lon, double lat) 7 { 8 var hx = WgsToHx(lon, lat); 9 var bd = HxToBd(hx.longitude, hx.latitude); 10 return bd; 11 } 12 13 public static StationGps HxToBd(double lon, double lat) 14 { 15 var result = new StationGps(); 16 double x = lon, y = lat; 17 var z = Math.Sqrt(x * x + y * y) + 0.00002 * Math.Sin(y * x_pi); 18 var theta = Math.Atan2(y, x) + 0.000003 * Math.Cos(x * x_pi); 19 result.longitude = z * Math.Cos(theta) + 0.0065; 20 result.latitude = z * Math.Sin(theta) + 0.006; 21 return result; 22 } 23 24 public static StationGps WgsToHx(double lon, double lat) 25 { 26 var result = new StationGps(); 27 double dLat = TransformLat(lat - 35.0, lon - 105.0); 28 double dLon = TransformLon(lat - 35.0, lon - 105.0); 29 double radLat = lat / 180.0 * pi; 30 double magic = Math.Sin(radLat); 31 magic = 1 - ee * magic * magic; 32 var sqrtMagic = Math.Sqrt(magic); 33 dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi); 34 dLon = (dLon * 180.0) / (a / sqrtMagic * Math.Cos(radLat) * pi); 35 result.latitude = lat + dLat; 36 result.longitude = lon + dLon; 37 return result; 38 } 39 40 private static double TransformLat(double lon, double lat) 41 { 42 var ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.Sqrt(Math.Abs(lat)); 43 ret += (20.0 * Math.Sin(6.0 * lat * pi) + 20.0 * Math.Sin(2.0 * lat * pi)) * 2.0 / 3.0; 44 ret += (20.0 * Math.Sin(lon * pi) + 40.0 * Math.Sin(lon / 3.0 * pi)) * 2.0 / 3.0; 45 ret += (160.0 * Math.Sin(lon / 12.0 * pi) + 320 * Math.Sin(lon * pi / 30.0)) * 2.0 / 3.0; 46 return ret; 47 } 48 49 private static double TransformLon(double lon, double lat) 50 { 51 var ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.Sqrt(Math.Abs(lat)); 52 ret += (20.0 * Math.Sin(6.0 * lat * pi) + 20.0 * Math.Sin(2.0 * lat * pi)) * 2.0 / 3.0; 53 ret += (20.0 * Math.Sin(lat * pi) + 40.0 * Math.Sin(lat / 3.0 * pi)) * 2.0 / 3.0; 54 ret += (150.0 * Math.Sin(lat / 12.0 * pi) + 300.0 * Math.Sin(lat / 30.0 * pi)) * 2.0 / 3.0; 55 return ret; 56 }