我有一个使用 WinForms 的旧版地图查看器应用程序。太慢了。(过去速度可以接受,但谷歌地图、谷歌地球出现了,用户被宠坏了。现在我可以让速度更快了:)
在进行了所有明显的速度改进(缓存、并行执行、不绘制不需要绘制的内容等)之后,我的分析器向我展示了真正的瓶颈是在将点从地图空间转换到屏幕空间时的坐标转换. 通常转换代码如下所示:
public Point MapToScreen(PointF input)
{
// Note that North is negative!
var result = new Point(
(int)((input.X - this.currentView.X) * this.Scale),
(int)((input.Y - this.currentView.Y) * this.Scale));
return result;
}
真正的实现更棘手。纬度/经度以整数表示。为避免丢失精度,它们乘以 2^20(约 100 万)。这就是坐标的表示方式。
public struct Position
{
public const int PrecisionCompensationPower = 20;
public const int PrecisionCompensationScale = 1048576; // 2^20
public readonly int LatitudeInt; // North is negative!
public readonly int LongitudeInt;
}
重要的是,可能的比例因子也明确地绑定到 2 的幂。这允许我们用位移替换乘法。所以真正的算法是这样的:
public Point MapToScreen(Position input)
{
Point result = new Point();
result.X = (input.LongitudeInt - this.UpperLeftPosition.LongitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
result.Y = (input.LatitudeInt - this.UpperLeftPosition.LatitudeInt) >>
(Position.PrecisionCompensationPower - this.ZoomLevel);
return result;
}
(UpperLeftPosition 代表地图空间中屏幕的左上角。) 我现在正在考虑将这个计算卸载到 GPU上。谁能告诉我一个例子如何做到这一点?
我们使用 .NET4.0,但代码也最好在 Windows XP 上运行。此外,我们不能使用 GPL 下的库。