Em algumas situações específicas, precisamos mostrar mapas nos nossos aplicativos. Se você trabalhar no desenvolvimento de algum aplicativo que lide de alguma forma com endereços, é bem provável você precisará exibir esses endereços em um controle de mapas. Em aplicativos para a Windows Store (WinRT ou Metro Style Apps), podemos utilizar o controle do Bing Maps para exibirmos mapas, pontos, polígonos e rotas. E esse é o assunto do artigo dessa semana.

A documentação do controle do Bing Maps para aplicativos WinRT até que é bem escrita. Consegui utilizá-la como fonte de pesquisa para este artigo com sucesso. Porém, ela não foi traduzida para o português, e ela está espalhada em muitos tópicos, o que faz com que facilmente nos sintamos perdidos. Por isso, resolvi escrever este artigo onde abordo os principais pontos relacionados ao controle Bing Maps em aplicativos para a Windows Store.

Instalando o Bing Maps SDK

O primeiro passo necessário que temos que seguir é instalar o SDK do Bing Maps. Ele é simplesmente um arquivo vsix (extensão do Visual Studio) e pode ser baixado neste link. Após instalá-lo podemos utilizar o controle do Bing Maps em qualquer projeto de aplicativo para a Windows Store (desde que a referência seja adicionada – veremos mais detalhes a seguir).

Caso você se interesse, a Microsoft escreveu vários exemplos mostrando as mais diversas funcionalidades desse controle. Esses exemplos podem ser acessados aqui ou aqui. É importante observar que o controle de mapas não está disponível em algumas regiões. Felizmente no Brasil ele pode ser utilizado sem maiores problemas. Confira a lista completa dos países em que o controle do Bing Maps não é suportado.

Criando uma chave de autenticação

Antes de prosseguirmos com a criação da aplicação de exemplo, vamos criar uma chave de autenticação para o controle do Bing Maps. Como podemos fazer chamadas às APIs de roteamento, a Microsoft restringiu esse componente de forma que você só consegue utilizá-lo se tiver uma chave de autenticação.

O tutorial oficial que explica como gerar chaves de autenticação para o controle do Bing Maps é bem detalhado. Porém, vamos descrever os passos aqui neste artigo para que você tenha acesso a todo o procedimento em um só lugar.

Primeiramente, vá até o site https://www.bingmapsportal.com e crie uma conta utilizando a sua Microsoft Account. Feito isso, utilize o menu superior e escolha a opção “My account / Create or view keys“:

Na página que se abre, dê um nome para o aplicativo, escolha um tipo de licença, o tipo da aplicação e preencha o “captcha” conforme a figura apresentada:

Basicamente existem três opções de licença: “Trial” (gratuita que expira em 90 dias), “Basic” (gratuita que não expira, mas contém algumas restrições) ou “Enterprise” (paga, para grandes empresas que fazem um número muito grande de requisições). Para entender melhor os tipos de licença, confira este link. Eu escolhi o tipo de licença “Trial” para este aplicativo de exemplo.

Uma vez preenchidas as informações e clicado em “Create“, uma nova chave de autenticação será criada e as suas informações serão exibidas na parte inferior da página:

Guarde a informação da “Key“, pois precisaremos dela nas próximas etapas.

Agora que já temos a chave de ativação, vamos partir para a criação do exemplo.

Exibindo o mapa mundial

Crie um projeto em branco de aplicativo para a Windows Store e, logo de cara, adicione uma referência ao controle do Bing Maps. Ele se encontra dentro da categoria “Windows 8.1 / Extensions“:

Feito isso, repare que as referências aparecem com um ícone esquisito no “Solution Explorer“:

E, se você tentar compilar, receberá dois erros de compilação:

The processor architecture of the project being built “Any CPU” is not supported by the referenced SDK “Bing.Maps.Xaml, Version=1.313.0825.0”. Please consider changing the targeted processor architecture of your project (in Visual Studio this can be done through the Configuration Manager) to one of the architectures supported by the SDK: “x86, x64, ARM”.

The processor architecture of the project being built “Any CPU” is not supported by the referenced SDK “Microsoft.VCLibs, Version=12.0”. Please consider changing the targeted processor architecture of your project (in Visual Studio this can be done through the Configuration Manager) to one of the architectures supported by the SDK: “x86, x64, ARM”.

Isso se deve ao fato que o controle do Bing Maps não suporta projetos que estejam configurados para compilar em “Any CPU” (e esse é o padrão quando criamos um aplicativo para a Windows Store). Utilize o menu na barra do Visual Studio e escolha uma das arquiteturas disponíveis (eu escolhi x86 para este exemplo):

Após alterar a arquitetura do processador, você deve conseguir compilar o projeto sem problema algum.

O próximo passo é adicionar o controle de mapas na MainPage. Para isso, abra o arquivo “MainPage.xaml” e adicione uma declaração de namespace na abertura da tagPage“:

[code language=”xml”] xmlns:BingMaps="using:Bing.Maps"
[/code]

Feito isso, adicione uma instância do controle de mapas dentro do Grid:

[code language=”xml”] <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<BingMaps:Map x:Name="MapControl"/>
</Grid>
[/code]

Note que nesse ponto o designer da página já mostra o controle de mapas:

Execute a aplicação e veja que você receberá uma mensagem no meio do controle de mapas indicando que as credenciais estão inválidas. Isso acontece porque nós ainda não especificamos as credenciais no controle.

The specified credentials are invalid. You can sign up for a free developer account at http://www.bingmapsportal.com

Para especificar a chave de autenticação, é só utilizar a propriedade “Credentials” do controle, colocando a chave gerada anteriormente:

[code language=”xml”] <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<BingMaps:Map x:Name="MapControl"
Credentials="SUA_KEY_AQUI"/>
</Grid>
[/code]

Se você executar novamente a aplicação você conseguirá visualizar o mapa mundial e conseguirá navegar por ele utilizando o mouse ou touch. Antigamente os mapas do Bing Maps eram bem pobres, mas, eles evoluíram muito nos últimos tempos.

Note que o controle já vem com opções de exibir a visão de ruas, visão aérea ou visão mista. Além disso, ele também conta informações de tráfego e botões de zoom no canto superior direito:

Adicionando Pushpins (alfinetes?)

Uma das funcionalidades mais utilizadas em controles de mapas (além de exibir o mapa, é claro) é a exibição de pushpins (a tradução seria “alfinete“? – vou utilizar o termo em inglês por não ter encontrado uma tradução melhor para esse termo). A criação de pushpins no controle do Bing Maps é muito simples. Veja como podemos adicionar pushpins através do XAML:

[code language=”xml”] <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<BingMaps:Map x:Name="MapControl"
Credentials="SUA_KEY_AQUI">
<BingMaps:Map.Children>
<BingMaps:Pushpin>
<BingMaps:MapLayer.Position>
<BingMaps:Location Latitude="47.9232265"
Longitude="9.755016" />
</BingMaps:MapLayer.Position>
</BingMaps:Pushpin>
</BingMaps:Map.Children>
</BingMaps:Map>
</Grid>
[/code]

E através do code-behind, em C#, fica mais fácil ainda:

[code language=”csharp”] public MainPage()
{
this.InitializeComponent();

var pushPinLimeira = new Bing.Maps.Pushpin();
Bing.Maps.MapLayer.SetPosition(pushPinLimeira, new Bing.Maps.Location(-22.5633975, -47.4016201));
MapControl.Children.Add(pushPinLimeira);
}
[/code]

Vamos implementar agora a funcionalidade de adicionar um pushpin no centro do mapa. Para isso, vamos adicionar primeiramente um AppBar ao nosso aplicativo com um botão para que o usuário acesse esse comando:

[code language=”xml”] <Page.BottomAppBar>
<CommandBar>
<AppBarButton x:Name="AdicionarPushpin"
Label="Adicionar Pushpin"
Icon="Flag"
Tapped="AdicionarPushpin_Tapped"/>
</CommandBar>
</Page.BottomAppBar>
[/code]

E então, no code-behind da MainPage, temos que adicionar a implementação do handlerAdicionarPushpin_Tapped“:

[code language=”csharp”] private void AdicionarPushpin_Tapped(object sender, TappedRoutedEventArgs e)
{
var novoPushPin = new Bing.Maps.Pushpin();
Bing.Maps.MapLayer.SetPosition(novoPushPin, MapControl.Center);
MapControl.Children.Add(novoPushPin);
}
[/code]

Note que a única diferença é que ao invés de utilizarmos uma coordenada específica, nós utilizamos como posição o centro do mapa (“MapControl.Center“).

É possível fazer com que os pushpins sejam arrastáveis, mas, essa funcionalidade não é disponibilizada nativamente. Caso você se interesse por essa possibilidade, dê uma olhada neste exemplo da MSDN Code Gallery.

Desenhando polígonos

Outra necessidade bem comum ao utilizarmos controles de mapas é a exibição de pontos ou polígonos. Isso é facilmente resolvido pelo controle do Bing Maps utilizando as chamadas “MapPolygons“. Veja como fica no XAML:

[code language=”xml”] <BingMaps:Map.ShapeLayers>
<BingMaps:MapShapeLayer>
<BingMaps:MapShapeLayer.Shapes>
<BingMaps:MapPolygon FillColor="Red">
<BingMaps:MapPolygon.Locations>
<BingMaps:Location Latitude="-19"
Longitude="-46" />
<BingMaps:Location Latitude="-19"
Longitude="-44" />
<BingMaps:Location Latitude="-21"
Longitude="-44" />
<BingMaps:Location Latitude="-21"
Longitude="-46" />
</BingMaps:MapPolygon.Locations>
</BingMaps:MapPolygon>
</BingMaps:MapShapeLayer.Shapes>
</BingMaps:MapShapeLayer>
</BingMaps:Map.ShapeLayers>
[/code]

E confira abaixo como podemos desenhar o mesmo polígono através do code-behind em C#:

[code language=”csharp”] var layerPoligono = new Bing.Maps.MapShapeLayer();
var poligono = new Bing.Maps.MapPolygon();
poligono.Locations = new Bing.Maps.LocationCollection()
{
new Bing.Maps.Location(-19, -46),
new Bing.Maps.Location(-19, -44),
new Bing.Maps.Location(-21, -44),
new Bing.Maps.Location(-21, -46)
};
poligono.FillColor = Windows.UI.Colors.Red;
layerPoligono.Shapes.Add(poligono);
MapControl.ShapeLayers.Add(layerPoligono);
[/code]

Com a ajuda de uma biblioteca externa é possível também carregarmos arquivos de shapes da ESRI (shape files – .shp). Caso você tenha que implementar essa funcionalidade no seu aplicativo, confira a biblioteca “Microsoft Maps Spatial Toolbox“.

Calculando rotas

Para finalizar, vou mostrar como calcular a rota entre Salvador e Belém. Adicione mais um AppBarButton para chamarmos o método que será responsável por essa funcionalidade:

[code language=”xml”] <AppBarButton x:Name="CalcularRota"
Label="Calcular Rota"
Icon="Directions"
Tapped="CalcularRota_Tapped" />
[/code]

E então, adicione no code-behind da MainPage o handlerCalcularRota_Tapped“, que calculará e exibirá no mapa a rota entre Salvador e Belém:

[code language=”csharp”] private async void CalcularRota_Tapped(object sender, TappedRoutedEventArgs e)
{
Bing.Maps.Directions.Waypoint inicio = new Bing.Maps.Directions.Waypoint(new Bing.Maps.Location(-12.8809348, -38.4175336));
Bing.Maps.Directions.Waypoint fim = new Bing.Maps.Directions.Waypoint(new Bing.Maps.Location(-1.3631202, -48.4757975));

Bing.Maps.Directions.WaypointCollection waypoints = new Bing.Maps.Directions.WaypointCollection();
waypoints.Add(inicio);
waypoints.Add(fim);

MapControl.DirectionsManager.Waypoints = waypoints;
Bing.Maps.Directions.RouteResponse response = await MapControl.DirectionsManager.CalculateDirectionsAsync();
MapControl.DirectionsManager.ShowRoutePath(response.Routes[0]);
}
[/code]

É possível adicionarmos diversos WayPoints (no nosso exemplo só adicionamos dois Waypoints: as coordenadas de Salvador e de Belém). Teoricamente poderíamos utilizar os próprios nomes das cidades nos WayPoints, mas, ao tentar isso, acabei recebendo um erro:

There is no route data for the specified waypoints

Concluindo

Visualização de mapas em aplicativo móveis é uma necessidade bem comum. Nesse ponto a Microsoft acertou e disponibilizou o controle do Bing Maps diretamente na plataforma WinRT. Nesse artigo você aprendeu a criar a chave de autenticação para o controle do Bing Maps, viu como adicionar o controle de mapa em uma página e adicionar pushpins, além de ter aprendido a desenhar polígonos e calcular rotas com esse controle. Agora é só começar a utilizá-lo nas suas aplicações!

Qualquer dúvida ou sugestão, poste um comentário. Até a próxima!

André Lima

Image by http://maps.bpl.org used under Creative Commons
https://www.flickr.com/photos/normanbleventhalmapcenter/2674855383/