C#实现地图坐标系的转换(WGS-84、GCJ-02、BD-09)
程序员文章站
2023-11-15 16:53:10
WGS-84坐标系:全球定位系统使用,GPS、北斗等 GCJ-02坐标系:中国地区使用,由WGS-84偏移而来 BD-09坐标系:百度专用,由GCJ-02偏移而来 (PS:源于项目需求,本来是想读图片的经纬度显示在百度离线地图上的。后来发现定位偏差太大,仔细一想,原来是图片和百度使用的坐标系不一样。 ......
wgs-84坐标系:全球定位系统使用,gps、北斗等
gcj-02坐标系:中国地区使用,由wgs-84偏移而来
bd-09坐标系:百度专用,由gcj-02偏移而来
(ps:源于项目需求,本来是想读图片的经纬度显示在百度离线地图上的。后来发现定位偏差太大,仔细一想,原来是图片和百度使用的坐标系不一样。
计算转换部分
public class gpschange { private const double pi = 3.14159265358979324; private const double x_pi = 3.14159265358979324 * 3000.0 / 180.0; //克拉索天斯基椭球体参数值 private const double a = 6378245.0; //第一偏心率 private const double ee = 0.00669342162296594323; /// <summary> /// gcj-02转换bd-09 /// </summary> /// <param name="gg_lat">纬度</param> /// <param name="gg_lon">经度</param> /// <returns></returns> public static gpspoint gcj02_to_bd09(double gg_lat, double gg_lon) { gpspoint point = new gpspoint(); double x = gg_lon, y = gg_lat; 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); double bd_lon = z * math.cos(theta) + 0.0065; double bd_lat = z * math.sin(theta) + 0.006; point.setlat(bd_lat); point.setlng(bd_lon); return point; } /// <summary> /// bd-09转换gcj-02 /// </summary> /// <param name="bd_lat">纬度</param> /// <param name="bd_lon">经度</param> /// <returns></returns> public static gpspoint bd09_to_gcj02(double bd_lat, double bd_lon) { gpspoint point = new gpspoint(); double x = bd_lon - 0.0065, y = bd_lat - 0.006; 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); double gg_lon = z * math.cos(theta); double gg_lat = z * math.sin(theta); point.setlat(gg_lat); point.setlng(gg_lon); return point; } /// <summary> /// wgs-84转换gcj-02 /// </summary> /// <param name="wglat">纬度</param> /// <param name="wglon">经度</param> /// <returns></returns> public static gpspoint wgs84_to_gcj02(double wglat, double wglon) { gpspoint point = new gpspoint(); if (outofchina(wglat, wglon)) { point.setlat(wglat); point.setlng(wglon); return point; } 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 - ee * magic * 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 lat = wglat + dlat; double lon = wglon + dlon; point.setlat(lat); point.setlng(lon); return point; } public static void transform(double wglat, double wglon, double[] latlng) { if (outofchina(wglat, wglon)) { latlng[0] = wglat; latlng[1] = wglon; return; } 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 - ee * magic * 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); latlng[0] = wglat + dlat; latlng[1] = wglon + dlon; } private static 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; } private 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; return ret; } private 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; return ret; } }
基础类
public class gpspoint { private double lat;// 纬度 private double lng;// 经度 public gpspoint() { } public gpspoint(double lng, double lat) { this.lng = lng; this.lat = lat; } public double getlat() { return lat; } public void setlat(double lat) { this.lat = lat; } public double getlng() { return lng; } public void setlng(double lng) { this.lng = lng; } }
下一篇: Yii分页用法实例详解