WPF中Lambert正形圆锥投影经纬度转像素坐标问题求助
WPF Lambert投影Y坐标方向反转问题解决
核心原因
WPF Canvas采用左上角为原点,Y轴向下递增的坐标系,而你实现的Lambert正形圆锥投影输出的Y轴是向上递增(纬度越高Y值越大),二者方向完全相反,这就是点位Y坐标颠倒的直接原因。
分步解决方案
1. 修正Lambert投影的Y轴方向
直接调整LatLonToLambertXY方法中的Y值计算逻辑,反转Y轴方向以匹配WPF坐标系:
public void LatLonToLambertXY(double latitude, double longitude, out double x, out double y) { latitude = this.DegreesToRadians(latitude); longitude = this.DegreesToRadians(longitude); double t = 1 / Math.Tan(Math.PI / 4 - latitude / 2) / Math.Pow((1 - Math.Sqrt(eccentricity) * Math.Sin(latitude)) / (1 + Math.Sqrt(eccentricity) * Math.Sin(latitude)), Math.Sqrt(eccentricity) / 2); rho = earthRadius * F * Math.Pow(t, n); double theta = n * (longitude - originLongitude); double lambertX = rho * Math.Sin(theta); // 反转Y轴方向,对齐WPF坐标系规则 double lambertY = rho * Math.Cos(theta) - rho0; x = lambertX; y = lambertY; }
2. 修复代码中的硬编码不一致问题
你的构造函数存在变量与硬编码混用的问题,统一替换为WGS84椭球的标准参数:
// 类级别常量:WGS84椭球参数 private const double eccentricity = 0.0818191908426; // 第一偏心率e private const double earthRadius = 6378137; // 椭球长半轴
然后修正构造函数中t2、t0的硬编码部分,同时去掉重复的弧度转换:
double t2 = Math.Tan(Math.PI / 4 - this.standardParallel2 / 2) / Math.Pow((1 - Math.Sqrt(eccentricity) * Math.Sin(this.standardParallel2)) / (1 + Math.Sqrt(eccentricity) * Math.Sin(this.standardParallel2)), Math.Sqrt(eccentricity) / 2); double t0 = Math.Tan(Math.PI / 4 - this.originLatitude / 2) / Math.Pow((1 - Math.Sqrt(eccentricity) * Math.Sin(this.originLatitude)) / (1 + Math.Sqrt(eccentricity) * Math.Sin(this.originLatitude)), Math.Sqrt(eccentricity) / 2);
3. Lambert坐标转Canvas像素坐标
完成投影转换后,将地理坐标映射到Canvas像素空间:
- 计算地图范围的Lambert极值:用你的经纬度范围(经度-130°-65°,纬度25°50°)调用
LatLonToLambertXY,得到Xmin, Xmax, Ymin, Ymax - 计算缩放比例:
const double canvasWidth = 3960; const double canvasHeight = 2452; double scaleX = canvasWidth / (Xmax - Xmin); double scaleY = canvasHeight / (Ymax - Ymin); - 转换为像素坐标:
得到的double pixelX = (lambertX - Xmin) * scaleX; double pixelY = (lambertY - Ymin) * scaleY;pixelX,pixelY可直接用于Canvas绘制。
验证测试
用原点经纬度(39°N,-90°W)测试:
- 转换后的Lambert坐标应为
(0, 0) - 映射到Canvas后应为
(1980, 1226)(画布中心),确认点位位置正确。
内容的提问来源于stack exchange,提问作者Jarda
相关产品推荐
相关产品推荐

