Xamarin Forms Maps - how to refresh/update the map - CustomMap Renderer

前端 未结 4 1884
予麋鹿
予麋鹿 2021-02-06 14:06

If you are searching for a full polylines, pins, tiles, UIOptions (and 3D effects soon) renderings/implementations, you should take a loot at the public github I made at

4条回答
  •  误落风尘
    2021-02-06 14:23

    I followed the tutorial available on Xamarin Docs and it worked for me with some changes based on @Sven-Michael Stübe answer

    I load the coordinates from a WebService and then I create a separate List, and after this, I set the new list to the RouteCoordinates property on Custom Map.

    Some changes are made on Android Renderer

    I'm using MVVM.

    CustomMap Class:

    public static readonly BindableProperty RouteCoordinatesProperty =
            BindableProperty.Create(nameof(RouteCoordinates), typeof(List), typeof(CustomMap), new List(), BindingMode.TwoWay);
    
    public List RouteCoordinates
    {
        get { return (List)GetValue(RouteCoordinatesProperty); }
        set { SetValue(RouteCoordinatesProperty, value); }
    }
    
    public CustomMap()
    {
        RouteCoordinates = new List();
    }
    

    ViewModel (Codebehind, in your case):

    private async void LoadCoordinates(string oidAula, CustomMap mapa)
    {
        IsBusy = true;
    
        var percurso = await ComunicacaoServidor.GetPercurso(oidAula); // Get coordinates from WebService
        var pontos = percurso.Select(p => new Position(p.Latitude, p.Longitude)).ToList(); // Create coordinates list from webservice result
    
        var latitudeMedia = percurso[percurso.Count / 2].Latitude;
        var longitudeMedia = percurso[percurso.Count / 2].Longitude;
    
        mapa.RouteCoordinates = pontos;
        mapa.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(latitudeMedia, longitudeMedia), Distance.FromMiles(1.0)));
    
        IsBusy = false;
    }
    

    XAML:

    
    

    Android Renderer:

    public class CustomMapRenderer : MapRenderer
    {
        bool isDrawn;
    
        protected override void OnElementChanged(ElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
    
            if (e.OldElement != null)
            {
                // Unsubscribe
            }
    
            if (e.NewElement != null)
                Control.GetMapAsync(this);
        }
    
        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
    
            if ((e.PropertyName == "RouteCoordinates" || e.PropertyName == "VisibleRegion") && !isDrawn)
            {
                var polylineOptions = new PolylineOptions();
                polylineOptions.InvokeColor(0x66FF0000);
    
                var coordinates = ((CustomMap)Element).RouteCoordinates;
    
                foreach (var position in coordinates)
                    polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
    
                NativeMap.AddPolyline(polylineOptions);
                isDrawn = coordinates.Count > 0;
            }
        }
    }
    

    This example have more than 3600 points of location and the polyline shows correctly on device:

    Screenshot

提交回复
热议问题