我有一个使用Bing Maps的Silverlight应用。我需要在地球表面显示约10,000个标记。这些标记是简单的Path
个实例,大多数都是相同的形状,尽管它们具有不同的旋转,通过RotateTransform
应用。
目前,性能约为6 FPS。我已经尝试了各种方法来改善这种情况,但没有比这更好的了。
逻辑树类似于:
<Map>
<MapLayer>
<Path ... />
<Path ... />
<Path ... /> <!-- and so on, several thousand times -->
然而,以编程方式添加Path
个实例。他们的位置是通过绑定建立的,虽然这些绑定在平移期间不会触发,因此不应该导致我看到的问题。
var path = new Path { /* ... */ };
path.SetBinding(MapLayer.PositionProperty, new Binding("Location")
{
Source = asset,
Mode = BindingMode.OneWay
});
我尝试为MapLayer
启用GPU加速和位图缓存,并通过观察Process Explorer中的GPU统计信息以及在Silverlight主机中启用FPS计数器/缓存重叠来验证这是否已正确启用。这对FPS几乎没有影响。即使这确实有帮助,也不可能将位图缓存高于某个阈值(2048像素的方块?),因此当您放大一点时,它会回退到软件渲染。
使用dotTrace CPU分析器进一步挖掘,似乎限制因素是重复调用Measure
/ Arrange
。我怀疑这是因为当地图左边的孩子滚动到左边足够远时,他们环绕地球并被移动到最右边(反之亦然),这会导致布局失效,以及任何位图缓存。我认为没有一种简单的方法可以支付这笔罚款。
有没有其他人遇到过这个问题,理想情况下找到了探索的途径?
要尝试的一些随机想法:
MapLayerBase
而不是MapLayer
导出并自行实施布局算法,绕过MapLayer.PositionProperty
依赖项属性并完全支持IProjectable
。MapItemsControl
代替MapLayer
进行调查。答案 0 :(得分:4)
要加快基本的平移和缩放操作,您可以通过继承MapLayer并挂钩到父地图的ViewChange事件来禁用(在鼠标事件期间)富标记图层的渲染,如下所示。我忘记了我最初发现这个的地方,所以如果主人想要获得信用,那么当你的大约10K引脚时,至少保持一致的平移UI体验非常有用。除此之外,我会使用一些自定义聚类,这显然更多地涉及模型层。 HTH
public class OnPanDisableRenderMapLayer : MapLayer
{
#region Private Properties
private Visibility _visibility;
#endregion
#region Constructor
///<summary>
/// Constructor
///</summary>
public OnPanDisableRenderMapLayer()
: base()
{
this.Loaded += (sender, evt) =>
{
Map map = (Map)base.ParentMap;
map.ViewChangeStart += (s, e) =>
{
_visibility = base.Visibility;
if (base.Visibility == Visibility.Visible)
{
base.Visibility = Visibility.Collapsed;
}
};
map.ViewChangeEnd += (s, e) =>
{
base.Visibility = _visibility;
};
};
}
#endregion
#region Public Properties
public Visibility Visibility
{
get { return base.Visibility; }
set
{
base.Visibility = value;
_visibility = value;
}
}
#endregion
}