我正在尝试使用WPF UI中的DrawingGroup
绘制一些项目,代码看起来有点像这样:
foreach( var path in allRoads )
{
var wpfPen = new Pen(brush, penSize);
GeometryDrawing geometry = new GeometryDrawing();
geometry.Pen = wpfPen;
geometry.Geometry = GetPathGeometry(path);
drawingGroup.Children.Add(geometry);
}
当我绘制我正在渲染的各种几何项目时,我会反复调用它(我将它们添加到DrawingGroup
然后要求DrawingContext
之后绘制它)但它会遇到麻烦并崩溃输出以下消息:
线程0x3228已退出,代码为0(0x0)。抛出异常: PresentationCore.dll中的“System.OverflowException”未处理 发生在'System.OverflowException'类型的异常 PresentationCore.dll图像数据在生成期间产生溢出 处理
崩溃似乎发生在第38000个几何项目(所有这些多点路径,有些可能很长,因为这是GIS数据)被添加到DrawingGroup.Children
集合中。
我猜这可能会推动系统超越它的设计目标 - 在WPF中有更好的方法来处理这个问题吗?它可以处理大量的几何数据,如果没有,下落就是限制吗?
答案 0 :(得分:1)
在尝试渲染点之前,您可以使用Non-parametric Ramer-Douglas-Peucker算法简化点的集合。这将保持相同的基本形状,但大大减少细节(在您正在谈论的缩放级别甚至可以看到的细节)。
来自维基百科的伪代码:
function DouglasPeucker(PointList[], epsilon)
// Find the point with the maximum distance
dmax = 0
index = 0
end = length(PointList)
for i = 2 to ( end - 1) {
d = perpendicularDistance(PointList[i], Line(PointList[1], PointList[end]))
if ( d > dmax ) {
index = i
dmax = d
}
}
// If max distance is greater than epsilon, recursively simplify
if ( dmax > epsilon ) {
// Recursive call
recResults1[] = DouglasPeucker(PointList[1...index], epsilon)
recResults2[] = DouglasPeucker(PointList[index...end], epsilon)
// Build the result list
ResultList[] = {recResults1[1...length(recResults1)-1], recResults2[1...length(recResults2)]}
} else {
ResultList[] = {PointList[1], PointList[end]}
}
// Return the result
return ResultList[]
end
以下是C# implementation的链接。
您可以根据缩放级别动态调整epsilon
值,无论您缩放的距离有多近,都可以保持正确。