Este artículo es la parte final de la serie que nos permite desplegar un archivo Shapefile sobre un mapa en Windows Phone. Para poder continuar lo primero que necesitas es crear un proyecto de Windows Phone en Visual Studio, una vez que lo tengas, debes agregar el paquete de NuGet para los servicios móviles de Windows Azure, puedes hacerlo desde el gestor de paquetes sin problemas.
Ya con el paquete agregado en tu proyecto ve a tu MainPage.xaml e inserta un control de mapa en toda el área (es recomendable que primero elimines todo lo que viene en la plantilla por defecto). El XAML de la página lucirá así.
<phone:PhoneApplicationPage x:Class="EstadosMexico.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:maps="clr-namespace:Microsoft.Phone.Maps.Controls;assembly=Microsoft.Phone.Maps" SupportedOrientations="Landscape" Orientation="Landscape" shell:SystemTray.IsVisible="False"> <Grid x:Name="LayoutRoot" Background="Transparent"> <maps:Map Name="mapa" CartographicMode="Road" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ZoomLevel="5" Center="19.41292, -99.145"/> </Grid> </phone:PhoneApplicationPage> |
Las coordendas y el centro del mapa corresponden a una forma cómoda de ver a México en su totalidad, obviamente puedes modificarlo de acuerdo a tus gustos. Después de eso debes crear una nueva clase, aquí si es necesario que la clase se llame Estados dado que el nombre debe empatar exactamente con el nombre de la tabla que utilizas en tu servicio móvil. La clase debe llevar las siguientes propiedades.
namespace EstadosMexico { class Estados { public int Id { get; set; } public string NombreEntidad { get; set; } public string ubicacion { get; set; } } } |
Ya con la clase creada, debes crear en MainPage.xaml.cs la invocación al servicio móvil de Azure, esto lo haces con un objeto estático, también, como objeto estático estableces un enlace con la tabla por medio de la interfaz IMobileServiceTable y su método GetTable()
namespace EstadosMexico { public partial class MainPage : PhoneApplicationPage { static MobileServiceClient mobileService = new MobileServiceClient("la direccion de tu servicio", "tu llave principal"); static IMobileServiceTable<Estados> statesTable = mobileService.GetTable<Estados>(); public MainPage() { InitializeComponent(); } } } |
Después crea un nuevo método de tipo asíncrono que te permitirá obtener un polígono, en el método puedes ver que solo estamos obteniendo un estado a través de la consulta con LINQ, si gustas puedes eliminar la sentencia Where para obtener todos los polígonos, considera bien esta opción dado que dibujarlos todos tomará mucho tiempo y recursos del dispositivo.
async static Task<Estados> GetPlacesInformation() { List<Estados> statesList = new List<Estados>(); statesList = await statesTable.Where(e => e.Id == 20).ToListAsync(); return statesList.FirstOrDefault(); } |
Después, crea un nuevo método, este método obtendrá del enorme arreglo de coordenadas del polígono cada una de ellas y las organizará de la forma que es necesaria para poder acumularlas en la colección de coordenadas del polígono para que después solo establezcas sus propiedades necesarias para hacerlo visible y agregarlo en el mapa.
private void ShowStatePolygon(Estados estado) { IEnumerable<string> coordenadas = estado.ubicacion.Split(new Char [] {',', '(', ')' }); MapPolygon poligonoEstado = new MapPolygon(); foreach (string elemento in coordenadas) { if (!elemento.Contains("POLYGON")) { if (string.IsNullOrEmpty(elemento)) { } else { double latitud = 0; double longitud = 0; var pair=elemento.Split(' ').Where(pre=>!string.IsNullOrEmpty(pre)); if (double.TryParse(pair.ElementAt(1), out latitud) && double.TryParse(pair.ElementAt(0), out longitud)) { poligonoEstado.Path.Add(new GeoCoordinate(latitud, longitud)); } } } } poligonoEstado.StrokeThickness = 1; poligonoEstado.StrokeColor = Color.FromArgb(125, 0, 0, 255); poligonoEstado.FillColor = Color.FromArgb(125, 0, 0, 255); mapa.MapElements.Add(poligonoEstado); } |
Ahora, para finalizar, solo terminar con invocar el método sobre escrito OnNavigatedTo y ahí manda llamar a los dos métodos que acabas de crear.
protected async override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Estados estadoElegido = new Estados(); estadoElegido = await GetPlacesInformation(); ShowStatePolygon(estadoElegido); } |
Compila y ejecuta tu solución, el resultado será el siguiente.
Listo!!! Así es como ya puedes desplegar elementos geográficos de cualquier tipo, ya sean puntos, líneas o polígonos sobre tu mapa si tienen su origen en un Shapefile y más importante aún, si es compatible con la referencia espacial WGS84. Así que a hacer nuevas y grandes Apps!!