Maui.GoogleMaps icon indicating copy to clipboard operation
Maui.GoogleMaps copied to clipboard

Adding large number of pins (20 thousand or more)

Open andersonvieiragomeslopes opened this issue 8 months ago • 14 comments

This may not be a problem, but rather a limitation or implementation error, I'm still investigating.

VERSIONS

  • Maui.GoogleMaps - 5.0.3
  • .NET SDK - 8.0.300

IDE

  • [ ] Rider
  • [x] Visual Studio
  • [ ] Visual Studio for Mac

PLATFORMS

  • [x] Android
  • [ ] iOS - Not tested

ACTUAL BEHAVIOR

In other apps I see the pin being loaded dynamically without lag with high numbers of pins, when I zoom in, more pins in that region are loaded in a specific radius of the map where it is visible to me, I did that, but I would like to know if there is a performance problem related to the map or if I really shouldn't upload too many pins or if there is a limit to showing on the map, because I realized that if I increase the radius where I upload items from 10km to 50km I start to have lags when scrolling on the map, I did a "loading more" to refresh the map list and remove the previous pins, but I don't know if it would also be necessary to do some clearing on the map as well. Sorry to tag you @plppp2001, but I saw that you worked on another item also related to performance with pins on the map and mentioned this component to be used. #14778 #19906

ACTUAL SCREENSHOTS/STACKTRACE

EXPECTED BEHAVIOR

No freezing with many items within a 50km radius Because if I decrease the MinimumDistanceKm to 1.0 and radiusKm to a smaller value 5.0 or 10.0 things start to work without freezing because I will have fewer pins on the map.

HOW TO REPRODUCE

`
private bool isCameraMoving = false; private const int UpdateInterval = 500; private double previousLat = 0; private double previousLon = 0; private const double MinimumDistanceKm = 10.0; // Distância mínima em km para atualizar os pins

    public TheftViewModel(INavigationService navigationService, ILocationService locationService) : base(navigationService)
    {
        _locationService = locationService;
    }
    [RelayCommand]
    public async Task Disappearing()
    {
    }
    [RelayCommand]
    private async Task CameraMovingTo(CameraMovingEventArgs e)
    {
        if (IsFlipped)
        {
            isCameraMoving = true;
            var lon = e.Position.Target.Longitude;
            var lat = e.Position.Target.Latitude;
            if (CalculateDistance(previousLat, previousLon, lat, lon) < MinimumDistanceKm)
            {
                return;
            }
            previousLat = lat;
            previousLon = lon;

            await Task.Delay(UpdateInterval);

            if (!isCameraMoving)
            {
                return;
            }
            UpdateDisplayedData(lat, lon);
            isCameraMoving = false;
        }
    }
    private void UpdateDisplayedData(double centerLat, double centerLon)
    {

        const double radiusKm = 50.0;
        var filteredPins = UploadedPins.Where(pin => CalculateDistance(centerLat, centerLon, pin.Position.Latitude, pin.Position.Longitude) <= radiusKm).ToList();
        MainThread.BeginInvokeOnMainThread(() =>
        {
            Pins.Clear();
            foreach (var item in filteredPins)
            {
                Pins.Add(item);
            }
        });


    }
    private double CalculateDistance(double lat1, double lon1, double lat2, double lon2)
    {
        const double R = 6371; // Raio da Terra em km
        var lat = (lat2 - lat1) * Math.PI / 180;
        var lon = (lon2 - lon1) * Math.PI / 180;
        var a = Math.Sin(lat / 2) * Math.Sin(lat / 2) +
                Math.Cos(lat1 * Math.PI / 180) * Math.Cos(lat2 * Math.PI / 180) *
                Math.Sin(lon / 2) * Math.Sin(lon / 2);
        var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
        return R * c;
    }`
    
  1. Upload 20 thousand pins
  2. Set the ItemsSource binding to a property in your VM
  3. Populate said property