0

我正在尝试在地图上显示图钉,但只有那些可以在您当前位置周围显示屏幕的图钉取决于我在地图出现时设置的缩放级别,因为我有 10 个图钉并且当我打开地图时它加载每个引脚并且需要很长时间才能加载。

关于如何做的任何想法?

加载引脚的方法:

    async Task ExecuteLoadPinsCommand()
    {
        IsBusy = true;

        try
        {
            Map.Pins.Clear();
            Map.MapElements.Clear();
            Map.CustomPins.Clear();
            var contents = await placeRepository.GetAllPlacesWithoutRelatedDataAsync();

            if (contents == null || contents.Count < 1)
            {
                await App.Current.MainPage.DisplayAlert("No places found", "No places have been found for that category, please try again later", "Ok");
                await ExecuteLoadPinsCommand();
            }

            if (contents != null)
            {
                places.Clear();
                var customPins = this.Map.CustomPins;
                places = contents;
                foreach (var item in places)
                {
                    CustomPin devicePin = new CustomPin
                    {
                        Type = PinType.Place,
                        PlaceId = item.PlaceId.ToString(),
                        Position = new Position(item.Latitude, item.Longitude),
                        Label = $"{item.Name}",
                        Address = $"{item.Name}"
                    };

                    Map.CustomPins.Add(devicePin);
                    Map.Pins.Add(devicePin);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex);
        }
        finally
        {
            IsBusy = false;
        }
    }

自定义地图渲染器:

    protected override MarkerOptions CreateMarker(Pin pin)
    {
        CustomPin pin = (CustomPin)pin;
        var thePlace = Task.Run(async () => await placeRepository.GetPlaceByIdWithMoodAndEventsAsync(Guid.Parse(pin.PlaceId)));
        var place = thePlace.ConfigureAwait(true)
                            .GetAwaiter()
                            .GetResult();

        var marker = new MarkerOptions();

        marker.SetPosition(new LatLng(place.Position.Latitude, place.Position.Longitude));
        if (place.Category == "" && place.SomethingCount == 0)
        {
            marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.icon));
        }
        //else if ...

        return marker;

    }
4

1 回答 1

0

编程的一个主要部分是学习调试好。

当面临性能问题时,将时间延迟隔离到尽可能少的代码是很重要的。

这是我要经历的思考过程:

  • 您的观察:当有一个引脚时,只需不到一秒钟。当有 20 个引脚时,可能需要 10 秒。(相差 9 秒。)

  • 您的假设(考虑到您发布的问题):也许在地图上添加 20 个图钉需要 9 秒的大部分时间或大部分时间。

  • 测试:我们如何才能准确地测试“将引脚添加到地图”的代码?
    A:“分而治之”:
    让所有其他代码运行 20 次。也就是说,有 20 个引脚作为数据。但是禁止添加这些引脚的代码。

测试 #1:GetAllPlacesWithoutRelatedDataAsync 返回 20 个引脚。所以所有这些工作都完成了 20 次。
只注释掉添加引脚的代码。进行此更改:

//Map.CustomPins.Add(devicePin);
//Map.Pins.Add(devicePin);

结果 #1:_____ 秒

没有引脚可能允许地图跳过加载一些与引脚相关的代码。让我们看看当我们只添加 20 个引脚中的一个时它有多快。

测试 #2:数据中有 20 个引脚。但只添加其中一个。进行此 ONE-LINE 更改:

            foreach (var item in places)
            {
                CustomPin devicePin = new CustomPin
                {
                    Type = PinType.Place,
                    PlaceId = item.PlaceId.ToString(),
                    Position = new Position(item.Latitude, item.Longitude),
                    Label = $"{item.Name}",
                    Address = $"{item.Name}"
                };

                Map.CustomPins.Add(devicePin);
                Map.Pins.Add(devicePin);
                break;   // <--- ADD THIS LINE.
            }

结果 #2:_____ 秒

(测试#2 是我试图要求你做的,在我对这个问题的评论之一。我已经删除了这些评论。)

现在我们有足够的信息来确定大约 9 秒的额外时间中有多少是由于通过该 foreach 循环 20 次,添加 20 个引脚。

这将决定尝试加速 ADDS 是否有任何意义,或者其他地方是否存在问题。


如果大部分时间都花在了其他地方,那么您需要将可疑代码添加到 question中。然后在那里做类似的测试。直到您可以准确报告大部分时间花费的代码。


如果 20xmap.Pins.Add(..)需要大量时间,那么这里有两种技术,恕我直言,其中任何一种都应该更快。

更快的添加 #1:

使用Map.ItemsSource.

更快的添加#2:

在显示地图之前,使用其引脚创建地图。

using Xamarin.Forms;
using Xamarin.Forms.Maps;

namespace XFSOAnswers
{
    // Based on https://github.com/xamarin/xamarin-forms-samples/blob/main/WorkingWithMaps/WorkingWithMaps/WorkingWithMaps/PinPageCode.cs
    public class PinPageCode : ContentPage
    {
        public PinPageCode()
        {
            Title = "Pins demo";

            Position position = new Position(36.9628066, -122.0194722);
            MapSpan mapSpan = new MapSpan(position, 0.01, 0.01);

            Map map = new Map(mapSpan);

            Pin pin = new Pin
            {
                Label = "Santa Cruz",
                Address = "The city with a boardwalk",
                Type = PinType.Place,
                Position = position
            };
            map.Pins.Add(pin);
            // ... more pins.

            Content = new StackLayout
            {
                Margin = new Thickness(10),
                Children =
                {
                    map
                }
            };
        }
    }
}
于 2022-01-01T00:56:37.540 回答