Windows Phone. Actualizando los mapas a la versión de Windows Phone 8

Después de varios días dándome cabezazos con el nuevo control de mapas, he conseguido amaestrarlo, aunque de la forma en la que me hubiera gustado. Como bien nos cuenta Yerary en su blog, Windows Phone 8 tiene un nuevo control de mapas con mucha más potencia que los anteriores, por muchas funcionalidades entre las que destaco las siguientes:

  • Los mapas son vectoriales y el usuario puede descargar los mapas para tenerlos Offline
  • Incluyen servicios de búsqueda de lugares y cálculos de rutas, con lo que obteniendo la nueva clave de aplicación del centro de desarrollo de Windows Phone nos permite utilizar también estos servicios.

Ahora bien, como ya nos pasó con el control de mapas de Bing de Windows 8, no parecen que estén bien terminados o con las funcionalidades que todos esperamos, y, sin entender el motivo, no existe un control que nos permita representar una colección de puntos, mediante el uso de Binding. Si miramos al control de Windows Phone 7, hacíamos lo siguiente para representar una serie de puntos:

        <my:Map  x:Name=”MyMap”  CredentialsProvider=”{Binding CredentialsProvider}”

                    ZoomLevel=”{Binding Zoom, Mode=TwoWay}”

                    Center=”{Binding Center, Mode=TwoWay}”>

            <my:MapItemsControl x:Name=”PushpinEstaciones”

                    ItemsSource=”{Binding EstacionesPushpin}” >

                <my:MapItemsControl.ItemTemplate>

                    <DataTemplate>

                        <my:Pushpin x:Name=”pushpin” Style=”{StaticResource CirclePushpin}” Background=”#FF4499ff”

                                Location=”{Binding Location}” Tap=”EstacionesTap”>

                            <Image Source=”{Binding Rotulo, Converter={StaticResource LogoConverterImage}}” Stretch=”Fill” />

                        </my:Pushpin>

                    </DataTemplate>

                </my:MapItemsControl.ItemTemplate>

            </my:MapItemsControl>

        </my:Map>

 

Como hijo del control de mapas, utilizábamos el control MapItemsControl enlazado a nuestro ViewModel con el ItemsSource. Si migramos a Windows Phone 8, y actualizamos los mapas, nos encontramos con que no tenemos este control, MapItemsControl, y que tendremos que crear nuestros puntos en código.

            foreach (var item in viewModel.EstacionesPushpin)

            {

                var estacionButton = new Button() {Content = item.Rotulo};

                //Creamos una overlay con el botón
						

                MapOverlay MyOverlay = new MapOverlay();

                MyOverlay.Content = estacionButton;

                //Establecemos la posición del elemento
						

                MyOverlay.GeoCoordinate = item.Location;

                //Creamos una capa y le añadimos el overlay
						

                MapLayer MyLayer = new MapLayer();

                MyLayer.Add(MyOverlay);

                MyMap.Layers.Add(MyLayer);

            }

 

Una mejor aproximación, recomendada en la MSDN, la encontramos en unas extensiones para el mapa que han incluido en el Windows Phone Toolkit. Con estas extensiones, podemos utilizar el MapItemsControl y enlazar su ItemsSource en código con la colección de nuestro ViewModel, porque no está implementado el Binding. Veamos cómo quedaría:

        <maps:Map x:Name="MyMap" ZoomLevel="{Binding Zoom, Mode=TwoWay}" Center="{Binding Center, Mode=TwoWay}">
																											

            <maptk:MapExtensions.Children>
										

                <maptk:MapItemsControl Name="PushpinEstaciones">
											

                    <maptk:MapItemsControl.ItemTemplate>
										

                        <DataTemplate>
								

                            <maptk:Pushpin GeoCoordinate="{Binding Location}" Style="{StaticResource CirclePushpin}"
																			

                                           Background="#FF4499ff" Tap="EstacionesTap" >
									

                                <Image Source="{Binding Rotulo, Converter={StaticResource LogoConverterImage}}" Stretch="Fill" />
																			

                            </maptk:Pushpin>
										

                        </DataTemplate>
								

                    </maptk:MapItemsControl.ItemTemplate>
										

                </maptk:MapItemsControl>
										

            </maptk:MapExtensions.Children>
										

        </maps:Map>
										

 

En la carga de la página, enlazamos el MapItemsControl a los datos.

PushpinEstaciones.ItemsSource = viewModel.EstacionesPushpin;

 

Además, tenemos que asegurarnos que antes de que enlacemos los datos se ejecuta un método que configura los controles de las extensiones:

        /// <summary>
								

        /// Setup the map extensions objects.
							

        /// All named objects inside the map extensions will have its references properly set
							

        /// </summary>
								

        /// <param name="map">The map that uses the map extensions</param>
										

        private void MapExtensionsSetup(Microsoft.Phone.Maps.Controls.Map map)

        {

            ObservableCollection<DependencyObject> children = MapExtensions.GetChildren(map);

            var runtimeFields = this.GetType().GetRuntimeFields();

 

            foreach (DependencyObject i in children)

            {

                var info = i.GetType().GetProperty("Name");

 

                if (info != null)

                {

                    string name = (string)info.GetValue(i);

 

                    if (name != null)

                    {

                        foreach (FieldInfo j in runtimeFields)

                        {

                            if (j.Name == name)

                            {

                                j.SetValue(this, i);

                                break;

                            }

                        }

                    }

                }

            }

        }

 

Dos opciones a elegir y, particularmente, ninguna me convence del todo. La primera porque metemos lógica de presentación en el código de la vista y la segunda porque no me convence el método que configura la extensión, porque estamos trabajando con un Toolkit que siempre ha tenido pequeños bugs y porque no tiene el Binding implementado.

¿Cuál elegirías tú?

 

Saludos a todos…

Un pensamiento en “Windows Phone. Actualizando los mapas a la versión de Windows Phone 8”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *