第10章-坐标系统与投影转换
第10章:坐标系统与投影转换
10.1 坐标系统基础
10.1.1 常用坐标系统
| EPSG | 名称 | 类型 | 用途 |
|---|---|---|---|
| 4326 | WGS84 | 地理坐标系 | GPS、通用经纬度 |
| 3857 | Web Mercator | 投影坐标系 | 网络地图 |
| 4490 | CGCS2000 | 地理坐标系 | 中国国家标准 |
| 4547 | CGCS2000 / 3度带 | 投影坐标系 | 中国大比例尺测绘 |
10.1.2 WKT 格式
// WGS84 WKT
string wgs84Wkt = @"
GEOGCS[""WGS 84"",
DATUM[""WGS_1984"",
SPHEROID[""WGS 84"",6378137,298.257223563]],
PRIMEM[""Greenwich"",0],
UNIT[""degree"",0.0174532925199433]]";
// Web Mercator WKT
string webMercatorWkt = @"
PROJCS[""WGS 84 / Pseudo-Mercator"",
GEOGCS[""WGS 84"",
DATUM[""WGS_1984"",
SPHEROID[""WGS 84"",6378137,298.257223563]],
PRIMEM[""Greenwich"",0],
UNIT[""degree"",0.0174532925199433]],
PROJECTION[""Mercator_1SP""],
PARAMETER[""central_meridian"",0],
PARAMETER[""scale_factor"",1],
PARAMETER[""false_easting"",0],
PARAMETER[""false_northing"",0],
UNIT[""metre"",1]]";
10.2 ProjNet 使用
10.2.1 安装配置
Install-Package ProjNet
10.2.2 创建坐标系统
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
var csFactory = new CoordinateSystemFactory();
var ctFactory = new CoordinateTransformationFactory();
// 从 WKT 创建
var wgs84 = csFactory.CreateFromWkt(wgs84Wkt);
// 使用预定义
var wgs84_2 = GeographicCoordinateSystem.WGS84;
// 创建投影坐标系
var webMercator = csFactory.CreateFromWkt(webMercatorWkt);
10.2.3 坐标转换
// 创建转换
var wgs84ToMercator = ctFactory.CreateFromCoordinateSystems(wgs84, webMercator);
var mercatorToWgs84 = ctFactory.CreateFromCoordinateSystems(webMercator, wgs84);
// 转换单个坐标
double[] input = { 116.4, 39.9 }; // 经度, 纬度
double[] output = wgs84ToMercator.MathTransform.Transform(input);
Console.WriteLine($"Mercator: {output[0]}, {output[1]}");
// 批量转换
double[] coords = { 116.4, 39.9, 121.5, 31.2, 113.3, 23.1 };
double[] transformed = new double[coords.Length];
wgs84ToMercator.MathTransform.Transform(coords, 0, transformed, 0, 3);
10.2.4 应用到图层
// 设置图层坐标转换
vectorLayer.CoordinateTransformation = wgs84ToMercator;
vectorLayer.ReverseCoordinateTransformation = mercatorToWgs84;
// 或者转换整个数据源
public static Geometry TransformGeometry(Geometry geometry,
ICoordinateTransformation transformation)
{
var transformed = geometry.Copy();
TransformCoordinates(transformed, transformation.MathTransform);
return transformed;
}
private static void TransformCoordinates(Geometry geometry, IMathTransform transform)
{
foreach (var coord in geometry.Coordinates)
{
var result = transform.Transform(new[] { coord.X, coord.Y });
coord.X = result[0];
coord.Y = result[1];
}
}
10.3 CGCS2000 坐标系
10.3.1 CGCS2000 定义
// CGCS2000 地理坐标系
string cgcs2000Wkt = @"
GEOGCS[""China Geodetic Coordinate System 2000"",
DATUM[""China_2000"",
SPHEROID[""CGCS2000"",6378137,298.257222101]],
PRIMEM[""Greenwich"",0],
UNIT[""degree"",0.0174532925199433]]";
// CGCS2000 / 3度带 (以 117度为中央经线)
string cgcs2000_3degreeWkt = @"
PROJCS[""CGCS2000 / 3-degree Gauss-Kruger zone 39"",
GEOGCS[""China Geodetic Coordinate System 2000"",
DATUM[""China_2000"",
SPHEROID[""CGCS2000"",6378137,298.257222101]],
PRIMEM[""Greenwich"",0],
UNIT[""degree"",0.0174532925199433]],
PROJECTION[""Transverse_Mercator""],
PARAMETER[""latitude_of_origin"",0],
PARAMETER[""central_meridian"",117],
PARAMETER[""scale_factor"",1],
PARAMETER[""false_easting"",39500000],
PARAMETER[""false_northing"",0],
UNIT[""metre"",1]]";
10.3.2 CGCS2000 转换
public class Cgcs2000Helper
{
private readonly CoordinateSystemFactory _csFactory;
private readonly CoordinateTransformationFactory _ctFactory;
public Cgcs2000Helper()
{
_csFactory = new CoordinateSystemFactory();
_ctFactory = new CoordinateTransformationFactory();
}
// WGS84 转 CGCS2000(两者差异很小,通常可直接使用)
public Coordinate Wgs84ToCgcs2000(Coordinate point)
{
// WGS84 和 CGCS2000 椭球参数几乎相同
// 在厘米级精度下可直接使用
return point;
}
// CGCS2000 地理坐标转投影坐标
public Coordinate Cgcs2000ToProjected(Coordinate point, int centralMeridian)
{
var geoCS = _csFactory.CreateFromWkt(GetCgcs2000GeographicWkt());
var projCS = _csFactory.CreateFromWkt(GetCgcs2000ProjectedWkt(centralMeridian));
var transform = _ctFactory.CreateFromCoordinateSystems(geoCS, projCS);
var result = transform.MathTransform.Transform(new[] { point.X, point.Y });
return new Coordinate(result[0], result[1]);
}
// 根据经度自动选择带号
public int GetZoneNumber(double longitude)
{
return (int)Math.Floor((longitude + 1.5) / 3);
}
private string GetCgcs2000GeographicWkt() => cgcs2000Wkt;
private string GetCgcs2000ProjectedWkt(int centralMeridian)
{
int zoneNumber = (centralMeridian + 3) / 3;
return $@"
PROJCS[""CGCS2000 / 3-degree Gauss-Kruger zone {zoneNumber}"",
GEOGCS[""China Geodetic Coordinate System 2000"",
DATUM[""China_2000"",
SPHEROID[""CGCS2000"",6378137,298.257222101]],
PRIMEM[""Greenwich"",0],
UNIT[""degree"",0.0174532925199433]],
PROJECTION[""Transverse_Mercator""],
PARAMETER[""latitude_of_origin"",0],
PARAMETER[""central_meridian"",{centralMeridian}],
PARAMETER[""scale_factor"",1],
PARAMETER[""false_easting"",{zoneNumber * 1000000 + 500000}],
PARAMETER[""false_northing"",0],
UNIT[""metre"",1]]";
}
}
10.4 坐标转换工具类
10.4.1 通用转换器
public class CoordinateTransformService
{
private readonly Dictionary<string, ICoordinateSystem> _coordinateSystems;
private readonly CoordinateSystemFactory _csFactory;
private readonly CoordinateTransformationFactory _ctFactory;
public CoordinateTransformService()
{
_csFactory = new CoordinateSystemFactory();
_ctFactory = new CoordinateTransformationFactory();
_coordinateSystems = new Dictionary<string, ICoordinateSystem>();
InitializeCommonCoordinateSystems();
}
private void InitializeCommonCoordinateSystems()
{
_coordinateSystems["EPSG:4326"] = GeographicCoordinateSystem.WGS84;
_coordinateSystems["EPSG:3857"] = CreateWebMercator();
// 添加更多...
}
public void RegisterCoordinateSystem(string code, string wkt)
{
_coordinateSystems[code] = _csFactory.CreateFromWkt(wkt);
}
public Coordinate Transform(Coordinate point, string sourceCode, string targetCode)
{
var sourceCS = _coordinateSystems[sourceCode];
var targetCS = _coordinateSystems[targetCode];
var transform = _ctFactory.CreateFromCoordinateSystems(sourceCS, targetCS);
var result = transform.MathTransform.Transform(new[] { point.X, point.Y });
return new Coordinate(result[0], result[1]);
}
public IEnumerable<Coordinate> TransformAll(IEnumerable<Coordinate> points,
string sourceCode, string targetCode)
{
var sourceCS = _coordinateSystems[sourceCode];
var targetCS = _coordinateSystems[targetCode];
var transform = _ctFactory.CreateFromCoordinateSystems(sourceCS, targetCS);
return points.Select(p =>
{
var result = transform.MathTransform.Transform(new[] { p.X, p.Y });
return new Coordinate(result[0], result[1]);
});
}
}
10.5 与地图集成
10.5.1 动态投影
public class ProjectedMapManager
{
private readonly Map _map;
private readonly CoordinateTransformService _transformService;
private string _currentProjection = "EPSG:3857";
public ProjectedMapManager(Map map)
{
_map = map;
_transformService = new CoordinateTransformService();
}
public void SetProjection(string projectionCode)
{
if (_currentProjection == projectionCode)
return;
// 更新所有图层的坐标转换
foreach (var layer in _map.Layers.OfType<VectorLayer>())
{
UpdateLayerTransformation(layer, projectionCode);
}
_currentProjection = projectionCode;
}
private void UpdateLayerTransformation(VectorLayer layer, string targetProjection)
{
// 假设数据源坐标系为 WGS84
string sourceProjection = "EPSG:4326";
// ... 设置坐标转换
}
}
10.6 本章小结
本章介绍了 SharpMap 的坐标系统与投影转换:
- 坐标系基础:了解了常用坐标系和 WKT 格式
- ProjNet 使用:掌握了坐标转换的基本方法
- CGCS2000:学习了中国坐标系的处理
- 工具类实现:了解了通用转换器的设计
下一章预告:第11章将介绍空间查询与分析功能。

浙公网安备 33010602011771号