Mapeamento
O controle .NET MAUI (.NET Multi-Platform App UI) Map é uma exibição multiplataforma para exibir e anotar mapas. O controle Map usa o controle de mapa nativo em cada plataforma e é fornecido pelo pacote NuGet Microsoft.Maui.Controls.Maps.
Importante
O controle Map não é compatível com o Windows devido à falta de um controle de mapa no WinUI. No entanto, o pacote NuGet CommunityToolkit.Maui.Maps fornece acesso ao Bing Mapas por meio de um WebView
no Windows. Para obter mais informações, consulte Introdução.
Instalação
O controle Map usa o controle de mapa nativo em cada plataforma. Isso fornece uma experiência de mapas rápida e familiar para os usuários, mas significa que algumas etapas de configuração são necessárias para aderir aos requisitos de API de cada plataforma.
Inicialização do Mapa
O controle Map é fornecido pelo pacote NuGet Microsoft.Maui.Controls.Maps, que deve ser adicionado ao seu projeto de aplicativo do .NET MAUI.
Depois de instalar o pacote NuGet, ele precisa ser inicializado em seu aplicativo chamando o método UseMauiMap
no objeto MauiAppBuilder
no método CreateMauiApp
de sua classe MauiProgram
:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseMauiMaps();
return builder.Build();
}
}
Depois que o pacote NuGet tiver sido adicionado e inicializado, as APIs Map poderão ser usadas em seu projeto.
Configuração da plataforma
Para que o mapa seja exibido, é necessário realizar configuração adicional no Android. Além disso, no iOS, Android e Mac Catalyst, acessar a localização do usuário requer que permissões de localização tenham sido concedidas ao seu aplicativo.
Catalisador para iOS e Mac
Exibir e interagir com um mapa no iOS e no Mac Catalyst não requer nenhuma configuração adicional. No entanto, para acessar os serviços de localização, você deve definir as solicitações de serviços de localização necessárias em Info.plist. Normalmente, eles serão um ou mais dos seguintes:
NSLocationAlwaysAndWhenInUseUsageDescription
– para usar serviços de localização em todos os momentos.NSLocationWhenInUseUsageDescription
– para usar serviços de localização quando o aplicativo estiver em uso.
Para obter mais informações, confira Escolher a autorização de serviços de localização a ser solicitada em developer.apple.com.
A representação XML para essas chaves em Info.plist é mostrada abaixo. Você deve atualizar os valores de string
para refletir como seu aplicativo está usando as informações de localização:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Can we use your location at all times?</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Can we use your location when your app is being used?</string>
Um prompt é exibido quando seu aplicativo tenta acessar a localização do usuário, solicitando acesso:
Android
O processo de configuração para exibir e interagir com um mapa no Android é:
- Obter uma chave de API do Google Maps e adicioná-la ao manifesto do aplicativo.
- Especifique o número de versão dos serviços do Google Play no manifesto.
- [opcional] Especifique permissões de local no manifesto.
- [opcional] Especifique a permissão WRITE_EXTERNAL_STORAGE no manifesto.
Obter uma chave da API do Google Maps
Para usar o controle Map no Android, você precisa gerar uma chave de API, que será consumida pelo SDK do Google Maps no qual o controle Map depende do Android. Para fazer isso, siga as instruções em Configurar no Console do Google Cloud e Usar chaves de API em developers.google.com.
Depois que você obtiver uma chave de API, ela precisará ser adicionada no elemento <application>
do arquivo Platforms/Android/AndroidManifest.xml, especificando-a como o valor dos metadados com.google.android.geo.API_KEY
:
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true">
<meta-data android:name="com.google.android.geo.API_KEY" android:value="PASTE-YOUR-API-KEY-HERE" />
</application>
Isso insere a chave de API no manifesto. Sem uma chave de API válida, o controle Map exibirá uma grade em branco.
Observação
com.google.android.geo.API_KEY
é o nome de metadados recomendado para a chave de API. Uma chave com esse nome pode ser usada para autenticar em várias APIs baseadas no Google Maps no Android. Para compatibilidade com versões anteriores, o nome dos metadados com.google.android.maps.v2.API_KEY
pode ser usado, mas só permite a autenticação para a API v2 do Android Maps. Um aplicativo só pode especificar um dos nomes de metadados da chave de API.
Especificar o número de versão dos serviços do Google Play
Adicione a seguinte declaração no elemento <application>
de AndroidManifest.xml:
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Isso insere no manifesto a versão dos serviços do Google Play com os quais o aplicativo foi compilado.
Especificar permissões de localização
Se o aplicativo precisar acessar a localização do usuário, você precisará solicitar permissão adicionando as permissões ACCESS_COARSE_LOCATION
ou ACCESS_FINE_LOCATION
(ou ambas) ao manifesto, como um filho do elemento <manifest>
:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<!-- Required to access the user's location -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>
A permissão ACCESS_COARSE_LOCATION
permite que a API use Wi-Fi ou dados móveis, ou ambos, para determinar a localização do dispositivo. As permissões ACCESS_FINE_LOCATION
permitem que a API use o GPS (Sistema de Posicionamento Global), Wi-Fi ou dados móveis para determinar uma localização com o máximo possível de precisão.
Um prompt é exibido quando seu aplicativo tenta acessar a localização do usuário, solicitando acesso:
Como alternativa, essas permissões podem ser habilitadas no editor de manifesto do Android do Visual Studio.
Especificar a permissão WRITE_EXTERNAL_STORAGE
Se o aplicativo for destinado à API 22 ou inferior, será necessário adicionar a permissão WRITE_EXTERNAL_STORAGE
ao manifesto, como um filho do elemento <manifest>
:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Isso não será necessário se o aplicativo for direcionado à API 23 ou superior.
Controle de mapeamento
A classe Map define as seguintes propriedades que controlam a aparência e o comportamento do mapa:
IsShowingUser
, do tipobool
, indica se o mapa está mostrando a localização atual do usuário.ItemsSource
, do tipoIEnumerable
, que especifica a coleção de itens de alfineteIEnumerable
a serem exibidos.ItemTemplate
, do tipo DataTemplate, que especifica o DataTemplate a ser aplicado a cada item na coleção de alfinetes exibidos.ItemTemplateSelector
, do tipo DataTemplateSelector, que especifica o DataTemplateSelector que será usado para escolher um DataTemplate para um alfinete em runtime.IsScrollEnabled
, do tipobool
, determina se o mapa tem permissão para rolar.IsTrafficEnabled
, do tipobool
, indica se os dados de tráfego são sobrepostos no mapa.IsZoomEnabled
, do tipobool
, determina se o mapa tem permissão para ampliar.MapElements
, do tipoIList<MapElement>
, representa a lista de elementos no mapa, como polígonos e polilinhas.MapType
, do tipoMapType
, indica o estilo de exibição do mapa.Pins
, do tipoIList<Pin>
, representa a lista de alfinetes no mapa.VisibleRegion
, do tipoMapSpan
, retorna a região do mapa exibida no momento.
Essas propriedades, com exceção das propriedades MapElements
, Pins
e VisibleRegion
, são apoiadas por objetos BindableProperty, o que significa que elas podem ser destinos de associações de dados.
A classe Map também define um evento MapClicked
que é disparado quando o mapa é tocado. O objeto MapClickedEventArgs
que acompanha o evento tem apenas uma propriedade chamada Location
, do tipo Location
. Quando o evento é disparado, a propriedade Location
é definida como o local do mapa que foi tocado. Para obter informações sobre a classe Location
, consulte Localização e distância.
Para obter informações sobre as propriedades ItemsSource
, ItemTemplate
e ItemTemplateSelector
, consulte Exibir uma coleção de alfinetes.
Exibir um mapa
Um Map pode ser exibido adicionando-o a um layout ou página:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<maps:Map x:Name="map" />
</ContentPage>
Este é o código C# equivalente:
using Map = Microsoft.Maui.Controls.Maps.Map;
namespace WorkingWithMaps
{
public class MapTypesPageCode : ContentPage
{
public MapTypesPageCode()
{
Map map = new Map();
Content = map;
}
}
}
Este exemplo chama o construtor padrão Map, que centraliza o mapa em Maui, Havaí:
Como alternativa, um argumento MapSpan
pode ser passado para um construtor Map para definir o ponto central e o nível de zoom do mapa quando ele é carregado. Para obter mais informações, confira Exibir um local específico em um mapa.
Importante
O .NET MAUI tem dois tipos Map
- Microsoft.Maui.Controls.Maps.Map e Microsoft.Maui.ApplicationModel.Map. Como o namespace Microsoft.Maui.ApplicationModel é uma das diretivas global using
do .NET MAUI, ao usar o controle Microsoft.Maui.Controls.Maps.Map no código, você terá que qualificar totalmente o uso de Map
ou usar um alias usando.
Tipos de mapa
A propriedade Map.MapType
pode ser definida como um membro de enumeração MapType
para definir o estilo de exibição do mapa. A enumeração MapType
define os seguintes membros:
Street
especifica que um mapa de ruas será exibido.Satellite
especifica que um mapa contendo imagens de satélite será exibido.Hybrid
especifica que um mapa combinando dados de ruas e de satélite será exibido.
Por padrão, um Map exibirá um mapa de ruas se a propriedade MapType
estiver indefinida. Como alternativa, a propriedade MapType
pode ser definida como um dos membros da enumeração MapType
:
<maps:Map MapType="Satellite" />
Este é o código C# equivalente:
Map map = new Map
{
MapType = MapType.Satellite
};
Exibir uma localização específica em um mapa
A região de um mapa a ser exibida quando um mapa é carregado pode ser definida passando um argumento MapSpan
para o construtor Map:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<x:Arguments>
<maps:MapSpan>
<x:Arguments>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
<x:Double>0.01</x:Double>
<x:Double>0.01</x:Double>
</x:Arguments>
</maps:MapSpan>
</x:Arguments>
</maps:Map>
</ContentPage>
Este é o código C# equivalente:
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Location location = new Location(36.9628066, -122.0194722);
MapSpan mapSpan = new MapSpan(location, 0.01, 0.01);
Map map = new Map(mapSpan);
Este exemplo cria um objeto Map que mostra a região especificada pelo objeto MapSpan
. O objeto MapSpan
é centrado na latitude e longitude representadas por um objeto Location
, e abrange 0,01 graus de latitude e 0,01 graus de longitude. Para obter informações sobre a classe Location
, consulte Localização e distância. Para obter informações sobre como passar argumentos em XAML, confira Passar argumentos em XAML.
O resultado é que, quando o mapa é exibido, ele é centralizado em um local específico e abrange um número específico de graus de latitude e longitude:
Criar um objeto MapSpan
Há uma série de abordagens para a criação de objetos MapSpan
. Uma abordagem comum é fornecer os argumentos necessários ao construtor MapSpan
. Estes são uma latitude e longitude representadas por um objeto Location
, e valores double
que representam os graus de latitude e longitude que são estendidos pelo MapSpan
. Para obter informações sobre a classe Location
, consulte Localização e distância.
Como alternativa, há três métodos na classe MapSpan
que retornam novos objetos MapSpan
:
ClampLatitude
retorna umMapSpan
com o mesmoLongitudeDegrees
que a instância de classe do método e um raio definido pelos argumentosnorth
esouth
dele.FromCenterAndRadius
retorna umMapSpan
que é definido pelos argumentosLocation
eDistance
dele.WithZoom
retorna umMapSpan
com o mesmo centro que a instância de classe do método, mas com um raio multiplicado pelo argumentodouble
dele.
Para obter informações sobre o struct Distance
, consulte Localização e distância.
Depois que um MapSpan
tiver sido criado, as seguintes propriedades podem ser acessadas para recuperar dados sobre ele:
Center
, do tipoLocation
, que representa o local no centro geográfico doMapSpan
.LatitudeDegrees
, do tipodouble
, que representa os graus de latitude que são abrangidos peloMapSpan
.LongitudeDegrees
, do tipodouble
, que representa os graus de longitude que são abrangidos peloMapSpan
.Radius
, do tipoDistance
, que representa o raio deMapSpan
.
Mover o mapa
O método Map.MoveToRegion
pode ser chamado para alterar a posição e o nível de zoom de um mapa. Esse método aceita um argumento MapSpan
que define a região do mapa a ser exibida e seu nível de zoom.
O seguinte código mostra um exemplo de como mover a região exibida em um mapa:
using Microsoft.Maui.Maps;
using Microsoft.Maui.Controls.Maps.Map;
...
MapSpan mapSpan = MapSpan.FromCenterAndRadius(location, Distance.FromKilometers(0.444));
map.MoveToRegion(mapSpan);
Ampliar o mapa
O nível de zoom de um Map pode ser alterado sem alterar a localização dele. Isso pode ser feito usando a interface do usuário do mapa ou programaticamente, chamando o método MoveToRegion
com um argumento MapSpan
que usa o local atual como argumento Location
:
double zoomLevel = 0.5;
double latlongDegrees = 360 / (Math.Pow(2, zoomLevel));
if (map.VisibleRegion != null)
{
map.MoveToRegion(new MapSpan(map.VisibleRegion.Center, latlongDegrees, latlongDegrees));
}
Neste exemplo, o método MoveToRegion
é chamado com um argumento MapSpan
, que especifica o local atual do mapa por meio da propriedade Map.VisibleRegion
, e o nível de zoom como graus de latitude e longitude. O resultado geral é que o nível de zoom do mapa é alterado, mas a localização dele não. Uma abordagem alternativa para implementar o zoom em um mapa é usar o método MapSpan.WithZoom
para controlar o fator de zoom.
Importante
Ampliar um mapa, seja por meio da interface do usuário do mapa ou programaticamente, requer que a propriedade Map.IsZoomEnabled
seja true
. Para obter mais informações sobre essa propriedade, confira Desabilitar zoom.
Personalizar o comportamento do mapa
O comportamento de um Map pode ser personalizado definindo algumas de suas propriedades e manipulando o evento MapClicked
.
Observação
Uma personalização adicional do comportamento de mapa pode ser obtida personalizando o manipulador dele. Para obter mais informações, confira Personalizar controles com manipuladores.
Mostrar dados de tráfego
A classe Map define uma propriedade IsTrafficEnabled
do tipo bool
. Por padrão, essa propriedade é false
, o que indica que os dados de tráfego não serão sobrepostos no mapa. Quando essa propriedade é definida como true
, os dados de tráfego são sobrepostos no mapa:
<maps:Map IsTrafficEnabled="true" />
Este é o código C# equivalente:
Map map = new Map
{
IsTrafficEnabled = true
};
Desativar rolagem
A classe Map define uma propriedade IsScrollEnabled
do tipo bool
. Por padrão, essa propriedade é true
, o que indica que o mapa permite rolagem. Quando essa propriedade é definida como false
, o mapa não tem rolagem:
<maps:Map IsScrollEnabled="false" />
Este é o código C# equivalente:
Map map = new Map
{
IsScrollEnabled = false
};
Desabilitar zoom
A classe Map define uma propriedade IsZoomEnabled
do tipo bool
. Por padrão, essa propriedade é true
, o que indica que o zoom pode ser executado no mapa. Quando essa propriedade é definida como false
, o mapa não pode ser ampliado ou reduzido:
<maps:Map IsZoomEnabled="false" />
Este é o código C# equivalente:
Map map = new Map
{
IsZoomEnabled = false
};
Detectar a localização do usuário
A classe Map define uma propriedade IsShowingUser
do tipo bool
. Por padrão, essa propriedade é false
, que indica que o mapa não está mostrando a localização atual do usuário. Quando essa propriedade é definida como true
, o mapa mostra a localização atual do usuário:
<maps:Map IsShowingUser="true" />
Este é o código C# equivalente:
Map map = new Map
{
IsShowingUser = true
};
Importante
Acessar a localização do usuário requer que permissões de localização tenham sido concedidas ao aplicativo. Para obter mais informações, confira Configuração da plataforma.
Cliques no mapa
A classe Map define um evento MapClicked
que é acionado quando o mapa é tocado. O objeto MapClickedEventArgs
que acompanha o evento tem apenas uma propriedade chamada Location
, do tipo Location
. Quando o evento é disparado, a propriedade Location
é definida como o local do mapa que foi tocado. Para obter informações sobre a classe Location
, consulte Localização e distância.
O seguinte exemplo de código mostra um manipulador de eventos para o evento MapClicked
:
void OnMapClicked(object sender, MapClickedEventArgs e)
{
System.Diagnostics.Debug.WriteLine($"MapClick: {e.Location.Latitude}, {e.Location.Longitude}");
}
Neste exemplo, o manipulador de eventos OnMapClicked
gera a latitude e a longitude que representam o local do mapa tocado. O manipulador de eventos precisa ser registrado com o evento MapClicked
:
<maps:Map MapClicked="OnMapClicked" />
Este é o código C# equivalente:
Map map = new Map();
map.MapClicked += OnMapClicked;
Localização e distância
O namespace Microsoft.Maui.Devices.Sensors
contém uma classe Location
que normalmente é usada ao posicionar um mapa e seus alfinetes. O namespace Microsoft.Maui.Maps
contém um struct Distance
que pode ser usado opcionalmente ao posicionar um mapa.
Localidade
A classe Location
encapsula um local armazenado como valores de latitude e longitude. Essa classe define as seguintes propriedades:
Accuracy
, do tipodouble?
, que representa a precisão horizontal doLocation
, em metros.Altitude
, do tipodouble?
, que representa a altitude em metros em um sistema de referência especificado pela propriedadeAltitudeReferenceSystem
.AltitudeReferenceSystem
, do tipoAltitudeReferenceSystem
, que especifica o sistema de referência no qual o valor de altitude é fornecido.Course
, do tipodouble?
, que indica o valor de graus relativo ao norte verdadeiro.IsFromMockProvider
, do tipobool
, que indica se o local é do GPS ou de um provedor de localização fictício.Latitude
, do tipodouble
, que representa a latitude do local em graus decimais.Longitude
, do tipodouble
, que representa a longitude do local em graus decimais.Speed
, do tipodouble?
, que representa a velocidade em metros por segundo.Timestamp
, do tipoDateTimeOffset
, que representa o carimbo de data/hora quando oLocation
foi criado.VerticalAccuracy
, do tipodouble?
, que especifica a precisão vertical doLocation
, em metros.
Os objetos Location
são criados com uma das sobrecargas do construtor Location
, que normalmente exigem argumentos mínimos de latitude e longitude especificados como valores double
:
Location location = new Location(36.9628066, -122.0194722);
Ao criar um objeto Location
, o valor de latitude será fixado entre -90,0 e 90,0, e o valor de longitude será fixado entre -180,0 e 180,0.
Observação
A classe GeographyUtils
tem um método de extensão ToRadians
que converte um valor double
de graus em radianos e um método de extensão ToDegrees
que converte um valor double
de radianos em graus.
A classe Location
também tem métodos CalculateDistance
que calculam a distância entre dois locais.
Distância
O struct Distance
encapsula uma distância armazenada como um valor double
, que representa a distância em metros. Esse struct define três propriedades somente leitura:
Kilometers
, do tipodouble
, que representa a distância em quilômetros que é abrangida peloDistance
.Meters
, do tipodouble
, que representa a distância em metros que é abrangida peloDistance
.Miles
, do tipodouble
, que representa a distância em milhas que é abrangida peloDistance
.
Os objetos Distance
podem ser criados com o construtor Distance
, que requer um argumento de metros especificado como um double
:
Distance distance = new Distance(1450.5);
Como alternativa, os objetos Distance
podem ser criados com os métodos de fábrica FromKilometers
, FromMeters
, FromMiles
e BetweenPositions
:
Distance distance1 = Distance.FromKilometers(1.45); // argument represents the number of kilometers
Distance distance2 = Distance.FromMeters(1450.5); // argument represents the number of meters
Distance distance3 = Distance.FromMiles(0.969); // argument represents the number of miles
Distance distance4 = Distance.BetweenPositions(location1, location2);
marcadores
O controle Map permite que os locais sejam marcados com objetos Pin
. Um Pin
é um marcador de mapa que abre uma janela de informações quando tocado:
Quando um objeto Pin
é adicionado à coleção Map.Pins
, o alfinete é renderizado no mapa.
A classe Pin
tem as propriedades a seguir:
Address
, do tipostring
, que normalmente representa o endereço da localização do alfinete. No entanto, isso pode ser qualquer conteúdostring
, não apenas um endereço.- Label, do tipo
string
, que normalmente representa o título do alfinete. Location
, do tipoLocation
, que representa a latitude e longitude do alfinete.Type
, do tipoPinType
, que representa o tipo de alfinete.
Essas propriedades são apoiadas por objetos BindableProperty, o que significa que um Pin
pode ser alvo de associações de dados. Para obter mais informações sobre objetos Pin
de vinculação de dados, consulte Exibir uma coleção de alfinetes.
Além disso, a classe Pin
define eventos MarkerClicked
e InfoWindowClicked
. O evento MarkerClicked
é disparado quando um alfinete é tocado e o evento InfoWindowClicked
é disparado quando a janela de informações é tocada. O objeto PinClickedEventArgs
que acompanha ambos os eventos tem apenas uma propriedade HideInfoWindow
, do tipo bool
.
Exibir um alfinete
Um Pin
pode ser adicionado a um Map em XAML:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map x:Name="map">
<x:Arguments>
<maps:MapSpan>
<x:Arguments>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
<x:Double>0.01</x:Double>
<x:Double>0.01</x:Double>
</x:Arguments>
</maps:MapSpan>
</x:Arguments>
<maps:Map.Pins>
<maps:Pin Label="Santa Cruz"
Address="The city with a boardwalk"
Type="Place">
<maps:Pin.Location>
<sensors:Location>
<x:Arguments>
<x:Double>36.9628066</x:Double>
<x:Double>-122.0194722</x:Double>
</x:Arguments>
</sensors:Location>
</maps:Pin.Location>
</maps:Pin>
</maps:Map.Pins>
</maps:Map>
</ContentPage>
Esse XAML cria um objeto Map que mostra a região especificada pelo objeto MapSpan
. O objeto MapSpan
é centrado na latitude e longitude representadas por um objeto Location
, que se estende 0,01 graus de latitude e longitude. Um objeto Pin
é adicionado à coleção Map.Pins
e desenhado no Map no local especificado pela propriedade Location
dele. Para obter informações sobre a classe Location
, consulte Localização e distância. Para obter informações sobre como passar argumentos em XAML para objetos que não têm construtores padrão, consulte Passar argumentos em XAML.
Este é o código C# equivalente:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map
{
...
};
Pin pin = new Pin
{
Label = "Santa Cruz",
Address = "The city with a boardwalk",
Type = PinType.Place,
Location = new Location(36.9628066, -122.0194722)
};
map.Pins.Add(pin);
Este código de exemplo resulta em apenas um alfinete sendo renderizado em um mapa:
Interagir com um alfinete
Por padrão, quando um Pin
é tocado, a janela de informações dele é exibida:
Tocar em outro lugar no mapa fecha a janela de informações.
A classe Pin
define um evento MarkerClicked
, que é acionado quando um Pin
é tocado. Não é necessário manipular esse evento para exibir a janela de informações. Em vez disso, esse evento deverá ser manipulado quando houver um requisito para ser notificado de que um alfinete específico foi tocado.
A classe Pin
também define um evento InfoWindowClicked
que é acionado quando uma janela de informações é tocada. Esse evento deverá ser manipulado quando houver um requisito para ser notificado de que uma janela de informações específica foi tocada.
O seguinte código mostra um exemplo de manipulação desses eventos:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Pin boardwalkPin = new Pin
{
Location = new Location(36.9641949, -122.0177232),
Label = "Boardwalk",
Address = "Santa Cruz",
Type = PinType.Place
};
boardwalkPin.MarkerClicked += async (s, args) =>
{
args.HideInfoWindow = true;
string pinName = ((Pin)s).Label;
await DisplayAlert("Pin Clicked", $"{pinName} was clicked.", "Ok");
};
Pin wharfPin = new Pin
{
Location = new Location(36.9571571, -122.0173544),
Label = "Wharf",
Address = "Santa Cruz",
Type = PinType.Place
};
wharfPin.InfoWindowClicked += async (s, args) =>
{
string pinName = ((Pin)s).Label;
await DisplayAlert("Info Window Clicked", $"The info window was clicked for {pinName}.", "Ok");
};
O objeto PinClickedEventArgs
que acompanha ambos os eventos tem apenas uma propriedade HideInfoWindow
, do tipo bool
. Quando essa propriedade é definida como true
dentro de um manipulador de eventos, a janela de informações é ocultada.
Tipos de alfinete
Os objetos Pin
incluem uma propriedade Type
, do tipo PinType
, que representa o tipo de alfinete. A enumeração PinType
define os seguintes membros:
Generic
, que representa um alfinete genérico.Place
, que representa um alfinete para um lugar.SavedPin
, que representa um alfinete para um local salvo.SearchResult
, que representa um alfinete para um resultado de pesquisa.
No entanto, definir a propriedade Pin.Type
como qualquer membro PinType
não altera a aparência do alfinete renderizado. Em vez disso, você precisa personalizar o manipulador Pin
para personalizar a aparência do alfinete. Para obter mais informações sobre a personalização do manipulador, consulte Personalizar controles com manipuladores.
Exibir uma coleção de marcadores
A classe Map define as seguintes propriedades associáveis:
ItemsSource
, do tipoIEnumerable
, que especifica a coleção de itens de alfineteIEnumerable
a serem exibidos.ItemTemplate
, do tipo DataTemplate, que especifica o DataTemplate a ser aplicado a cada item na coleção de alfinetes exibidos.ItemTemplateSelector
, do tipo DataTemplateSelector, que especifica o DataTemplateSelector que será usado para escolher um DataTemplate para um alfinete em runtime.
Importante
A propriedade ItemTemplate
tem precedência quando as propriedades ItemTemplate
e ItemTemplateSelector
estão definidas.
Um Map pode ser preenchido com alfinetes usando a associação de dados para associar sua propriedade ItemsSource
a uma coleção IEnumerable
:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<Grid>
...
<maps:Map x:Name="map"
ItemsSource="{Binding Positions}">
<maps:Map.ItemTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</maps:Map.ItemTemplate>
</maps:Map>
...
</Grid>
</ContentPage>
Os dados da propriedade ItemsSource
se vinculam à propriedade Positions
do modelo de exibição conectado, que retorna um ObservableCollection
de objetos Position
, que é um tipo personalizado. Cada objeto Position
define propriedades Address
e Description
, do tipo string
, e uma propriedade Location
, do tipo Location
.
A aparência de cada item na coleção IEnumerable
é definida configurando-se a propriedade ItemTemplate
como um DataTemplate que contém um objeto Pin
, cujos dados são associados às propriedades adequadas.
A seguinte captura de tela mostra um Map exibindo uma coleção Pin
usando a associação de dados:
Escolher a aparência do item em tempo de execução
A aparência de cada item na coleção IEnumerable
pode ser escolhida em tempo de execução, com base no valor do item, definindo a propriedade ItemTemplateSelector
como DataTemplateSelector:
<ContentPage ...
xmlns:templates="clr-namespace:WorkingWithMaps.Templates"
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps">
<ContentPage.Resources>
<templates:MapItemTemplateSelector x:Key="MapItemTemplateSelector">
<templates:MapItemTemplateSelector.DefaultTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="{Binding Description}" />
</DataTemplate>
</templates:MapItemTemplateSelector.DefaultTemplate>
<templates:MapItemTemplateSelector.SanFranTemplate>
<DataTemplate>
<maps:Pin Location="{Binding Location}"
Address="{Binding Address}"
Label="Xamarin!" />
</DataTemplate>
</templates:MapItemTemplateSelector.SanFranTemplate>
</templates:MapItemTemplateSelector>
</ContentPage.Resources>
<Grid>
...
<maps:Map x:Name="map"
ItemsSource="{Binding Positions}"
ItemTemplateSelector="{StaticResource MapItemTemplateSelector}">
...
</Grid>
</ContentPage>
O exemplo a seguir mostra a classe MapItemTemplateSelector
:
using WorkingWithMaps.Models;
namespace WorkingWithMaps.Templates;
public class MapItemTemplateSelector : DataTemplateSelector
{
public DataTemplate DefaultTemplate { get; set; }
public DataTemplate SanFranTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((Position)item).Address.Contains("San Francisco") ? SanFranTemplate : DefaultTemplate;
}
}
A MapItemTemplateSelector
classe define propriedades DefaultTemplate
e SanFranTemplate
DataTemplate que são configuradas para diferentes modelos de dados. O método OnSelectTemplate
retorna o SanFranTemplate
, que exibe "Xamarin" como um rótulo quando um Pin
é tocado, quando o item tem um endereço que contém "San Francisco". Quando o item não tem um endereço que contém "São Francisco", o método OnSelectTemplate
retorna o DefaultTemplate
.
Observação
Um caso de uso para essa funcionalidade é associar propriedades de objetos Pin
com subclasse a propriedades diferentes, com base no subtipo Pin
.
Para obter mais informações sobre seletores de modelo de dados, consulte Criar um DataTemplateSelector.
Polígonos, polilinhas e círculos
Os elementos Polygon
, Polyline
e Circle
permitem realçar áreas específicas em um mapa. Uma Polygon
é uma forma totalmente fechada que pode ter um traçado e uma cor de preenchimento. Uma Polyline
é uma linha que não abrange totalmente uma área. Uma Circle
destaca uma área circular do mapa:
As classes Polygon
, Polyline
e Circle
derivam da classe MapElement
, que expõe as seguintes propriedades associáveis:
StrokeColor
é um objeto Color que determina a cor da linha.StrokeWidth
é um objetofloat
que determina a largura da linha.
A classe Polygon
define uma propriedade associável adicional:
FillColor
é um objeto Color que determina a cor da tela de fundo do polígono.
Além disso, as classes Polygon
e Polyline
definem uma propriedade GeoPath
, que é uma lista de objetos Location
que especificam os pontos da forma.
A classe Circle
define as seguintes propriedades associáveis:
Center
é um objetoLocation
que define o centro do círculo, em latitude e longitude.Radius
é um objetoDistance
que define o raio do círculo em metros, quilômetros ou milhas.FillColor
é uma propriedade Color que determina a cor dentro do perímetro do círculo.
Criar um polígono
Um objeto Polygon
pode ser adicionado a um mapa instanciando-o e adicionando-o à coleção MapElements
do mapa:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Polygon StrokeColor="#FF9900"
StrokeWidth="8"
FillColor="#88FF9900">
<maps:Polygon.Geopath>
<sensors:Location>
<x:Arguments>
<x:Double>47.6458676</x:Double>
<x:Double>-122.1356007</x:Double>
</x:Arguments>
</sensors:Location>
<sensors:Location>
<x:Arguments>
<x:Double>47.6458097</x:Double>
<x:Double>-122.142789</x:Double>
</x:Arguments>
</sensors:Location>
...
</maps:Polygon.Geopath>
</maps:Polygon>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Este é o código C# equivalente:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map();
// Instantiate a polygon
Polygon polygon = new Polygon
{
StrokeWidth = 8,
StrokeColor = Color.FromArgb("#1BA1E2"),
FillColor = Color.FromArgb("#881BA1E2"),
Geopath =
{
new Location(47.6368678, -122.137305),
new Location(47.6368894, -122.134655),
...
}
};
// Add the polygon to the map's MapElements collection
map.MapElements.Add(polygon);
As propriedades StrokeColor
e StrokeWidth
são especificadas para definir o contorno do polígono. Neste exemplo, o valor da propriedade FillColor
corresponde ao valor da propriedade StrokeColor
, mas tem um valor alfa especificado para torná-lo transparente, permitindo que o mapa subjacente fique visível através da forma. A propriedade GeoPath
contém uma lista de objetos Location
que definem as coordenadas geográficas dos pontos de polígono. Um objeto Polygon
é renderizado no mapa depois de ter sido adicionado à coleção MapElements
do Map.
Observação
Um Polygon
é uma forma totalmente fechada. O primeiro e o último pontos serão automaticamente conectados se não corresponderem.
Criar uma polilinha
Um objeto Polyline
pode ser adicionado a um mapa instanciando-o e adicionando-o à coleção MapElements
do mapa:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Polyline StrokeColor="Black"
StrokeWidth="12">
<maps:Polyline.Geopath>
<sensors:Location>
<x:Arguments>
<x:Double>47.6381401</x:Double>
<x:Double>-122.1317367</x:Double>
</x:Arguments>
</sensors:Location>
<sensors:Location>
<x:Arguments>
<x:Double>47.6381473</x:Double>
<x:Double>-122.1350841</x:Double>
</x:Arguments>
</sensors:Location>
...
</maps:Polyline.Geopath>
</maps:Polyline>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Este é o código C# equivalente:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
...
Map map = new Map();
// instantiate a polyline
Polyline polyline = new Polyline
{
StrokeColor = Colors.Blue,
StrokeWidth = 12,
Geopath =
{
new Location(47.6381401, -122.1317367),
new Location(47.6381473, -122.1350841),
...
}
};
// Add the Polyline to the map's MapElements collection
map.MapElements.Add(polyline);
As propriedades StrokeColor
e StrokeWidth
são especificadas para definir a aparência da linha. A propriedade GeoPath
contém uma lista de objetos Location
que definem as coordenadas geográficas dos pontos de polilinha. Um objeto Polyline
é renderizado no mapa depois de ter sido adicionado à coleção MapElements
do Map.
Criar um círculo
Um objeto Circle
pode ser adicionado a um mapa instanciando-o e adicionando-o à coleção MapElements
do mapa:
<ContentPage ...
xmlns:maps="http://schemas.microsoft.com/dotnet/2021/maui/maps"
xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials">
<maps:Map>
<maps:Map.MapElements>
<maps:Circle StrokeColor="#88FF0000"
StrokeWidth="8"
FillColor="#88FFC0CB">
<maps:Circle.Center>
<sensors:Location>
<x:Arguments>
<x:Double>37.79752</x:Double>
<x:Double>-122.40183</x:Double>
</x:Arguments>
</sensors:Location>
</maps:Circle.Center>
<maps:Circle.Radius>
<maps:Distance>
<x:Arguments>
<x:Double>250</x:Double>
</x:Arguments>
</maps:Distance>
</maps:Circle.Radius>
</maps:Circle>
</maps:Map.MapElements>
</maps:Map>
</ContentPage>
Este é o código C# equivalente:
using Microsoft.Maui.Controls.Maps;
using Microsoft.Maui.Maps;
using Map = Microsoft.Maui.Controls.Maps.Map;
Map map = new Map();
// Instantiate a Circle
Circle circle = new Circle
{
Center = new Location(37.79752, -122.40183),
Radius = new Distance(250),
StrokeColor = Color.FromArgb("#88FF0000"),
StrokeWidth = 8,
FillColor = Color.FromArgb("#88FFC0CB")
};
// Add the Circle to the map's MapElements collection
map.MapElements.Add(circle);
A localização do Circle
no Mapa é determinada pelo valor das propriedades Center
e Radius
. A propriedade Center
define o centro do círculo em latitude e longitude, enquanto a propriedade Radius
define o raio do círculo em metros. As propriedades StrokeColor
e StrokeWidth
são especificadas para definir o contorno do círculo. O valor da propriedade FillColor
especifica a cor dentro do perímetro do círculo. Neste exemplo, ambos os valores de cor especificam um canal alfa, permitindo que o mapa subjacente fique visível através do círculo. O objeto Circle
é renderizado no mapa depois de ter sido adicionado à coleção MapElements
do Map.
Observação
A classe GeographyUtils
tem um método de extensão ToCircumferencePositions
que converte um objeto Circle
(que define os valores de propriedade Center
e Radius
) em uma lista de objetos Location
que compõem as coordenadas de latitude e longitude do perímetro do círculo.
Geocodificação e geolocalização
A classe Geocoding
, no namespace Microsoft.Maui.Devices.Sensors
, pode ser usada para codificar geograficamente uma marca de lugar para coordenadas posicionais e reverter coordenadas de código geográfico em uma marca de lugar. Para obter mais informações, confira Codificação geográfica.
A classe Geolocation
, no namespace Microsoft.Maui.Devices.Sensors
, fornece APIs para recuperar as coordenadas de geolocalização atuais do dispositivo. Para obter mais informações, confira Geolocalização.
Iniciar o aplicativo de mapa nativo
O aplicativo de mapa nativo em cada plataforma pode ser iniciado a partir de um aplicativo do .NET MAUI pela classe Launcher
. Essa classe permite que um aplicativo abra outro aplicativo por meio do respectivo esquema de URI personalizado. A funcionalidade do iniciador pode ser invocada com o método OpenAsync
, passando um argumento string
ou Uri
que representa o esquema de URL personalizado a ser aberto. Para obter mais informações sobre a classe Launcher
, consulte Launcher.
Observação
Uma alternativa ao uso da classe Launcher
é usar a classe Map do namespace Microsoft.Maui.ApplicationModel
. Para obter mais informações, confira Mapa.
O aplicativo de mapas em cada plataforma usa um esquema de URI personalizado exclusivo. Para obter informações sobre o esquema de URI de mapas no iOS, consulte Links de mapa em developer.apple.com. Para obter informações sobre o esquema de URI do Google Maps no Android, consulte o Guia do desenvolvedor do Google Maps e Intenções do Google Maps para Android em developers.android.com. Para obter informações sobre o esquema de URI de mapas no Windows, consulte Iniciar o aplicativo Mapas do Windows.
Iniciar o aplicativo de mapa em uma localização específica
Uma localização no aplicativo de mapas nativo pode ser aberta adicionando parâmetros de consulta apropriados ao esquema de URI personalizado para cada aplicativo de mapa:
if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
// https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
await Launcher.OpenAsync("http://maps.apple.com/?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
// opens the Maps app directly
await Launcher.OpenAsync("geo:0,0?q=394+Pacific+Ave+San+Francisco+CA");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
await Launcher.OpenAsync("bingmaps:?where=394 Pacific Ave San Francisco CA");
}
Este código de exemplo resulta no aplicativo de mapa nativo sendo iniciado em cada plataforma, com o mapa centralizado em um alfinete representando a localização especificada.
Iniciar o aplicativo de mapa com direções
O aplicativo de mapas nativos pode ser iniciado exibindo direções, adicionando parâmetros de consulta apropriados ao esquema de URI personalizado para cada aplicativo de mapa:
if (DeviceInfo.Current.Platform == DevicePlatform.iOS || DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
{
// https://developer.apple.com/library/ios/featuredarticles/iPhoneURLScheme_Reference/MapLinks/MapLinks.html
await Launcher.OpenAsync("http://maps.apple.com/?daddr=San+Francisco,+CA&saddr=cupertino");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.Android)
{
// opens the 'task chooser' so the user can pick Maps, Chrome or other mapping app
await Launcher.OpenAsync("http://maps.google.com/?daddr=San+Francisco,+CA&saddr=Mountain+View");
}
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
{
await Launcher.OpenAsync("bingmaps:?rtp=adr.394 Pacific Ave San Francisco CA~adr.One Microsoft Way Redmond WA 98052");
}
Este código de exemplo resulta no aplicativo de mapa nativo sendo iniciado em cada plataforma, com o mapa centralizado em uma rota entre as localizações especificadas.