You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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像素空间:

  1. 计算地图范围的Lambert极值:用你的经纬度范围(经度-130°-65°,纬度25°50°)调用LatLonToLambertXY,得到Xmin, Xmax, Ymin, Ymax
  2. 计算缩放比例:
    const double canvasWidth = 3960;
    const double canvasHeight = 2452;
    double scaleX = canvasWidth / (Xmax - Xmin);
    double scaleY = canvasHeight / (Ymax - Ymin);
    
  3. 转换为像素坐标:
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 20:14:52