En este artículo vamos a crear una aplicación simple que permita al usuario buscar por ubicaciones usando el contrato de Búsqueda. Para hacer esto, hay tres tareas principales que deben ser hechas.
1. Crear una aplicación de mapas sencilla
2. Integrar el contrato de búsqueda
3. Agregar la lógica de geocoding al contrato de búsqueda.
Al hacer uso del contrato de Búsqueda, los usuarios pueden buscar dentro de su aplicación cualquier cosa en sus sistema. El código completo en C# y VB para este artículo esta disponible en las galerías de Visual Studio aquí y en español aquí.
Creando una Aplicación Básica de Mapas
Antes de comenzar a agregar lógica para enlazar el contrato de búsqueda, vamos a iniciar creando una aplicación básica de mapas que servirá para desplegar los resultados.
1) Inicia abriendo Visual Studio 2012 y crea un nuevo proyecto. En la ventana que aparece, selecciona C# –> Windows Store. Selecciona la plantilla Blank App. Asigna un nombre al proyecto de la aplicación y presiona OK.
2) Agrega una referencia al SDK de Bing Maps. Para hacer esto, selecciona el folder de Referencias y presiona Agregar referencia. Selecciona Windows –> Extensions selecciona Bing Maps for C++ Runtime Package como es requerido por el SDK de Bing Maps cuando es desarrollado usando C# o Visual Basic.
Quizá hayas notado que hay un indicador amarillo en las referencias que acabas de agregar. La razón por esto es que cuando estás usando el paquete de C++ runtime, tienes que ajustar el Plataforma de solución activa en Visual Studio a una de las siguientes opciones: ARM, x86 o x64. Para hacer esto, da clic derecho sobre el folder de la solución y selecciona Propiedades. Después ve a Propiedades de configuración –> Configuración. Encuentra tu proyecto y debajo de la columna Plataforma ajusta la plataforma deseada. Para este ejemplo voy a usar x64. Presiona Ok y el indicador amarillo debería desaparecer de nuestras referencias.
4) Ahora agrega un mapa a nuestra aplicación. Para hacer esto, abre el archivo MainPage.xaml. Necesitarás primero agregar el espacio de nombres en la cima del archivo. Después de hacer esto puedes agregar un objeto Map en el control Grid y agregar tu llave de Bing Maps a la propiedad de credenciales del mapa. Dale al mapa el nombre de mapa.
<Page x:Class="GeocodingContratoBusqueda.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:GeocodingContratoBusqueda" xmlns:maps="using:Bing.Maps" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <maps:Map Credentials="Aj2-XGT9fZ1QTYnExLafzRXrpvn-VaNu97tQKamHtU-E5xj" Name="mapa"/> </Grid> </Page> |
5) Hasta este punto, si corres la aplicación, terminarás con un mapa de Bing que toma toda la pantalla y luce como esto:
Integrando el contrato de búsqueda
Ahora que tienes un mapa para desplegar los resultados de búsqueda, el siguiente paso es enlazarlo con el contrato de Búsqueda.
1) Agrega un contrato de búsqueda al proyecto. Para hacer esto da clic derecho en el proyecto y selecciona Agregar –> Nuevo elemento. Localiza el elemento de contrato de búsqueda y llámalo PaginaResultadosBusqueda.xaml
2) Una alerta estará desplegada que pregunta si te gustaría agregar algunos archivos faltantes a tu proyecto. Selecciona Si.
3) En este punto, notarás un número de cambios que se han hecho en el proyecto.
– En el app manifest, el contrato de Búsqueda esta declarado bajo la tabla de Declaraciones.
– Una página de resultados de búsqueda básica esta creada para tu app. Esta página de resultados se adhiere a las guías de UX para páginas de resultados en las guías de diseño para búsqueda.
– El manejador de eventos OnSearchActivated es agregado al archivo App.xaml.cs. Esto permite a tu aplicación responder a consultas de búsqueda incluso cuando tu app no está en la pantalla.
– Un número de archivos de ayuda son agregados bajo el folder Common.
4) Para este ejemplo no necesitas PaginaResultadosBusqueda.xaml. Así que puedes borrar el archivo del proyecto.
5)Abre el archivo App.xaml.cs y localiza el manejador de eventos OnSearchActivated(). Cerca del final de este manejador de eventos, encuentra la siguiente línea de código.
frame.Navigate(typeof(PaginaResultadosBusqueda), args.QueryText); |
Reemplaza el valor PaginaResultadosBusqueda con MainPage. Esto causará que la aplicación principal inicie cuando realices una búsqueda, incluso si la App no está abierta.
6) Abre el archivo MainPage.xaml.cs. Aquí, vas a querer obtener una referencia al panel del contrato de búsqueda y vas a adjuntar un método QuerySubmitted cuando el usuario navegue a la App. También debes remover este manejador cuando el usuario deje la aplicación. Este archivo deberá lucir como lo siguiente.
using Windows.ApplicationModel.Search; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace GeocodingContratoBusqueda { public sealed partial class MainPage : Page { private SearchPane panelBusqueda; public MainPage() { this.InitializeComponent(); panelBusqueda = SearchPane.GetForCurrentView(); panelBusqueda.PlaceholderText = "Busca una dirección, ciudad o lugar"; panelBusqueda.ShowOnKeyboardInput = true; } protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); panelBusqueda.QuerySubmitted += panelBusqueda_QuerySubmitted; } protected override void OnNavigatedFrom(NavigationEventArgs e) { base.OnNavigatedFrom(e); panelBusqueda.QuerySubmitted -= panelBusqueda_QuerySubmitted; } void panelBusqueda_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args) { } } } |
Agregando la lógica de Geocoding
Hasta este punto tenemos dos de las tres tareas completadas. El siguiente paso es integrar la lógica de geocoding usando los servicios REST de Bing Maps.
1) Primero necesitamos agregar los contratos JSON para los servicios REST de Bing Maps a tu proyectos. Para hacer esto, da clic derecho en tu proyecto y selecciona Agregar –> Nuevo elemento. Crea una clase llamada BingMapsRESTServices.cs. Abre el archivo y borra su contenido.
2) Copia los contratos de datos de C# JSON para los servicios REST de Bing Maps desde la documentación de MSDN. Pégalos los contratos de datos JSON en BingMapsRESTServices.cs.
3) En el archivo MainPage.xaml.cs agrega el siguiente método de ayuda para manejar solicitudes a los mapas de los servicios REST de Bing Maps
private async Task<Response> ObtenerRespuesta(Uri uri) { HttpClient cliente = new HttpClient(); var respuesta = await cliente.GetAsync(uri); using (var stream = await respuesta.Content.ReadAsStreamAsync()) { DataContractJsonSerializer serializador = new DataContractJsonSerializer(typeof(Response)); return serializador.ReadObject(stream) as Response; } } |
4) Enseguida la lógica para crear la consulta al servicio de geocoding puede ser agregada en el manejador de eventos de searchPane_QuerySubmitted. Una vez que la consulta ha sido hecha, puedes iterar entre los resultados y agregarlos como marcadores en el mapa. Actualiza el manejador de eventos para searchPane_QuerySubmitted tal como luce a continuación:
async void panelBusqueda_QuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args) { mapa.Children.Clear(); if (!string.IsNullOrWhiteSpace(args.QueryText)) { Uri direccionConsulta = new Uri(string.Format("http://dev.virtualearth.net/REST/v1/Locations?q={0}&c={1}&key={2}", Uri.EscapeUriString(args.QueryText), args.Language, mapa.Credentials)); Response respuesta = await ObtenerRespuestaAsync(direccionConsulta); if (respuesta != null && respuesta.ResourceSets != null && respuesta.ResourceSets.Length > 0 && respuesta.ResourceSets[0].Resources != null && respuesta.ResourceSets[0].Resources.Length > 0) { LocationCollection ubicaciones = new LocationCollection(); int i = 1; foreach (GeocodingContratoBusqueda.Location loc in respuesta.ResourceSets[0].Resources) { Bing.Maps.Location ubicacion = new Bing.Maps.Location(loc.Point.Coordinates[0], loc.Point.Coordinates[1]); Pushpin marcador = new Pushpin() { Tag = loc.Name, Text = i.ToString() }; i++; marcador.Tapped += (s, a) => { var p = s as Pushpin; new MessageDialog(p.Tag as string).ShowAsync(); }; MapLayer.SetPosition(marcador, ubicacion); mapa.Children.Add(marcador); ubicaciones.Add(ubicacion); } mapa.SetView(new LocationRect(ubicaciones)); } else { await new MessageDialog("No hay resultados.").ShowAsync(); } } } |
Hasta este punto, la aplicación esta completa. El paso final es ejecutarla y probar la aplicación. Presiona el botón de depuración para lanzar la aplicación. Abre la función de búsqueda desde el panel a la derecha y realiza una consulta. Debajo esta una captura de pantalla de una búsqueda de Londres.