Cómo crear Mapas bindable en Xamarin.Forms (Parte 3)

Estrada Web Group
Administrador
Cómo crear Mapas bindable en Xamarin.Forms (Parte 3)

Xamarin Forms Maps

Si estas desarrollando una plicación Xamarin.Forms y vas a utilizar mapas Xamarin.Forms.Maps, te permite visualizar un mapa dentro de una aplicación Xamarin.Forms. En este artículo veremos cómo mostrar varias ubicaciones, mostrar la ubicación actual y como generar una ruta. Puedes leer la primera parte en Cómo crear Mapas bindable en Xamarin.Forms (Parte 1) y Cómo crear Mapas bindable en Xamarin.Forms (Parte 2)

Para que las rutas funcionen se debe crear una clase en los proyectos iOS y Android para que se muestren las líneas de la ruta.

Androide

[assembly: ExportRenderer(typeof(CustomMap), typeof(logistico.Droid.CustomMapRender))]

namespace logistico.Droid

{

    public class CustomMapRender: MapRenderer

    {

        List<Position> routeCoordinates;


        public CustomMapRender(Context context) : base(context)

        {

        }


        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

        {

            base.OnElementPropertyChanged(sender, e);

            if(sender !=null){

                var formsMap = (CustomMap)sender;

                routeCoordinates = formsMap.RouteCoordinates;

                Control.GetMapAsync(this);

            }

        }


        protected override void OnElementChanged(ElementChangedEventArgs<Map> e){

            base.OnElementChanged(e);

            if(e.OldElement!=null){               

            }

            if(e.NewElement!=null){

                var formsMap = (CustomMap)e.NewElement;

                routeCoordinates = formsMap.RouteCoordinates;

                Control.GetMapAsync(this);

            }

        }

        protected override void OnMapReady(Android.Gms.Maps.GoogleMap map){

            base.OnMapReady(map);

            var polylineOptions = new PolylineOptions();

            polylineOptions.InvokeColor(0x66FF0000);

            foreach(var position in routeCoordinates){

                polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));

            }

            NativeMap.AddPolyline(polylineOptions);

        }

    }

}

iOS

[assembly: ExportRenderer(typeof(CustomMap), typeof(logistico.iOS.CustomMapRender))]

namespace logistico.iOS

{

    public class CustomMapRender:MapRenderer

    {

        MKPolylineRenderer polylineRenderer;

        protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)

        {

            base.OnElementPropertyChanged(sender, e);

            if(sender!=null){

                var formsMap = (CustomMap)sender;

                var nativeMap = Control as MKMapView;

                nativeMap.OverlayRenderer = GetOverlayRenderer;

                if (formsMap.RouteCoordinates != null)

                {

                    CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];

                    int index = 0;

                    foreach (var position in formsMap.RouteCoordinates)

                    {

                        coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);

                        index++;

                    }

                    var routeOverlay = MKPolyline.FromCoordinates(coords);

                    nativeMap.AddOverlay(routeOverlay);

                }

            }

        }

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)

        {

            base.OnElementChanged(e);

            if (e.OldElement != null)

            {

                var nativeMap = Control as MKMapView;

                if (nativeMap != null)

                {

                    nativeMap.RemoveOverlays(nativeMap.Overlays);

                    nativeMap.OverlayRenderer = null;

                    polylineRenderer = null;

                }

            }

            if (e.NewElement != null)

            {

                var formsMap = (CustomMap)e.NewElement;

                var nativeMap = Control as MKMapView;

                nativeMap.OverlayRenderer = GetOverlayRenderer;

                if(formsMap.RouteCoordinates!=null){

                    CLLocationCoordinate2D[] coords = new CLLocationCoordinate2D[formsMap.RouteCoordinates.Count];

                    int index = 0;

                    foreach (var position in formsMap.RouteCoordinates)

                    {

                        coords[index] = new CLLocationCoordinate2D(position.Latitude, position.Longitude);

                        index++;

                    }

                    var routeOverlay = MKPolyline.FromCoordinates(coords);

                    nativeMap.AddOverlay(routeOverlay);

                }

            }

        }

        MKOverlayRenderer GetOverlayRenderer(MKMapView mapView, IMKOverlay overlayWrapper)

        {

            if (polylineRenderer == null && !Equals(overlayWrapper, null))

            {

                var overlay = Runtime.GetNSObject(overlayWrapper.Handle) as IMKOverlay;

                polylineRenderer = new MKPolylineRenderer(overlay as MKPolyline)

                {

                    FillColor = UIColor.Blue,

                    StrokeColor = UIColor.DarkGray,

                    LineWidth = 3,

                    Alpha = 0.4f

                };

            }

            return polylineRenderer;

        }

    }

}

Implementación en Xamarin.Forms

Para implementarlo en Xaml es de la siguiente manera

<?xml version="1.0" encoding="utf-8"?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"

    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"

    xmlns:local="clr-namespace:logistico"

    xmlns:cntrl="clr-namespace:logistico.Controls"

    x:Class="logistico.logisticoPage">

    <ContentPage.Content>

        <cntrl:CustomMap

        MapType="Street"

        WidthRequest="300"

        HeightRequest="300"

        MapPosition="{Binding MyPosition}"

        MapPins="{Binding AllPines}"

        RouteCoordinates="{Binding Ruta}"></cntrl:CustomMap>

    </ContentPage.Content>

</ContentPage>

 

 

 

Compartir artículo:

Más artículos geniales

Manténgase actualizado

Obtenga excelente contenido en su bandeja de entrada todas las semanas.
Solo contenido excelente, no compartimos su correo electrónico con terceros.
Subir al inicio de la pantalla ;