0

我正在实施 ZoomableCanvas http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx

它是一个 WPF 控件,允许在画布中虚拟化显示对象。为了利用虚拟化,该库要求您在数据源对象上实现一个名为“查询”的方法。Query 方法在给定 Rect 的情况下延迟返回 IEnumerable<int>,其中 int 表示元素在数据源中的位置,Rect 是画布的可见区域(画布中不可见的项目不返回,因此不绘制) . 我的数据源已排序,以便对 X 和 Y 值进行排序(myList[0] 将包含最小的 X,Y 坐标)

鉴于此信息,我可以简单地执行以下操作来获取我的物品

int c = this.Count;

for (int j = 0; j < c; j++)
{
    if (rectangle.Contains(new Point(this[j].left, this[j].top)))
    {
       yield return (int)j;
    }
}

但是,我们正在遍历整个列表,并且列表中有 100k+ 项。这表现得非常糟糕,尤其是在查看画布的右下角时,因为这些项目位于列表的末尾。

所以我尝试转置数据,以便我可以在画布上的可见区域中获取点,并准确知道数组中对应的索引。

        var tilewidth = MapWidthInTiles;

        for (var x = Math.Max(left, 0); x <= right; x++)
        {
            for (var y = Math.Max(top, 0); y <= bottom; y++)
            {

                var i = (y * tilewidth) + x;

                if (i < Count)
                {
                    yield return (int)i;
                }
            }
        }

除了我的数据集不规则(我正在绘制地图)之外,此方法有效,因为地图可能缺少或不完整的“图块”。因此,我的阵列基本上是锯齿状的。锯齿状数据集缺少“瓦片”的插图

基本上,我正在寻找一种方法,可以快速识别一维数组中给定二维几何的元素,其中二维数组中的元素可能不完整或不连续。通常 [y * widthOfAllItems] + x 会给我正确的 2d -> 1d 转置。但由于缺少元素,等式不成立。任何帮助表示赞赏!

4

1 回答 1

0

您不需要将您的项目存储在一维数组中,您需要将它们返回到一维数组中的 ZoomableCanvas。因此,请随意以您能想到的最有效的方式存储它们。
QuadTree 可能是存储您的点的一种解决方案:一棵树,其中每个节点有 4 个子节点 NE、SE、SW、NW,(NE=North-East,...)每个节点要么是空的,要么用一种颜色填充,要么有4个孩子也。另一种解决方案:使用岛屿作为基础对象,使用边界框更快......也许将岛屿存储在树中。

于 2012-07-16T09:25:30.703 回答