百度(bd09)、高德(gcj02)、WGS84坐标系转标准平面坐标
百度、高德、WGS84为球面坐标系可以通过算法直接转换
通用参数:
public static String BAIDU_LBS_TYPE = "bd09ll"; public static double pi = 3.1415926535897932384626; public static double a = 6378245.0D; public static double ee = 0.006693421622965943D; private static double X_PI= pi * 3000.0D / 180.0D;
百度->高德->WGS84
/** * * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param * bd_lat * @param bd_lon * @return */ public static Gps bd09_To_Gcj02(double bd_lon, double bd_lat) { 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() { lon = gg_lon, lat = gg_lat }; } /** * * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return * */ public static Gps gcj_To_Gps84(double lon, double lat) { Gps gps = transform(lon, lat); double lontitude = lon * 2 - gps.lon; double latitude = lat * 2 - gps.lat; return new Gps() { lat = latitude, lon = lontitude }; } public static Gps transform(double lon, double lat) { if (outOfChina(lon, lat)) { return new Gps() { lon = lon, lat = lat }; } double dLat = transformLat(lon - 105.0, lat - 35.0); double dLon = transformLon(lon - 105.0, lat - 35.0); double radLat = lat / 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 mgLat = lat + dLat; double mgLon = lon + dLon; return new Gps() { lon = mgLon, lat = mgLat }; } public static bool outOfChina(double lon, double lat) { if (lon < 72.004 || lon > 137.8347) return true; if (lat < 0.8293 || lat > 55.8271) return true; return false; } 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; return ret; } 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; return ret; }
/** * 84 to 火星坐标系 (GCJ-02) * * @param lat * @param lon * @return */ public static Gps gps84_To_Gcj02(double lon, double lat) { //if (outOfChina(lon, lat)) //{ // 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 * 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 mgLat = lat + dLat; double mgLon = lon + dLon; return new Gps() { lat=mgLat,lon=mgLon}; } /** * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标 * * @param gg_lat * @param gg_lon */ public static Gps gcj02_To_Bd09(double gg_lon, double gg_lat) { double x = gg_lon, y = gg_lat; 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() { lat=bd_lat,lon=bd_lon}; }
标准的球面坐标要转到标准的平面坐标可以通过墨卡托投影实现
这里使用ARCGIS的API实现需要导入ESRI.ArcGIS.Geometry.dll、ESRI.ArcGIS.System.dll、ESRI.ArcGIS.Version.dll(dll下载)
/// <summary> /// 平面转球面 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static Gps GetProject(double x, double y) { try { ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop); ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironment(); ISpatialReference pSpatialReference = spatialReferenceFactory.CreateProjectedCoordinateSystem(2437);//平面 IGeographicCoordinateSystem projectedCoordinateSystem = spatialReferenceFactory.CreateGeographicCoordinateSystem(4326);//球面 //进行坐标转换 IPoint pt = new PointClass { SpatialReference = pSpatialReference, X = x, Y = y }; pt.Project(projectedCoordinateSystem); //System.Threading.Thread.Sleep(500); Gps xy = new Gps() { lat = pt.X, lon = pt.Y }; return xy; } catch (Exception e) { var v = e.Message; return null; } }
代码中的2437和4326为坐标系的WKID,2437标识表示Beijing_1954_3_Degree_GK_CM_120E的坐标系,4326标识表示GCS_WGS_1984的坐标系(坐标系WKID对照信息)
球面转平面将 SpatialReference 赋的值与pt.Project()的参数互换
/// <summary> /// 球面转平面 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public static Gps GetProjectNew(double x, double y) { try { ESRI.ArcGIS.RuntimeManager.Bind(ESRI.ArcGIS.ProductCode.EngineOrDesktop); ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironment(); ISpatialReference pSpatialReference = spatialReferenceFactory.CreateProjectedCoordinateSystem(4549);//平面 IGeographicCoordinateSystem projectedCoordinateSystem = spatialReferenceFactory.CreateGeographicCoordinateSystem(4326);//球面 //进行坐标转换 IPoint pt = new PointClass { SpatialReference = projectedCoordinateSystem, X = x, Y = y }; pt.Project(pSpatialReference); //System.Threading.Thread.Sleep(500); Gps xy = new Gps() { lat = pt.X, lon = pt.Y }; return xy; } catch (Exception e) { var v = e.Message; return null; } }
在使用.net core编写demo时有遇到ESRI.ArcGIS.Version.dll无法读取加载情况,要修改配置信息:右键项目->属性->生成->目标平台->x86

浙公网安备 33010602011771号