Dentro de los talleres orientados a aplicaciones de negocio de la plataforma Silverlight, que en próximas fechas desarrollaré en el Centro de Excelencia Software Microsoft, he tenido que trabajar con la Geocodificación que Bing Maps pone a nuestra disposición a través de una serie de servicio.
Pero que significa esta palabra tan rimbombante (Geocodificación), pues es el proceso de asignar coordenadas geográficas (e.g. latitud-longitud) a puntos del mapa (direcciones, puntos de interés, etc.). Las coordenadas geográficas producidas pueden luego ser usadas para localizar el punto del mapa en un Sistema de Información Geográfica. Para que nos entendamos, en el ejemplo que vamos a desarrollar en este artículo, el usuario final va a introducir una dirección, reflejando dicha dirección en un objeto Mapa (que nos ofrece el SDK de Bing Maps para Silverlight).El usuario final podrá interactuar con dicho elemento a través de la plataforma Silverlight.
Para este artículo vamos a usar Silverlight 4 y Bing Maps Silverlight Control SDK, podéis descargarlos en los correspondientes enlaces. También tenemos que crear una cuenta Bing Maps para poder disfrutar de las diferentes características que nos ofrece esta plataforma. Para ello accedemos aquí, para crear una nueva cuenta.
Hacemos clic sobre Crear en la sección Nuevo Usuario.
Al realizar esta acción nos pedirá la autentificación mediante Windows Live ID. Una vez introducidos los credenciales, pasaremos a rellenar los datos de la cuenta.
Seguidamente vamos a presionar sobre Create or View Keys, de este modo crearemos una clave que asociaremos en nuestro proyecto. Rellenamos los campos(Nombre de la aplicación, Url de la aplicación y tipo de aplicación) como podemos ver en la siguiente imagen:
Al presionar en Create Key se ha generado una nueva clave que hemos de introducirla en nuestro desarrollo:
Una vez realizada dicha acción, vamos a desarrollar nuestro proyecto en Silverlight, más adelante utilizaremos la citada clave.
Abrimos Visual Studio 2010, para crear una nueva aplicación Silverlight que llamaremos PuntosInteresSL, como podemos observar en la siguiente imagen:
Por otro lado marcaremos que queremos alojar nuestra aplicación Silverlight en un sitio web y elegiremos la versión 4 de Silverlight para el proyecto que nos ocupa.
Añadimos las bibliotecas de Bing Maps que necesitamos para desarrollar las diferentes funcionalidades de ambas plataformas. Para ellos nos situamos sobre la carpeta Referencias, hacemos clic con el botón derecho del ratón y elegimos Añadir Referencia. Seleccionamos la pestaña Buscar y en la siguiente ruta C:Program FilesBing Maps Silverlight ControlV1Libraries, seleccionamos las siguientes bibliotecas:
El siguiente paso es añadir el servicio de Bing Maps que nos va permitir la Geocodificación. Nos situamos nuevamente sobre la carpeta Referencias, hacemos clic con el botón derecho sobre la misma y elegimos Agregar referencia de servicio. En la ventana emergente que nos aparece al realizar la anterior acción, debemos introducir en el campo Dirección, la url del servicio (http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc). Presionamos sobre el botón Go para comprobar que la comunicación con el servicio se realiza de forma correcta. El servicio lo identificaremos con el nombre GeocodeService que debemos introducirlo en el apartado NameSpace:
Presionamos en OK y ya tenemos preparado el servicio para su posterior utilización.
El siguiente paso es introducir la clave de la cuenta Bing Maps creada con anterioridad en App.xaml, de este modo utilizaremos dicho elemento como un recurso, sin necesidad de introducir en todo momento la clave.
Una vez situados en App.xaml, dentro de la etiqueta <Application.Resources> introducimos <sys:String x:Key="MisCredenciales">Clave Cuenta Bing Maps</sys:String> siendo el resultado final de dicho archivo el siguiente:
Credenciales
- <Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:sys="clr-namespace:System;assembly=mscorlib"
- x:Class="PuntosInteresSL.App"
- >
- <Application.Resources>
- <sys:String x:Key="MisCredenciales">Clave Cuenta Bing Maps</sys:String>
- </Application.Resources>
- </Application>
Ahora vamos a centrarnos en la creación de la interfaz de usuario, para ello abrimos MainPage.xaml, el primer paso es referenciar las librerías de Bing Maps. Para ello dentro de la etiqueta <UserControl> introducimos xmlns:map="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl".
Seguidamente, vamos a definir la estructura de los diferentes objetos que incluiremos dentro de la misma, para ellos añadimos el siguiente fragmento de código:
- <Grid x:Name="LayoutRoot" Background="White">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="271*"/>
- <ColumnDefinition Width="100*"/>
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="255*"/>
- <RowDefinition Height="45*"/>
- </Grid.RowDefinitions>
- </Grid>
Ahora vamos a introducir el objeto Mapa que hemos referenciado con anterioridad. En dicho objeto vamos a trabajar con las propiedades Center que muestra la latitud y longitud inicial del mapa. La propiedad ZoomLevel ofrece el nivel de ampliación del mapa en su estado original. Por último la propiedad Mode que es la vista que deseamos mostrar en el objeto Mapa.
- <map:Map x:Name="mapa" Center="40.225,-1.794" ZoomLevel="6" Mode="Road" Grid.Row="0" Grid.ColumnSpan="2"/>
Ejecutamos la aplicación y podemos ver como aparece un mensaje sobre el mapa, en el que nos informa que no podemos utilizar dicho elemento por tener credenciales inválidos.
Ante este requisito, debemos utilizar el recurso que hemos creado con anterioridad del siguiente modo:
- <map:Map x:Name="mapa" Center="40.225,-1.794" ZoomLevel="6" Mode="Road" Grid.Row="0" Grid.ColumnSpan="2">
- <map:Map.CredentialsProvider>
- <map:ApplicationIdCredentialsProvider ApplicationId="{StaticResource MisCredenciales}"/>
- </map:Map.CredentialsProvider>
- </map:Map>
Ejecutamos y vemos como ahora podemos utilizar el mapa sin ningún tipo de problema.Por último en la interfaz de usuario vamos a introducir los dos últimos elemento. Por un lado introducimos un objeto TextBox que recogerá el punto de interés que desea el usuario introducir en el mapa. Por otro un botón que será el disparador de las diferentes acciones que permitan introducir en el mapa ese punto de interés.
- <TextBox x:Name="txbPI" Grid.Row="1" Grid.Column="0" Margin="10"/>
- <Button x:Name="btnGeocode" Content="Punto de Interés" Grid.Row="1" Grid.Column="1" Margin="5" Click="btnGeocode_Click"/>
Ahora nos vamos a situar en MainPage.xaml.cs, seguidamente nos desplazaremos hasta el evento clic generado con anterioridad para el botón. Primeramente referenciamos las librerías:
- using Microsoft.Maps.MapControl;
Dentro de dicho evento introducimos el siguiente fragmento de código:
- private void btnGeocode_Click(object sender, RoutedEventArgs e)
- {
- GeocodeService.GeocodeServiceClient geocodeClient = new GeocodeService.GeocodeServiceClient
-
- ("CustomBinding_IGeocodeService");
-
- GeocodeService.GeocodeRequest resquest = new GeocodeService.GeocodeRequest();
- resquest.Query = txbPI.Text;
- resquest.Credentials = new Microsoft.Maps.MapControl.Credentials();
- resquest.Credentials.ApplicationId = App.Current.Resources["MisCredenciales"] as string;
-
- geocodeClient.GeocodeCompleted += new EventHandler<GeocodeService.GeocodeCompletedEventArgs>(geocodeClient_GeocodeCompleted);
- geocodeClient.GeocodeAsync(resquest);
- }
Como podemos observar creamos un objeto GeocodeServiceClient, que nos permite comunicar la aplicación con el servicio GeocodeService. Dicho servicio requiere del Objeto GeocodeRequest que envía la petición de un nuevo punto de interés a través del texto introducido en el TextBox. Pero este acceso al servicio no sería posible si no enviaríamos los credenciales de la cuenta Bing Maps. Por último la petición al servicio se ha de realizar de forma asincrona, cuando la petición regresa la controlamos a través del controlador de eventos geocodeClient_GeocodeCompleted.
Ahora vamos a introducir el evento citado con anterioridad. En el obtenemos un array con una serie de coincidencias con el texto introducido en el TextBox. Como solo nos interesa el primer elemento, a través de LINQ obtenemos ese primer elemento.Tomamos la longitud y latitud de ese elemento y creamos en la interfaz de usuario un nuevo localizados(Punto de Interés). El último paso es ofrecer la mejor vista de ese punto de interés por lo que el objeto mapa realizará un Zoom sobre dicho punto de interés a fin de mejorar la experiencia de usuario.
- private void geocodeClient_GeocodeCompleted(object sender, GeocodeService.GeocodeCompletedEventArgs e)
- {
- GeocodeService.GeocodeResponse response = e.Result;
- if (response.Results.Count > 0)
- {
- GeocodeService.GeocodeResult result = response.Results.First();
- if (result.Locations.Count > 0)
- {
- Pushpin pushpin = new Pushpin();
- Location location = new Location(result.Locations.First().Latitude, result.Locations.First().Longitude);
- pushpin.Location = location;
- mapa.Children.Add(pushpin);
- mapa.SetView(result.BestView);
-
-
- }
- }
-
- }
Ejecutamos la aplicación e introducimos en el TextBox Niagara Falls y podemos ver el siguiente resultado:
En definitiva, podemos obtener un mayor rendimiento de las dos plataformas al utilizar todas las capacidades de una forma dinámica, ayudando con ello a la mejora de la experiencia de usuario, además de ofrecer al mismo aplicaciones útiles.
Podéis descargar el proyecto completo aquí