GDAL3.0下C#使用OSR库进行坐标转换,测试下精度还不错。
辛辛苦苦自己写了好久的不同参考系下坐标转换的自定义库,突然想起来GDAL好像有自带的,于是便测试了一下,如果能够自己完全弄懂坐标转换中的公式,对于大批量的数据可能还是自己写的更稳定并且更容易操作,也能随意控制精度。但对于单点的转换,明显使用OSR库明显就更为方便了。
1.以下代码展示使用EPSG来创建投影坐标系,并进行同椭球下的投影坐标系和地理坐标系之间的相互转换。
EPSG大地测量参数数据集是由EPSG组织定义的坐标参考系统和坐标转换的结构化数据集,现由IOGP地理信息委员会的大地测量小组委员会维护。不同的EPSG编号能代表不同的坐标系统、椭球体、大地水准面等等。
可以通过网址:epsg.io查询不同坐标系的EPSG代号,或查询EPSG代号的含义,还可在该页面查询EPSG坐标系的WKT文本或者Proj.4表示。
#region 同椭球下进行坐标转换
//spatialReference.ImportFromEPSG(4326);//WGS84
//spatialReference.ImportFromEPSG(4214);//BeiJing54
//spatialReference.ImportFromEPSG(4610);//XIAN80
//spatialReference.ImportFromEPSG(4490);//CGCS2000
SpatialReference Xian_80 = new SpatialReference("");
Xian_80.ImportFromEPSG(4610); //4610代号为西安80坐标系
Xian_80.SetTM(0, 117, 1.0, 39500000, 0);//设置Xian80坐标系,3度带带号39的横轴墨卡托投影
string wkt;
Xian_80.ExportToWkt(out wkt, null);
Console.WriteLine("Coordinate System is:");
Console.WriteLine(wkt);
Console.WriteLine("DEST IsGeographic:" + Xian_80.IsGeographic() + " IsProjected:" + Xian_80.IsProjected());
// 获取该投影坐标系统中的地理坐标系统
SpatialReference xian = Xian_80.CloneGeogCS();
xian.ExportToWkt(out wkt, null);
Console.WriteLine("Coordinate System is:");
Console.WriteLine(wkt);
Console.WriteLine("DEST IsGeographic:" + xian.IsGeographic() + " IsProjected:" + xian.IsProjected());
//投影坐标系转换到地理坐标系
CoordinateTransformation coordinateTransformation = new CoordinateTransformation(Xian_80, xian);
if (coordinateTransformation == null)
{
Console.WriteLine("创建坐标转换关系失败!\n");
return;
}
///转换方式为单点
double[] p = new double[3] { 39464667.861, 4441766.356, 0 };
Console.WriteLine("平面坐标:X:" + p[1] + " Y:" + p[0]);
coordinateTransformation.TransformPoint(p);
Console.WriteLine("经纬度坐标:B:" + p[0] + " L: " + p[1]);
//地理坐标系转换到投影坐标系
CoordinateTransformation coordinateTransformation1 = new CoordinateTransformation(xian, Xian_80);
if (coordinateTransformation == null)
{
Console.WriteLine("创建坐标转换关系失败!\n");
return;
}
///转换方式为多点
double[] B = { 40.109450692 };
double[] L = { 116.585583357 };
double[] H = { 0 };
coordinateTransformation1.TransformPoints(1, B, L, H);
Console.WriteLine("平面坐标:X:" + L[0] + " Y:" + B[0]);
#endregion
2.以下代码展示使用EPSG来创建投影坐标系,并进行不同椭球下的投影坐标系和地理坐标系之间的相互转换。
#region 不同椭球下进行坐标转换
SpatialReference CGCS2000 = new SpatialReference("");
CGCS2000.ImportFromEPSG(4490);//CGCS2000
CGCS2000.SetTM(0, 117, 1.0, 39500000, 0); //CGCS2000,3度带带号39的横轴墨卡托投影投影坐标系
//Xian_80,3度带带号39的横轴墨卡托投影投影坐标系
//转换到CGCS2000,3度带带号39的横轴墨卡托投影投影坐标系
CoordinateTransformation coordinateTransformation2 = new CoordinateTransformation(Xian_80, CGCS2000);
if (coordinateTransformation == null)
{
Console.WriteLine("创建坐标转换关系失败!\n");
return;
}
///转换方式为单点
p = new double[3] { 39464667.861, 4441766.356, 0 };
Console.WriteLine("Xian_80平面坐标:X:" + p[1] + " Y:" + p[0]);
coordinateTransformation2.TransformPoint(p);
Console.WriteLine("CGCS2000平面坐标:X:" + p[1] + " Y:" + p[0]);
SpatialReference BeiJing54 = new SpatialReference("");
BeiJing54.ImportFromEPSG(4214);//BeiJing54
BeiJing54.SetTM(0, 117, 1.0, 39500000, 0); //BeiJing54,3度带带号39的横轴墨卡托投影投影坐标系
//Xian_80,3度带带号39的横轴墨卡托投影投影坐标系
//转换到BeiJing54,3度带带号39的横轴墨卡托投影投影坐标系
CoordinateTransformation coordinateTransformation3 = new CoordinateTransformation(Xian_80, BeiJing54);
if (coordinateTransformation == null)
{
Console.WriteLine("创建坐标转换关系失败!\n");
return;
}
///转换方式为单点
p = new double[3] { 39464667.861, 4441766.356, 0 };
Console.WriteLine("Xian_80平面坐标:X:" + p[1] + " Y:" + p[0]);
coordinateTransformation3.TransformPoint(p);
Console.WriteLine("BeiJing54平面坐标:X:" + p[1] + " Y:" + p[0]);
//WGS84
SpatialReference WGS84 = new SpatialReference("");
WGS84.ImportFromEPSG(4326);//WGS84
WGS84.SetTM(0, 117, 1.0, 39500000, 0); //WGS84,3度带带号39的横轴墨卡托投影投影坐标系
SpatialReference WGS84GEO = new SpatialReference("");
WGS84GEO = WGS84.CloneGeogCS();// 获取该投影坐标系统中的地理坐标系统
//Xian_80,3度带带号39的横轴墨卡托投影投影坐标系
//转换到WGS84,3度带带号39的横轴墨卡托投影投影坐标系
CoordinateTransformation coordinateTransformation4 = new CoordinateTransformation(Xian_80, WGS84GEO);
if (coordinateTransformation == null)
{
Console.WriteLine("创建坐标转换关系失败!\n");
return;
}
///转换方式为单点
p = new double[3] { 39464667.861, 4441766.356, 0 };
Console.WriteLine("Xian_80平面坐标:X:" + p[1] + " Y:" + p[0]);
coordinateTransformation4.TransformPoint(p);
Console.WriteLine("WGS84经纬度坐标:B:" + p[0] + " L: " + p[1]);
#endregion