Usar un API a mi en lo personal siempre me causa cierta emoción me encanta la idea de consumir varios servicios dentro de una misma aplicación y una de las mejores APIs que he encontrado es la de Bing Maps, dado que permite muchos usos así como una enorme sencillez en su formato para Silverlight.
Ahora comencemos a ver que onda con el servicio de imágenes de Bing Maps, la idea aquí es aprender a como lograr que podamos obtener en una ventana nueva la imagen del mapa que estamos viendo, aclaro que esto es un tanto complicado, pues si queremos exportar del mapa a una imagen de una manera mas directa no podremos por la sencilla razón de que es un “contenido protegido” y no pueden leerse sus píxeles, entonces consumiendo el servicio de imágenes (que la misma API permite) podremos hacerlo sin mayor problema, la idea de este tutorial es que puedas enviar el “extent” de tu mapa a una imagen que puedas guardar, los usos como siempre serán tu idea.
Después de haber creado un nuevo proyecto lo primero que debemos hacer es agregar una referencia a la librería de:
Microsoft.Maps.MapControl
La cual podrás descargar abriendo una cuenta de desarrollador en la página de Bing Maps que por cierto necesitarás dado que necesitas igualmente la Bing Maps Key así que pasar por ahí no es opcional.
Ya que tu referencia ha sido añadida, lo primero que debes hacer es añadir el namespace adecuado para poder usar el mapa en XAML.
xmlns:mapas="clr-namespace:Microsoft.Maps.MapControl;assembly=Microsoft.Maps.MapControl" |
Ya que tu namespace esta listo, simplemente añade el mapa dentro de tu control principal de la siguiente forma.
Coloqué las coordenadas adecuadas para que el mapa se ubicara en la república mexicana, si quieres poner las coordenadas de otro país solo calcula un poco o si te da flojera hazlo desde la página de la API interactiva.
Ya con el mapa en la posición adecuada puedes seguir adelante, colocando cuatro botones en donde gustes para cambiar de tipo de mapa y uno mas para exportar la imagen.
Algo así de sencillo, te servirá para seguir, ahora lo que debes hacer es solo crear los métodos, para los primeros tres botones la cosa es sencilla, solo inserta este código a cada uno.
private void CambiarMapa_Click(object sender, System.Windows.RoutedEventArgs e) { Button elemento = sender as Button; switch (elemento.Name) { case "btnMapa": mapa.Mode = new RoadMode(); break; case "btnImagen": mapa.Mode = new AerialMode(false); break; case "btnImagenNombres": mapa.Mode = new AerialMode(true); break; } } |
Listo, hasta aquí lo que has logrado es cambiar el modo en el que puedes cambiar el mapa, eso es prácticamente la mitad de lo que debes hacer, para continuar ve a insertar una referencia de servicio a la siguiente URL.
http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc
Ya que tienes la referencia al servicio web de imagenes de Bing, crea una función de la siguiente forma.
private void ObtenerImagenes(string ubicacion, int zoom) { bool httpsUriScheme = !Application.Current.IsRunningOutOfBrowser && HtmlPage.Document.DocumentUri.Scheme.Equals(Uri.UriSchemeHttps); BasicHttpBinding binding = httpsUriScheme ? new BasicHttpBinding(BasicHttpSecurityMode.Transport) : new BasicHttpBinding(BasicHttpSecurityMode.None); UriBuilder serviceUri = new UriBuilder("<a href="http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc">http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc");</a> if (httpsUriScheme) { serviceUri.Scheme = Uri.UriSchemeHttps; serviceUri.Port = -1; } Servicio1.ImageryServiceClient imagenServicio = new ImageryServiceClient(binding, new EndpointAddress(serviceUri.Uri)); MapUriRequest solicitud = new MapUriRequest(); solicitud.Credentials = new Credentials(); solicitud.Credentials.ApplicationId = "Aquí tus credenciales"; solicitud.Center = new Location(); string[] digitos = ubicacion.Split(','); solicitud.Center.Latitude = double.Parse(digitos[0].Trim()); solicitud.Center.Longitude = double.Parse(digitos[1].Trim()); opciones.ZoomLevel = zoom; opciones.ImageSize = new Servicio1.SizeOfint(); opciones.ImageSize.Height = 428; opciones.ImageSize.Width = 758; solicitud.Options = opciones; imagenServicio.GetMapUriCompleted += imagenServicio_GetMapUriCompleted; imagenServicio.GetMapUriAsync(solicitud); } |
Una función que recibirá dos parámetros, a la cual le estableces los parámetros necesarios para el contrato que utiliza el servicio de imágenes, después de eso con los objetos de tipo MapUriRequest y MapUriOptions (este último por favor colócalo de manera global pues lo necesitaremos mas adelante), establecerás la condición necesaria para poder ejecutar el método asíncrono de “GetMapUri” de tu servicio.
Ya que hayas pasado por este método, solo debes terminar por mandar el resultado en una nueva ventana para que puedas verlo, esto lo haces con el Event Handler del método “GetMapUri” de tu servicio.
void imagenServicio_GetMapUriCompleted(object sender, GetMapUriCompletedEventArgs e) { if (e.Error == null) { MapUriResponse resultado = new MapUriResponse(); resultado = e.Result; HtmlPage.Window.Navigate(new Uri(resultado.Uri), "_blank"); } } |
Por último, lo único que necesitas hacer es mandar llamar la función con los parámetros adecuados para poder ejecutarla de manera adecuada
private void btnExportar_Click(object sender, RoutedEventArgs e) { string direccion = mapa.Center.ToString(); int escala = Convert.ToInt16(mapa.ZoomLevel); ObtenerImagenes(direccion, escala); } |
En donde estás pasando el centro del mapa que tienes en pantalla, así como su nivel de zoom, nada mas que eso, ejecuta tu proyecto y checa el resultado.
Podría decir que acabamos, pero se que como buen desarrollador te diste cuenta de que solo exportas la imagen en un solo tipo de mapa, el de tipo mapa, y lo que tu quieres es que la imagen se exporte con cada tipo de mapa que hayas seleccionado, para esto modifica la función de los tres primeros botones de la siguiente forma.
private void CambiarMapa_Click(object sender, System.Windows.RoutedEventArgs e) { Button elemento = sender as Button; switch (elemento.Name) { case "btnMapa": opciones.Style = Microsoft.Maps.MapControl.PlatformServices.MapStyle.Road; mapa.Mode = new RoadMode(); break; case "btnImagen": opciones.Style = Microsoft.Maps.MapControl.PlatformServices.MapStyle.Aerial; mapa.Mode = new AerialMode(false); break; case "btnImagenNombres": opciones.Style = Microsoft.Maps.MapControl.PlatformServices.MapStyle.AerialWithLabels; mapa.Mode = new AerialMode(true); break; } } |
Ahora si lo puedo decir: Listo!!!!!! Ya estuvo, así puedes exportar tu mapa de Bing a una imagen usando el servicio de imágenes que la API de Bing te proporciona.
Puedes descargar el código aquí por cualquier duda que te haya surgido. (Recuerda que debes tener una API key para hacer funcionar el proyecto correctamente).