C#热图生成(三)——with Silverlight改进热图显示

前文C#热图生成(二)——with Silverlight介绍了如何在Silverlight中在客户端生成热图并与Bing Maps集成,但当时生成的热图是通过一个Image对象呈现在地图控件之上,有许多不便之处:

  • 为免Image挡住Map控件接收事件,Image必须设IsHitVisible为false
  • Heat Map会挡住Map控件上的元素,比如Navigation和PushPin及其他Map Layer:
    C#热图生成(三)——with Silverlight改进热图显示_第1张图片
  • 移动地图时,若要实时显示热图,必须不断重复绘制,但会让用户感觉很卡

在前文末尾,提出了使用Bing Maps MapLayer的一种解决方法,尝试之后,终于解决了以上问题,现在的效果如下,热图已经在Navigation之下了:
C#热图生成(三)——with Silverlight改进热图显示_第2张图片

同时,由于现在热图实现为Map控件中的一个MapLayer,因此在拖动地图时,热图会跟随地图一起移动。

具体实现

热图绘制等部分保持不变,只是改了热图的呈现方式:

private void map_ViewChangeEnd (object sender, Microsoft.Maps.MapControl.MapEventArgs e)
{
    var newHeatMap = drawHeatMap ();
    mapLayer.Children.Remove (_heatMapImg);
    _heatMapImg.Source = newHeatMap;
    _heatMapImg.Stretch = Stretch.None;

    mapLayer.AddChild (_heatMapImg, map.BoundingRectangle);
}

其中,mapLayer定义如下:

<m:Map x:Name="map" 
        CredentialsProvider="AqQWILmINH_nbZxuj5BZvkAQSw0r2LtA1WHR5kDjpQVEbOp4vhWAoEFyZEm9LwXD"
        HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
        ViewChangeEnd="map_ViewChangeEnd" 
        ViewChangeOnFrame="map_ViewChangeOnFrame">
    <m:MapLayer x:Name="mapLayer">m:MapLayer>
m:Map>

而_heatMapImg即一个Image对象。

不过,由于地图放大缩小时,暂时无法让Image跟着变化,所以依然必须先将其隐藏:

private void map_ViewChangeOnFrame (object sender, Microsoft.Maps.MapControl.MapEventArgs e)
{
    if (map.ZoomLevel != _lastZoomLevel)
    {
        mapLayer.Children.Remove (_heatMapImg);
        _lastZoomLevel = map.ZoomLevel;
    }
}

另外,当加载其他的地图Tile时,由于在Map的Children中Add会将mapLayer盖住,所以使用
map.Children.Insert (0, tileLayer);

来添加tile到最下层,也可以通过代码方式在添加tile后添加mapLayer.

----------------------

源码下载:HeatMapDemos_src_2.zip

你可能感兴趣的:(C#热图生成(三)——with Silverlight改进热图显示)