Lazy loading of pins in Maui maps flickers/re-draws all the pins at every update

70 views Asked by At

I am trying to lazy load a collection of over 300 pins I need to display on a map.

Considering that my pins data is not much for an API to fetch, I load this information only once at the "Component_Loaded" event, so I have an ObservableCollection _allProviders containing all the data I need during the maps navigation.

According to this data, I can calculate for each "Provider" the distance from the visible region centre the user is currently displaying on the map. This algorithm seems to work well.

I have tried many different things, such as adding multiple pins at a time using MvvmHelpers.ObservableRangeCollection or a debouncer. No luck. :/

The problem I have is that the markers are re-drawn (causing a "flickering") every time I add even just a single new pin, and it's not nice to see. Once all the pins of an area have been loaded, the performances are perfect.

One option I haven't managed to implement yet could be to - somehow - stop the maps updating and invoke it when some new pins are added but I am lacking of ideas to be honest and I would not like to try alternative map components.

I'd really appreciate some help, thanks.


    using Microsoft.Maui.Controls.Maps;

    ...

    public MapsView()
    {
        InitializeComponent();

        if (DeviceInfo.Platform == DevicePlatform.Android || DeviceInfo.Platform == DevicePlatform.iOS)
        {
            map.IsShowingUser = true;

            map.Loaded += Component_Loaded;
            map.PropertyChanged += HandleVisibleRegionEvent;
        }
    }

    private async void HandleVisibleRegionEvent(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "VisibleRegion")
        {
            foreach (Provider p in _allProviders)
            {
                if (!p.IsMapped)
                {
                    var d = GeoCalculator.CalculateDistance(p.Location.Latitude, p.Location.Longitude, map.VisibleRegion.Center.Latitude, map.VisibleRegion.Center.Longitude);

                    if (d < map.VisibleRegion.Radius.Kilometers)
                    {
                        p.IsMapped = true;

                        map.Pins.Add(new Pin()
                        {
                            Label = p.title,
                            Location = p.Location
                        });

                        await Task.Delay(100);
                    }
                }
            }
        }
    }
0

There are 0 answers