我正在实施ZoomableCanvas http://blogs.msdn.com/b/kaelr/archive/2010/08/11/zoomableapplication2-a-million-items.aspx
它是一个WPF控件,允许在画布中虚拟显示对象。要利用虚拟化,库需要您在数据源对象上实现一个名为“Query”的方法。 Query方法懒惰地返回IEnumerable< int>给定一个Rect,其中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 - &gt; 1d换位。但由于缺少元素,方程式关闭。任何帮助表示赞赏!
答案 0 :(得分:0)
您无需在1D数组中存储项目,您需要将它们返回到1D数组中的ZoomableCanvas。因此,请随意以您能想到的最有效的方式存储它们 QuadTree可能是一个存储点的解决方案:一个树,每个节点有4个子节点NE,SE,SW,NW,(NE =东北,......)每个节点都是空的,填充一种颜色,或者有还有4个孩子。 另一种解决方案:使用岛屿作为基础对象,使用边界框更快......并且可以将岛屿存储在树中。