如何提高Windows Phone 8地图控件的性能

德芙

在我的Windows Phone 8应用程序中,我具有包含平面(图钉)集合的地图控件。

像这样在xaml中定义地图:

<maps:Map x:Name="Map">
    <maptk:MapExtensions.Children>

        <maptk:MapItemsControl Name="Planes" ItemTemplate="{StaticResource PlaneTemplate}"/>

    </maptk:MapExtensions.Children>
</maps:Map>

平面MapItemsControl绑定到视图模型中的对象的集合(ObservableCollection),如下所示:

private ObservableCollection<IPlane> _planes;
public ObservableCollection<IPlane> Planes
{
    get { return _planes; }
    set
    {
        _planes = value;
        NotifyOfPropertyChange(() => Planes);
    }
}

public async void GetPlanes()
{
    IReadOnlyCollection<IPlane> planes = await realtimePlanes.GetAllPlanesAsync();

    foreach (IPlane newPlane in planes)
    {
        this.Vehicles.Add(newPlane);
    }
}

当我调用GetPlaes()时,要从Web api获取飞机并更新集合,整个应用程序将释放几秒钟。通常,“飞机”集合机中大约有150-300件物品。

在更新Planes集合时,应该如何改善它以使用户体验更好,消除滞后?

我可以以某种方式强制在后台线程(?)中进行此集合更新,还是问题图控件性能良好?它不能一口气绘制所有项目吗?

更新

这是更多代码,说明我的实际应用程序如何工作。

只需构建快速而肮脏的测试类/服务即可生成测试平面:

public class TestRealtimePlaneService : IRealtimePlaneService
{
    private Random random;

    public async Task<IEnumerable<IRealtimePlane>> GetAllPlanesAsync()
    {
        this.random = new Random();

        int count = 350;
        double x0 = 24.9375;
        double y0 = 60.170833;
        int radius = 8000;

        List<TestRealtimePlane> planes = new List<TestRealtimePlane>();

        for (int i = 0; i < count; i++)
        {
            planes.Add(new TestRealtimePlane() { Location = getLocation(x0, y0, radius), Bearing = 1 });
        }

        await Task.Delay(5000); // Just to simulate webservice call

        return planes;
    }

    // Taken from http://gis.stackexchange.com/questions/25877/how-to-generate-random-locations-nearby-my-location
    public GeoCoordinate getLocation(double x0, double y0, int radius)
    {
        double radiusInDegrees = radius / 111000f;

        double u = this.random.NextDouble();
        double v = this.random.NextDouble();
        double w = radiusInDegrees * Math.Sqrt(u);
        double t = 2 * Math.PI * v;
        double x = w * Math.Cos(t);
        double y = w * Math.Sin(t);

        double new_x = x / Math.Cos(y0);

        double foundLongitude = new_x + x0;
        double foundLatitude = y + y0;

        return new GeoCoordinate(foundLatitude, foundLongitude);
    }
}

这是实际的地图组件

<maps:Map x:Name="Map">
    <maptk:MapExtensions.Children>

        <maptk:MapItemsControl Name="Planes">
            <maptk:MapItemsControl.ItemTemplate>
                <DataTemplate>
                    <maptk:Pushpin GeoCoordinate="{Binding Location}" PositionOrigin="0.5,0.5">
                        <maptk:Pushpin.Template>
                            <ControlTemplate TargetType="maptk:Pushpin">
                                <Grid Width="45" Height="45" Background="Transparent">
                                    <Polygon Fill="Yellow" Points="22,0 34,13, 12,13" Width="45" Height="45" RenderTransformOrigin="0.5,0.5">
                                        <Polygon.RenderTransform>
                                            <RotateTransform CenterX="0.5" CenterY="0.5" Angle="{Binding Bearing}"/>
                                        </Polygon.RenderTransform>
                                    </Polygon>
                                    <Ellipse Fill="Yellow" Stroke="Black" HorizontalAlignment="Center" VerticalAlignment="Center" Width="15" Height="15" StrokeThickness="2" />
                                </Grid>
                            </ControlTemplate>
                        </maptk:Pushpin.Template>
                    </maptk:Pushpin>
                </DataTemplate>
            </maptk:MapItemsControl.ItemTemplate>
        </maptk:MapItemsControl>

    </maptk:MapExtensions.Children>
</maps:Map>

似乎图钉模板也对性能有很大影响。如果我从图钉中删除自己的控制模板,则其工作速度会加快一点。

米科·维塔拉(Mikko Viitala)

当您使用WPToolkit的MapExtension显示图钉时,您正在寻找麻烦。您希望BindingItemsSource能够ObservableCollection<T>为您提供简便的方法来更新地图,并提供流畅的用户体验。

一定不行!我引用(我自己):

WPToolkit的MapExtensions糟透了驴子的屁股。这种组件使您质疑为什么首先要进行编程。

可以绑定ItemsSource到集合,但不能在XAML中这样做。不,您必须自己挖掘ItemsSource,并在代码隐藏中明确设置它。

var control = MapExtensions.GetChildren(MyMap).OfType<MapItemsControl>().FirstOrDefault();

还不错,但是等等,还有更多!如果collection中有项目,则不能仅将其替换为新的项目,否则最终会出现异常。不,相反,您必须清除这些项目,然后逐个添加新项目。是的,这是对的。一对一!

var planes = (await PlaneRepository.GetAllPlanesAsync()).ToList();

if (Planes.Any())
    Planes.Clear();

foreach (var plane in planes)
    Planes.Add(plane);

当您更新集合时,UI将被阻止。没有DispatcherBackgroundWorkerTask<T>无法解决这个问题。

如果有人有任何疑问,请务必指出我错了。我设置了一个公共GitHub存储库master分支)作为分支。

为了使地图不被阻塞,您必须做出一些折衷并完全放弃MapExtensions。创建new时MapOverlay,将其中一个Pushpin作为内容,然后将其手动添加到地图中,UI会保持响应状态。

但是也有一个陷阱。如果您一次添加很多MapOverlay,那么您仍然会短暂冻结。如果您故意拖延添加每个项目(例如75毫秒),那么图钉会一一出现在地图上并且UI保持响应状态会产生很好的效果。

Task.Factory.StartNew(() =>
    {
        if (message.Delay != null)
        {
            foreach (var plane in message.Planes)
            {
                AddPins(new[] {plane});
                Thread.Sleep(message.Delay.Value);
            }
        }
    });
private void AddPins(IEnumerable<IPlane> planes)
{
    DispatcherHelper.CheckBeginInvokeOnUI(() =>
        {
            foreach (var plane in planes)
            {
                var pushpin = new Pushpin
                    {
                        Style = Resources["PlaneStyle"] as Style
                    };

                var pushpinOverlay = new MapOverlay
                    {
                        GeoCoordinate = plane.Location,
                        Content = pushpin
                    };
                _pushpinLayer.Add(pushpinOverlay);
            }
        });
}

使用MapOverlays的响应式地图示例位于同一GitHub存储库中,但位于no-map-extensions分支中。

图片

这就是提高Windows Phone 8 Map控件性能的方法:)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何将图钉添加到Windows Phone 8.1地图控件?

来自分类Dev

Windows Phone 8.1地图AuthenticationToken

来自分类Dev

如何在Windows Phone 8.1中提高性能方法GetThumbnailAsync

来自分类Dev

如何通过WP8地图控件使用特定的Google地图-C#

来自分类Dev

在Windows Phone 8中更新图像控件

来自分类Dev

Windows Phone 8和新地图控件中MapOverlay上的可拖动内容

来自分类Dev

Google在Windows Phone 8上进行地图

来自分类Dev

如何从Windows Phone WebView控件获取内容

来自分类Dev

在Windows Phone上使用Linq to SQL时是否可以提高批量删除的性能?

来自分类Dev

Windows Phone 8替换默认图释

来自分类Dev

Windows Phone 8记录

来自分类Dev

Windows Phone 8的LockScreen

来自分类Dev

Windows Phone 8记录

来自分类Dev

Windows Phone 8.1 WinRT App中未显示地图控件

来自分类Dev

如何禁用Windows Phone 8的缩放

来自分类Dev

如何创建Windows Phone 8应用包?

来自分类Dev

如何阅读列表<>?Windows Phone 8

来自分类Dev

如何替换.txt文件Windows Phone 8

来自分类Dev

如何使用静态库(Windows Phone 8)

来自分类Dev

Windows Phone 8.1 DatePicker控件

来自分类Dev

Windows Phone HttpClient GetAsync性能

来自分类Dev

Windows Phone HttpClient GetAsync性能

来自分类Dev

“ Windows Phone Silverlight 8”是否与“ Windows Phone 8”相同?

来自分类Dev

Windows Phone 8中BitmapImage / Image控件的内存消耗

来自分类Dev

Windows Phone 8中设置的弹出控件名称

来自分类Dev

无法在WebBrowser控件中上传文件-Windows Phone 8

来自分类Dev

Windows Phone 8 Image Binding

来自分类Dev

Windows Phone 8:显示pdf

来自分类Dev

Windows Phone 8中的NavigationDrawer