<一>基本操作
一、一些基本设置
如中心点、最大最小当前比例尺设置、地图、还有
这些都写在gMapControl1_Load(),加载函数里,我为了方便将GMapControl控件命名为了gmap
private void gmap_Load(object sender, EventArgs e)
{
//加载谷歌中国地图
GMapProvider.TimeoutMs = 0;
gmap.MapProvider = GMapProviders.GoogleChinaMap;
gmap.MapProvider = GMap.NET.MapProviders.GoogleChinaMapProvider.Instance;
////加载谷歌卫星地图
//gmap.MapProvider = GMapProviders.GoogleChinaSatelliteMap;
//GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
gmap.DragButton = System.Windows.Forms.MouseButtons.Left;//地图拖拽使用鼠标左键
gmap.Zoom = 12;//当前的比例尺
gmap.ShowCenter = false;//是否显示红色十字标
gmap.MaxZoom = 24;//最大比例尺
gmap.MinZoom = 2;//最小比例尺
this.gmap.Position = new PointLatLng(39.923518, 116.539009);//gmapControl地图的中心位置
this.gmap.IsAccessible = false;//
GMapProvider.TimeoutMs = 1000;
TopologyElement.Point pt = new TopologyElement.Point();
pt.Lat = 39.923518;
pt.Lon = 116.539009;
pt.ID = 1;
}
GMapProvider类是提供地图、目前支持谷歌地图、百度地图、高德地图及其卫星地图
二、添加点、路线
GMapMarker是GMap.NET的图标类
GMarkerGoogle是枚举类型
所以设置一个GMapMarker通过给定位置信息和图标种类,并将该图标加入到图层,并把图层加入到gmapControl既可以实时显示了
//点PointLatLng、图标GMapMarker
GMapMarker gMapMarker = new GMarkerGoogle(new PointLatLng(38.0,122.0), GMarkerGoogleType.green);
gMapMarker.ToolTipText = string.Format("点编号{0}:经度{1},纬度{2}", 1, gMapMarker.Position.Lon, gMapMarker.Position.Lat);
gMapMarker.ToolTip.Foreground = Brushes.Black;//设置提示框
gMapMarker.ToolTip.TextPadding = new Size(20, 10);
//图层
GMapOverlay overlay = new GMapOverlay("图层名称");
//图标加入到图层中
overlay.Markers.Add(gMapMarker);
//路线--需要添加点集合如List<PointLatLng>
List<PointLatLng> points=new List<PointLatLng>();
points.Add(new PointLatLng(38.0,122.0));
points.Add(new PointLatLng(38.1,122,1));//至此两个点确定了一条直线
GMapRoute route=new GMapRoute(points,"路线名称");
//路线加入到图层中
overlay.Routes.Add(route);
//图层加入到控件中
this.gmap.Overlays.Add(overlay)
三、切换地图源操作
我用了三个RadioButton来实现这个
所以在CheckChanged事件中写
private void rb_SatelliteMap_CheckedChanged(object sender, EventArgs e)
{
if (rb_SatelliteMap.Checked)
{
gmap.MapProvider = GMapProviders.GoogleChinaSatelliteMap;
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
gmap.ReloadMap();
GMapProvider.TimeoutMs = 1000;
}
}
private void rb_OthersMap_CheckedChanged(object sender, EventArgs e)
{
if (rb_OthersMap.Checked)
{
gmap.MapProvider = GMapProviders.EmptyProvider;
GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
gmap.ReloadMap();
GMapProvider.TimeoutMs = 1000;
}
}
private void map_Normal_CheckedChanged(object sender, EventArgs e)
{
if (map_Normal.Checked)
{
gmap.MapProvider = GMapProviders.GoogleChinaMap;
gmap.MapProvider = GMap.NET.MapProviders.GoogleChinaMapProvider.Instance; GMap.NET.GMaps.Instance.Mode = GMap.NET.AccessMode.ServerAndCache;
gmap.ReloadMap();
GMapProvider.TimeoutMs = 1000;
}
}
<二>拓展操作
一、设置全屏幕
其实原理就是找到图层的最大/最小纬度/经度,组成一个矩形,利用GMap自己的方法this.gmap.SetZoomToFitRect(area);
#region 设置最佳视图
/// <summary>
/// 是否显示最佳视图
/// </summary>
/// <param name="isCurrentOverlay">是否设置当前图层</param>
/// <param name="isSetPerfectPos">是否设置最佳视图</param>
/// <param name="overlay">tuc</param>
private void SetPerfectPos(bool isCurrentOverlay, bool isSetPerfectPos, GMapOverlay overlay)
{
if (isCurrentOverlay)
{
currentOverlay = overlay;
txtCurrentOverlay.Caption = string.Format("当前图层:{0}", overlay.Id);
}
if (isSetPerfectPos)
{
SetPerfectPos(overlay.Markers);
}
}
/// <summary>
/// 设置最佳视图
/// </summary>
/// <param name="gpoints">所有点的范围</param>
private void SetPerfectPos(List<PointLatLng> gpoints)
{
if (gpoints.Count != 0)
{
double minlat = gpoints.Min(a => a.Lat);
double maxlat = gpoints.Max(a => a.Lat);
double minlng = gpoints.Min(a => a.Lng);
double maxlng = gpoints.Max(a => a.Lng);
PointLatLng lefttop = new PointLatLng(minlat, minlng);
PointLatLng center = new PointLatLng((minlat + maxlat) / 2.0, (minlng + maxlng) / 2.0);
lefttop.Lat += maxlat - minlat;
RectLatLng area = new RectLatLng();
area.LocationTopLeft = lefttop;
area.Size = new SizeLatLng(maxlat - minlat, maxlng - minlng);
this.gmap.SelectedArea = area;
this.gmap.SetZoomToFitRect(area);
}
}
/// <summary>
/// 设置最佳视图
/// </summary>
/// <param name="gMarkers">GMarkers</param>
private void SetPerfectPos(GMap.NET.ObjectModel.ObservableCollectionThreadSafe<GMapMarker> gMarkers)
{
List<PointLatLng> points = new List<PointLatLng>();
foreach (GMapMarker m in gMarkers)
{
points.Add(m.Position);
}
SetPerfectPos(points);
}
#endregion
#region 适应全屏幕
private void btn_ViewAll_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
///
if (gMapOverlays.Count != 0)//如果没有打开地图文件
{
List<PointLatLng> points = new List<PointLatLng>();
foreach (GMapOverlay overlay in gMapOverlays)
{
if (overlay.Markers.Count != 0)
{ points.AddRange(SearchCertainPoint(overlay)); }
}
SetPerfectPos(points);
}
}
catch (Exception ex)
{
WriteLog(ex.Message);
XtraMessageBox.Show(ex.Message);
}
}
/// <summary>
/// 找到图层中的左上和右下的地理点
/// </summary>
/// <returns></returns>
private List<PointLatLng> SearchCertainPoint(GMapOverlay overlay)
{
GMap.NET.ObjectModel.ObservableCollectionThreadSafe<GMapMarker> markers = overlay.Markers;
var minlat = markers.Min(a => a.Position.Lat);
var maxlat = markers.Max(a => a.Position.Lat);
var minlng = markers.Min(a => a.Position.Lng);
var maxlng = markers.Max(a => a.Position.Lng);
PointLatLng lefttop = new PointLatLng(maxlat, minlng);
PointLatLng rightbottom = new PointLatLng(minlat, maxlng);
return new List<PointLatLng>() { lefttop, rightbottom };
}
#endregion
二、测距算法
原理:坐标系的转换和欧式距离的计算
#region 计算距离
private const double EARTH_RADIUS = 6378137.0;//地球赤道半径(单位:m。6378137m是1980年的标准,比1975年的标准6378140少3m)
/// <summary>
/// 角度数转换为弧度公式
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
private static double radians(double d)
{
return d * Math.PI / 180.0;
}
/// <summary>
/// 弧度转换为角度数公式
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
private static double degrees(double d)
{
return d * (180 / Math.PI);
}
/// <summary>
/// 计算两点之间的距离
/// 单位:米
/// </summary>
/// <param name="Degree1"></param>
/// <param name="Degree2"></param>
/// <returns></returns>
public static double GetDistance(PointLatLng PointLatLng1, PointLatLng PointLatLng2)
{
double radLat1 = radians(PointLatLng1.Lat);
double radLat2 = radians(PointLatLng2.Lat);
double a = radLat1 - radLat2;
double b = radians(PointLatLng1.Lng) - radians(PointLatLng2.Lng);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) +
Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
double CalcDistance(double fromX,double fromY,double toX,double toY)
{
double rad = 6371 * 1000; //Earth radius in m
double p1X = fromX / 180 * Math.PI;
double p1Y = fromY / 180 * Math.PI;
double p2X = toX / 180 * Math.PI;
double p2Y = toY / 180 * Math.PI;
double d = Math.Acos(Math.Sin(p1Y) * Math.Sin(p2Y) +
Math.Cos(p1Y) * Math.Cos(p2Y) * Math.Cos(p2X - p1X)) * rad;
return d;
}
public static double GetDistance(double lat1,double lng1, double lat2,double lng2)
{
double radLat1 = lat1 * Math.PI / 180;
double radLat2 = lat2 * Math.PI / 180;
double a = radLat1 - radLat2;
double b = lng1 * Math.PI / 180 - lng2 * Math.PI / 180;
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1)
* Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2)));
s = s * 6378137.0;// 取WGS84标准参考椭球中的地球长半径(单位:m)
s = Math.Round(s * 10000) / 10000;
return s;
}
/// <summary>
/// 计算两个经纬度之间的直接距离(google 算法)
/// </summary>
public static double GetDistanceGoogle(PointLatLng pointlatlng1, PointLatLng pointlatlng2)
{
double radLat1 = radians(pointlatlng1.Lat);
double radLng1 = radians(pointlatlng1.Lng);
double radLat2 = radians(pointlatlng2.Lat);
double radLng2 = radians(pointlatlng2.Lng);
double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
public static double GetDistanceGoogle(double Lat1,double Lng1,double Lat2,double Lng2)
{
double radLat1 = radians(Lat1);
double radLng1 = radians(Lng1);
double radLat2 = radians(Lat2);
double radLng2 = radians(Lng2);
double s = Math.Acos(Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Cos(radLng1 - radLng2) + Math.Sin(radLat1) * Math.Sin(radLat2));
s = s * EARTH_RADIUS;
s = Math.Round(s * 10000) / 10000;
return s;
}
/// <summary>
/// 以一个经纬度为中心计算出四个顶点
/// </summary>
/// <param name="Degree1">中心点</param>
/// <param name="distance">半径(米)</param>
/// <returns></returns>
public static PointLatLng[] GetDegreeCoordinates(PointLatLng pointlatlng, double distance)
{
double dlng = 2 * Math.Asin(Math.Sin(distance / (2 * EARTH_RADIUS)) / Math.Cos(pointlatlng.Lng));
dlng = degrees(dlng);//一定转换成角度数
double dlat = distance / EARTH_RADIUS;
dlat = degrees(dlat);//一定转换成角度数
return new PointLatLng[] { new PointLatLng( Math.Round(pointlatlng.Lat + dlat,6),Math.Round(pointlatlng.Lng - dlng,6)),//left-top
new PointLatLng(Math.Round(pointlatlng.Lat- dlat,6),Math.Round(pointlatlng.Lng - dlng,6)),//left-bottom
new PointLatLng( Math.Round(pointlatlng.Lat + dlat,6),Math.Round(pointlatlng.Lng + dlng,6)),//right-top
new PointLatLng(Math.Round(pointlatlng.Lat - dlat,6),Math.Round(pointlatlng.Lng + dlng,6)) //right-bottom
};
}
#endregion
三、查找周围点
#region 查找周围点操作
//度 转换成 弧度
public static double DegreesToRadians(double degrees)
{
const double degToRadFactor = Math.PI / 180;
return degrees * degToRadFactor;
}
//弧度 转换成 度
public static double RadiansToDegrees(double radians)
{
const double radToDegFactor = 180 / Math.PI;
return radians * radToDegFactor;
}
/**
* 求B点经纬度
* @param A 已知点的经纬度,
* @param distance AB两地的距离 单位km
* @param angle AB连线与正北方向的夹角(0~360)
* @return B点的经纬度
*/
public static MyLatLng getMyLatLng(MyLatLng A, double distance, double angle)
{
double dx = distance * 1000 * Math.Sin(DegreesToRadians(angle));
double dy = distance * 1000 * Math.Cos(DegreesToRadians(angle));
double bjd = (dx / A.Ed + A.m_RadLo) * 180 / Math.PI;
double bwd = (dy / A.Ec + A.m_RadLa) * 180 / Math.PI;
return new MyLatLng(bjd, bwd);
}
/**
* 求B点经纬度
* @param A 已知点的经纬度,
* @param distance AB两地的距离 单位m
* @param angle AB连线与正北方向的夹角(0~360)
* @return B点的经纬度
*/
public static MyLatLng getMyLatLng2(MyLatLng A, double distance, double angle)
{
double dx = distance * Math.Sin(DegreesToRadians(angle));
double dy = distance * Math.Cos(DegreesToRadians(angle));
double bjd = (dx / A.Ed + A.m_RadLo) * 180 / Math.PI;
double bwd = (dy / A.Ec + A.m_RadLa) * 180 / Math.PI;
return new MyLatLng(bjd, bwd);
}
//描述:以centerP为圆心,绘制半径为radius的圆
//gMapControl:Gmap控制器 overlay:图层
//centerP:圆心点 radius:圆半径(单位:m)
public static void DrawEllipse2(GMapControl gMapControl, GMapOverlay overlay, PointLatLng centerP, int radius)
{
try
{
if (radius <= 0)
return;
List<PointLatLng> latLngs = new List<PointLatLng>();
MyLatLng centerLatLng = new MyLatLng(centerP.Lng, centerP.Lat);
// 0 - 360度 寻找半径为radius,圆心为centerP的圆上点的经纬度
for (int i = 0; i < 360; i++)
{
//获取目标经纬度,单位为m
MyLatLng tempLatLng = getMyLatLng2(centerLatLng, radius, i);
//将自定义的经纬度类 转换成 标准经纬度类
PointLatLng p = new PointLatLng(tempLatLng.m_Latitude, tempLatLng.m_Longitude);
//通过绘制标记点的方式绘制圆
GMapMarker gMapMarker = new GMarkerGoogle(p, GMarkerGoogleType.red);
overlay.Markers.Add(gMapMarker);
}
}
catch (Exception ex)
{
WriteLog(ex.Message);
}
}
//描述:以centerP为圆心,绘制半径为radius的圆
//gMapControl:Gmap控制器 overlay:图层
//centerP:圆心点 radius:圆半径(单位: km) name:多边形id
public static void DrawEllipse2(GMapControl gMapControl, GMapOverlay overlay, PointLatLng centerP, int radius, string name)
{
try
{
if (radius <= 0)
return;
List<PointLatLng> latLngs = new List<PointLatLng>();
MyLatLng centerLatLng = new MyLatLng(centerP.Lng, centerP.Lat);
// 0 - 360度 寻找半径为radius,圆心为centerP的圆上点的经纬度
for (int i = 0; i < 360; i++)
{
//获取目标经纬度
MyLatLng tempLatLng = getMyLatLng2(centerLatLng, radius, i);
//将自定义的经纬度类 转换成 标准经纬度类
PointLatLng p = new PointLatLng(tempLatLng.m_Latitude, tempLatLng.m_Longitude);
latLngs.Add(p);
}
//安全性检查
if (latLngs.Count < 20)
{
return;
}
//通过绘制多边形的方式绘制圆
GMapPolygon gpol = new GMapPolygon(latLngs, name);
gpol.Stroke = new Pen(System.Drawing.Color.Red, 1.0f);
gpol.Fill = new SolidBrush(System.Drawing.Color.FromArgb(20, System.Drawing.Color.Red));
gpol.IsHitTestVisible = true;
overlay.Polygons.Add(gpol);
}
catch (Exception ex)
{
WriteLog(ex.Message);
}
}
//描述:以centerP为圆心,绘制半径为radius的圆
//gMapControl:Gmap控制器 overlay:图层
//centerP:圆心点 radius:圆半径(单位: km) name:多边形id
public static void DrawEllipse2(GMapControl gMapControl, GMapOverlay overlay, PointLatLng centerP, double radius, string name)
{
try
{
if (radius <= 0)
return;
List<PointLatLng> latLngs = new List<PointLatLng>();
MyLatLng centerLatLng = new MyLatLng(centerP.Lng, centerP.Lat);
// 0 - 360度 寻找半径为radius,圆心为centerP的圆上点的经纬度
for (int i = 0; i < 360; i++)
{
//获取目标经纬度
MyLatLng tempLatLng = getMyLatLng2(centerLatLng, radius, i);
//将自定义的经纬度类 转换成 标准经纬度类
PointLatLng p = new PointLatLng(tempLatLng.m_Latitude, tempLatLng.m_Longitude);
latLngs.Add(p);
}
//安全性检查
if (latLngs.Count < 20)
{
return;
}
//通过绘制多边形的方式绘制圆
GMapPolygon gpol = new GMapPolygon(latLngs, name);
gpol.Stroke = new Pen(System.Drawing.Color.Red, 1.0f);
gpol.Fill = new SolidBrush(System.Drawing.Color.FromArgb(20, System.Drawing.Color.Red));
gpol.IsHitTestVisible = true;
overlay.Polygons.Add(gpol);
}
catch (Exception ex)
{
WriteLog(ex.Message);
}
}
private void btnSearch_Click(object sender, EventArgs e)
{
try
{
currentOverlay.Polygons.Clear();
searchResultCombox.Properties.Items.Clear();
string s = txt_centerPos.Text.Trim();
double radius = Convert.ToDouble(txt_Radius.EditValue);
string[] centerlatlng = s.Split(new char[] { ',', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
PointLatLng centerP = new PointLatLng(Convert.ToDouble(centerlatlng[1]), Convert.ToDouble(centerlatlng[0]));
DrawEllipse2(this.gmap, currentOverlay, centerP, radius, "Circle");
foreach (GMapOverlay o in this.gmap.Overlays)
{
string oname = o.Id;
foreach (GMapMarker m in o.Markers)
{
bool flag = isInsidePolygon(m.Position, centerP, radius);
if (flag)
{
string ss = string.Format("{0},{1},{2},{3}", oname, m.ToolTipText.Substring(0, m.ToolTipText.LastIndexOf(':')), m.Position.Lng, m.Position.Lat);
searchResultCombox.Properties.Items.Add(ss);
}
}
}
}
catch (Exception ex)
{
XtraMessageBox.Show(ex.Message);
WriteLog(ex.Message);
}
}
private bool isInsidePolygon(PointLatLng p, PointLatLng centerP, double radius)
{
bool flag = false;
double length = GetDistance(p, centerP);
if (0 < length && length <= radius)
{
flag = true;
}
return flag;
}
private void btnClearResult_Click(object sender, EventArgs e)
{
txt_centerPos.EditValue = null;
txt_Radius.Text = null;
searchResultCombox.Properties.Items.Clear();
searchResultCombox.Text = null;
if (this.gmap.Overlays.Count != 0)
{
foreach (GMapOverlay o in this.gmap.Overlays)
{
if (o.Polygons.Count != 0)
{
o.Polygons.Clear();
}
}
}
}
#endregion
四、GPS纠偏算法
#region GPS纠偏算法
/**
* gps纠偏算法,适用于google,高德体系的地图
*/
//public static double pi = 3.1415926535897932384626;
public static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
public static double a = 6378245.0;
public static double ee = 0.00669342162296594323;
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;
}
/// <summary>
/// 纠偏GCJ02之后
/// </summary>
/// <param name="lat">WGS84下纬度</param>
/// <param name="lon">WGS84下经度</param>
/// <returns>double[0]=lat,double[1]=lng</returns>
public static double[] transform(double lat, double lon)
{
if (outOfChina(lat, lon))
{
return new double[] { 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 * 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 double[] { mgLat, mgLon };
}
public 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;
}
/**
* 84 to 火星坐标系 (GCJ-02) World Geodetic System ==> Mars Geodetic System
*
* @param lat
* @param lon
* @return
*/
public static double[] gps84_To_Gcj02(double lat, double lon)
{
if (outOfChina(lat, lon))
{
return new double[] { 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 * 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 double[] { mgLat, mgLon };
}
/**
* * 火星坐标系 (GCJ-02) to 84 * * @param lon * @param lat * @return
* */
public static double[] gcj02_To_Gps84(double lat, double lon)
{
double[] gps = transform(lat, lon);
double lontitude = lon * 2 - gps[1];
double latitude = lat * 2 - gps[0];
return new double[] { latitude, lontitude };
}
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 将 GCJ-02 坐标转换成 BD-09 坐标
*
* @param lat
* @param lon
*/
public static double[] gcj02_To_Bd09(double lat, double lon)
{
double x = lon, y = 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 tempLon = z * Math.Cos(theta) + 0.0065;
double tempLat = z * Math.Sin(theta) + 0.006;
double[] gps = { tempLat, tempLon };
return gps;
}
/**
* * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换算法 * * 将 BD-09 坐标转换成GCJ-02 坐标 * * @param
* bd_lat * @param bd_lon * @return
*/
public static double[] bd09_To_Gcj02(double lat, double lon)
{
double x = lon - 0.0065, y = 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 tempLon = z * Math.Cos(theta);
double tempLat = z * Math.Sin(theta);
double[] gps = { tempLat, tempLon };
return gps;
}
/**将gps84转为bd09
* @param lat
* @param lon
* @return
*/
public static double[] gps84_To_bd09(double lat, double lon)
{
double[] gcj02 = gps84_To_Gcj02(lat, lon);
double[] bd09 = gcj02_To_Bd09(gcj02[0], gcj02[1]);
return bd09;
}
public static double[] bd09_To_gps84(double lat, double lon)
{
double[] gcj02 = bd09_To_Gcj02(lat, lon);
double[] gps84 = gcj02_To_Gps84(gcj02[0], gcj02[1]);
//保留小数点后六位
gps84[0] = retain6(gps84[0]);
gps84[1] = retain6(gps84[1]);
return gps84;
}
/**保留小数点后六位
* @param num
* @return
*/
private static double retain6(double num)
{
string result = String.Format("%.6f", num);
return Convert.ToDouble(result);
}
#endregion