Cómo crear Mapas bindable en Xamarin.Forms (Parte 3)
.jpg)
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>